diff --git a/include/scratchcpp/iengine.h b/include/scratchcpp/iengine.h index 0d9d8fca..c6d2312a 100644 --- a/include/scratchcpp/iengine.h +++ b/include/scratchcpp/iengine.h @@ -15,6 +15,9 @@ class IBlockSection; class Broadcast; class Block; class Target; +class Sprite; +class Variable; +class List; class Script; /*! @@ -70,6 +73,9 @@ class LIBSCRATCHCPP_EXPORT IEngine */ virtual void stopTarget(Target *target, VirtualMachine *exceptScript) = 0; + /*! Calls the "when I start as a clone" blocks of the given sprite. */ + virtual void initClone(Sprite *clone) = 0; + /*! * Runs the event loop and calls "when green flag clicked" blocks. * \note This function returns when all scripts finish.\n @@ -157,6 +163,9 @@ class LIBSCRATCHCPP_EXPORT IEngine /*! Registers the broadcast script. */ virtual void addBroadcastScript(std::shared_ptr whenReceivedBlock, std::shared_ptr broadcast) = 0; + /* Registers the given "when I start as clone" script. */ + virtual void addCloneInitScript(std::shared_ptr hatBlock) = 0; + /*! Returns the list of targets. */ virtual const std::vector> &targets() const = 0; @@ -169,6 +178,12 @@ class LIBSCRATCHCPP_EXPORT IEngine /*! Returns the index of the target with the given name. */ virtual int findTarget(const std::string &targetName) const = 0; + /*! Returns the target which owns the given variable. If it is the stage, the variable is global. */ + virtual Target *variableOwner(Variable *variable) const = 0; + + /*! Returns the target which owns the given list. If it is the stage, the list is global. */ + virtual Target *listOwner(List *list) const = 0; + /*! Returns the list of extension names. */ virtual const std::vector &extensions() const = 0; diff --git a/include/scratchcpp/script.h b/include/scratchcpp/script.h index 8090d603..78afd2d4 100644 --- a/include/scratchcpp/script.h +++ b/include/scratchcpp/script.h @@ -15,6 +15,7 @@ class Target; class IEngine; class Value; class VirtualMachine; +class Variable; class List; class ScriptPrivate; @@ -25,6 +26,8 @@ class LIBSCRATCHCPP_EXPORT Script Script(Target *target, IEngine *engine); Script(const Script &) = delete; + Target *target() const; + unsigned int *bytecode() const; const std::vector &bytecodeVector() const; void setBytecode(const std::vector &code); @@ -32,10 +35,11 @@ class LIBSCRATCHCPP_EXPORT Script void setProcedures(const std::vector &procedures); void setFunctions(const std::vector &functions); void setConstValues(const std::vector &values); - void setVariables(const std::vector &variables); + void setVariables(const std::vector &variables); void setLists(const std::vector &lists); std::shared_ptr start(); + std::shared_ptr start(Target *target); private: spimpl::unique_impl_ptr impl; diff --git a/include/scratchcpp/sprite.h b/include/scratchcpp/sprite.h index d9ede3d5..dd50f56e 100644 --- a/include/scratchcpp/sprite.h +++ b/include/scratchcpp/sprite.h @@ -22,9 +22,19 @@ class LIBSCRATCHCPP_EXPORT Sprite : public Target }; Sprite(); + ~Sprite(); void setInterface(ISpriteHandler *newInterface); + std::shared_ptr clone(); + + bool isClone() const; + + Sprite *cloneRoot() const; + Sprite *cloneParent() const; + const std::vector> &children() const; + std::vector> allChildren() const; + bool visible() const; void setVisible(bool newVisible); @@ -50,6 +60,8 @@ class LIBSCRATCHCPP_EXPORT Sprite : public Target void setRotationStyle(const char *newRotationStyle); private: + Target *dataSource() const override; + spimpl::unique_impl_ptr impl; }; diff --git a/include/scratchcpp/target.h b/include/scratchcpp/target.h index 3a9b01a7..fe9e7e23 100644 --- a/include/scratchcpp/target.h +++ b/include/scratchcpp/target.h @@ -10,6 +10,7 @@ namespace libscratchcpp { +class IEngine; class Variable; class List; class Block; @@ -67,6 +68,13 @@ class LIBSCRATCHCPP_EXPORT Target int volume() const; void setVolume(int newVolume); + IEngine *engine() const; + void setEngine(IEngine *engine); + + protected: + /*! Override this method to set a custom data source for blocks and assets. */ + virtual Target *dataSource() const { return nullptr; } + private: spimpl::unique_impl_ptr impl; }; diff --git a/include/scratchcpp/virtualmachine.h b/include/scratchcpp/virtualmachine.h index 0e262cff..41dd40ea 100644 --- a/include/scratchcpp/virtualmachine.h +++ b/include/scratchcpp/virtualmachine.h @@ -102,6 +102,8 @@ class LIBSCRATCHCPP_EXPORT VirtualMachine void setConstValues(const Value *values); void setVariables(Value **variables); void setLists(List **lists); + void setVariablesVector(const std::vector &variables); + void setListsVector(const std::vector &lists); void setBytecode(unsigned int *code); diff --git a/src/engine/internal/engine.cpp b/src/engine/internal/engine.cpp index 2eefcca0..3572e4fa 100644 --- a/src/engine/internal/engine.cpp +++ b/src/engine/internal/engine.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -111,7 +112,7 @@ void Engine::compile() if (m_scripts.count(block) == 1) { m_scripts[block]->setProcedures(procedureBytecodes); m_scripts[block]->setConstValues(compiler.constValues()); - m_scripts[block]->setVariables(compiler.variablePtrs()); + m_scripts[block]->setVariables(compiler.variables()); m_scripts[block]->setLists(compiler.lists()); } } @@ -201,22 +202,21 @@ void Engine::broadcast(unsigned int index, VirtualMachine *sourceScript, bool wa const std::vector