mirror of
https://github.com/rive-app/rive-cpp.git
synced 2026-01-18 13:11:19 +01:00
Fix libjpg on Mac Sonoma
Diffs= dde676085 Fix libjpg on Mac Sonoma (#7329) e0a786c90 Runtime API for Nested Inputs (#7316) Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com> Co-authored-by: Gordon Hayes <pggordonhayes@gmail.com> Co-authored-by: Philip Chung <philterdesign@gmail.com>
This commit is contained in:
@@ -1 +1 @@
|
||||
01d20e02661309cd2f8a0702f9de102107c1a0f1
|
||||
dde676085908d492af545660cbbb19ee0d10d91d
|
||||
|
||||
4
dependencies/jconfig.h
vendored
4
dependencies/jconfig.h
vendored
@@ -1,3 +1,5 @@
|
||||
#include <stdio.h> // Required on Mac -- libjpg expects FILE to be already defined.
|
||||
|
||||
#define HAVE_PROTOTYPES
|
||||
#define HAVE_UNSIGNED_CHAR
|
||||
#define HAVE_UNSIGNED_SHORT
|
||||
@@ -8,4 +10,4 @@
|
||||
#undef NEED_SYS_TYPES_H
|
||||
#undef NEED_FAR_POINTERS
|
||||
#undef NEED_SHORT_EXTERNAL_NAMES
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
#undef INCOMPLETE_TYPES_BROKEN
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef _RIVE_NESTED_INPUT_HPP_
|
||||
#define _RIVE_NESTED_INPUT_HPP_
|
||||
#include "rive/animation/nested_state_machine.hpp"
|
||||
#include "rive/animation/state_machine_input_instance.hpp"
|
||||
#include "rive/generated/animation/nested_input_base.hpp"
|
||||
#include <stdio.h>
|
||||
namespace rive
|
||||
@@ -21,7 +22,6 @@ public:
|
||||
|
||||
virtual void applyValue() {}
|
||||
|
||||
protected:
|
||||
SMIInput* input() const
|
||||
{
|
||||
auto parent = this->parent();
|
||||
@@ -34,6 +34,16 @@ protected:
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::string name() const
|
||||
{
|
||||
auto smi = input();
|
||||
if (smi != nullptr)
|
||||
{
|
||||
return smi->name();
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
};
|
||||
} // namespace rive
|
||||
|
||||
|
||||
@@ -30,6 +30,9 @@ public:
|
||||
HitResult pointerExit(Vec2D position);
|
||||
|
||||
void addNestedInput(NestedInput* input);
|
||||
size_t inputCount() { return m_nestedInputs.size(); }
|
||||
NestedInput* input(size_t index);
|
||||
NestedInput* input(std::string name);
|
||||
};
|
||||
} // namespace rive
|
||||
|
||||
|
||||
@@ -32,6 +32,10 @@ class StateMachineInstance;
|
||||
class Joystick;
|
||||
class TextValueRun;
|
||||
class Event;
|
||||
class SMIBool;
|
||||
class SMIInput;
|
||||
class SMINumber;
|
||||
class SMITrigger;
|
||||
|
||||
class Artboard : public ArtboardBase, public CoreContext, public ShapePaintContainer
|
||||
{
|
||||
@@ -120,6 +124,8 @@ public:
|
||||
|
||||
const std::vector<Core*>& objects() const { return m_Objects; }
|
||||
const std::vector<NestedArtboard*> nestedArtboards() const { return m_NestedArtboards; }
|
||||
NestedArtboard* nestedArtboard(const std::string& name) const;
|
||||
NestedArtboard* nestedArtboardAtPath(const std::string& path) const;
|
||||
|
||||
AABB bounds() const;
|
||||
|
||||
@@ -295,6 +301,13 @@ public:
|
||||
// 3. first animation instance
|
||||
// 4. nullptr
|
||||
std::unique_ptr<Scene> defaultScene();
|
||||
|
||||
SMIInput* input(const std::string& name, const std::string& path);
|
||||
template <typename InstType>
|
||||
InstType* getNamedInput(const std::string& name, const std::string& path);
|
||||
SMIBool* getBool(const std::string& name, const std::string& path);
|
||||
SMINumber* getNumber(const std::string& name, const std::string& path);
|
||||
SMITrigger* getTrigger(const std::string& name, const std::string& path);
|
||||
};
|
||||
} // namespace rive
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@ namespace rive
|
||||
{
|
||||
class ArtboardInstance;
|
||||
class NestedAnimation;
|
||||
class NestedInput;
|
||||
class NestedStateMachine;
|
||||
class StateMachineInstance;
|
||||
class NestedArtboard : public NestedArtboardBase
|
||||
{
|
||||
|
||||
@@ -37,6 +40,10 @@ public:
|
||||
|
||||
bool hasNestedStateMachines() const;
|
||||
Span<NestedAnimation*> nestedAnimations();
|
||||
NestedArtboard* nestedArtboard(std::string name) const;
|
||||
NestedStateMachine* stateMachine(std::string name) const;
|
||||
NestedInput* input(std::string name) const;
|
||||
NestedInput* input(std::string name, std::string stateMachineName) const;
|
||||
|
||||
/// Convert a world space (relative to the artboard that this
|
||||
/// NestedArtboard is a child of) to the local space of the Artboard
|
||||
|
||||
@@ -32,7 +32,6 @@ void NestedStateMachine::initializeAnimation(ArtboardInstance* artboard)
|
||||
nestedInput->applyValue();
|
||||
}
|
||||
}
|
||||
m_nestedInputs.clear();
|
||||
}
|
||||
|
||||
StateMachineInstance* NestedStateMachine::stateMachineInstance()
|
||||
@@ -76,4 +75,25 @@ HitResult NestedStateMachine::pointerExit(Vec2D position)
|
||||
return HitResult::none;
|
||||
}
|
||||
|
||||
NestedInput* NestedStateMachine::input(size_t index)
|
||||
{
|
||||
if (index < m_nestedInputs.size())
|
||||
{
|
||||
return m_nestedInputs[index];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NestedInput* NestedStateMachine::input(std::string name)
|
||||
{
|
||||
for (auto input : m_nestedInputs)
|
||||
{
|
||||
if (input->name() == name)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NestedStateMachine::addNestedInput(NestedInput* input) { m_nestedInputs.push_back(input); }
|
||||
@@ -15,6 +15,10 @@
|
||||
#include "rive/importers/backboard_importer.hpp"
|
||||
#include "rive/nested_artboard.hpp"
|
||||
#include "rive/joystick.hpp"
|
||||
#include "rive/animation/nested_bool.hpp"
|
||||
#include "rive/animation/nested_number.hpp"
|
||||
#include "rive/animation/nested_trigger.hpp"
|
||||
#include "rive/animation/state_machine_input_instance.hpp"
|
||||
#include "rive/animation/state_machine_instance.hpp"
|
||||
#include "rive/shapes/shape.hpp"
|
||||
#include "rive/text/text_value_run.hpp"
|
||||
@@ -758,6 +762,47 @@ int Artboard::defaultStateMachineIndex() const
|
||||
return index;
|
||||
}
|
||||
|
||||
NestedArtboard* Artboard::nestedArtboard(const std::string& name) const
|
||||
{
|
||||
for (auto nested : m_NestedArtboards)
|
||||
{
|
||||
if (nested->name() == name)
|
||||
{
|
||||
return nested;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NestedArtboard* Artboard::nestedArtboardAtPath(const std::string& path) const
|
||||
{
|
||||
// name parameter can be a name or a path to recursively find a nested artboard
|
||||
std::string delimiter = "/";
|
||||
size_t firstDelim = path.find(delimiter);
|
||||
std::string artboardName = firstDelim == std::string::npos ? path : path.substr(0, firstDelim);
|
||||
std::string restOfPath =
|
||||
firstDelim == std::string::npos ? "" : path.substr(firstDelim + 1, path.size());
|
||||
|
||||
// Find the nested artboard at this level
|
||||
if (!artboardName.empty())
|
||||
{
|
||||
auto nested = nestedArtboard(artboardName);
|
||||
if (nested != nullptr)
|
||||
{
|
||||
if (restOfPath.empty())
|
||||
{
|
||||
return nested;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto artboard = nested->artboard();
|
||||
return artboard->nestedArtboardAtPath(restOfPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// std::unique_ptr<ArtboardInstance> Artboard::instance() const
|
||||
// {
|
||||
// std::unique_ptr<ArtboardInstance> artboardClone(new ArtboardInstance);
|
||||
@@ -896,6 +941,43 @@ std::unique_ptr<Scene> ArtboardInstance::defaultScene()
|
||||
return scene;
|
||||
}
|
||||
|
||||
SMIInput* ArtboardInstance::input(const std::string& name, const std::string& path)
|
||||
{
|
||||
return getNamedInput<SMIInput>(name, path);
|
||||
}
|
||||
|
||||
template <typename InstType>
|
||||
InstType* ArtboardInstance::getNamedInput(const std::string& name, const std::string& path)
|
||||
{
|
||||
if (!path.empty())
|
||||
{
|
||||
auto nestedArtboard = nestedArtboardAtPath(path);
|
||||
if (nestedArtboard != nullptr)
|
||||
{
|
||||
auto input = nestedArtboard->input(name);
|
||||
if (input != nullptr && input->input() != nullptr)
|
||||
{
|
||||
return static_cast<InstType*>(input->input());
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SMIBool* ArtboardInstance::getBool(const std::string& name, const std::string& path)
|
||||
{
|
||||
return getNamedInput<SMIBool>(name, path);
|
||||
}
|
||||
|
||||
SMINumber* ArtboardInstance::getNumber(const std::string& name, const std::string& path)
|
||||
{
|
||||
return getNamedInput<SMINumber>(name, path);
|
||||
}
|
||||
SMITrigger* ArtboardInstance::getTrigger(const std::string& name, const std::string& path)
|
||||
{
|
||||
return getNamedInput<SMITrigger>(name, path);
|
||||
}
|
||||
|
||||
#ifdef EXTERNAL_RIVE_AUDIO_ENGINE
|
||||
rcp<AudioEngine> Artboard::audioEngine() const { return m_audioEngine; }
|
||||
void Artboard::audioEngine(rcp<AudioEngine> audioEngine)
|
||||
|
||||
@@ -164,6 +164,56 @@ bool NestedArtboard::hasNestedStateMachines() const
|
||||
|
||||
Span<NestedAnimation*> NestedArtboard::nestedAnimations() { return m_NestedAnimations; }
|
||||
|
||||
NestedArtboard* NestedArtboard::nestedArtboard(std::string name) const
|
||||
{
|
||||
if (m_Instance != nullptr)
|
||||
{
|
||||
return m_Instance->nestedArtboard(name);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NestedStateMachine* NestedArtboard::stateMachine(std::string name) const
|
||||
{
|
||||
for (auto animation : m_NestedAnimations)
|
||||
{
|
||||
if (animation->is<NestedStateMachine>() && animation->name() == name)
|
||||
{
|
||||
return animation->as<NestedStateMachine>();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NestedInput* NestedArtboard::input(std::string name) const { return input(name, ""); }
|
||||
|
||||
NestedInput* NestedArtboard::input(std::string name, std::string stateMachineName) const
|
||||
{
|
||||
if (!stateMachineName.empty())
|
||||
{
|
||||
auto nestedSM = stateMachine(stateMachineName);
|
||||
if (nestedSM != nullptr)
|
||||
{
|
||||
return nestedSM->input(name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto animation : m_NestedAnimations)
|
||||
{
|
||||
if (animation->is<NestedStateMachine>())
|
||||
{
|
||||
auto input = animation->as<NestedStateMachine>()->input(name);
|
||||
if (input != nullptr)
|
||||
{
|
||||
return input;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool NestedArtboard::worldToLocal(Vec2D world, Vec2D* local)
|
||||
{
|
||||
assert(local != nullptr);
|
||||
|
||||
BIN
test/assets/runtime_nested_inputs.riv
Normal file
BIN
test/assets/runtime_nested_inputs.riv
Normal file
Binary file not shown.
139
test/nested_input_test.cpp
Normal file
139
test/nested_input_test.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
#include "rive/core/binary_reader.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include "rive/nested_artboard.hpp"
|
||||
#include "rive/animation/nested_bool.hpp"
|
||||
#include "rive/animation/nested_input.hpp"
|
||||
#include "rive/animation/nested_number.hpp"
|
||||
#include "rive/animation/nested_trigger.hpp"
|
||||
#include "rive/animation/state_machine_instance.hpp"
|
||||
#include "rive/animation/state_machine_input_instance.hpp"
|
||||
#include "catch.hpp"
|
||||
#include "rive_file_reader.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
TEST_CASE("validate nested boolean get/set", "[nestedInput]")
|
||||
{
|
||||
auto file = ReadRiveFile("../../test/assets/runtime_nested_inputs.riv");
|
||||
|
||||
auto artboard = file->artboard("MainArtboard")->instance();
|
||||
REQUIRE(artboard != nullptr);
|
||||
REQUIRE(artboard->stateMachineCount() == 1);
|
||||
|
||||
// Test getting/setting boolean SMIInput via nested artboard path
|
||||
auto boolInput = artboard->getBool("CircleOuterState", "CircleOuter");
|
||||
auto smiInput = artboard->input("CircleOuterState", "CircleOuter");
|
||||
auto smiBoolInput = static_cast<rive::SMIBool*>(smiInput);
|
||||
auto nestedArtboard = artboard->nestedArtboard("CircleOuter");
|
||||
auto nestedInput = nestedArtboard->input("CircleOuterState")->as<rive::NestedBool>();
|
||||
REQUIRE(boolInput->value() == false);
|
||||
REQUIRE(smiBoolInput->value() == false);
|
||||
REQUIRE(nestedInput->nestedValue() == false);
|
||||
|
||||
boolInput->value(true);
|
||||
REQUIRE(boolInput->value() == true);
|
||||
REQUIRE(smiBoolInput->value() == true);
|
||||
REQUIRE(nestedInput->nestedValue() == true);
|
||||
|
||||
smiBoolInput->value(false);
|
||||
REQUIRE(boolInput->value() == false);
|
||||
REQUIRE(smiBoolInput->value() == false);
|
||||
REQUIRE(nestedInput->nestedValue() == false);
|
||||
|
||||
nestedInput->nestedValue(true);
|
||||
REQUIRE(boolInput->value() == true);
|
||||
REQUIRE(smiBoolInput->value() == true);
|
||||
REQUIRE(nestedInput->nestedValue() == true);
|
||||
}
|
||||
|
||||
TEST_CASE("validate nested number get/set", "[nestedInput]")
|
||||
{
|
||||
auto file = ReadRiveFile("../../test/assets/runtime_nested_inputs.riv");
|
||||
|
||||
auto artboard = file->artboard("MainArtboard")->instance();
|
||||
REQUIRE(artboard != nullptr);
|
||||
REQUIRE(artboard->stateMachineCount() == 1);
|
||||
|
||||
// Test getting/setting number SMIInput via nested artboard path
|
||||
auto numInput = artboard->getNumber("CircleOuterNumber", "CircleOuter");
|
||||
auto smiInput = artboard->input("CircleOuterNumber", "CircleOuter");
|
||||
auto smiNumInput = static_cast<rive::SMINumber*>(smiInput);
|
||||
auto nestedArtboard = artboard->nestedArtboardAtPath("CircleOuter");
|
||||
auto nestedInput = nestedArtboard->input("CircleOuterNumber")->as<rive::NestedNumber>();
|
||||
REQUIRE(numInput->value() == 0);
|
||||
REQUIRE(smiNumInput->value() == 0);
|
||||
REQUIRE(nestedInput->nestedValue() == 0);
|
||||
|
||||
numInput->value(10);
|
||||
REQUIRE(numInput->value() == 10);
|
||||
REQUIRE(smiNumInput->value() == 10);
|
||||
REQUIRE(nestedInput->nestedValue() == 10);
|
||||
|
||||
smiNumInput->value(5);
|
||||
REQUIRE(numInput->value() == 5);
|
||||
REQUIRE(smiNumInput->value() == 5);
|
||||
REQUIRE(nestedInput->nestedValue() == 5);
|
||||
|
||||
nestedInput->nestedValue(99);
|
||||
REQUIRE(numInput->value() == 99);
|
||||
REQUIRE(smiNumInput->value() == 99);
|
||||
REQUIRE(nestedInput->nestedValue() == 99);
|
||||
}
|
||||
|
||||
TEST_CASE("validate nested trigger fire", "[nestedInput]")
|
||||
{
|
||||
auto file = ReadRiveFile("../../test/assets/runtime_nested_inputs.riv");
|
||||
|
||||
auto artboard = file->artboard("MainArtboard")->instance();
|
||||
REQUIRE(artboard != nullptr);
|
||||
REQUIRE(artboard->stateMachineCount() == 1);
|
||||
|
||||
// Test getting/setting number SMIInput via nested artboard path
|
||||
auto tInput = artboard->getTrigger("CircleOuterTrigger", "CircleOuter");
|
||||
auto smiInput = artboard->input("CircleOuterTrigger", "CircleOuter");
|
||||
auto smiTInput = static_cast<rive::SMITrigger*>(smiInput);
|
||||
auto nestedArtboard = artboard->nestedArtboardAtPath("CircleOuter");
|
||||
auto nestedInput = nestedArtboard->input("CircleOuterTrigger")->as<rive::NestedTrigger>();
|
||||
auto nestedSMI = static_cast<rive::SMITrigger*>(nestedInput->input());
|
||||
REQUIRE(tInput->didFire() == false);
|
||||
REQUIRE(smiTInput->didFire() == false);
|
||||
REQUIRE(nestedSMI->didFire() == false);
|
||||
|
||||
tInput->fire();
|
||||
REQUIRE(tInput->didFire() == true);
|
||||
REQUIRE(smiTInput->didFire() == true);
|
||||
REQUIRE(nestedSMI->didFire() == true);
|
||||
}
|
||||
|
||||
TEST_CASE("validate nested boolean get/set multiple nested artboards deep", "[nestedInput]")
|
||||
{
|
||||
auto file = ReadRiveFile("../../test/assets/runtime_nested_inputs.riv");
|
||||
|
||||
auto artboard = file->artboard("MainArtboard")->instance();
|
||||
REQUIRE(artboard != nullptr);
|
||||
REQUIRE(artboard->stateMachineCount() == 1);
|
||||
|
||||
// Test getting/setting boolean SMIInput via nested artboard path
|
||||
auto boolInput = artboard->getBool("CircleInnerState", "CircleOuter/CircleInner");
|
||||
auto smiInput = artboard->input("CircleInnerState", "CircleOuter/CircleInner");
|
||||
auto smiBoolInput = static_cast<rive::SMIBool*>(smiInput);
|
||||
auto nestedArtboard = artboard->nestedArtboardAtPath("CircleOuter/CircleInner");
|
||||
auto nestedInput = nestedArtboard->input("CircleInnerState")->as<rive::NestedBool>();
|
||||
REQUIRE(boolInput->value() == false);
|
||||
REQUIRE(smiBoolInput->value() == false);
|
||||
REQUIRE(nestedInput->nestedValue() == false);
|
||||
|
||||
boolInput->value(true);
|
||||
REQUIRE(boolInput->value() == true);
|
||||
REQUIRE(smiBoolInput->value() == true);
|
||||
REQUIRE(nestedInput->nestedValue() == true);
|
||||
|
||||
smiBoolInput->value(false);
|
||||
REQUIRE(boolInput->value() == false);
|
||||
REQUIRE(smiBoolInput->value() == false);
|
||||
REQUIRE(nestedInput->nestedValue() == false);
|
||||
|
||||
nestedInput->nestedValue(true);
|
||||
REQUIRE(boolInput->value() == true);
|
||||
REQUIRE(smiBoolInput->value() == true);
|
||||
REQUIRE(nestedInput->nestedValue() == true);
|
||||
}
|
||||
Reference in New Issue
Block a user