summaryrefslogtreecommitdiffstats
path: root/scriptwidget.cpp
diff options
context:
space:
mode:
authorSamuel Rødal <srodal@gmail.com>2008-11-30 17:41:26 +0100
committerSamuel Rødal <srodal@gmail.com>2008-11-30 17:41:26 +0100
commit8b9e2e330c6d5d97b4170703e543adbd555e8be7 (patch)
treed8443301bec8b121299e34920b79f30b81daf43f /scriptwidget.cpp
parent67ccfa20650a55f6c4301bf334a92998ba90f59e (diff)
Split into more source files.
Diffstat (limited to 'scriptwidget.cpp')
-rw-r--r--scriptwidget.cpp141
1 files changed, 141 insertions, 0 deletions
diff --git a/scriptwidget.cpp b/scriptwidget.cpp
new file mode 100644
index 0000000..9b6bbe6
--- /dev/null
+++ b/scriptwidget.cpp
@@ -0,0 +1,141 @@
+#include "scriptwidget.h"
+#include "mazescene.h"
+#include "entity.h"
+
+static QScriptValue qsRand(QScriptContext *, QScriptEngine *engine)
+{
+ QScriptValue value(engine, qrand() / (RAND_MAX + 1.0));
+ return value;
+}
+
+void ScriptWidget::setPreset(int preset)
+{
+ const char *presets[] =
+ {
+ "// available functions:\n"
+ "// entity.turnLeft()\n"
+ "// entity.turnRight()\n"
+ "// entity.turnTowards(x, y)\n"
+ "// entity.walk()\n"
+ "// entity.stop()\n"
+ "// rand()\n"
+ "// script.display()\n"
+ "\n"
+ "// available variables:\n"
+ "// my_x\n"
+ "// my_y\n"
+ "// player_x\n"
+ "// player_y\n"
+ "// time\n"
+ "\n"
+ "entity.stop();\n",
+ "entity.walk();\n"
+ "if ((time % 20000) < 10000) {\n"
+ " entity.turnTowards(10, 2.5);\n"
+ " if (my_x >= 5.5)\n"
+ " entity.stop();\n"
+ "} else {\n"
+ " entity.turnTowards(-10, 2.5);\n"
+ " if (my_x <= 2.5)\n"
+ " entity.stop();\n"
+ "}\n",
+ "dx = player_x - my_x;\n"
+ "dy = player_y - my_y;\n"
+ "if (dx * dx + dy * dy < 5) {\n"
+ " entity.stop();\n"
+ "} else {\n"
+ " entity.walk();\n"
+ " entity.turnTowards(player_x, player_y);\n"
+ "}\n"
+ };
+
+ m_sourceEdit->setPlainText(QLatin1String(presets[preset]));
+}
+
+ScriptWidget::ScriptWidget(MazeScene *scene, Entity *entity)
+ : m_scene(scene)
+ , m_entity(entity)
+{
+ new QVBoxLayout(this);
+
+ m_statusView = new QLineEdit;
+ m_statusView->setReadOnly(true);
+ layout()->addWidget(m_statusView);
+
+ m_sourceEdit = new QPlainTextEdit;
+ layout()->addWidget(m_sourceEdit);
+
+ QPushButton *compileButton = new QPushButton(QLatin1String("Compile"));
+ layout()->addWidget(compileButton);
+
+ QComboBox *combo = new QComboBox;
+ layout()->addWidget(combo);
+
+ combo->addItem(QLatin1String("Default"));
+ combo->addItem(QLatin1String("Patrol"));
+ combo->addItem(QLatin1String("Follow"));
+
+ setPreset(0);
+ connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(setPreset(int)));
+ connect(compileButton, SIGNAL(clicked()), this, SLOT(updateSource()));
+
+ m_engine = new QScriptEngine(this);
+ QScriptValue entityObject = m_engine->newQObject(m_entity);
+ m_engine->globalObject().setProperty("entity", entityObject);
+ QScriptValue widgetObject = m_engine->newQObject(this);
+ m_engine->globalObject().setProperty("script", widgetObject);
+ m_engine->globalObject().setProperty("rand", m_engine->newFunction(qsRand));
+
+ m_engine->setProcessEventsInterval(5);
+
+ resize(300, 400);
+ updateSource();
+
+ startTimer(50);
+ m_time.start();
+}
+
+void ScriptWidget::timerEvent(QTimerEvent *)
+{
+ QPointF player = m_scene->camera().pos();
+ QPointF entity = m_entity->pos();
+
+ QScriptValue px(m_engine, player.x());
+ QScriptValue py(m_engine, player.y());
+ QScriptValue ex(m_engine, entity.x());
+ QScriptValue ey(m_engine, entity.y());
+ QScriptValue time(m_engine, m_time.elapsed());
+
+ m_engine->globalObject().setProperty("player_x", px);
+ m_engine->globalObject().setProperty("player_y", py);
+ m_engine->globalObject().setProperty("my_x", ex);
+ m_engine->globalObject().setProperty("my_y", ey);
+ m_engine->globalObject().setProperty("time", time);
+
+ m_engine->evaluate(m_source);
+ if (m_engine->hasUncaughtException()) {
+ QString text = m_engine->uncaughtException().toString();
+ m_statusView->setText(text);
+ }
+}
+
+void ScriptWidget::display(QScriptValue value)
+{
+ m_statusView->setText(value.toString());
+}
+
+void ScriptWidget::updateSource()
+{
+ bool wasEvaluating = m_engine->isEvaluating();
+ if (wasEvaluating)
+ m_engine->abortEvaluation();
+
+ m_time.restart();
+ m_source = m_sourceEdit->toPlainText();
+ if (wasEvaluating)
+ m_statusView->setText(QLatin1String("Aborted long running evaluation!"));
+ else if (m_engine->canEvaluate(m_source))
+ m_statusView->setText(QLatin1String("Evaluation succeeded"));
+ else
+ m_statusView->setText(QLatin1String("Evaluation failed"));
+}