Default scene API idea
diff --git a/include/rive/scene.hpp b/include/rive/scene.hpp index 90de466..a30da58 100644 --- a/include/rive/scene.hpp +++ b/include/rive/scene.hpp
@@ -51,6 +51,8 @@ virtual SMIBool* getBool(const std::string&) const; virtual SMINumber* getNumber(const std::string&) const; virtual SMITrigger* getTrigger(const std::string&) const; + + static std::unique_ptr<Scene> importDefault(Span<uint8_t>, Factory*); }; } // namespace rive
diff --git a/src/scene_default.cpp b/src/scene_default.cpp new file mode 100644 index 0000000..e85a7b4 --- /dev/null +++ b/src/scene_default.cpp
@@ -0,0 +1,58 @@ +#include "rive/artboard.hpp" +#include "rive/file.hpp" +#include "rive/scene.hpp" + +using namespace rive; + +class SelfContainedScene : public Scene { + std::unique_ptr<File> m_File; + std::unique_ptr<ArtboardInstance> m_ABI; + std::unique_ptr<Scene> m_Scene; + +public: + SelfContainedScene(std::unique_ptr<File> file, + std::unique_ptr<ArtboardInstance> abi, + std::unique_ptr<Scene> scene) + : Scene(abi.get()) + , m_File(std::move(file)) + , m_ABI(std::move(abi)) + , m_Scene(std::move(scene)) {} + + ~SelfContainedScene() = default; + + // Forward to our m_Scene + + std::string name() const { return m_Scene->name(); } + Loop loop() const { return m_Scene->loop(); } + bool isTranslucent() const { return m_Scene->isTranslucent(); } + float durationSeconds() const { return m_Scene->durationSeconds(); } + + bool advanceAndApply(float seconds) { return m_Scene->advanceAndApply(seconds); } + void draw(Renderer* renderer) { return m_Scene->draw(renderer); } + + void pointerDown(Vec2D pos) { return m_Scene->pointerDown(pos); } + void pointerMove(Vec2D pos) { return m_Scene->pointerMove(pos); } + void pointerUp(Vec2D pos) { return m_Scene->pointerUp(pos); } + + size_t inputCount() const { return m_Scene->inputCount(); } + SMIInput* input(size_t index) const { return m_Scene->input(index); } + SMIBool* getBool(const std::string& name) const { return m_Scene->getBool(name); } + SMINumber* getNumber(const std::string& name) const { return m_Scene->getNumber(name); } + SMITrigger* getTrigger(const std::string& name) const { return m_Scene->getTrigger(name); } +}; + +std::unique_ptr<Scene> Scene::importDefault(Span<uint8_t> span, Factory* factory) { + auto file = File::import(span, factory); + if (file) { + auto abi = file->artboardDefault(); + if (abi) { + auto scene = abi->defaultScene(); + if (scene) { + return std::make_unique<SelfContainedScene>(std::move(file), + std::move(abi), + std::move(scene)); + } + } + } + return nullptr; +} \ No newline at end of file
diff --git a/test/default_state_machine_test.cpp b/test/default_state_machine_test.cpp index bfe7d1a..54bae7d 100644 --- a/test/default_state_machine_test.cpp +++ b/test/default_state_machine_test.cpp
@@ -29,3 +29,9 @@ REQUIRE(scene != nullptr); REQUIRE(scene->name() == smi->name()); } + +TEST_CASE("load default scene", "[file]") { + auto bytes = ReadFile("../../test/assets/entry.riv"); + auto scene = rive::Scene::importDefault(rive::toSpan(bytes), &rive::gNoOpFactory); + REQUIRE(scene.get()); +} \ No newline at end of file
diff --git a/test/rive_file_reader.hpp b/test/rive_file_reader.hpp index 1076359..f06dd6e 100644 --- a/test/rive_file_reader.hpp +++ b/test/rive_file_reader.hpp
@@ -6,16 +6,9 @@ #include "no_op_factory.hpp" #include "../src/render_counter.hpp" -static inline std::unique_ptr<rive::File> -ReadRiveFile(const char path[], - rive::Factory* factory = nullptr, - rive::FileAssetResolver* resolver = nullptr) { - if (!factory) { - factory = &rive::gNoOpFactory; - } - +static inline std::vector<uint8_t> ReadFile(const char path[]) { FILE* fp = fopen(path, "rb"); - REQUIRE(fp != nullptr); + REQUIRE(fp); fseek(fp, 0, SEEK_END); const size_t length = ftell(fp); @@ -24,6 +17,19 @@ REQUIRE(fread(bytes.data(), 1, length, fp) == length); fclose(fp); + return bytes; +} + +static inline std::unique_ptr<rive::File> +ReadRiveFile(const char path[], + rive::Factory* factory = nullptr, + rive::FileAssetResolver* resolver = nullptr) { + if (!factory) { + factory = &rive::gNoOpFactory; + } + + auto bytes = ReadFile(path); + rive::ImportResult result; auto file = rive::File::import(rive::toSpan(bytes), factory, &result, resolver); REQUIRE(result == rive::ImportResult::success);