Skip to content

Commit

Permalink
feat: embed python into hobbits with a limited API for #23
Browse files Browse the repository at this point in the history
There's still a lot of API expansion possible on the Python side, but the current embedded capabilities superset the previous system python integration and are a decent starting point for as-needed expansion.
  • Loading branch information
hello-adam committed Aug 20, 2020
1 parent a552e64 commit 2f4ef03
Show file tree
Hide file tree
Showing 26 changed files with 781 additions and 29 deletions.
2 changes: 2 additions & 0 deletions src/hobbits-core/bitcontainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "settingsmanager.h"
#include <QBuffer>
#include <QDebug>
#include <QColor>
#include <QPixmap>

BitContainer::BitContainer(QObject *parent) :
QObject(parent),
Expand Down
6 changes: 3 additions & 3 deletions src/hobbits-core/bitcontainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,9 @@

#include "frame.h"

#include <QBitArray>
#include <QColor>
#include <QJsonDocument>
#include <QMap>
#include <QObject>
#include <QPixmap>
#include <QSharedPointer>
#include <QUuid>
#include "bitinfo.h"
Expand All @@ -18,6 +15,9 @@
class PluginActionLineage;
class PluginAction;

class QColor;
class QPixmap;

class HOBBITSCORESHARED_EXPORT BitContainer : public QObject
{
Q_OBJECT
Expand Down
1 change: 1 addition & 0 deletions src/hobbits-core/bitcontainerlistmodel.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "bitcontainerlistmodel.h"
#include "displayhelper.h"
#include <QPixmap>

BitContainerListModel::BitContainerListModel(QObject *parent) :
QAbstractListModel(parent)
Expand Down
1 change: 1 addition & 0 deletions src/hobbits-core/bitcontainertreemodel.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "bitcontainertreemodel.h"
#include "displayhelper.h"
#include <QPixmap>

BitContainerTreeModel::BitContainerTreeModel(QObject *parent) :
QAbstractItemModel(parent)
Expand Down
8 changes: 8 additions & 0 deletions src/hobbits-core/bitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ void BitInfo::setFrames(QVector<Range> frames)
initFrames();
}

void BitInfo::setFramesFromInfo(QSharedPointer<BitInfo> frameSource)
{
m_mutex.lock();
m_ranges = frameSource->m_ranges;
m_mutex.unlock();
initFrames();
}

