| #ifndef _RIVE_SCRIPT_ASSET_HPP_ |
| #define _RIVE_SCRIPT_ASSET_HPP_ |
| #ifdef WITH_RIVE_SCRIPTING |
| #include "rive/lua/rive_lua_libs.hpp" |
| #endif |
| #include "rive/file.hpp" |
| #include "rive/generated/assets/script_asset_base.hpp" |
| #include "rive/simple_array.hpp" |
| #include <stdio.h> |
| namespace rive |
| { |
| class Artboard; |
| class Component; |
| class DataBind; |
| class ScriptedObject; |
| |
| enum ScriptProtocol |
| { |
| utility, |
| node, |
| layout, |
| converter, |
| pathEffect |
| }; |
| |
| #ifdef WITH_RIVE_SCRIPTING |
| class ScriptAssetImporter; |
| #endif |
| |
| class ScriptInput |
| { |
| protected: |
| ScriptedObject* m_scriptedObject = nullptr; |
| DataBind* m_dataBind = nullptr; |
| |
| public: |
| virtual ~ScriptInput() {}; |
| virtual void initScriptedValue(); |
| virtual bool validateForScriptInit() = 0; |
| static ScriptInput* from(Core* component); |
| DataBind* dataBind() { return m_dataBind; } |
| void dataBind(DataBind* dataBind) { m_dataBind = dataBind; } |
| ScriptedObject* scriptedObject() { return m_scriptedObject; } |
| void scriptedObject(ScriptedObject* object) { m_scriptedObject = object; } |
| }; |
| |
| class OptionalScriptedMethods |
| { |
| private: |
| static const int m_advancesBit = 1 << 0; |
| static const int m_updatesBit = 1 << 1; |
| static const int m_measuresBit = 1 << 2; |
| static const int m_wantsPointerDownBit = 1 << 3; |
| static const int m_wantsPointerMoveBit = 1 << 4; |
| static const int m_wantsPointerUpBit = 1 << 5; |
| static const int m_wantsPointerExitBit = 1 << 6; |
| static const int m_wantsPointerCancelBit = 1 << 7; |
| static const int m_drawsBit = 1 << 8; |
| static const int m_initsBit = 1 << 9; |
| |
| int m_implementedMethods = 0; |
| |
| protected: |
| bool verifyImplementation(ScriptedObject* object, LuaState* luaState); |
| |
| public: |
| int implementedMethods() { return m_implementedMethods; } |
| void implementedMethods(int implemented) |
| { |
| m_implementedMethods = implemented; |
| } |
| bool listensToPointerEvents() |
| { |
| return (m_implementedMethods & |
| (m_wantsPointerDownBit | m_wantsPointerMoveBit | |
| m_wantsPointerUpBit | m_wantsPointerExitBit | |
| m_wantsPointerCancelBit)) != 0; |
| } |
| bool advances() { return (m_implementedMethods & m_advancesBit) != 0; } |
| bool updates() { return (m_implementedMethods & m_updatesBit) != 0; } |
| bool measures() { return (m_implementedMethods & m_measuresBit) != 0; } |
| bool wantsPointerDown() |
| { |
| return (m_implementedMethods & m_wantsPointerDownBit) != 0; |
| } |
| bool wantsPointerMove() |
| { |
| return (m_implementedMethods & m_wantsPointerMoveBit) != 0; |
| } |
| bool wantsPointerUp() |
| { |
| return (m_implementedMethods & m_wantsPointerUpBit) != 0; |
| } |
| bool wantsPointerExit() |
| { |
| return (m_implementedMethods & m_wantsPointerExitBit) != 0; |
| } |
| bool wantsPointerCancel() |
| { |
| return (m_implementedMethods & m_wantsPointerCancelBit) != 0; |
| } |
| bool draws() { return (m_implementedMethods & m_drawsBit) != 0; } |
| bool inits() { return (m_implementedMethods & m_initsBit) != 0; } |
| }; |
| |
| class ModuleDetails |
| { |
| public: |
| virtual ~ModuleDetails() = default; |
| virtual std::string moduleName() = 0; |
| virtual void registrationComplete(int ref) {} |
| virtual Span<uint8_t> moduleBytecode() { return Span<uint8_t>(); } |
| virtual bool isProtocolScript() = 0; |
| virtual bool verified() const { return false; } |
| void addMissingDependency(std::string name) { m_dependencies.insert(name); } |
| void clearMissingDependency(std::string name) |
| { |
| auto it = m_dependencies.find(name); |
| if (it != m_dependencies.end()) |
| { |
| m_dependencies.erase(it); |
| } |
| } |
| std::unordered_set<std::string> missingDependencies() |
| { |
| return m_dependencies; |
| } |
| |
| private: |
| std::unordered_set<std::string> m_dependencies; |
| }; |
| |
| class ScriptAsset : public ScriptAssetBase, |
| public OptionalScriptedMethods, |
| public ModuleDetails |
| { |
| |
| public: |
| #ifdef WITH_RIVE_SCRIPTING |
| friend class ScriptAssetImporter; |
| |
| bool verified() const override { return m_verified; } |
| Span<uint8_t> moduleBytecode() override { return m_bytecode; } |
| #endif |
| |
| bool initScriptedObject(ScriptedObject* object); |
| |
| /// Sets the bytecode from data with header format: |
| /// [flags:1] [signature:64 if signed] [luau_bytecode:N] |
| /// Flags byte: bits 0-6 = version, bit 7 = isSigned |
| /// Returns true if bytecode was set (verification is separate from return). |
| bool bytecode(Span<uint8_t> data); |
| |
| /// Bytecode provided via decode should only happen with in-band bytecode. |
| /// The signature will later be verified once file loading completes, so it |
| /// is immediately marked as unverified. |
| bool decode(SimpleArray<uint8_t>& data, Factory* factory) override; |
| |
| std::string fileExtension() const override { return "lua"; } |
| void file(File* value) { m_file = value; } |
| File* file() const { return m_file; } |
| #ifdef WITH_RIVE_SCRIPTING |
| LuaState* vm(); |
| void registrationComplete(int ref) override; |
| #endif |
| std::string moduleName() override { return name(); } |
| bool isProtocolScript() override { return !isModule(); } |
| |
| private: |
| File* m_file = nullptr; |
| #ifdef WITH_RIVE_SCRIPTING |
| bool m_scriptRegistered = false; |
| bool m_verified = false; |
| SimpleArray<uint8_t> m_bytecode; |
| bool m_initted = false; |
| #endif |
| |
| bool initScriptedObjectWith(ScriptedObject* object); |
| }; |
| } // namespace rive |
| |
| #endif |