Skip to content

Commit

Permalink
feat: [api] revise plugin interfaces (hopefully close to 1.0 now)
Browse files Browse the repository at this point in the history
  • Loading branch information
hello-adam committed Oct 22, 2020
1 parent 69f8d4e commit da0a893
Show file tree
Hide file tree
Showing 24 changed files with 515 additions and 140 deletions.
39 changes: 28 additions & 11 deletions src/hobbits-core/batchrunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,17 @@ QSharedPointer<BatchRunner> BatchRunner::create(
runner->m_batch = batch;
runner->m_inputContainers = inputContainers;


for (auto step: batch->actionSteps()) {
QList<QPair<QUuid, int>> trueInputs;
for (auto input: step->inputs) {
if (input.first.isNull()) {
QUuid specialInput = QUuid::createUuid();
runner->m_stepOutputs.insert(specialInput, {inputContainers.takeFirst()});
trueInputs.append({specialInput, 0});
}
else {
trueInputs.append(input);
}
if (step->action->pluginType() == PluginAction::NoAction) {
QUuid specialInput = QUuid::createUuid();
runner->m_stepOutputs.insert(specialInput, {inputContainers.takeFirst()});
trueInputs.append({specialInput, 0});
runner->m_trueStepInputs.insert(step, trueInputs);
}
else {
runner->m_trueStepInputs.insert(step, step->inputs);
}
runner->m_trueStepInputs.insert(step, trueInputs);
}

return runner;
Expand Down Expand Up @@ -92,6 +89,11 @@ void BatchRunner::checkFinishedImporter(QUuid id)
}
else {
auto result = finished.second->watcher()->result();
if (result.isNull()) {
m_errorList.append("Importer step returned null");
this->cancel();
return;
}
if (!result->errorString().isEmpty()) {
m_errorList.append("Importer step failed: " + result->errorString());
this->cancel();
Expand All @@ -112,6 +114,11 @@ void BatchRunner::checkFinishedExporter(QUuid id)
}
else {
auto result = finished.second->watcher()->result();
if (result.isNull()) {
m_errorList.append("Exporter step returned null");
this->cancel();
return;
}
if (!result->errorString().isEmpty()) {
m_errorList.append("Exporter step failed: " + result->errorString());
this->cancel();
Expand All @@ -132,6 +139,11 @@ void BatchRunner::checkFinishedAnalyzer(QUuid id)
}
else {
auto result = finished.second->watcher()->result();
if (result.isNull()) {
m_errorList.append("Analyzer step returned null");
this->cancel();
return;
}
if (!result->errorString().isEmpty()) {
m_errorList.append("Analyzer step failed: " + result->errorString());
this->cancel();
Expand All @@ -152,6 +164,11 @@ void BatchRunner::checkFinishedOperator(QUuid id)
}
else {
auto result = finished.second->watcher()->result();
if (result.isNull()) {
m_errorList.append("Operator step returned null");
this->cancel();
return;
}
if (!result->errorString().isEmpty()) {
m_errorList.append("Operator step failed: " + result->errorString());
this->cancel();
Expand Down
5 changes: 5 additions & 0 deletions src/hobbits-core/bitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ QVariant BitInfo::metadata(QString key) const
return m_metadata.value(key);
}

QList<QString> BitInfo::metadataKeys() const
{
return m_metadata.keys();
}

qint64 BitInfo::frameOffsetContaining(qint64 value, Range indexBounds) const
{
return m_frames->indexOf(value, indexBounds);
Expand Down
3 changes: 2 additions & 1 deletion src/hobbits-core/bitinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class HOBBITSCORESHARED_EXPORT BitInfo : public QObject
Q_OBJECT

public:
static QSharedPointer<BitInfo> create(qint64 bitLength, QSharedPointer<const BitInfo> other = QSharedPointer<const BitInfo>(), bool clearFrames = false);
static QSharedPointer<BitInfo> create(qint64 bitLength = 0, QSharedPointer<const BitInfo> other = QSharedPointer<const BitInfo>(), bool clearFrames = false);
static QSharedPointer<BitInfo> copyFromContainer(QSharedPointer<const BitContainer> container, bool clearFrames = false);

void setFrames(QSharedPointer<const RangeSequence> frames);
Expand All @@ -39,6 +39,7 @@ class HOBBITSCORESHARED_EXPORT BitInfo : public QObject
QList<QString> highlightCategories() const;
bool containsHighlightCategory(QString category) const;
QVariant metadata(QString key) const;
QList<QString> metadataKeys() const;

qint64 frameOffsetContaining(qint64 value, Range indexBounds = Range()) const;

Expand Down
27 changes: 24 additions & 3 deletions src/hobbits-core/parameterdelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,38 @@

ParameterDelegate::ParameterDelegate(QList<ParameterDelegate::ParameterInfo> parameters,
std::function<QString(const QJsonObject&)> actionDescriber) :
m_actionDescriber(actionDescriber)
ParameterDelegate(parameters,
actionDescriber,
[](QSharedPointer<ParameterDelegate> delegate, QSize targetBounds){
Q_UNUSED(delegate)
Q_UNUSED(targetBounds)
return nullptr;
})
{
}

ParameterDelegate::ParameterDelegate(QList<ParameterDelegate::ParameterInfo> parameters,
std::function<QString (const QJsonObject &)> actionDescriber,
std::function<AbstractParameterEditor *(QSharedPointer<ParameterDelegate>, QSize)> editorCreator) :
m_actionDescriber(actionDescriber),
m_editorCreator(editorCreator)
{
for (auto parameter : parameters) {
m_parameterMap.insert(parameter.name, parameter);
}
}

QSharedPointer<ParameterDelegate> ParameterDelegate::create(
QList<ParameterDelegate::ParameterInfo> parameterInfos,
std::function<QString (const QJsonObject &)> actionDescriber,
std::function<AbstractParameterEditor *(QSharedPointer<ParameterDelegate>, QSize)> editorCreator)
{
return QSharedPointer<ParameterDelegate>(new ParameterDelegate(parameterInfos, actionDescriber, editorCreator));
}

AbstractParameterEditor* ParameterDelegate::createEditor(QSize targetBounds)
{
Q_UNUSED(targetBounds)
return nullptr;
return m_editorCreator(sharedFromThis(), targetBounds);
}

QList<ParameterDelegate::ParameterInfo> ParameterDelegate::parameterInfos() const
Expand Down
11 changes: 10 additions & 1 deletion src/hobbits-core/parameterdelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class AbstractParameterEditor;
* expected to provide a ParameterDelegate.
*
*/
class HOBBITSCORESHARED_EXPORT ParameterDelegate
class HOBBITSCORESHARED_EXPORT ParameterDelegate : public QEnableSharedFromThis<ParameterDelegate>
{
public:
struct ParameterInfo
Expand All @@ -42,8 +42,16 @@ class HOBBITSCORESHARED_EXPORT ParameterDelegate
};

ParameterDelegate(QList<ParameterInfo> parameterInfos, std::function<QString(const QJsonObject&)> actionDescriber);
ParameterDelegate(QList<ParameterInfo> parameterInfos,
std::function<QString(const QJsonObject&)> actionDescriber,
std::function<AbstractParameterEditor*(QSharedPointer<ParameterDelegate>, QSize)> editorCreator);
virtual ~ParameterDelegate() = default;

static QSharedPointer<ParameterDelegate> create(
QList<ParameterInfo> parameterInfos,
std::function<QString(const QJsonObject&)> actionDescriber,
std::function<AbstractParameterEditor*(QSharedPointer<ParameterDelegate>, QSize)> editorCreator);

virtual AbstractParameterEditor* createEditor(QSize targetBounds = QSize());

QList<ParameterInfo> parameterInfos() const;
Expand All @@ -56,6 +64,7 @@ class HOBBITSCORESHARED_EXPORT ParameterDelegate
static bool validateAgainstInfos(const QJsonObject &parameters, QList<ParameterInfo> infos);
QMap<QString, ParameterInfo> m_parameterMap;
std::function<QString(const QJsonObject&)> m_actionDescriber;
std::function<AbstractParameterEditor*(QSharedPointer<ParameterDelegate>, QSize)> m_editorCreator;
};

#endif // PLUGINSTATEDELEGATE_H
5 changes: 5 additions & 0 deletions src/hobbits-core/pluginaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ PluginAction::PluginAction(PluginType pluginType, QString pluginName, QJsonObjec

}

QSharedPointer<PluginAction> PluginAction::createAction(PluginAction::PluginType pluginType, QString pluginName, QJsonObject pluginState)
{
return QSharedPointer<PluginAction>(new PluginAction(pluginType, pluginName, pluginState));
}

QSharedPointer<PluginAction> PluginAction::analyzerAction(QString pluginName, QJsonObject pluginState)
{
return QSharedPointer<PluginAction>(new PluginAction(PluginAction::Analyzer, pluginName, pluginState));
Expand Down
1 change: 1 addition & 0 deletions src/hobbits-core/pluginaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class HOBBITSCORESHARED_EXPORT PluginAction

PluginAction(PluginType pluginType, QString pluginName, QJsonObject pluginState);

static QSharedPointer<PluginAction> createAction(PluginType pluginType, QString pluginName, QJsonObject pluginState);
static QSharedPointer<PluginAction> analyzerAction(QString pluginName, QJsonObject pluginState);
static QSharedPointer<PluginAction> operatorAction(QString pluginName, QJsonObject pluginState);
static QSharedPointer<PluginAction> importerAction(QString pluginName, QJsonObject pluginState = QJsonObject());
Expand Down
75 changes: 40 additions & 35 deletions src/hobbits-core/pluginactionbatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ QSharedPointer<PluginActionBatch> PluginActionBatch::fromLineage(QSharedPointer<
QQueue<QPair<QSharedPointer<const PluginActionLineage>, int>> lineageQueue;
QQueue<QSharedPointer<const PluginActionLineage>> stageTwoQueue;

auto firstLineage = lineage;
while (firstLineage->getPluginAction()->pluginType() == PluginAction::Analyzer) {
auto input = firstLineage->getInputs().at(0);
if (input->getPluginAction()->pluginType() == PluginAction::Analyzer) {
lineageQueue.enqueue({input, (Mode::Inclusive | (batchMode & Mode::IncludeImportersFull))});
}
firstLineage = input;
}

lineageQueue.enqueue({lineage, batchMode});
while (!lineageQueue.isEmpty()) {
auto lineageModePair = lineageQueue.dequeue();
Expand Down Expand Up @@ -86,10 +95,9 @@ QSharedPointer<PluginActionBatch> PluginActionBatch::fromLineage(QSharedPointer<
}
alreadyAssigned.insert(currLineage->getPluginAction());

// If it's a "no action" step, it will get a null QUuid input
// If it's a "no action" step (anonymous input), it doesn't have inputs
if (stepMap[currLineage->getPluginAction()]->action->pluginType() == PluginAction::NoAction) {
// TODO: what if there's a "no action" that isn't in the beginning?
stepMap[currLineage->getPluginAction()]->inputs = {{QUuid(), 0}};
stepMap[currLineage->getPluginAction()]->inputs = {};
continue;
}

Expand All @@ -103,15 +111,21 @@ QSharedPointer<PluginActionBatch> PluginActionBatch::fromLineage(QSharedPointer<
inputs.append({stepMap.value(input->getPluginAction())->stepId, input->getOutputPosition()});
}
else {
inputs.append({QUuid(), 0});
auto anonymousInput = PluginAction::noAction();
auto step = createStep(QUuid::createUuid(), anonymousInput);
stepMap.insert(anonymousInput, step);
inputs.append({step->stepId, 0});
}
}
stepMap[currLineage->getPluginAction()]->inputs = inputs;
}


QList<QSharedPointer<const ActionStep>> constSteps;
int stepCount = 0;
for (auto step: stepMap.values()) {
step->editorPosition = QPointF(300 * (stepCount % 4), 200 * (stepCount / 4));
stepCount++;
constSteps.append(step);
}

Expand Down Expand Up @@ -145,6 +159,12 @@ QJsonObject PluginActionBatch::serialize() const
stepInputs.append(inputObject);
}
stepObject.insert("inputs", stepInputs);

QJsonObject stepPos;
stepPos.insert("x", step->editorPosition.x());
stepPos.insert("y", step->editorPosition.y());
stepObject.insert("editorPosition", stepPos);

steps.append(stepObject);
}
obj.insert("steps", steps);
Expand All @@ -162,6 +182,7 @@ QSharedPointer<PluginActionBatch> PluginActionBatch::deserialize(QJsonObject dat

QSharedPointer<PluginActionBatch> deserialized;
QList<QSharedPointer<ActionStep>> steps;
int stepCount = 0;
for (auto step : data.value("steps").toArray()) {
if (!step.isObject()) {
return nullBatch;
Expand Down Expand Up @@ -206,6 +227,19 @@ QSharedPointer<PluginActionBatch> PluginActionBatch::deserialize(QJsonObject dat
deserializedStep->inputs.append({inputId, outputPosition});
}
}

bool posSet = false;
if (stepObject.contains("editorPosition") && stepObject.value("editorPosition").isObject()) {
QJsonObject posObj = stepObject.value("editorPosition").toObject();
if (posObj.contains("x") && posObj.contains("y")) {
deserializedStep->editorPosition = QPointF(posObj.value("x").toDouble(), posObj.value("y").toDouble());
posSet = true;
}
}
if (!posSet) {
deserializedStep->editorPosition = QPointF(300 * (stepCount % 4), 200 * (stepCount / 4));
}
stepCount++;
}

QList<QSharedPointer<const ActionStep>> constSteps;
Expand All @@ -216,41 +250,12 @@ QSharedPointer<PluginActionBatch> PluginActionBatch::deserialize(QJsonObject dat
return QSharedPointer<PluginActionBatch>(new PluginActionBatch(constSteps));
}

int PluginActionBatch::getMinRequiredInputs(QSharedPointer<const HobbitsPluginManager> pluginManager) const
int PluginActionBatch::getRequiredInputs() const
{
int inputTotal = 0;
for (auto step : m_actionSteps) {
if (step->action->pluginType() == PluginAction::NoAction) {
inputTotal += 1;
continue;
}
int actionInputs = step->action->minPossibleInputs(pluginManager);
int internalInputs = 0;
for (auto input : step->inputs) {
if (!input.first.isNull()) {
internalInputs++;
}
}
if (actionInputs > internalInputs) {
inputTotal += actionInputs - internalInputs;
}
}
return inputTotal;
}

int PluginActionBatch::getMaxPossibleInputs(QSharedPointer<const HobbitsPluginManager> pluginManager) const
{
int inputTotal = 0;
for (auto step : m_actionSteps) {
int actionInputs = step->action->maxPossibleInputs(pluginManager);
int internalInputs = 0;
for (auto input : step->inputs) {
if (!input.first.isNull()) {
internalInputs++;
}
}
if (actionInputs > internalInputs) {
inputTotal += actionInputs - internalInputs;
inputTotal ++;
}
}
return inputTotal;
Expand Down
12 changes: 7 additions & 5 deletions src/hobbits-core/pluginactionbatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "bitcontainer.h"
#include "hobbits-core_global.h"
#include "pluginactionlineage.h"
#include <QPointF>

/**
* @brief The PluginActionBatch class describes a (possibly branching or merging) sequence of plugin actions
Expand All @@ -29,8 +30,6 @@ class HOBBITSCORESHARED_EXPORT PluginActionBatch : public QEnableSharedFromThis<
ActionModeSegment = 0xf0
};

static QSharedPointer<PluginActionBatch> fromLineage(QSharedPointer<const PluginActionLineage> lineage, int batchMode);

class ActionStep {
public:
ActionStep(QUuid id, QSharedPointer<const PluginAction> action) :
Expand All @@ -40,20 +39,23 @@ class HOBBITSCORESHARED_EXPORT PluginActionBatch : public QEnableSharedFromThis<
QUuid stepId;
QSharedPointer<const PluginAction> action;
QList<QPair<QUuid, int>> inputs;
QPointF editorPosition;
};

PluginActionBatch(QList<QSharedPointer<const ActionStep>> actionSteps);
static QSharedPointer<PluginActionBatch> fromLineage(QSharedPointer<const PluginActionLineage> lineage, int batchMode);


static QSharedPointer<ActionStep> createStep(QUuid id, QSharedPointer<const PluginAction> action);

QJsonObject serialize() const;
static QSharedPointer<PluginActionBatch> deserialize(QJsonObject data);

int getMinRequiredInputs(QSharedPointer<const HobbitsPluginManager> pluginManager) const;
int getMaxPossibleInputs(QSharedPointer<const HobbitsPluginManager> pluginManager) const;
int getRequiredInputs() const;

QList<QSharedPointer<const ActionStep>> actionSteps() const;

private:
PluginActionBatch(QList<QSharedPointer<const ActionStep>> actionSteps);
QList<QSharedPointer<const ActionStep>> m_actionSteps;
};

Expand Down
7 changes: 7 additions & 0 deletions src/hobbits-core/pluginactionlineage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ void PluginActionLineage::recordLineage(
outputGroup.append(lineage.toWeakRef());
}

// if input container is output container (analyzer), don't add output group
if (inputContainers.size() == 1
&& outputContainers.size() == 1
&& inputContainers.at(0) == outputContainers.at(0)) {
return;
}

for (auto input: inputContainers) {
input->actionLineage()->addOutputGroup(outputGroup);
}
Expand Down
Loading

0 comments on commit da0a893

Please sign in to comment.