qint64 BitInfo::maxFrameWidth() const
{
return m_maxFrameWidth;
Expand Down
1 change: 1 addition & 0 deletions src/hobbits-core/bitinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class HOBBITSCORESHARED_EXPORT BitInfo : public QObject

void setBits(QSharedPointer<const BitArray> bits);
void setFrames(QVector<Range> frames);
void setFramesFromInfo(QSharedPointer<BitInfo> frameSource);
void addHighlight(RangeHighlight highlight);
void addHighlights(QList<RangeHighlight> highlights);
void setMetadata(QString key, QVariant value);
Expand Down
3 changes: 3 additions & 0 deletions src/hobbits-core/displaybase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ void DisplayBase::drawHighlights(
if (m_displayHandle->getContainer().isNull()) {
return;
}
if (frameOffset < 0 || bitOffset < 0) {
return;
}

painter->setPen(Qt::transparent);
for (QString category: m_displayHandle->getContainer()->bitInfo()->highlightCategories()) {
Expand Down
1 change: 1 addition & 0 deletions src/hobbits-core/displayhelper.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "displayhelper.h"
#include "settingsmanager.h"
#include <QPixmap>

QImage DisplayHelper::getBitRasterImage(QSharedPointer<const BitContainer> bits, qint64 x, qint64 y, int w, int h)
{
Expand Down
21 changes: 17 additions & 4 deletions src/hobbits-core/rangehighlight.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#include "rangehighlight.h"
#include <QColor>

RangeHighlight::RangeHighlight(QString category, QString label, Range range, QColor color, QList<RangeHighlight> children) :
m_category(category),
m_label(label),
m_range(range),
m_color(color),
m_color(color.rgba()),
m_children(children)
{

Expand All @@ -13,7 +14,7 @@ RangeHighlight::RangeHighlight(QString category, QString label, Range range, QCo
RangeHighlight::RangeHighlight(QString category, QString label, QList<RangeHighlight> children, QColor color) :
m_category(category),
m_label(label),
m_color(color),
m_color(color.rgba()),
m_children(children)
{
std::sort(m_children.begin(), m_children.end());
Expand All @@ -23,6 +24,11 @@ RangeHighlight::RangeHighlight(QString category, QString label, QList<RangeHighl
m_range = Range(m_children.first().range().start(), m_children.last().range().end());
}

RangeHighlight RangeHighlight::simple(QString category, QString label, Range range, unsigned int color)
{
return RangeHighlight(category, label, range, QColor::fromRgba(color));
}

bool operator<(const RangeHighlight &a, const RangeHighlight &b)
{
return a.range() < b.range();
Expand All @@ -43,11 +49,16 @@ Range RangeHighlight::range() const
return m_range;
}

QColor RangeHighlight::color() const
unsigned int RangeHighlight::rgbaColor() const
{
return m_color;
}

QColor RangeHighlight::color() const
{
return QColor::fromRgba(m_color);
}

QList<RangeHighlight> RangeHighlight::children() const
{
return m_children;
Expand Down Expand Up @@ -81,10 +92,12 @@ QDataStream& operator>>(QDataStream& stream, RangeHighlight& highlight)
QString version;
stream >> version;
if (version == VERSION_1 || version == VERSION_2) {
QColor c;
stream >> highlight.m_category;
stream >> highlight.m_label;
stream >> highlight.m_range;
stream >> highlight.m_color;
stream >> c;
highlight.m_color = c.rgba();
if (version == VERSION_2) {
stream >> highlight.m_children;
}
Expand Down
8 changes: 6 additions & 2 deletions src/hobbits-core/rangehighlight.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#ifndef RANGEHIGHLIGHT_H
#define RANGEHIGHLIGHT_H

#include <QColor>
#include <QString>
#include "range.h"
#include "hobbits-core_global.h"

class QColor;

class HOBBITSCORESHARED_EXPORT RangeHighlight
{
public:
Expand All @@ -17,9 +18,12 @@ class HOBBITSCORESHARED_EXPORT RangeHighlight
RangeHighlight(QString category, QString label, Range range, QColor color, QList<RangeHighlight> children = {});
RangeHighlight(QString category, QString label, QList<RangeHighlight> children, QColor color);

static RangeHighlight simple(QString category, QString label, Range range, unsigned int color);

QString label() const;
QString category() const;
Range range() const;
unsigned int rgbaColor() const;
QColor color() const;
QList<RangeHighlight> children() const;
QList<RangeHighlight> allDescendants() const;
Expand All @@ -31,7 +35,7 @@ class HOBBITSCORESHARED_EXPORT RangeHighlight
QString m_category;
QString m_label;
Range m_range;
QColor m_color;
unsigned int m_color;
QList<RangeHighlight> m_children;
};

Expand Down
22 changes: 16 additions & 6 deletions src/hobbits-plugins/operators/PythonRunner/pythonrunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

PythonRunner::PythonRunner() :
ui(new Ui::PythonRunner()),
m_stateHelper(new PluginStateHelper())
m_stateHelper(new PluginStateHelper()),
m_hasUi(false)
{
m_stateHelper->addTextEditStringParameter("script", [this](){return ui->te_pythonScript;});
}
Expand All @@ -36,6 +37,7 @@ void PythonRunner::provideCallback(QSharedPointer<PluginCallback> pluginCallback
void PythonRunner::applyToWidget(QWidget *widget)
{
ui->setupUi(widget);
m_hasUi = true;

ui->te_pluginOutput->hide();

Expand Down Expand Up @@ -117,9 +119,11 @@ QSharedPointer<const OperatorResult> PythonRunner::operateOnContainers(
userScriptFile.close();

auto outputBits = QSharedPointer<BitArray>(new BitArray());
auto outputInfo = QSharedPointer<BitInfo>(new BitInfo());
auto pyRequest = PythonRequest::create(userScriptFile.fileName())->setFunctionName("process_bits");
pyRequest->addArg(PythonArg::constBitArray(inputContainers.at(0)->bits()));
pyRequest->addArg(PythonArg::constBitContainer(inputContainers.at(0)));
pyRequest->addArg(PythonArg::bitArray(outputBits));
pyRequest->addArg(PythonArg::bitInfo(outputInfo));
auto watcher = HobbitsPython::getInstance().runProcessScript(pyRequest, progressTracker);
watcher->watcher()->future().waitForFinished();
auto result = watcher->result();
Expand All @@ -144,6 +148,8 @@ QSharedPointer<const OperatorResult> PythonRunner::operateOnContainers(

QSharedPointer<BitContainer> outputContainer = QSharedPointer<BitContainer>(new BitContainer());
outputContainer->setBits(outputBits);
outputInfo->setFramesFromInfo(outputContainer->bitInfo());
outputContainer->setBitInfo(outputInfo);
outputContainer->setName(QString("python <- %1").arg(inputContainers.at(0)->name()));

return OperatorResult::result({outputContainer}, recallablePluginState);
Expand All @@ -161,12 +167,16 @@ OperatorInterface* PythonRunner::createDefaultOperator()

void PythonRunner::updateOutputText(QString text)
{
ui->te_pluginOutput->appendPlainText(text);
ui->te_pluginOutput->show();
if (m_hasUi) {
ui->te_pluginOutput->appendPlainText(text);
ui->te_pluginOutput->show();
}
}

void PythonRunner::clearOutputText()
{
ui->te_pluginOutput->hide();
ui->te_pluginOutput->clear();
if (m_hasUi) {
ui->te_pluginOutput->hide();
ui->te_pluginOutput->clear();
}
}
1 change: 1 addition & 0 deletions src/hobbits-plugins/operators/PythonRunner/pythonrunner.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public Q_SLOTS:
QSharedPointer<PluginCallback> m_pluginCallback;
QSharedPointer<PluginStateHelper> m_stateHelper;
QString m_outputText;
bool m_hasUi;
};

#endif // PYTHONRUNNER_H
14 changes: 8 additions & 6 deletions src/hobbits-plugins/operators/PythonRunner/pythonrunner.ui
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,17 @@
<enum>QPlainTextEdit::NoWrap</enum>
</property>
<property name="plainText">
<string>
def process_bits(input, output, progress):
output.resize(input.size())
for i in range(0, input.size()):
output.set(i, not input.at(i))
<string># example of inverting and highlighting
def process_bits(input, output_bits, output_info, progress):
if input.bits.size() &gt; 3000:
output_info.add_highlight(&quot;python&quot;, &quot;mychunk&quot;, 20, 3000)
output_bits.resize(input.bits.size())
for i in range(0, input.bits.size()):
output_bits.set(i, not input.bits.at(i))

if progress.is_cancelled():
return
progress.set_progress(i, input.size())</string>
progress.set_progress(i, input.bits.size())</string>
</property>
</widget>
</item>
Expand Down
4 changes: 4 additions & 0 deletions src/hobbits-python/hobbits-python.pro
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ SOURCES += \
hobbitspython.cpp \
py_actionprogress.cpp \
py_bitarray.cpp \
py_bitcontainer.cpp \
py_bitinfo.cpp \
py_hobbits.cpp \
pythonarg.cpp \
pythoninterpreter.cpp \
Expand All @@ -37,6 +39,8 @@ HEADERS += \
hobbits-python_global.h \
py_actionprogress.h \
py_bitarray.h \
py_bitcontainer.h \
py_bitinfo.h \
py_hobbits.h \
pythonarg.h \
pythoninterpreter.h \
Expand Down
Loading

0 comments on commit 2f4ef03

Please sign in to comment.