22
33#pragma once
44
5- #include " ../engine/engine.h"
65#include " ../scratch/target.h"
76#include " block.h"
87#include < map>
9- #include < iostream>
108
119namespace libscratchcpp
1210{
@@ -17,134 +15,21 @@ class LIBSCRATCHCPP_EXPORT RunningScript
1715 public:
1816 RunningScript (std::shared_ptr<Block> block, std::shared_ptr<Target> target, Engine *engine);
1917
20- /* ! Returns the current block. */
21- std::shared_ptr<Block> currentBlock () const { return m_currentBlock; }
18+ std::shared_ptr<Block> currentBlock () const ;
19+ void moveToNextBlock ();
2220
23- /* !
24- * Continues to the next block, cMouth() or to the first block of a C mouth.
25- * \note Use moveToSubstack() to move to the substack of e. g. a loop, or
26- * skipSubstack(), if it doesn't have one.
27- */
28- void moveToNextBlock ()
29- {
30- if (m_currentBlock) {
31- if (!m_currentBlock->next () && !m_tree.empty ()) {
32- bool ret = substackEnd ();
33- if (!ret)
34- return ;
35- moveToNextBlock ();
36- return ;
37- }
38- m_currentBlock = m_currentBlock->next ();
39- }
40- }
21+ std::shared_ptr<Block> cMouth ();
22+ void moveToSubstack (std::shared_ptr<Block> substackBlock);
23+ void moveToSubstack (const BlockArgs &args, int inputId);
24+ std::shared_ptr<Block> getSubstack (const BlockArgs &args, int inputId) const ;
25+ void skipSubstack ();
4126
42- /* ! Returns the C mouth block or nullptr if the block isn't in a C mouth. */
43- std::shared_ptr<Block> cMouth ()
44- {
45- if (m_tree.empty ())
46- return nullptr ;
47- return m_tree[m_tree.size () - 1 ].first ;
48- }
27+ std::shared_ptr<Target> target () const ;
4928
50- /* !
51- * Moves to a substack, e. g. in a loop.
52- * \note Please use the overloaded function with the list of inputs
53- * and the index of the substack input because it'll automatically
54- * check if there's a substack defined.
55- */
56- void moveToSubstack (std::shared_ptr<Block> substackBlock)
57- {
58- if (!substackBlock) {
59- std::cout << " warning: moving to null substack block (nothing will happen)" << std::endl;
60- return ;
61- }
62-
63- if (!m_currentBlock)
64- std::cout << " warning: " << substackBlock->id () << " : moving to substack from a null block" << std::endl;
65-
66- m_tree.push_back ({ m_currentBlock, substackBlock });
67- m_currentBlock = substackBlock;
68- m_engine->stayOnCurrentBlock ();
69- }
70-
71- /* !
72- * Moves to a substack, e. g. in a loop.
73- * \param[in] args The arguments passed to the block.
74- * \param[in] inputId The ID of the substack input (registered by the block section).
75- */
76- void moveToSubstack (const BlockArgs &args, int inputId)
77- {
78- auto substack = getSubstack (args, inputId);
79- if (substack)
80- moveToSubstack (substack);
81- else
82- skipSubstack ();
83- }
84-
85- /* !
86- * Finds the substack.
87- * \param[in] args The arguments passed to the block.
88- * \param[in] inputId The ID of the substack input (registered by the block section).
89- */
90- std::shared_ptr<Block> getSubstack (const BlockArgs &args, int inputId) const
91- {
92- auto block = args.block ();
93- auto input = block->findInputById (inputId);
94- if (input) {
95- auto ret = input->valueBlock ();
96- if (ret)
97- return ret;
98- }
99- return nullptr ;
100- }
101-
102- /* ! Use this to avoid passing a null block to moveToSubstack(). */
103- void skipSubstack ()
104- {
105- m_tree.push_back ({ m_currentBlock, nullptr });
106- m_currentBlock = nullptr ;
107- bool ret = substackEnd ();
108- if (!ret) {
109- m_tree.pop_back ();
110- m_engine->stayOnCurrentBlock ();
111- }
112- }
113-
114- /* ! Returns the Target which started the script. */
115- std::shared_ptr<Target> target () const { return m_target; }
116-
117- /* !
118- * Returns true if a block implementation has been
119- * called to check whether to break from a C mouth.
120- */
121- bool atCMouthEnd () const { return m_atCMouthEnd; }
29+ bool atCMouthEnd () const ;
12230
12331 private:
124- bool substackEnd ()
125- {
126- /*
127- * Call the C mouth block implementation
128- * to check whether to break from the C
129- * mouth or to jump to the beginning of it.
130- */
131- auto cMouthBlock = cMouth ();
132- m_atCMouthEnd = true ;
133- bool ret = cMouthBlock->run (this , true ).toBool ();
134- m_atCMouthEnd = false ;
135- if (!m_engine->isAtomic ())
136- m_engine->breakFrame ();
137- if (ret) {
138- m_currentBlock = cMouthBlock;
139- m_tree.pop_back ();
140- } else {
141- m_currentBlock = m_tree[m_tree.size () - 1 ].second ;
142- if (!m_currentBlock)
143- m_currentBlock = cMouthBlock;
144- }
145- return ret;
146- }
147-
32+ bool substackEnd ();
14833 std::shared_ptr<Block> m_currentBlock;
14934 // pair<C mouth block, first block of the substack>
15035 std::vector<std::pair<std::shared_ptr<Block>, std::shared_ptr<Block>>> m_tree;
0 commit comments