Add javascript variable inputs: Float, Int, Check, Color, Select
parent
cc51fdafe0
commit
af792a9bdc
|
@ -404,6 +404,9 @@ HEADERS += src/updateschecker.h
|
||||||
SOURCES += src/updatescheckwidget.cpp
|
SOURCES += src/updatescheckwidget.cpp
|
||||||
HEADERS += src/updatescheckwidget.h
|
HEADERS += src/updatescheckwidget.h
|
||||||
|
|
||||||
|
SOURCES += src/intnumberwidget.cpp
|
||||||
|
HEADERS += src/intnumberwidget.h
|
||||||
|
|
||||||
SOURCES += src/main.cpp
|
SOURCES += src/main.cpp
|
||||||
|
|
||||||
HEADERS += src/version.h
|
HEADERS += src/version.h
|
||||||
|
|
|
@ -3346,16 +3346,20 @@ void Document::updateScript(const QString &script)
|
||||||
|
|
||||||
void Document::updateVariable(const QString &name, const std::map<QString, QString> &value)
|
void Document::updateVariable(const QString &name, const std::map<QString, QString> &value)
|
||||||
{
|
{
|
||||||
|
bool needRunScript = false;
|
||||||
auto variable = m_cachedVariables.find(name);
|
auto variable = m_cachedVariables.find(name);
|
||||||
if (variable == m_cachedVariables.end()) {
|
if (variable == m_cachedVariables.end()) {
|
||||||
qDebug() << "Update a nonexist variable:" << name << "value:" << value;
|
m_cachedVariables[name] = value;
|
||||||
|
needRunScript = true;
|
||||||
|
} else if (variable->second != value) {
|
||||||
|
variable->second = value;
|
||||||
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (variable->second == value)
|
|
||||||
return;
|
|
||||||
variable->second = value;
|
|
||||||
m_mergedVariables[name] = value;
|
m_mergedVariables[name] = value;
|
||||||
emit mergedVaraiblesChanged();
|
emit mergedVaraiblesChanged();
|
||||||
|
if (needRunScript)
|
||||||
|
runScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::updateVariableValue(const QString &name, const QString &value)
|
void Document::updateVariableValue(const QString &name, const QString &value)
|
||||||
|
@ -3368,22 +3372,36 @@ void Document::updateVariableValue(const QString &name, const QString &value)
|
||||||
auto &variableValue = variable->second["value"];
|
auto &variableValue = variable->second["value"];
|
||||||
if (variableValue == value)
|
if (variableValue == value)
|
||||||
return;
|
return;
|
||||||
qDebug() << "Update variable:" << name << "from:" << variableValue << "to:" << value;
|
|
||||||
variableValue = value;
|
variableValue = value;
|
||||||
m_mergedVariables[name] = variable->second;
|
m_mergedVariables[name] = variable->second;
|
||||||
runScript();
|
runScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::updateDefaultVariables(const std::map<QString, std::map<QString, QString>> &defaultVariables)
|
bool Document::updateDefaultVariables(const std::map<QString, std::map<QString, QString>> &defaultVariables)
|
||||||
{
|
{
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
for (const auto &it: defaultVariables) {
|
for (const auto &it: defaultVariables) {
|
||||||
if (m_mergedVariables.find(it.first) != m_mergedVariables.end())
|
auto findMergedVariable = m_mergedVariables.find(it.first);
|
||||||
|
if (findMergedVariable != m_mergedVariables.end()) {
|
||||||
|
bool hasChangedAttribute = false;
|
||||||
|
for (const auto &attribute: it.second) {
|
||||||
|
if (attribute.first == "value")
|
||||||
continue;
|
continue;
|
||||||
|
const auto &findMatch = findMergedVariable->second.find(attribute.first);
|
||||||
|
if (findMatch != findMergedVariable->second.end()) {
|
||||||
|
if (findMatch->second == attribute.second)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
hasChangedAttribute = true;
|
||||||
|
}
|
||||||
|
if (!hasChangedAttribute)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
updated = true;
|
updated = true;
|
||||||
auto findCached = m_cachedVariables.find(it.first);
|
auto findCached = m_cachedVariables.find(it.first);
|
||||||
if (findCached != m_cachedVariables.end()) {
|
if (findCached != m_cachedVariables.end()) {
|
||||||
m_mergedVariables[it.first] = findCached->second;
|
m_mergedVariables[it.first] = it.second;
|
||||||
|
m_mergedVariables[it.first]["value"] = valueOfKeyInMapOrEmpty(findCached->second, "value");
|
||||||
} else {
|
} else {
|
||||||
m_mergedVariables[it.first] = it.second;
|
m_mergedVariables[it.first] = it.second;
|
||||||
m_cachedVariables[it.first] = it.second;
|
m_cachedVariables[it.first] = it.second;
|
||||||
|
@ -3402,6 +3420,7 @@ void Document::updateDefaultVariables(const std::map<QString, std::map<QString,
|
||||||
if (updated) {
|
if (updated) {
|
||||||
emit mergedVaraiblesChanged();
|
emit mergedVaraiblesChanged();
|
||||||
}
|
}
|
||||||
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::runScript()
|
void Document::runScript()
|
||||||
|
@ -3420,7 +3439,9 @@ void Document::runScript()
|
||||||
m_scriptRunner = new ScriptRunner();
|
m_scriptRunner = new ScriptRunner();
|
||||||
m_scriptRunner->moveToThread(thread);
|
m_scriptRunner->moveToThread(thread);
|
||||||
m_scriptRunner->setScript(new QString(m_script));
|
m_scriptRunner->setScript(new QString(m_script));
|
||||||
m_scriptRunner->setVariables(new std::map<QString, std::map<QString, QString>>(m_mergedVariables));
|
m_scriptRunner->setVariables(new std::map<QString, std::map<QString, QString>>(
|
||||||
|
m_mergedVariables.empty() ? m_cachedVariables : m_mergedVariables
|
||||||
|
));
|
||||||
connect(thread, &QThread::started, m_scriptRunner, &ScriptRunner::process);
|
connect(thread, &QThread::started, m_scriptRunner, &ScriptRunner::process);
|
||||||
connect(m_scriptRunner, &ScriptRunner::finished, this, &Document::scriptResultReady);
|
connect(m_scriptRunner, &ScriptRunner::finished, this, &Document::scriptResultReady);
|
||||||
connect(m_scriptRunner, &ScriptRunner::finished, thread, &QThread::quit);
|
connect(m_scriptRunner, &ScriptRunner::finished, thread, &QThread::quit);
|
||||||
|
@ -3435,6 +3456,7 @@ void Document::scriptResultReady()
|
||||||
std::map<QString, std::map<QString, QString>> *defaultVariables = m_scriptRunner->takeDefaultVariables();
|
std::map<QString, std::map<QString, QString>> *defaultVariables = m_scriptRunner->takeDefaultVariables();
|
||||||
bool errorChanged = false;
|
bool errorChanged = false;
|
||||||
bool consoleLogChanged = false;
|
bool consoleLogChanged = false;
|
||||||
|
bool mergedVariablesChanged = false;
|
||||||
|
|
||||||
const QString &scriptError = m_scriptRunner->scriptError();
|
const QString &scriptError = m_scriptRunner->scriptError();
|
||||||
if (m_scriptError != scriptError) {
|
if (m_scriptError != scriptError) {
|
||||||
|
@ -3455,7 +3477,7 @@ void Document::scriptResultReady()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nullptr != defaultVariables) {
|
if (nullptr != defaultVariables) {
|
||||||
updateDefaultVariables(*defaultVariables);
|
mergedVariablesChanged = updateDefaultVariables(*defaultVariables);
|
||||||
delete defaultVariables;
|
delete defaultVariables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3470,7 +3492,7 @@ void Document::scriptResultReady()
|
||||||
|
|
||||||
qDebug() << "Script run done";
|
qDebug() << "Script run done";
|
||||||
|
|
||||||
if (m_isScriptResultObsolete) {
|
if (m_isScriptResultObsolete || mergedVariablesChanged) {
|
||||||
runScript();
|
runScript();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -658,7 +658,6 @@ public slots:
|
||||||
void applyPreferenceFlatShadingChange();
|
void applyPreferenceFlatShadingChange();
|
||||||
void initScript(const QString &script);
|
void initScript(const QString &script);
|
||||||
void updateScript(const QString &script);
|
void updateScript(const QString &script);
|
||||||
void updateDefaultVariables(const std::map<QString, std::map<QString, QString>> &defaultVariables);
|
|
||||||
void runScript();
|
void runScript();
|
||||||
void scriptResultReady();
|
void scriptResultReady();
|
||||||
void updateVariable(const QString &name, const std::map<QString, QString> &value);
|
void updateVariable(const QString &name, const std::map<QString, QString> &value);
|
||||||
|
@ -680,6 +679,7 @@ private:
|
||||||
void removeRigResults();
|
void removeRigResults();
|
||||||
void updateLinkedPart(QUuid oldPartId, QUuid newPartId);
|
void updateLinkedPart(QUuid oldPartId, QUuid newPartId);
|
||||||
//void addToolToMesh(MeshLoader *mesh);
|
//void addToolToMesh(MeshLoader *mesh);
|
||||||
|
bool updateDefaultVariables(const std::map<QString, std::map<QString, QString>> &defaultVariables);
|
||||||
private: // need initialize
|
private: // need initialize
|
||||||
bool m_isResultMeshObsolete;
|
bool m_isResultMeshObsolete;
|
||||||
MeshGenerator *m_meshGenerator;
|
MeshGenerator *m_meshGenerator;
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
#include <QtWidgets>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include "theme.h"
|
||||||
|
#include "intnumberwidget.h"
|
||||||
|
|
||||||
|
IntNumberWidget::IntNumberWidget(QWidget *parent, bool singleLine) :
|
||||||
|
QWidget(parent)
|
||||||
|
{
|
||||||
|
m_slider = new QSlider(Qt::Horizontal, this);
|
||||||
|
m_slider->setRange(0, 100);
|
||||||
|
m_slider->setFixedWidth(120);
|
||||||
|
|
||||||
|
m_label = new QLabel(this);
|
||||||
|
m_label->setAlignment(Qt::AlignLeft);
|
||||||
|
|
||||||
|
connect(m_slider, &QAbstractSlider::valueChanged, [=](int value) {
|
||||||
|
updateValueLabel(value);
|
||||||
|
emit valueChanged(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
QBoxLayout *layout = nullptr;
|
||||||
|
if (singleLine) {
|
||||||
|
layout = new QHBoxLayout(this);
|
||||||
|
layout->setMargin(2);
|
||||||
|
layout->addWidget(m_slider);
|
||||||
|
layout->addWidget(m_label);
|
||||||
|
} else {
|
||||||
|
layout = new QVBoxLayout(this);
|
||||||
|
layout->setMargin(2);
|
||||||
|
layout->addWidget(m_label);
|
||||||
|
layout->addWidget(m_slider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntNumberWidget::updateValueLabel(int value)
|
||||||
|
{
|
||||||
|
QString valueString = QString::number(value);
|
||||||
|
if (m_itemName.isEmpty())
|
||||||
|
m_label->setText(valueString);
|
||||||
|
else
|
||||||
|
m_label->setText(m_itemName + ": " + valueString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntNumberWidget::setItemName(const QString &name)
|
||||||
|
{
|
||||||
|
m_itemName = name;
|
||||||
|
updateValueLabel(value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntNumberWidget::setRange(int min, int max)
|
||||||
|
{
|
||||||
|
m_slider->setRange(min, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntNumberWidget::increaseValue()
|
||||||
|
{
|
||||||
|
m_slider->triggerAction(QSlider::SliderPageStepAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntNumberWidget::descreaseValue()
|
||||||
|
{
|
||||||
|
m_slider->triggerAction(QSlider::SliderPageStepSub);
|
||||||
|
}
|
||||||
|
|
||||||
|
int IntNumberWidget::value() const
|
||||||
|
{
|
||||||
|
return m_slider->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntNumberWidget::setValue(int value)
|
||||||
|
{
|
||||||
|
m_slider->setValue(value);
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef DUST3D_INT_NUMBER_WIDGET_H
|
||||||
|
#define DUST3D_INT_NUMBER_WIDGET_H
|
||||||
|
#include <QToolButton>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QLabel)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QSlider)
|
||||||
|
|
||||||
|
class IntNumberWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit IntNumberWidget(QWidget *parent = nullptr, bool singleLine=true);
|
||||||
|
void setRange(int min, int max);
|
||||||
|
int value() const;
|
||||||
|
void setItemName(const QString &name);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void increaseValue();
|
||||||
|
void descreaseValue();
|
||||||
|
void setValue(int value);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void valueChanged(int value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateValueLabel(int value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLabel *m_label = nullptr;
|
||||||
|
QSlider *m_slider = nullptr;
|
||||||
|
QString m_itemName;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,6 +2,7 @@
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include "scriptrunner.h"
|
#include "scriptrunner.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
JSClassID ScriptRunner::js_partClassId = 0;
|
JSClassID ScriptRunner::js_partClassId = 0;
|
||||||
JSClassID ScriptRunner::js_componentClassId = 0;
|
JSClassID ScriptRunner::js_componentClassId = 0;
|
||||||
|
@ -206,16 +207,82 @@ static JSValue js_createNode(JSContext *context, JSValueConst thisValue,
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_createVariable(JSContext *context, JSValueConst thisValue,
|
static JSValue js_createFloatInput(JSContext *context, JSValueConst thisValue,
|
||||||
|
int argc, JSValueConst *argv)
|
||||||
|
{
|
||||||
|
ScriptRunner *runner = (ScriptRunner *)JS_GetContextOpaque(context);
|
||||||
|
if (argc < 4) {
|
||||||
|
runner->consoleLog() += "Incomplete parameters, expect: name, defaultValue, minValue, maxValue\r\n";
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
double mergedValue = 0.0;
|
||||||
|
|
||||||
|
const char *name = nullptr;
|
||||||
|
double defaultValue = 0.0;
|
||||||
|
double minValue = 0.0;
|
||||||
|
double maxValue = 0.0;
|
||||||
|
|
||||||
|
name = JS_ToCString(context, argv[0]);
|
||||||
|
if (!name)
|
||||||
|
goto fail;
|
||||||
|
JS_ToFloat64(context, &defaultValue, argv[1]);
|
||||||
|
JS_ToFloat64(context, &minValue, argv[2]);
|
||||||
|
JS_ToFloat64(context, &maxValue, argv[3]);
|
||||||
|
|
||||||
|
mergedValue = runner->createFloatInput(name, defaultValue, minValue, maxValue);
|
||||||
|
JS_FreeCString(context, name);
|
||||||
|
|
||||||
|
return JS_NewFloat64(context, mergedValue);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
JS_FreeCString(context, name);
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue js_createIntInput(JSContext *context, JSValueConst thisValue,
|
||||||
|
int argc, JSValueConst *argv)
|
||||||
|
{
|
||||||
|
ScriptRunner *runner = (ScriptRunner *)JS_GetContextOpaque(context);
|
||||||
|
if (argc < 4) {
|
||||||
|
runner->consoleLog() += "Incomplete parameters, expect: name, defaultValue, minValue, maxValue\r\n";
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t mergedValue = 0.0;
|
||||||
|
|
||||||
|
const char *name = nullptr;
|
||||||
|
int64_t defaultValue = 0;
|
||||||
|
int64_t minValue = 0;
|
||||||
|
int64_t maxValue = 0;
|
||||||
|
|
||||||
|
name = JS_ToCString(context, argv[0]);
|
||||||
|
if (!name)
|
||||||
|
goto fail;
|
||||||
|
JS_ToInt64(context, &defaultValue, argv[1]);
|
||||||
|
JS_ToInt64(context, &minValue, argv[2]);
|
||||||
|
JS_ToInt64(context, &maxValue, argv[3]);
|
||||||
|
|
||||||
|
mergedValue = runner->createIntInput(name, defaultValue, minValue, maxValue);
|
||||||
|
JS_FreeCString(context, name);
|
||||||
|
|
||||||
|
return JS_NewInt64(context, mergedValue);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
JS_FreeCString(context, name);
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue js_createColorInput(JSContext *context, JSValueConst thisValue,
|
||||||
int argc, JSValueConst *argv)
|
int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
ScriptRunner *runner = (ScriptRunner *)JS_GetContextOpaque(context);
|
ScriptRunner *runner = (ScriptRunner *)JS_GetContextOpaque(context);
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
runner->consoleLog() += "Incomplete parameters, expect: name, value\r\n";
|
runner->consoleLog() += "Incomplete parameters, expect: name, defaultValue\r\n";
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString mergedValue;
|
QColor mergeValue;
|
||||||
|
|
||||||
const char *name = nullptr;
|
const char *name = nullptr;
|
||||||
const char *defaultValue = nullptr;
|
const char *defaultValue = nullptr;
|
||||||
|
@ -227,11 +294,12 @@ static JSValue js_createVariable(JSContext *context, JSValueConst thisValue,
|
||||||
if (!defaultValue)
|
if (!defaultValue)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
mergedValue = runner->createVariable(name, defaultValue);
|
mergeValue = runner->createColorInput(name, defaultValue);
|
||||||
|
|
||||||
JS_FreeCString(context, name);
|
JS_FreeCString(context, name);
|
||||||
JS_FreeCString(context, defaultValue);
|
JS_FreeCString(context, defaultValue);
|
||||||
|
|
||||||
return JS_NewFloat64(context, mergedValue.toDouble());
|
return JS_NewString(context, mergeValue.name().toUtf8().constData());
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
JS_FreeCString(context, name);
|
JS_FreeCString(context, name);
|
||||||
|
@ -239,6 +307,98 @@ fail:
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JSValue js_createCheckInput(JSContext *context, JSValueConst thisValue,
|
||||||
|
int argc, JSValueConst *argv)
|
||||||
|
{
|
||||||
|
ScriptRunner *runner = (ScriptRunner *)JS_GetContextOpaque(context);
|
||||||
|
if (argc < 2) {
|
||||||
|
runner->consoleLog() += "Incomplete parameters, expect: name, defaultValue\r\n";
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mergedValue = false;
|
||||||
|
|
||||||
|
const char *name = nullptr;
|
||||||
|
const char *value = nullptr;
|
||||||
|
bool defaultValue = false;
|
||||||
|
|
||||||
|
name = JS_ToCString(context, argv[0]);
|
||||||
|
if (!name)
|
||||||
|
goto fail;
|
||||||
|
value = JS_ToCString(context, argv[1]);
|
||||||
|
if (!value)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
defaultValue = isTrueValueString(value);
|
||||||
|
mergedValue = runner->createCheckInput(name, defaultValue);
|
||||||
|
JS_FreeCString(context, name);
|
||||||
|
JS_FreeCString(context, value);
|
||||||
|
|
||||||
|
return JS_NewInt64(context, mergedValue);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
JS_FreeCString(context, name);
|
||||||
|
JS_FreeCString(context, value);
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue js_createSelectInput(JSContext *context, JSValueConst thisValue,
|
||||||
|
int argc, JSValueConst *argv)
|
||||||
|
{
|
||||||
|
ScriptRunner *runner = (ScriptRunner *)JS_GetContextOpaque(context);
|
||||||
|
if (argc < 3) {
|
||||||
|
runner->consoleLog() += "Incomplete parameters, expect: name, defaultValue, options\r\n";
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *name = nullptr;
|
||||||
|
int32_t defaultValue = 0;
|
||||||
|
int32_t mergedValue = 0;
|
||||||
|
JSValue *arrayItems = nullptr;
|
||||||
|
uint32_t arrayLength = 0;
|
||||||
|
QStringList options;
|
||||||
|
|
||||||
|
name = JS_ToCString(context, argv[0]);
|
||||||
|
if (!name)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
JS_ToInt32(context, &defaultValue, argv[1]);
|
||||||
|
|
||||||
|
if (true != JS_IsArray(context, argv[2])) {
|
||||||
|
runner->consoleLog() += "Expect array as the third parameter\r\n";
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!js_get_fast_array(context, argv[2], &arrayItems, &arrayLength)) {
|
||||||
|
runner->consoleLog() += "Read third parameter as array failed\r\n";
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < arrayLength; ++i) {
|
||||||
|
const char *optionValue = JS_ToCString(context, arrayItems[i]);
|
||||||
|
if (nullptr != optionValue) {
|
||||||
|
options.append(optionValue);
|
||||||
|
JS_FreeCString(context, optionValue);
|
||||||
|
} else {
|
||||||
|
options.append("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mergedValue = runner->createSelectInput(name, defaultValue, options);
|
||||||
|
if (mergedValue < 0)
|
||||||
|
mergedValue = 0;
|
||||||
|
else if (mergedValue >= options.size())
|
||||||
|
mergedValue = options.size() - 1;
|
||||||
|
|
||||||
|
JS_FreeCString(context, name);
|
||||||
|
|
||||||
|
return JS_NewInt32(context, mergedValue);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
JS_FreeCString(context, name);
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
}
|
||||||
|
|
||||||
ScriptRunner::ScriptRunner()
|
ScriptRunner::ScriptRunner()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -375,7 +535,7 @@ void ScriptRunner::run()
|
||||||
JS_SetContextOpaque(context, this);
|
JS_SetContextOpaque(context, this);
|
||||||
|
|
||||||
if (nullptr != m_script &&
|
if (nullptr != m_script &&
|
||||||
!m_script->isEmpty()) {
|
!m_script->trimmed().isEmpty()) {
|
||||||
auto buffer = m_script->toUtf8();
|
auto buffer = m_script->toUtf8();
|
||||||
|
|
||||||
JSValue globalObject = JS_GetGlobalObject(context);
|
JSValue globalObject = JS_GetGlobalObject(context);
|
||||||
|
@ -391,8 +551,20 @@ void ScriptRunner::run()
|
||||||
document, "createNode",
|
document, "createNode",
|
||||||
JS_NewCFunction(context, js_createNode, "createNode", 1));
|
JS_NewCFunction(context, js_createNode, "createNode", 1));
|
||||||
JS_SetPropertyStr(context,
|
JS_SetPropertyStr(context,
|
||||||
document, "createVariable",
|
document, "createFloatInput",
|
||||||
JS_NewCFunction(context, js_createVariable, "createVariable", 2));
|
JS_NewCFunction(context, js_createFloatInput, "createFloatInput", 4));
|
||||||
|
JS_SetPropertyStr(context,
|
||||||
|
document, "createIntInput",
|
||||||
|
JS_NewCFunction(context, js_createIntInput, "createIntInput", 4));
|
||||||
|
JS_SetPropertyStr(context,
|
||||||
|
document, "createColorInput",
|
||||||
|
JS_NewCFunction(context, js_createColorInput, "createColorInput", 2));
|
||||||
|
JS_SetPropertyStr(context,
|
||||||
|
document, "createCheckInput",
|
||||||
|
JS_NewCFunction(context, js_createCheckInput, "createCheckInput", 2));
|
||||||
|
JS_SetPropertyStr(context,
|
||||||
|
document, "createSelectInput",
|
||||||
|
JS_NewCFunction(context, js_createSelectInput, "createSelectInput", 3));
|
||||||
JS_SetPropertyStr(context,
|
JS_SetPropertyStr(context,
|
||||||
document, "connect",
|
document, "connect",
|
||||||
JS_NewCFunction(context, js_connect, "connect", 2));
|
JS_NewCFunction(context, js_connect, "connect", 2));
|
||||||
|
@ -552,13 +724,13 @@ void ScriptRunner::generateSnapshot()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ScriptRunner::createVariable(const QString &name, const QString &defaultValue)
|
QString ScriptRunner::createInput(const QString &name, const std::map<QString, QString> &attributes)
|
||||||
{
|
{
|
||||||
if (nullptr != m_defaultVariables) {
|
if (nullptr != m_defaultVariables) {
|
||||||
if (m_defaultVariables->find(name) != m_defaultVariables->end()) {
|
if (m_defaultVariables->find(name) != m_defaultVariables->end()) {
|
||||||
m_scriptError += "Repeated variable name found: \"" + name + "\"\r\n";
|
m_scriptError += "Repeated variable name found: \"" + name + "\"\r\n";
|
||||||
}
|
}
|
||||||
(*m_defaultVariables)[name]["value"] = defaultValue;
|
(*m_defaultVariables)[name] = attributes;
|
||||||
}
|
}
|
||||||
if (nullptr != m_variables) {
|
if (nullptr != m_variables) {
|
||||||
auto findVariable = m_variables->find(name);
|
auto findVariable = m_variables->find(name);
|
||||||
|
@ -568,7 +740,73 @@ QString ScriptRunner::createVariable(const QString &name, const QString &default
|
||||||
return findValue->second;
|
return findValue->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return defaultValue;
|
auto findValue = attributes.find("value");
|
||||||
|
if (findValue != attributes.end())
|
||||||
|
return findValue->second;
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
float ScriptRunner::createFloatInput(const QString &name, float defaultValue, float minValue, float maxValue)
|
||||||
|
{
|
||||||
|
std::map<QString, QString> attributes;
|
||||||
|
attributes["input"] = "Float";
|
||||||
|
attributes["value"] = QString::number(defaultValue);
|
||||||
|
attributes["defaultValue"] = attributes["value"];
|
||||||
|
attributes["minValue"] = QString::number(minValue);
|
||||||
|
attributes["maxValue"] = QString::number(maxValue);
|
||||||
|
auto inputValue = createInput(name, attributes);
|
||||||
|
return inputValue.toFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScriptRunner::createIntInput(const QString &name, int defaultValue, int minValue, int maxValue)
|
||||||
|
{
|
||||||
|
std::map<QString, QString> attributes;
|
||||||
|
attributes["input"] = "Int";
|
||||||
|
attributes["value"] = QString::number(defaultValue);
|
||||||
|
attributes["defaultValue"] = attributes["value"];
|
||||||
|
attributes["minValue"] = QString::number(minValue);
|
||||||
|
attributes["maxValue"] = QString::number(maxValue);
|
||||||
|
auto inputValue = createInput(name, attributes);
|
||||||
|
return inputValue.toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor ScriptRunner::createColorInput(const QString &name, const QColor &defaultValue)
|
||||||
|
{
|
||||||
|
std::map<QString, QString> attributes;
|
||||||
|
attributes["input"] = "Color";
|
||||||
|
attributes["value"] = defaultValue.name();
|
||||||
|
attributes["defaultValue"] = attributes["value"];
|
||||||
|
auto inputValue = createInput(name, attributes);
|
||||||
|
return QColor(inputValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScriptRunner::createCheckInput(const QString &name, bool checked)
|
||||||
|
{
|
||||||
|
std::map<QString, QString> attributes;
|
||||||
|
attributes["input"] = "Check";
|
||||||
|
attributes["value"] = checked ? "true" : "false";
|
||||||
|
attributes["defaultValue"] = attributes["value"];
|
||||||
|
auto inputValue = createInput(name, attributes);
|
||||||
|
return isTrueValueString(inputValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScriptRunner::createSelectInput(const QString &name, int defaultSelectedIndex, const QStringList &options)
|
||||||
|
{
|
||||||
|
std::map<QString, QString> attributes;
|
||||||
|
attributes["input"] = "Select";
|
||||||
|
attributes["value"] = QString::number(defaultSelectedIndex);
|
||||||
|
attributes["defaultValue"] = attributes["value"];
|
||||||
|
attributes["length"] = QString::number(options.size());
|
||||||
|
for (int i = 0; i < options.size(); ++i) {
|
||||||
|
attributes["option" + QString::number(i)] = options[i];
|
||||||
|
}
|
||||||
|
auto inputValue = createInput(name, attributes);
|
||||||
|
int selectedIndex = inputValue.toInt();
|
||||||
|
if (selectedIndex >= options.size()) {
|
||||||
|
m_scriptError += QString("Selected index of select input \"%1\" is been reset to 0 because of out of range\r\n").arg(name);
|
||||||
|
selectedIndex = 0;
|
||||||
|
}
|
||||||
|
return selectedIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptRunner::process()
|
void ScriptRunner::process()
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#define DUST3D_SCRIPT_RUNNER_H
|
#define DUST3D_SCRIPT_RUNNER_H
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QStringList>
|
||||||
#include "snapshot.h"
|
#include "snapshot.h"
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "quickjs.h"
|
#include "quickjs.h"
|
||||||
|
@ -63,7 +65,6 @@ public:
|
||||||
std::map<QString, std::map<QString, QString>> *takeDefaultVariables();
|
std::map<QString, std::map<QString, QString>> *takeDefaultVariables();
|
||||||
const QString &scriptError();
|
const QString &scriptError();
|
||||||
static void mergeVaraibles(std::map<QString, std::map<QString, QString>> *target, const std::map<QString, std::map<QString, QString>> &source);
|
static void mergeVaraibles(std::map<QString, std::map<QString, QString>> *target, const std::map<QString, std::map<QString, QString>> &source);
|
||||||
QString createVariable(const QString &name, const QString &defaultValue);
|
|
||||||
DocumentPart *createPart(DocumentComponent *component);
|
DocumentPart *createPart(DocumentComponent *component);
|
||||||
DocumentComponent *createComponent(DocumentComponent *parentComponent);
|
DocumentComponent *createComponent(DocumentComponent *parentComponent);
|
||||||
DocumentNode *createNode(DocumentPart *part);
|
DocumentNode *createNode(DocumentPart *part);
|
||||||
|
@ -71,6 +72,12 @@ public:
|
||||||
QString attribute(DocumentElement *element, const QString &name);
|
QString attribute(DocumentElement *element, const QString &name);
|
||||||
void connect(DocumentNode *firstNode, DocumentNode *secondNode);
|
void connect(DocumentNode *firstNode, DocumentNode *secondNode);
|
||||||
QString &consoleLog();
|
QString &consoleLog();
|
||||||
|
QString createInput(const QString &name, const std::map<QString, QString> &attributes);
|
||||||
|
float createFloatInput(const QString &name, float defaultValue, float minValue, float maxValue);
|
||||||
|
int createIntInput(const QString &name, int defaultValue, int minValue, int maxValue);
|
||||||
|
QColor createColorInput(const QString &name, const QColor &defaultValue);
|
||||||
|
bool createCheckInput(const QString &name, bool checked);
|
||||||
|
int createSelectInput(const QString &name, int defaultSelectedIndex, const QStringList &options);
|
||||||
signals:
|
signals:
|
||||||
void finished();
|
void finished();
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
#include <QDoubleSpinBox>
|
#include <QDoubleSpinBox>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QColorDialog>
|
||||||
#include "scriptvariableswidget.h"
|
#include "scriptvariableswidget.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
|
#include "floatnumberwidget.h"
|
||||||
|
#include "intnumberwidget.h"
|
||||||
|
|
||||||
ScriptVariablesWidget::ScriptVariablesWidget(const Document *document,
|
ScriptVariablesWidget::ScriptVariablesWidget(const Document *document,
|
||||||
QWidget *parent) :
|
QWidget *parent) :
|
||||||
|
@ -23,14 +29,157 @@ void ScriptVariablesWidget::reload()
|
||||||
QFormLayout *formLayout = new QFormLayout;
|
QFormLayout *formLayout = new QFormLayout;
|
||||||
for (const auto &variable: m_document->variables()) {
|
for (const auto &variable: m_document->variables()) {
|
||||||
auto name = variable.first;
|
auto name = variable.first;
|
||||||
|
auto input = valueOfKeyInMapOrEmpty(variable.second, "input");
|
||||||
|
if ("Float" == input) {
|
||||||
|
auto minValue = valueOfKeyInMapOrEmpty(variable.second, "minValue").toFloat();
|
||||||
|
auto maxValue = valueOfKeyInMapOrEmpty(variable.second, "maxValue").toFloat();
|
||||||
auto value = valueOfKeyInMapOrEmpty(variable.second, "value").toFloat();
|
auto value = valueOfKeyInMapOrEmpty(variable.second, "value").toFloat();
|
||||||
qDebug() << "Script variable, name:" << name << "value:" << value;
|
auto defaultValue = valueOfKeyInMapOrEmpty(variable.second, "defaultValue").toFloat();
|
||||||
QDoubleSpinBox *inputBox = new QDoubleSpinBox;
|
FloatNumberWidget *floatWidget = new FloatNumberWidget;
|
||||||
inputBox->setValue(value);
|
floatWidget->setItemName(name);
|
||||||
connect(inputBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, [=](double toValue) {
|
floatWidget->setRange(minValue, maxValue);
|
||||||
|
floatWidget->setValue(value);
|
||||||
|
|
||||||
|
connect(floatWidget, &FloatNumberWidget::valueChanged, [=](float toValue) {
|
||||||
emit updateVariableValue(name, QString::number(toValue));
|
emit updateVariableValue(name, QString::number(toValue));
|
||||||
});
|
});
|
||||||
formLayout->addRow(name, inputBox);
|
|
||||||
|
QPushButton *floatEraser = new QPushButton(QChar(fa::eraser));
|
||||||
|
Theme::initAwesomeToolButton(floatEraser);
|
||||||
|
|
||||||
|
connect(floatEraser, &QPushButton::clicked, [=]() {
|
||||||
|
floatWidget->setValue(defaultValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
QHBoxLayout *floatLayout = new QHBoxLayout;
|
||||||
|
floatLayout->addWidget(floatEraser);
|
||||||
|
floatLayout->addWidget(floatWidget);
|
||||||
|
|
||||||
|
formLayout->addRow(floatLayout);
|
||||||
|
} else if ("Int" == input) {
|
||||||
|
auto minValue = valueOfKeyInMapOrEmpty(variable.second, "minValue").toInt();
|
||||||
|
auto maxValue = valueOfKeyInMapOrEmpty(variable.second, "maxValue").toInt();
|
||||||
|
auto value = valueOfKeyInMapOrEmpty(variable.second, "value").toInt();
|
||||||
|
auto defaultValue = valueOfKeyInMapOrEmpty(variable.second, "defaultValue").toInt();
|
||||||
|
IntNumberWidget *intWidget = new IntNumberWidget;
|
||||||
|
intWidget->setItemName(name);
|
||||||
|
intWidget->setRange(minValue, maxValue);
|
||||||
|
intWidget->setValue(value);
|
||||||
|
|
||||||
|
connect(intWidget, &IntNumberWidget::valueChanged, [=](int toValue) {
|
||||||
|
emit updateVariableValue(name, QString::number(toValue));
|
||||||
|
});
|
||||||
|
|
||||||
|
QPushButton *intEraser = new QPushButton(QChar(fa::eraser));
|
||||||
|
Theme::initAwesomeToolButton(intEraser);
|
||||||
|
|
||||||
|
connect(intEraser, &QPushButton::clicked, [=]() {
|
||||||
|
intWidget->setValue(defaultValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
QHBoxLayout *intLayout = new QHBoxLayout;
|
||||||
|
intLayout->addWidget(intEraser);
|
||||||
|
intLayout->addWidget(intWidget);
|
||||||
|
|
||||||
|
formLayout->addRow(intLayout);
|
||||||
|
} else if ("Check" == input) {
|
||||||
|
auto value = isTrueValueString(valueOfKeyInMapOrEmpty(variable.second, "value"));
|
||||||
|
auto defaultValue = isTrueValueString(valueOfKeyInMapOrEmpty(variable.second, "defaultValue"));
|
||||||
|
|
||||||
|
QCheckBox *checkBox = new QCheckBox;
|
||||||
|
checkBox->setText(name);
|
||||||
|
checkBox->setChecked(value);
|
||||||
|
|
||||||
|
connect(checkBox, &QCheckBox::stateChanged, [=](int) {
|
||||||
|
emit updateVariableValue(name, checkBox->isChecked() ? "true" : "false");
|
||||||
|
});
|
||||||
|
|
||||||
|
QPushButton *checkEraser = new QPushButton(QChar(fa::eraser));
|
||||||
|
Theme::initAwesomeToolButton(checkEraser);
|
||||||
|
|
||||||
|
connect(checkEraser, &QPushButton::clicked, [=]() {
|
||||||
|
checkBox->setChecked(defaultValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
QHBoxLayout *checkLayout = new QHBoxLayout;
|
||||||
|
checkLayout->addWidget(checkEraser);
|
||||||
|
checkLayout->addWidget(checkBox);
|
||||||
|
|
||||||
|
formLayout->addRow(checkLayout);
|
||||||
|
} else if ("Select" == input) {
|
||||||
|
auto value = valueOfKeyInMapOrEmpty(variable.second, "value").toInt();
|
||||||
|
auto defaultValue = valueOfKeyInMapOrEmpty(variable.second, "defaultValue").toInt();
|
||||||
|
auto length = valueOfKeyInMapOrEmpty(variable.second, "length").toInt();
|
||||||
|
|
||||||
|
QComboBox *selectBox = new QComboBox;
|
||||||
|
selectBox->setEditable(false);
|
||||||
|
selectBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||||
|
for (auto i = 0; i < length; ++i) {
|
||||||
|
selectBox->addItem(valueOfKeyInMapOrEmpty(variable.second, "option" + QString::number(i)));
|
||||||
|
}
|
||||||
|
selectBox->setCurrentIndex(value);
|
||||||
|
|
||||||
|
connect(selectBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=](int index) {
|
||||||
|
emit updateVariableValue(name, QString::number(index));
|
||||||
|
});
|
||||||
|
|
||||||
|
QPushButton *selectEraser = new QPushButton(QChar(fa::eraser));
|
||||||
|
Theme::initAwesomeToolButton(selectEraser);
|
||||||
|
|
||||||
|
connect(selectEraser, &QPushButton::clicked, [=]() {
|
||||||
|
selectBox->setCurrentIndex(defaultValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
QLabel *selectLabel = new QLabel;
|
||||||
|
selectLabel->setText(name);
|
||||||
|
|
||||||
|
QHBoxLayout *selectLayout = new QHBoxLayout;
|
||||||
|
selectLayout->addWidget(selectEraser);
|
||||||
|
selectLayout->addWidget(selectBox);
|
||||||
|
selectLayout->addWidget(selectLabel);
|
||||||
|
|
||||||
|
formLayout->addRow(selectLayout);
|
||||||
|
} else if ("Color" == input) {
|
||||||
|
auto value = valueOfKeyInMapOrEmpty(variable.second, "value");
|
||||||
|
auto defaultValue = valueOfKeyInMapOrEmpty(variable.second, "defaultValue");
|
||||||
|
|
||||||
|
QPushButton *colorEraser = new QPushButton(QChar(fa::eraser));
|
||||||
|
Theme::initAwesomeToolButton(colorEraser);
|
||||||
|
|
||||||
|
QPushButton *pickButton = new QPushButton();
|
||||||
|
Theme::initAwesomeToolButtonWithoutFont(pickButton);
|
||||||
|
|
||||||
|
auto updatePickButtonColor = [=](const QColor &color) {
|
||||||
|
QPalette palette = pickButton->palette();
|
||||||
|
palette.setColor(QPalette::Window, color);
|
||||||
|
palette.setColor(QPalette::Button, color);
|
||||||
|
pickButton->setPalette(palette);
|
||||||
|
};
|
||||||
|
updatePickButtonColor(QColor(value));
|
||||||
|
|
||||||
|
connect(colorEraser, &QPushButton::clicked, [=]() {
|
||||||
|
emit updateVariableValue(name, defaultValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(pickButton, &QPushButton::clicked, [=]() {
|
||||||
|
QColor color = QColorDialog::getColor(value, this);
|
||||||
|
if (color.isValid()) {
|
||||||
|
updatePickButtonColor(color.name());
|
||||||
|
emit updateVariableValue(name, color.name());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QLabel *selectLabel = new QLabel;
|
||||||
|
selectLabel->setText(name);
|
||||||
|
|
||||||
|
QHBoxLayout *colorLayout = new QHBoxLayout;
|
||||||
|
colorLayout->addWidget(colorEraser);
|
||||||
|
colorLayout->addWidget(pickButton);
|
||||||
|
colorLayout->addWidget(selectLabel);
|
||||||
|
colorLayout->addStretch();
|
||||||
|
|
||||||
|
formLayout->addRow(colorLayout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
widget->setLayout(formLayout);
|
widget->setLayout(formLayout);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ ScriptWidget::ScriptWidget(const Document *document, QWidget *parent) :
|
||||||
splitter->addWidget(scriptEditWidget);
|
splitter->addWidget(scriptEditWidget);
|
||||||
splitter->addWidget(m_consoleEdit);
|
splitter->addWidget(m_consoleEdit);
|
||||||
splitter->addWidget(scriptVariablesWidget);
|
splitter->addWidget(scriptVariablesWidget);
|
||||||
|
splitter->setStretchFactor(2, 1);
|
||||||
|
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||||
mainLayout->addWidget(splitter);
|
mainLayout->addWidget(splitter);
|
||||||
|
|
|
@ -13632,7 +13632,7 @@ static JSValue JS_GetIterator2(JSContext *ctx, JSValueConst obj,
|
||||||
return enum_obj;
|
return enum_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue JS_GetIterator(JSContext *ctx, JSValueConst obj, BOOL is_async)
|
JSValue JS_GetIterator(JSContext *ctx, JSValueConst obj, BOOL is_async)
|
||||||
{
|
{
|
||||||
JSValue method, ret, sync_iter;
|
JSValue method, ret, sync_iter;
|
||||||
|
|
||||||
|
@ -13707,7 +13707,7 @@ static JSValue JS_IteratorNext2(JSContext *ctx, JSValueConst enum_obj,
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue JS_IteratorNext(JSContext *ctx, JSValueConst enum_obj,
|
JSValue JS_IteratorNext(JSContext *ctx, JSValueConst enum_obj,
|
||||||
JSValueConst method,
|
JSValueConst method,
|
||||||
int argc, JSValueConst *argv, BOOL *pdone)
|
int argc, JSValueConst *argv, BOOL *pdone)
|
||||||
{
|
{
|
||||||
|
@ -13898,7 +13898,7 @@ static JSValue js_create_array_iterator(JSContext *ctx, JSValueConst this_val,
|
||||||
int argc, JSValueConst *argv, int magic);
|
int argc, JSValueConst *argv, int magic);
|
||||||
|
|
||||||
/* Access an Array's internal JSValue array if available */
|
/* Access an Array's internal JSValue array if available */
|
||||||
static BOOL js_get_fast_array(JSContext *ctx, JSValueConst obj,
|
int js_get_fast_array(JSContext *ctx, JSValueConst obj,
|
||||||
JSValue **arrpp, uint32_t *countp)
|
JSValue **arrpp, uint32_t *countp)
|
||||||
{
|
{
|
||||||
/* Try and handle fast arrays explicitly */
|
/* Try and handle fast arrays explicitly */
|
||||||
|
|
|
@ -894,4 +894,8 @@ int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
|
||||||
#undef js_unlikely
|
#undef js_unlikely
|
||||||
#undef js_force_inline
|
#undef js_force_inline
|
||||||
|
|
||||||
|
// https://www.freelists.org/post/quickjs-devel/how-to-iterator-over-a-JSValue-object,1
|
||||||
|
int js_get_fast_array(JSContext *ctx, JSValueConst obj,
|
||||||
|
JSValue **arrpp, uint32_t *countp);
|
||||||
|
|
||||||
#endif /* QUICKJS_H */
|
#endif /* QUICKJS_H */
|
||||||
|
|
|
@ -32,7 +32,7 @@ bool ChartPacker::tryPack(float textureSize)
|
||||||
std::vector<maxRectsSize> rects;
|
std::vector<maxRectsSize> rects;
|
||||||
int width = textureSize * m_floatToIntFactor;
|
int width = textureSize * m_floatToIntFactor;
|
||||||
int height = width;
|
int height = width;
|
||||||
if (m_tryNum > 3) {
|
if (m_tryNum > 50) {
|
||||||
qDebug() << "Try the " << m_tryNum << "nth times pack with factor:" << m_textureSizeFactor << " size:" << width << "x" << height;
|
qDebug() << "Try the " << m_tryNum << "nth times pack with factor:" << m_textureSizeFactor << " size:" << width << "x" << height;
|
||||||
}
|
}
|
||||||
for (const auto &chartSize: m_chartSizes) {
|
for (const auto &chartSize: m_chartSizes) {
|
||||||
|
|
Loading…
Reference in New Issue