From 35bc799125eec0d0c839af56fd136c8e85793a56 Mon Sep 17 00:00:00 2001 From: David Gow Date: Wed, 24 Sep 2014 21:59:02 +0800 Subject: [PATCH] Initial support for scripting actions. --- src/Makefile | 2 +- src/debugscript.cpp | 97 +++++++++++++++++++++++++++++++++++++++++++++ src/debugscript.h | 52 ++++++++++++++++++++++++ src/main.cpp | 7 ++++ src/main.h | 16 ++++++++ src/test.script | 6 +++ 6 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 src/debugscript.cpp create mode 100644 src/debugscript.h create mode 100644 src/test.script diff --git a/src/Makefile b/src/Makefile index dba3b2a..31ea736 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,7 +3,7 @@ ARCH := $(shell uname -m) # TODO: stb_truetype doesn't compile with some of these warnings. CXX = g++ -std=c++11 -g -Wall -Werror -Wshadow -pedantic -rdynamic MAIN = main.o -OBJ = log.o real.o bezier.o document.o objectrenderer.o view.o screen.o graphicsbuffer.o framebuffer.o shaderprogram.o stb_truetype.o gl_core44.o path.o paranoidnumber.o quadtree.o +OBJ = log.o real.o bezier.o document.o objectrenderer.o view.o screen.o graphicsbuffer.o framebuffer.o shaderprogram.o stb_truetype.o gl_core44.o path.o paranoidnumber.o quadtree.o debugscript.o QT_INCLUDE := -I/usr/share/qt4/mkspecs/linux-g++-64 -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -Itests -I. QT_DEF := -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB diff --git a/src/debugscript.cpp b/src/debugscript.cpp new file mode 100644 index 0000000..b8746ed --- /dev/null +++ b/src/debugscript.cpp @@ -0,0 +1,97 @@ +#include "debugscript.h" + +#include + +using namespace IPDF; + +void DebugScript::ParseAction() +{ + std::string actionType; + inp >> actionType; + // Skip comments + while (actionType[0] == '#') + { + std::string tmp; + std::getline(inp, tmp); + inp >> std::ws >> actionType; + } + if (actionType == "loop") + { + inp >> currentAction.loops >> actionType; + } + else + { + currentAction.loops = 1; + } + + if (actionType == "wait") + { + currentAction.type = AT_WaitFrame; + return; + } + else if (actionType == "translate") + { + std::string _x, _y; + inp >> _x >> _y; + currentAction.type = AT_Translate; + currentAction.x = RealFromStr(_x.c_str()); + currentAction.y = RealFromStr(_y.c_str()); + return; + } + else if (actionType == "zoom") + { + std::string _x, _y, _z; + inp >> _x >> _y >> _z; + currentAction.type = AT_Zoom; + currentAction.x = RealFromStr(_x.c_str()); + currentAction.y = RealFromStr(_y.c_str()); + currentAction.z = RealFromStr(_z.c_str()); + return; + } + else if (actionType == "pxtranslate") + { + inp >> currentAction.ix >> currentAction.iy; + currentAction.type = AT_TranslatePx; + return; + } + else if (actionType == "pxzoom") + { + inp >> currentAction.ix >> currentAction.iy >> currentAction.iz; + currentAction.type = AT_ZoomPx; + return; + } + else if (actionType == "quit") + { + currentAction.type = AT_Quit; + } +} + +bool DebugScript::Execute(View *view, Screen *scr) +{ + if (currentAction.loops == 0) + ParseAction(); + + switch(currentAction.type) + { + case AT_Quit: + return true; + case AT_WaitFrame: + break; + case AT_Translate: + view->Translate(currentAction.x, currentAction.y); + break; + case AT_TranslatePx: + view->Translate(Real(currentAction.ix)/Real(scr->ViewportWidth()), Real(currentAction.iy)/Real(scr->ViewportHeight())); + break; + case AT_Zoom: + view->ScaleAroundPoint(currentAction.x, currentAction.y, currentAction.z); + break; + case AT_ZoomPx: + view->ScaleAroundPoint(Real(currentAction.ix)/Real(scr->ViewportWidth()),Real(currentAction.iy)/Real(scr->ViewportHeight()), Real(expf(-currentAction.iz/20.f))); + break; + default: + Fatal("Unknown script command in queue."); + } + currentAction.loops--; + return false; +} diff --git a/src/debugscript.h b/src/debugscript.h new file mode 100644 index 0000000..822819a --- /dev/null +++ b/src/debugscript.h @@ -0,0 +1,52 @@ +#ifndef _DEBUGSCRIPT_H +#define _DEBUGSCRIPT_H + +#include "real.h" +#include "view.h" +#include "screen.h" +#include +#include + +namespace IPDF +{ + +class DebugScript +{ +public: + void Load(const char *filename) + { + inp.open(filename); + } + bool Execute(View *view, Screen *scr); +private: + enum ActionType + { + AT_WaitFrame, + AT_Translate, + AT_Zoom, + AT_TranslatePx, + AT_ZoomPx, + AT_Quit + }; + + struct Action + { + ActionType type; + Real x, y; + int ix, iy; + Real z; + int iz; + int loops; + Action() : type(AT_WaitFrame), x(0), y(0), ix(0), iy(0), z(0), loops(0) {} + }; + + std::ifstream inp; + + Action currentAction; + + void ParseAction(); +}; + +} + +#endif diff --git a/src/main.cpp b/src/main.cpp index 31ccf2e..e20a7bf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,7 @@ #include bool ignore_sigfpe = false; +const char *script_filename; void sigfpe_handler(int sig) { @@ -154,6 +155,12 @@ int main(int argc, char ** argv) hide_control_panel = true; window_visible = !window_visible; break; + case 's': + hide_control_panel = true; + if (++i >= argc) + Fatal("Expected filename after -s switch"); + script_filename = argv[i]; + break; } } diff --git a/src/main.h b/src/main.h index b9da3d7..5b9d263 100644 --- a/src/main.h +++ b/src/main.h @@ -3,12 +3,16 @@ #include "document.h" #include "view.h" #include "screen.h" +#include "debugscript.h" #include using namespace std; using namespace IPDF; + +extern const char *script_filename; + inline void OverlayBMP(Document & doc, const char * input, const char * output, const Rect & bounds = Rect(0,0,1,1), const Colour & c = Colour(0.f,0.f,0.f,1.f)) { @@ -73,10 +77,16 @@ void RatCatcher(int x, int y, int buttons, int wheel, Screen * scr, View * view) inline void MainLoop(Document & doc, Screen & scr, View & view, int max_frames = -1) { // order is important... segfaults occur when screen (which inits GL) is not constructed first -_- + DebugScript script; scr.DebugFontInit("fonts/DejaVuSansMono.ttf"); scr.SetMouseHandler(RatCatcher); + if (script_filename) + { + script.Load(script_filename); + } + double total_cpu_time = 0; double total_gpu_time = 0; double total_real_time = 0; @@ -99,6 +109,12 @@ inline void MainLoop(Document & doc, Screen & scr, View & view, int max_frames = //view.ForceBufferDirty(); //view.ForceRenderDirty(); + if (script_filename) + { + if (script.Execute(&view, &scr)) + return; + } + view.Render(scr.ViewportWidth(), scr.ViewportHeight()); double cpu_frame = scr.GetLastFrameTimeCPU(); diff --git a/src/test.script b/src/test.script new file mode 100644 index 0000000..fecd5d7 --- /dev/null +++ b/src/test.script @@ -0,0 +1,6 @@ +# Test script for IPDF automation. +loop 1000 pxzoom 400 300 1 +translate 10.0 -3.0 +loop 100 wait +loop 1000 zoom 0.5 0.5 0.95 +quit -- 2.20.1