@@ -85,13 +85,13 @@ void Engine::compile()
8585 variables = compiler.variables ();
8686 lists = compiler.lists ();
8787 constInputValues = compiler.constInputValues ();
88- auto vm = std::make_shared< VirtualMachine>( );
89- vm-> setFunctions (m_functions) ;
90- vm-> setConstValues (compiler. constValues () );
91- vm-> setVariables (compiler.variablePtrs ());
92- vm-> setLists (lists );
93- vm-> setBytecode (compiler. bytecode () );
94- m_scripts[block] = vm ;
88+ m_scripts[block] = VirtualMachine (target. get (), this );
89+ VirtualMachine &vm = m_scripts[block] ;
90+ vm. setFunctions (m_functions );
91+ vm. setConstValues (compiler.constValues ());
92+ vm. setVariables (compiler. variablePtrs () );
93+ vm. setLists (lists );
94+ vm. setBytecode (compiler. bytecode ()) ;
9595 } else
9696 std::cout << " warning: unsupported top level block: " << block->opcode () << std::endl;
9797 }
@@ -106,53 +106,24 @@ void Engine::compile()
106106 * \note Nothing will happen until start() is called.
107107 * \param[in] timeLimit The time limit for the frame (for atomic scripts). Set to 0 for no limit.
108108 */
109- void Engine::frame (std::chrono::milliseconds timeLimit )
109+ void Engine::frame ()
110110{
111- auto frameStartTime = std::chrono::steady_clock::now ();
112- std::vector<std::shared_ptr<RunningScript>> scriptsToRemove;
113- auto scripts = m_runningScripts;
114- for (auto script : scripts) {
115- std::shared_ptr<Block> block;
111+ for (VirtualMachine &script : m_runningScripts) {
116112 m_breakFrame = false ;
117- m_atomic = true ;
118113
119114 do {
120- block = script->currentBlock ();
121- if (!script->currentBlock ()) {
122- std::cout << " warning: encountered a null block in one of the scripts" << std::endl;
123- scriptsToRemove.push_back (script);
124- continue ;
125- }
126-
127- // Call the implementation of the block (if it has an implementation)
128- block->run (script.get ());
129-
130- // Move to next block
131- if (m_stayOnCurrentBlock) {
132- m_stayOnCurrentBlock = false ;
133- block = script->currentBlock ();
134- } else {
135- script->moveToNextBlock ();
136- block = script->currentBlock ();
137- if (!block) {
138- // There isn't any block to move to
139- // This means the script has finished
140- scriptsToRemove.push_back (script);
141- }
142- }
143-
144- if (timeLimit.count () > 0 ) {
145- auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now () - frameStartTime);
146- if (duration > timeLimit)
147- break ;
148- }
149- } while (block != nullptr && !m_breakFrame);
115+ script.run (nullptr );
116+ } while (script.atEnd () && !m_breakFrame);
150117 }
151118
152- for (auto script : scriptsToRemove) {
153- m_runningScripts.erase (std::remove (m_runningScripts.begin (), m_runningScripts.end (), script), m_runningScripts.end ());
119+ for (auto script : m_scriptsToRemove) {
120+ auto it = std::find (m_runningScriptPtrs.begin (), m_runningScriptPtrs.end (), script);
121+ auto index = it - m_runningScriptPtrs.begin ();
122+ m_runningScripts.erase (m_runningScripts.begin () + index);
123+ m_runningScriptPtrs.erase (m_runningScriptPtrs.begin () + index);
154124 scriptCount--;
155125 }
126+ m_scriptsToRemove.clear ();
156127}
157128
158129/* !
@@ -191,40 +162,30 @@ void Engine::startScript(std::shared_ptr<Block> topLevelBlock, std::shared_ptr<T
191162 }
192163
193164 if (topLevelBlock->next ()) {
194- auto script = std::make_shared<RunningScript>(topLevelBlock, target, this );
195- m_runningScripts.push_back (script);
196- script->moveToNextBlock ();
165+ m_runningScripts.push_back (m_scripts[topLevelBlock]);
166+ m_runningScriptPtrs.push_back (&m_runningScripts.back ());
197167 scriptCount++;
198168 }
199169}
200170
201171/* ! Stops the given script. */
202- void Engine::stopScript (RunningScript *script )
172+ void Engine::stopScript (VirtualMachine *vm )
203173{
204- assert (script);
205- int i = 0 ;
206- for (auto s : m_runningScripts) {
207- if (s.get () == script) {
208- m_runningScripts.erase (m_runningScripts.begin () + i);
209- break ;
210- }
211- i++;
212- }
213- scriptCount--;
174+ assert (vm);
175+ m_scriptsToRemove.push_back (vm);
214176}
215177
216178/* !
217179 * Stops all scripts in the given target.
218180 * \param[in] target The Target to stop.
219181 * \param[in] exceptScript Sets this parameter to stop all scripts except the given script.
220182 */
221- void Engine::stopTarget (Target *target, RunningScript *exceptScript)
183+ void Engine::stopTarget (Target *target, VirtualMachine *exceptScript)
222184{
223- std::vector<RunningScript *> scripts;
224- for (auto script : m_runningScripts) {
225- RunningScript *s = script.get ();
226- if ((script->target ().get () == target) && (s != exceptScript))
227- scripts.push_back (s);
185+ std::vector<VirtualMachine *> scripts;
186+ for (VirtualMachine &script : m_runningScripts) {
187+ if ((script.target () == target) && (&script != exceptScript))
188+ scripts.push_back (&script);
228189 }
229190
230191 for (auto script : scripts)
@@ -245,7 +206,7 @@ void Engine::run()
245206 while (true ) {
246207 auto lastFrameTime = std::chrono::steady_clock::now ();
247208 // Execute the frame
248- frame (frameDuration );
209+ frame ();
249210 if (scriptCount <= 0 )
250211 break ;
251212
0 commit comments