Skip to content

Commit da0a893

Browse files
committed
feat: [api] revise plugin interfaces (hopefully close to 1.0 now)
1 parent 69f8d4e commit da0a893

24 files changed

+515
-140
lines changed

src/hobbits-core/batchrunner.cpp

+28-11
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,17 @@ QSharedPointer<BatchRunner> BatchRunner::create(
2727
runner->m_batch = batch;
2828
runner->m_inputContainers = inputContainers;
2929

30-
3130
for (auto step: batch->actionSteps()) {
3231
QList<QPair<QUuid, int>> trueInputs;
33-
for (auto input: step->inputs) {
34-
if (input.first.isNull()) {
35-
QUuid specialInput = QUuid::createUuid();
36-
runner->m_stepOutputs.insert(specialInput, {inputContainers.takeFirst()});
37-
trueInputs.append({specialInput, 0});
38-
}
39-
else {
40-
trueInputs.append(input);
41-
}
32+
if (step->action->pluginType() == PluginAction::NoAction) {
33+
QUuid specialInput = QUuid::createUuid();
34+
runner->m_stepOutputs.insert(specialInput, {inputContainers.takeFirst()});
35+
trueInputs.append({specialInput, 0});
36+
runner->m_trueStepInputs.insert(step, trueInputs);
37+
}
38+
else {
39+
runner->m_trueStepInputs.insert(step, step->inputs);
4240
}
43-
runner->m_trueStepInputs.insert(step, trueInputs);
4441
}
4542

4643
return runner;
@@ -92,6 +89,11 @@ void BatchRunner::checkFinishedImporter(QUuid id)
9289
}
9390
else {
9491
auto result = finished.second->watcher()->result();
92+
if (result.isNull()) {
93+
m_errorList.append("Importer step returned null");
94+
this->cancel();
95+
return;
96+
}
9597
if (!result->errorString().isEmpty()) {
9698
m_errorList.append("Importer step failed: " + result->errorString());
9799
this->cancel();
@@ -112,6 +114,11 @@ void BatchRunner::checkFinishedExporter(QUuid id)
112114
}
113115
else {
114116
auto result = finished.second->watcher()->result();
117+
if (result.isNull()) {
118+
m_errorList.append("Exporter step returned null");
119+
this->cancel();
120+
return;
121+
}
115122
if (!result->errorString().isEmpty()) {
116123
m_errorList.append("Exporter step failed: " + result->errorString());
117124
this->cancel();
@@ -132,6 +139,11 @@ void BatchRunner::checkFinishedAnalyzer(QUuid id)
132139
}
133140
else {
134141
auto result = finished.second->watcher()->result();
142+
if (result.isNull()) {
143+
m_errorList.append("Analyzer step returned null");
144+
this->cancel();
145+
return;
146+
}
135147
if (!result->errorString().isEmpty()) {
136148
m_errorList.append("Analyzer step failed: " + result->errorString());
137149
this->cancel();
@@ -152,6 +164,11 @@ void BatchRunner::checkFinishedOperator(QUuid id)
152164
}
153165
else {
154166
auto result = finished.second->watcher()->result();
167+
if (result.isNull()) {
168+
m_errorList.append("Operator step returned null");
169+
this->cancel();
170+
return;
171+
}
155172
if (!result->errorString().isEmpty()) {
156173
m_errorList.append("Operator step failed: " + result->errorString());
157174
this->cancel();

src/hobbits-core/bitinfo.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ QVariant BitInfo::metadata(QString key) const
146146
return m_metadata.value(key);
147147
}
148148

149+
QList<QString> BitInfo::metadataKeys() const
150+
{
151+
return m_metadata.keys();
152+
}
153+
149154
qint64 BitInfo::frameOffsetContaining(qint64 value, Range indexBounds) const
150155
{
151156
return m_frames->indexOf(value, indexBounds);

src/hobbits-core/bitinfo.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class HOBBITSCORESHARED_EXPORT BitInfo : public QObject
2222
Q_OBJECT
2323

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

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

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

src/hobbits-core/parameterdelegate.cpp

+24-3
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,38 @@
44

55
ParameterDelegate::ParameterDelegate(QList<ParameterDelegate::ParameterInfo> parameters,
66
std::function<QString(const QJsonObject&)> actionDescriber) :
7-
m_actionDescriber(actionDescriber)
7+
ParameterDelegate(parameters,
8+
actionDescriber,
9+
[](QSharedPointer<ParameterDelegate> delegate, QSize targetBounds){
10+
Q_UNUSED(delegate)
11+
Q_UNUSED(targetBounds)
12+
return nullptr;
13+
})
14+
{
15+
}
16+
17+
ParameterDelegate::ParameterDelegate(QList<ParameterDelegate::ParameterInfo> parameters,
18+
std::function<QString (const QJsonObject &)> actionDescriber,
19+
std::function<AbstractParameterEditor *(QSharedPointer<ParameterDelegate>, QSize)> editorCreator) :
20+
m_actionDescriber(actionDescriber),
21+
m_editorCreator(editorCreator)
822
{
923
for (auto parameter : parameters) {
1024
m_parameterMap.insert(parameter.name, parameter);
1125
}
1226
}
1327

28+
QSharedPointer<ParameterDelegate> ParameterDelegate::create(
29+
QList<ParameterDelegate::ParameterInfo> parameterInfos,
30+
std::function<QString (const QJsonObject &)> actionDescriber,
31+
std::function<AbstractParameterEditor *(QSharedPointer<ParameterDelegate>, QSize)> editorCreator)
32+
{
33+
return QSharedPointer<ParameterDelegate>(new ParameterDelegate(parameterInfos, actionDescriber, editorCreator));
34+
}
35+
1436
AbstractParameterEditor* ParameterDelegate::createEditor(QSize targetBounds)
1537
{
16-
Q_UNUSED(targetBounds)
17-
return nullptr;
38+
return m_editorCreator(sharedFromThis(), targetBounds);
1839
}
1940

2041
QList<ParameterDelegate::ParameterInfo> ParameterDelegate::parameterInfos() const

src/hobbits-core/parameterdelegate.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class AbstractParameterEditor;
2424
* expected to provide a ParameterDelegate.
2525
*
2626
*/
27-
class HOBBITSCORESHARED_EXPORT ParameterDelegate
27+
class HOBBITSCORESHARED_EXPORT ParameterDelegate : public QEnableSharedFromThis<ParameterDelegate>
2828
{
2929
public:
3030
struct ParameterInfo
@@ -42,8 +42,16 @@ class HOBBITSCORESHARED_EXPORT ParameterDelegate
4242
};
4343

4444
ParameterDelegate(QList<ParameterInfo> parameterInfos, std::function<QString(const QJsonObject&)> actionDescriber);
45+
ParameterDelegate(QList<ParameterInfo> parameterInfos,
46+
std::function<QString(const QJsonObject&)> actionDescriber,
47+
std::function<AbstractParameterEditor*(QSharedPointer<ParameterDelegate>, QSize)> editorCreator);
4548
virtual ~ParameterDelegate() = default;
4649

50+
static QSharedPointer<ParameterDelegate> create(
51+
QList<ParameterInfo> parameterInfos,
52+
std::function<QString(const QJsonObject&)> actionDescriber,
53+
std::function<AbstractParameterEditor*(QSharedPointer<ParameterDelegate>, QSize)> editorCreator);
54+
4755
virtual AbstractParameterEditor* createEditor(QSize targetBounds = QSize());
4856

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

6170
#endif // PLUGINSTATEDELEGATE_H

src/hobbits-core/pluginaction.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ PluginAction::PluginAction(PluginType pluginType, QString pluginName, QJsonObjec
1313

1414
}
1515

16+
QSharedPointer<PluginAction> PluginAction::createAction(PluginAction::PluginType pluginType, QString pluginName, QJsonObject pluginState)
17+
{
18+
return QSharedPointer<PluginAction>(new PluginAction(pluginType, pluginName, pluginState));
19+
}
20+
1621
QSharedPointer<PluginAction> PluginAction::analyzerAction(QString pluginName, QJsonObject pluginState)
1722
{
1823
return QSharedPointer<PluginAction>(new PluginAction(PluginAction::Analyzer, pluginName, pluginState));

src/hobbits-core/pluginaction.h

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class HOBBITSCORESHARED_EXPORT PluginAction
3535

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

38+
static QSharedPointer<PluginAction> createAction(PluginType pluginType, QString pluginName, QJsonObject pluginState);
3839
static QSharedPointer<PluginAction> analyzerAction(QString pluginName, QJsonObject pluginState);
3940
static QSharedPointer<PluginAction> operatorAction(QString pluginName, QJsonObject pluginState);
4041
static QSharedPointer<PluginAction> importerAction(QString pluginName, QJsonObject pluginState = QJsonObject());

src/hobbits-core/pluginactionbatch.cpp

+40-35
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ QSharedPointer<PluginActionBatch> PluginActionBatch::fromLineage(QSharedPointer<
1616
QQueue<QPair<QSharedPointer<const PluginActionLineage>, int>> lineageQueue;
1717
QQueue<QSharedPointer<const PluginActionLineage>> stageTwoQueue;
1818

19+
auto firstLineage = lineage;
20+
while (firstLineage->getPluginAction()->pluginType() == PluginAction::Analyzer) {
21+
auto input = firstLineage->getInputs().at(0);
22+
if (input->getPluginAction()->pluginType() == PluginAction::Analyzer) {
23+
lineageQueue.enqueue({input, (Mode::Inclusive | (batchMode & Mode::IncludeImportersFull))});
24+
}
25+
firstLineage = input;
26+
}
27+
1928
lineageQueue.enqueue({lineage, batchMode});
2029
while (!lineageQueue.isEmpty()) {
2130
auto lineageModePair = lineageQueue.dequeue();
@@ -86,10 +95,9 @@ QSharedPointer<PluginActionBatch> PluginActionBatch::fromLineage(QSharedPointer<
8695
}
8796
alreadyAssigned.insert(currLineage->getPluginAction());
8897

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

@@ -103,15 +111,21 @@ QSharedPointer<PluginActionBatch> PluginActionBatch::fromLineage(QSharedPointer<
103111
inputs.append({stepMap.value(input->getPluginAction())->stepId, input->getOutputPosition()});
104112
}
105113
else {
106-
inputs.append({QUuid(), 0});
114+
auto anonymousInput = PluginAction::noAction();
115+
auto step = createStep(QUuid::createUuid(), anonymousInput);
116+
stepMap.insert(anonymousInput, step);
117+
inputs.append({step->stepId, 0});
107118
}
108119
}
109120
stepMap[currLineage->getPluginAction()]->inputs = inputs;
110121
}
111122

112123

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

@@ -145,6 +159,12 @@ QJsonObject PluginActionBatch::serialize() const
145159
stepInputs.append(inputObject);
146160
}
147161
stepObject.insert("inputs", stepInputs);
162+
163+
QJsonObject stepPos;
164+
stepPos.insert("x", step->editorPosition.x());
165+
stepPos.insert("y", step->editorPosition.y());
166+
stepObject.insert("editorPosition", stepPos);
167+
148168
steps.append(stepObject);
149169
}
150170
obj.insert("steps", steps);
@@ -162,6 +182,7 @@ QSharedPointer<PluginActionBatch> PluginActionBatch::deserialize(QJsonObject dat
162182

163183
QSharedPointer<PluginActionBatch> deserialized;
164184
QList<QSharedPointer<ActionStep>> steps;
185+
int stepCount = 0;
165186
for (auto step : data.value("steps").toArray()) {
166187
if (!step.isObject()) {
167188
return nullBatch;
@@ -206,6 +227,19 @@ QSharedPointer<PluginActionBatch> PluginActionBatch::deserialize(QJsonObject dat
206227
deserializedStep->inputs.append({inputId, outputPosition});
207228
}
208229
}
230+
231+
bool posSet = false;
232+
if (stepObject.contains("editorPosition") && stepObject.value("editorPosition").isObject()) {
233+
QJsonObject posObj = stepObject.value("editorPosition").toObject();
234+
if (posObj.contains("x") && posObj.contains("y")) {
235+
deserializedStep->editorPosition = QPointF(posObj.value("x").toDouble(), posObj.value("y").toDouble());
236+
posSet = true;
237+
}
238+
}
239+
if (!posSet) {
240+
deserializedStep->editorPosition = QPointF(300 * (stepCount % 4), 200 * (stepCount / 4));
241+
}
242+
stepCount++;
209243
}
210244

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

219-
int PluginActionBatch::getMinRequiredInputs(QSharedPointer<const HobbitsPluginManager> pluginManager) const
253+
int PluginActionBatch::getRequiredInputs() const
220254
{
221255
int inputTotal = 0;
222256
for (auto step : m_actionSteps) {
223257
if (step->action->pluginType() == PluginAction::NoAction) {
224-
inputTotal += 1;
225-
continue;
226-
}
227-
int actionInputs = step->action->minPossibleInputs(pluginManager);
228-
int internalInputs = 0;
229-
for (auto input : step->inputs) {
230-
if (!input.first.isNull()) {
231-
internalInputs++;
232-
}
233-
}
234-
if (actionInputs > internalInputs) {
235-
inputTotal += actionInputs - internalInputs;
236-
}
237-
}
238-
return inputTotal;
239-
}
240-
241-
int PluginActionBatch::getMaxPossibleInputs(QSharedPointer<const HobbitsPluginManager> pluginManager) const
242-
{
243-
int inputTotal = 0;
244-
for (auto step : m_actionSteps) {
245-
int actionInputs = step->action->maxPossibleInputs(pluginManager);
246-
int internalInputs = 0;
247-
for (auto input : step->inputs) {
248-
if (!input.first.isNull()) {
249-
internalInputs++;
250-
}
251-
}
252-
if (actionInputs > internalInputs) {
253-
inputTotal += actionInputs - internalInputs;
258+
inputTotal ++;
254259
}
255260
}
256261
return inputTotal;

src/hobbits-core/pluginactionbatch.h

+7-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "bitcontainer.h"
55
#include "hobbits-core_global.h"
66
#include "pluginactionlineage.h"
7+
#include <QPointF>
78

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

32-
static QSharedPointer<PluginActionBatch> fromLineage(QSharedPointer<const PluginActionLineage> lineage, int batchMode);
33-
3433
class ActionStep {
3534
public:
3635
ActionStep(QUuid id, QSharedPointer<const PluginAction> action) :
@@ -40,20 +39,23 @@ class HOBBITSCORESHARED_EXPORT PluginActionBatch : public QEnableSharedFromThis<
4039
QUuid stepId;
4140
QSharedPointer<const PluginAction> action;
4241
QList<QPair<QUuid, int>> inputs;
42+
QPointF editorPosition;
4343
};
4444

45+
PluginActionBatch(QList<QSharedPointer<const ActionStep>> actionSteps);
46+
static QSharedPointer<PluginActionBatch> fromLineage(QSharedPointer<const PluginActionLineage> lineage, int batchMode);
47+
48+
4549
static QSharedPointer<ActionStep> createStep(QUuid id, QSharedPointer<const PluginAction> action);
4650

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

50-
int getMinRequiredInputs(QSharedPointer<const HobbitsPluginManager> pluginManager) const;
51-
int getMaxPossibleInputs(QSharedPointer<const HobbitsPluginManager> pluginManager) const;
54+
int getRequiredInputs() const;
5255

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

5558
private:
56-
PluginActionBatch(QList<QSharedPointer<const ActionStep>> actionSteps);
5759
QList<QSharedPointer<const ActionStep>> m_actionSteps;
5860
};
5961

src/hobbits-core/pluginactionlineage.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ void PluginActionLineage::recordLineage(
3232
outputGroup.append(lineage.toWeakRef());
3333
}
3434

35+
// if input container is output container (analyzer), don't add output group
36+
if (inputContainers.size() == 1
37+
&& outputContainers.size() == 1
38+
&& inputContainers.at(0) == outputContainers.at(0)) {
39+
return;
40+
}
41+
3542
for (auto input: inputContainers) {
3643
input->actionLineage()->addOutputGroup(outputGroup);
3744
}

0 commit comments

Comments
 (0)