diff --git a/.gitignore b/.gitignore index 72dd7775..b8b44699 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,21 @@ skia/**/build/android /build/android /skia/dependencies/skia_rive_optimized /skia/dependencies/skia-experimental +build/windows/obj +dev/test +skia/renderer/build +skia/viewer/build/windows/dependencies/imgui +skia/viewer/build/windows/dependencies/gl3w +skia/viewer/build/windows/dependencies/skia +skia/viewer/build/windows/dependencies/glfw +skia/viewer/build/windows/dependencies/glfw_build +skia/viewer/build/windows/dependencies/bin +skia/viewer/build/windows/bin +skia/viewer/build/windows/obj +skia/viewer/build/windows/*.sln +skia/viewer/build/windows/*.vcxproj +skia/viewer/build/windows/*.vcxproj.filters +skia/viewer/build/*.sln +skia/viewer/build/*.vcxproj +skia/viewer/build/*.vcxproj.filters +*.pdb diff --git a/dev/defs/animation/listener_action.json b/dev/defs/animation/listener_action.json new file mode 100644 index 00000000..a1f0b1c9 --- /dev/null +++ b/dev/defs/animation/listener_action.json @@ -0,0 +1,33 @@ +{ + "name": "ListenerAction", + "key": { + "int": 125, + "string": "listener_action" + }, + "abstract": true, + "properties": { + "listenerId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "0", + "key": { + "int": 226, + "string": "listenerId" + }, + "description": "Identifier used to track the StateMachineListener this result belongs to.", + "runtime": false + }, + "order": { + "type": "FractionalIndex", + "initialValue": "FractionalIndex.invalid", + "initialValueRuntime": "0", + "key": { + "int": 230, + "string": "order" + }, + "description": "Order value for condition in a transition.", + "runtime": false + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/listener_align_target.json b/dev/defs/animation/listener_align_target.json new file mode 100644 index 00000000..b34168f1 --- /dev/null +++ b/dev/defs/animation/listener_align_target.json @@ -0,0 +1,21 @@ +{ + "name": "ListenerAlignTarget", + "key": { + "int": 126, + "string": "listeneraligntarget" + }, + "extends": "animation/listener_action.json", + "properties": { + "targetId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "0", + "key": { + "int": 240, + "string": "targetid" + }, + "description": "Identifier used to track the object use as a target fo this listener action." + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/listener_input_change.json b/dev/defs/animation/listener_input_change.json index df4cd3b7..445b3e4d 100644 --- a/dev/defs/animation/listener_input_change.json +++ b/dev/defs/animation/listener_input_change.json @@ -5,19 +5,8 @@ "string": "listener_input_change" }, "abstract": true, + "extends": "animation/listener_action.json", "properties": { - "listenerId": { - "type": "Id", - "typeRuntime": "uint", - "initialValue": "Core.missingId", - "initialValueRuntime": "0", - "key": { - "int": 226, - "string": "listenerId" - }, - "description": "Identifier used to track the StateMachineListener this result belongs to.", - "runtime": false - }, "inputId": { "type": "Id", "typeRuntime": "uint", @@ -28,17 +17,6 @@ "string": "inputid" }, "description": "Id of the StateMachineInput referenced." - }, - "order": { - "type": "FractionalIndex", - "initialValue": "FractionalIndex.invalid", - "initialValueRuntime": "0", - "key": { - "int": 230, - "string": "order" - }, - "description": "Order value for condition in a transition.", - "runtime": false } } } \ No newline at end of file diff --git a/dev/defs/animation/nested_bool.json b/dev/defs/animation/nested_bool.json new file mode 100644 index 00000000..b55c59a2 --- /dev/null +++ b/dev/defs/animation/nested_bool.json @@ -0,0 +1,19 @@ +{ + "name": "NestedBool", + "key": { + "int": 123, + "string": "nestedBool" + }, + "extends": "animation/nested_input.json", + "properties": { + "nestedValue": { + "type": "bool", + "initialValue": "false", + "animates": true, + "key": { + "int": 238, + "string": "value" + } + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/nested_input.json b/dev/defs/animation/nested_input.json new file mode 100644 index 00000000..4fd8fe10 --- /dev/null +++ b/dev/defs/animation/nested_input.json @@ -0,0 +1,22 @@ +{ + "name": "NestedInput", + "key": { + "int": 121, + "string": "nestedinput" + }, + "abstract": true, + "extends": "component.json", + "properties": { + "inputId": { + "type": "Id", + "typeRuntime": "uint", + "initialValue": "Core.missingId", + "initialValueRuntime": "-1", + "key": { + "int": 237, + "string": "inputid" + }, + "description": "Identifier used to track the actual backing state machine input." + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/nested_number.json b/dev/defs/animation/nested_number.json new file mode 100644 index 00000000..7315cf12 --- /dev/null +++ b/dev/defs/animation/nested_number.json @@ -0,0 +1,19 @@ +{ + "name": "NestedNumber", + "key": { + "int": 124, + "string": "nestedNumber" + }, + "extends": "animation/nested_input.json", + "properties": { + "nestedValue": { + "type": "double", + "initialValue": "0", + "animates": true, + "key": { + "int": 239, + "string": "nestedValue" + } + } + } +} \ No newline at end of file diff --git a/dev/defs/animation/nested_trigger.json b/dev/defs/animation/nested_trigger.json new file mode 100644 index 00000000..ea7f0771 --- /dev/null +++ b/dev/defs/animation/nested_trigger.json @@ -0,0 +1,8 @@ +{ + "name": "NestedTrigger", + "key": { + "int": 122, + "string": "nestedTrigger" + }, + "extends": "animation/nested_input.json" +} \ No newline at end of file diff --git a/dev/defs/assets/layered_asset.json b/dev/defs/assets/layered_asset.json index 042381f8..09a1713e 100644 --- a/dev/defs/assets/layered_asset.json +++ b/dev/defs/assets/layered_asset.json @@ -4,6 +4,6 @@ "int": 119, "string": "layeredasset" }, - "runtime": false, - "extends": "assets/drawable_asset.json" + "extends": "assets/drawable_asset.json", + "runtime": false } \ No newline at end of file diff --git a/dev/defs/nested_animation.json b/dev/defs/nested_animation.json index 2d896277..db6cbfb2 100644 --- a/dev/defs/nested_animation.json +++ b/dev/defs/nested_animation.json @@ -5,7 +5,7 @@ "string": "nestedanimation" }, "abstract": true, - "extends": "component.json", + "extends": "container_component.json", "properties": { "animationId": { "type": "Id", diff --git a/include/rive/animation/listener_action.hpp b/include/rive/animation/listener_action.hpp new file mode 100644 index 00000000..1b786590 --- /dev/null +++ b/include/rive/animation/listener_action.hpp @@ -0,0 +1,15 @@ +#ifndef _RIVE_LISTENER_ACTION_HPP_ +#define _RIVE_LISTENER_ACTION_HPP_ +#include "rive/generated/animation/listener_action_base.hpp" +#include "rive/math/vec2d.hpp" + +namespace rive { + class StateMachineInstance; + class ListenerAction : public ListenerActionBase { + public: + StatusCode import(ImportStack& importStack) override; + virtual void perform(StateMachineInstance* stateMachineInstance, Vec2D position) const = 0; + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/listener_align_target.hpp b/include/rive/animation/listener_align_target.hpp new file mode 100644 index 00000000..aec3c899 --- /dev/null +++ b/include/rive/animation/listener_align_target.hpp @@ -0,0 +1,12 @@ +#ifndef _RIVE_LISTENER_ALIGN_TARGET_HPP_ +#define _RIVE_LISTENER_ALIGN_TARGET_HPP_ +#include "rive/generated/animation/listener_align_target_base.hpp" +#include +namespace rive { + class ListenerAlignTarget : public ListenerAlignTargetBase { + public: + void perform(StateMachineInstance* stateMachineInstance, Vec2D position) const override; + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/listener_bool_change.hpp b/include/rive/animation/listener_bool_change.hpp index 2bc6efba..d821ae10 100644 --- a/include/rive/animation/listener_bool_change.hpp +++ b/include/rive/animation/listener_bool_change.hpp @@ -6,7 +6,7 @@ namespace rive { class ListenerBoolChange : public ListenerBoolChangeBase { public: bool validateInputType(const StateMachineInput* input) const override; - void perform(StateMachineInstance* stateMachineInstance) const override; + void perform(StateMachineInstance* stateMachineInstance, Vec2D position) const override; }; } // namespace rive diff --git a/include/rive/animation/listener_input_change.hpp b/include/rive/animation/listener_input_change.hpp index c7ccc043..c71047f3 100644 --- a/include/rive/animation/listener_input_change.hpp +++ b/include/rive/animation/listener_input_change.hpp @@ -3,12 +3,10 @@ #include "rive/generated/animation/listener_input_change_base.hpp" namespace rive { - class StateMachineInstance; class StateMachineInput; class ListenerInputChange : public ListenerInputChangeBase { public: StatusCode import(ImportStack& importStack) override; - virtual void perform(StateMachineInstance* stateMachineInstance) const = 0; virtual bool validateInputType(const StateMachineInput* input) const { return true; } }; } // namespace rive diff --git a/include/rive/animation/listener_number_change.hpp b/include/rive/animation/listener_number_change.hpp index a20c911a..9f933d91 100644 --- a/include/rive/animation/listener_number_change.hpp +++ b/include/rive/animation/listener_number_change.hpp @@ -6,7 +6,7 @@ namespace rive { class ListenerNumberChange : public ListenerNumberChangeBase { public: bool validateInputType(const StateMachineInput* input) const override; - void perform(StateMachineInstance* stateMachineInstance) const override; + void perform(StateMachineInstance* stateMachineInstance, Vec2D position) const override; }; } // namespace rive diff --git a/include/rive/animation/listener_trigger_change.hpp b/include/rive/animation/listener_trigger_change.hpp index ab89e1fe..cc983769 100644 --- a/include/rive/animation/listener_trigger_change.hpp +++ b/include/rive/animation/listener_trigger_change.hpp @@ -6,7 +6,7 @@ namespace rive { class ListenerTriggerChange : public ListenerTriggerChangeBase { public: bool validateInputType(const StateMachineInput* input) const override; - void perform(StateMachineInstance* stateMachineInstance) const override; + void perform(StateMachineInstance* stateMachineInstance, Vec2D position) const override; }; } // namespace rive diff --git a/include/rive/animation/nested_bool.hpp b/include/rive/animation/nested_bool.hpp new file mode 100644 index 00000000..6b084aea --- /dev/null +++ b/include/rive/animation/nested_bool.hpp @@ -0,0 +1,11 @@ +#ifndef _RIVE_NESTED_BOOL_HPP_ +#define _RIVE_NESTED_BOOL_HPP_ +#include "rive/generated/animation/nested_bool_base.hpp" +#include +namespace rive { + class NestedBool : public NestedBoolBase { + public: + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/nested_input.hpp b/include/rive/animation/nested_input.hpp new file mode 100644 index 00000000..94c2b69f --- /dev/null +++ b/include/rive/animation/nested_input.hpp @@ -0,0 +1,11 @@ +#ifndef _RIVE_NESTED_INPUT_HPP_ +#define _RIVE_NESTED_INPUT_HPP_ +#include "rive/generated/animation/nested_input_base.hpp" +#include +namespace rive { + class NestedInput : public NestedInputBase { + public: + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/nested_number.hpp b/include/rive/animation/nested_number.hpp new file mode 100644 index 00000000..f4c2f12e --- /dev/null +++ b/include/rive/animation/nested_number.hpp @@ -0,0 +1,11 @@ +#ifndef _RIVE_NESTED_NUMBER_HPP_ +#define _RIVE_NESTED_NUMBER_HPP_ +#include "rive/generated/animation/nested_number_base.hpp" +#include +namespace rive { + class NestedNumber : public NestedNumberBase { + public: + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/nested_trigger.hpp b/include/rive/animation/nested_trigger.hpp new file mode 100644 index 00000000..2fc040b5 --- /dev/null +++ b/include/rive/animation/nested_trigger.hpp @@ -0,0 +1,11 @@ +#ifndef _RIVE_NESTED_TRIGGER_HPP_ +#define _RIVE_NESTED_TRIGGER_HPP_ +#include "rive/generated/animation/nested_trigger_base.hpp" +#include +namespace rive { + class NestedTrigger : public NestedTriggerBase { + public: + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/animation/state_machine_instance.hpp b/include/rive/animation/state_machine_instance.hpp index fa8fe6f8..c189b812 100644 --- a/include/rive/animation/state_machine_instance.hpp +++ b/include/rive/animation/state_machine_instance.hpp @@ -39,7 +39,7 @@ namespace rive { /// Provide a hitListener if you want to process a down or an up for the pointer position /// too. - void updateListeners(Vec2D position, ListenerType hitListener = ListenerType::updateHover); + void updateListeners(Vec2D position, ListenerType hitListener); template InstType* getNamedInput(const std::string& name) const; @@ -85,6 +85,10 @@ namespace rive { float durationSeconds() const override { return -1; } Loop loop() const override { return Loop::oneShot; } bool isTranslucent() const override { return true; } + + /// Allow anything referencing a concrete StateMachineInstace access to + /// the backing artboard (explicitly not allowed on Scenes). + Artboard* artboard() { return m_ArtboardInstance; } }; } // namespace rive #endif diff --git a/include/rive/animation/state_machine_listener.hpp b/include/rive/animation/state_machine_listener.hpp index 14bd60bc..bea27639 100644 --- a/include/rive/animation/state_machine_listener.hpp +++ b/include/rive/animation/state_machine_listener.hpp @@ -2,29 +2,31 @@ #define _RIVE_STATE_MACHINE_LISTENER_HPP_ #include "rive/generated/animation/state_machine_listener_base.hpp" #include "rive/listener_type.hpp" +#include "rive/math/vec2d.hpp" namespace rive { class Shape; class StateMachineListenerImporter; - class ListenerInputChange; + class ListenerAction; class StateMachineInstance; class StateMachineListener : public StateMachineListenerBase { friend class StateMachineListenerImporter; private: std::vector m_HitShapesIds; - std::vector m_InputChanges; - void addInputChange(ListenerInputChange* inputChange); + std::vector m_Actions; + void addAction(ListenerAction* action); public: ListenerType listenerType() const { return (ListenerType)listenerTypeValue(); } - size_t inputChangeCount() const { return m_InputChanges.size(); } - const ListenerInputChange* inputChange(size_t index) const; + size_t actionCount() const { return m_Actions.size(); } + + const ListenerAction* action(size_t index) const; StatusCode import(ImportStack& importStack) override; StatusCode onAddedClean(CoreContext* context) override; const std::vector& hitShapeIds() const { return m_HitShapesIds; } - void performChanges(StateMachineInstance* stateMachineInstance) const; + void performChanges(StateMachineInstance* stateMachineInstance, Vec2D position) const; }; } // namespace rive diff --git a/include/rive/generated/animation/listener_action_base.hpp b/include/rive/generated/animation/listener_action_base.hpp new file mode 100644 index 00000000..e73cb1cd --- /dev/null +++ b/include/rive/generated/animation/listener_action_base.hpp @@ -0,0 +1,33 @@ +#ifndef _RIVE_LISTENER_ACTION_BASE_HPP_ +#define _RIVE_LISTENER_ACTION_BASE_HPP_ +#include "rive/core.hpp" +namespace rive { + class ListenerActionBase : public Core { + protected: + typedef Core Super; + + public: + static const uint16_t typeKey = 125; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override { + switch (typeKey) { + case ListenerActionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + void copy(const ListenerActionBase& object) {} + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { return false; } + + protected: + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/listener_align_target_base.hpp b/include/rive/generated/animation/listener_align_target_base.hpp new file mode 100644 index 00000000..d7e8c867 --- /dev/null +++ b/include/rive/generated/animation/listener_align_target_base.hpp @@ -0,0 +1,62 @@ +#ifndef _RIVE_LISTENER_ALIGN_TARGET_BASE_HPP_ +#define _RIVE_LISTENER_ALIGN_TARGET_BASE_HPP_ +#include "rive/animation/listener_action.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive { + class ListenerAlignTargetBase : public ListenerAction { + protected: + typedef ListenerAction Super; + + public: + static const uint16_t typeKey = 126; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override { + switch (typeKey) { + case ListenerAlignTargetBase::typeKey: + case ListenerActionBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t targetIdPropertyKey = 240; + + private: + uint32_t m_TargetId = 0; + + public: + inline uint32_t targetId() const { return m_TargetId; } + void targetId(uint32_t value) { + if (m_TargetId == value) { + return; + } + m_TargetId = value; + targetIdChanged(); + } + + Core* clone() const override; + void copy(const ListenerAlignTargetBase& object) { + m_TargetId = object.m_TargetId; + ListenerAction::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { + switch (propertyKey) { + case targetIdPropertyKey: + m_TargetId = CoreUintType::deserialize(reader); + return true; + } + return ListenerAction::deserialize(propertyKey, reader); + } + + protected: + virtual void targetIdChanged() {} + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/listener_bool_change_base.hpp b/include/rive/generated/animation/listener_bool_change_base.hpp index e4e667bd..c7d87c8d 100644 --- a/include/rive/generated/animation/listener_bool_change_base.hpp +++ b/include/rive/generated/animation/listener_bool_change_base.hpp @@ -16,6 +16,7 @@ namespace rive { switch (typeKey) { case ListenerBoolChangeBase::typeKey: case ListenerInputChangeBase::typeKey: + case ListenerActionBase::typeKey: return true; default: return false; diff --git a/include/rive/generated/animation/listener_input_change_base.hpp b/include/rive/generated/animation/listener_input_change_base.hpp index f4dca8ab..ef825528 100644 --- a/include/rive/generated/animation/listener_input_change_base.hpp +++ b/include/rive/generated/animation/listener_input_change_base.hpp @@ -1,11 +1,11 @@ #ifndef _RIVE_LISTENER_INPUT_CHANGE_BASE_HPP_ #define _RIVE_LISTENER_INPUT_CHANGE_BASE_HPP_ -#include "rive/core.hpp" +#include "rive/animation/listener_action.hpp" #include "rive/core/field_types/core_uint_type.hpp" namespace rive { - class ListenerInputChangeBase : public Core { + class ListenerInputChangeBase : public ListenerAction { protected: - typedef Core Super; + typedef ListenerAction Super; public: static const uint16_t typeKey = 116; @@ -15,6 +15,7 @@ namespace rive { bool isTypeOf(uint16_t typeKey) const override { switch (typeKey) { case ListenerInputChangeBase::typeKey: + case ListenerActionBase::typeKey: return true; default: return false; @@ -38,7 +39,10 @@ namespace rive { inputIdChanged(); } - void copy(const ListenerInputChangeBase& object) { m_InputId = object.m_InputId; } + void copy(const ListenerInputChangeBase& object) { + m_InputId = object.m_InputId; + ListenerAction::copy(object); + } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { switch (propertyKey) { @@ -46,7 +50,7 @@ namespace rive { m_InputId = CoreUintType::deserialize(reader); return true; } - return false; + return ListenerAction::deserialize(propertyKey, reader); } protected: diff --git a/include/rive/generated/animation/listener_number_change_base.hpp b/include/rive/generated/animation/listener_number_change_base.hpp index 54a72090..8106d29f 100644 --- a/include/rive/generated/animation/listener_number_change_base.hpp +++ b/include/rive/generated/animation/listener_number_change_base.hpp @@ -16,6 +16,7 @@ namespace rive { switch (typeKey) { case ListenerNumberChangeBase::typeKey: case ListenerInputChangeBase::typeKey: + case ListenerActionBase::typeKey: return true; default: return false; diff --git a/include/rive/generated/animation/listener_trigger_change_base.hpp b/include/rive/generated/animation/listener_trigger_change_base.hpp index 14985b3d..7e828323 100644 --- a/include/rive/generated/animation/listener_trigger_change_base.hpp +++ b/include/rive/generated/animation/listener_trigger_change_base.hpp @@ -15,6 +15,7 @@ namespace rive { switch (typeKey) { case ListenerTriggerChangeBase::typeKey: case ListenerInputChangeBase::typeKey: + case ListenerActionBase::typeKey: return true; default: return false; diff --git a/include/rive/generated/animation/nested_bool_base.hpp b/include/rive/generated/animation/nested_bool_base.hpp new file mode 100644 index 00000000..781fcfcb --- /dev/null +++ b/include/rive/generated/animation/nested_bool_base.hpp @@ -0,0 +1,63 @@ +#ifndef _RIVE_NESTED_BOOL_BASE_HPP_ +#define _RIVE_NESTED_BOOL_BASE_HPP_ +#include "rive/animation/nested_input.hpp" +#include "rive/core/field_types/core_bool_type.hpp" +namespace rive { + class NestedBoolBase : public NestedInput { + protected: + typedef NestedInput Super; + + public: + static const uint16_t typeKey = 123; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override { + switch (typeKey) { + case NestedBoolBase::typeKey: + case NestedInputBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t nestedValuePropertyKey = 238; + + private: + bool m_NestedValue = false; + + public: + inline bool nestedValue() const { return m_NestedValue; } + void nestedValue(bool value) { + if (m_NestedValue == value) { + return; + } + m_NestedValue = value; + nestedValueChanged(); + } + + Core* clone() const override; + void copy(const NestedBoolBase& object) { + m_NestedValue = object.m_NestedValue; + NestedInput::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { + switch (propertyKey) { + case nestedValuePropertyKey: + m_NestedValue = CoreBoolType::deserialize(reader); + return true; + } + return NestedInput::deserialize(propertyKey, reader); + } + + protected: + virtual void nestedValueChanged() {} + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/nested_input_base.hpp b/include/rive/generated/animation/nested_input_base.hpp new file mode 100644 index 00000000..df1fa054 --- /dev/null +++ b/include/rive/generated/animation/nested_input_base.hpp @@ -0,0 +1,61 @@ +#ifndef _RIVE_NESTED_INPUT_BASE_HPP_ +#define _RIVE_NESTED_INPUT_BASE_HPP_ +#include "rive/component.hpp" +#include "rive/core/field_types/core_uint_type.hpp" +namespace rive { + class NestedInputBase : public Component { + protected: + typedef Component Super; + + public: + static const uint16_t typeKey = 121; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override { + switch (typeKey) { + case NestedInputBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t inputIdPropertyKey = 237; + + private: + uint32_t m_InputId = -1; + + public: + inline uint32_t inputId() const { return m_InputId; } + void inputId(uint32_t value) { + if (m_InputId == value) { + return; + } + m_InputId = value; + inputIdChanged(); + } + + void copy(const NestedInputBase& object) { + m_InputId = object.m_InputId; + Component::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { + switch (propertyKey) { + case inputIdPropertyKey: + m_InputId = CoreUintType::deserialize(reader); + return true; + } + return Component::deserialize(propertyKey, reader); + } + + protected: + virtual void inputIdChanged() {} + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/nested_linear_animation_base.hpp b/include/rive/generated/animation/nested_linear_animation_base.hpp index 766a3357..a749818c 100644 --- a/include/rive/generated/animation/nested_linear_animation_base.hpp +++ b/include/rive/generated/animation/nested_linear_animation_base.hpp @@ -16,6 +16,7 @@ namespace rive { switch (typeKey) { case NestedLinearAnimationBase::typeKey: case NestedAnimationBase::typeKey: + case ContainerComponentBase::typeKey: case ComponentBase::typeKey: return true; default: diff --git a/include/rive/generated/animation/nested_number_base.hpp b/include/rive/generated/animation/nested_number_base.hpp new file mode 100644 index 00000000..3847b201 --- /dev/null +++ b/include/rive/generated/animation/nested_number_base.hpp @@ -0,0 +1,63 @@ +#ifndef _RIVE_NESTED_NUMBER_BASE_HPP_ +#define _RIVE_NESTED_NUMBER_BASE_HPP_ +#include "rive/animation/nested_input.hpp" +#include "rive/core/field_types/core_double_type.hpp" +namespace rive { + class NestedNumberBase : public NestedInput { + protected: + typedef NestedInput Super; + + public: + static const uint16_t typeKey = 124; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override { + switch (typeKey) { + case NestedNumberBase::typeKey: + case NestedInputBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + static const uint16_t nestedValuePropertyKey = 239; + + private: + float m_NestedValue = 0.0f; + + public: + inline float nestedValue() const { return m_NestedValue; } + void nestedValue(float value) { + if (m_NestedValue == value) { + return; + } + m_NestedValue = value; + nestedValueChanged(); + } + + Core* clone() const override; + void copy(const NestedNumberBase& object) { + m_NestedValue = object.m_NestedValue; + NestedInput::copy(object); + } + + bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { + switch (propertyKey) { + case nestedValuePropertyKey: + m_NestedValue = CoreDoubleType::deserialize(reader); + return true; + } + return NestedInput::deserialize(propertyKey, reader); + } + + protected: + virtual void nestedValueChanged() {} + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/animation/nested_remap_animation_base.hpp b/include/rive/generated/animation/nested_remap_animation_base.hpp index f8eadcb3..a743a908 100644 --- a/include/rive/generated/animation/nested_remap_animation_base.hpp +++ b/include/rive/generated/animation/nested_remap_animation_base.hpp @@ -17,6 +17,7 @@ namespace rive { case NestedRemapAnimationBase::typeKey: case NestedLinearAnimationBase::typeKey: case NestedAnimationBase::typeKey: + case ContainerComponentBase::typeKey: case ComponentBase::typeKey: return true; default: diff --git a/include/rive/generated/animation/nested_simple_animation_base.hpp b/include/rive/generated/animation/nested_simple_animation_base.hpp index 9c6e3573..d51e9417 100644 --- a/include/rive/generated/animation/nested_simple_animation_base.hpp +++ b/include/rive/generated/animation/nested_simple_animation_base.hpp @@ -18,6 +18,7 @@ namespace rive { case NestedSimpleAnimationBase::typeKey: case NestedLinearAnimationBase::typeKey: case NestedAnimationBase::typeKey: + case ContainerComponentBase::typeKey: case ComponentBase::typeKey: return true; default: diff --git a/include/rive/generated/animation/nested_state_machine_base.hpp b/include/rive/generated/animation/nested_state_machine_base.hpp index b6708a56..407de9d3 100644 --- a/include/rive/generated/animation/nested_state_machine_base.hpp +++ b/include/rive/generated/animation/nested_state_machine_base.hpp @@ -15,6 +15,7 @@ namespace rive { switch (typeKey) { case NestedStateMachineBase::typeKey: case NestedAnimationBase::typeKey: + case ContainerComponentBase::typeKey: case ComponentBase::typeKey: return true; default: diff --git a/include/rive/generated/animation/nested_trigger_base.hpp b/include/rive/generated/animation/nested_trigger_base.hpp new file mode 100644 index 00000000..61a9c322 --- /dev/null +++ b/include/rive/generated/animation/nested_trigger_base.hpp @@ -0,0 +1,33 @@ +#ifndef _RIVE_NESTED_TRIGGER_BASE_HPP_ +#define _RIVE_NESTED_TRIGGER_BASE_HPP_ +#include "rive/animation/nested_input.hpp" +namespace rive { + class NestedTriggerBase : public NestedInput { + protected: + typedef NestedInput Super; + + public: + static const uint16_t typeKey = 122; + + /// Helper to quickly determine if a core object extends another without RTTI + /// at runtime. + bool isTypeOf(uint16_t typeKey) const override { + switch (typeKey) { + case NestedTriggerBase::typeKey: + case NestedInputBase::typeKey: + case ComponentBase::typeKey: + return true; + default: + return false; + } + } + + uint16_t coreType() const override { return typeKey; } + + Core* clone() const override; + + protected: + }; +} // namespace rive + +#endif \ No newline at end of file diff --git a/include/rive/generated/core_registry.hpp b/include/rive/generated/core_registry.hpp index ed1a0f7b..ad48ce90 100644 --- a/include/rive/generated/core_registry.hpp +++ b/include/rive/generated/core_registry.hpp @@ -22,14 +22,20 @@ #include "rive/animation/keyframe_id.hpp" #include "rive/animation/layer_state.hpp" #include "rive/animation/linear_animation.hpp" +#include "rive/animation/listener_action.hpp" +#include "rive/animation/listener_align_target.hpp" #include "rive/animation/listener_bool_change.hpp" #include "rive/animation/listener_input_change.hpp" #include "rive/animation/listener_number_change.hpp" #include "rive/animation/listener_trigger_change.hpp" +#include "rive/animation/nested_bool.hpp" +#include "rive/animation/nested_input.hpp" #include "rive/animation/nested_linear_animation.hpp" +#include "rive/animation/nested_number.hpp" #include "rive/animation/nested_remap_animation.hpp" #include "rive/animation/nested_simple_animation.hpp" #include "rive/animation/nested_state_machine.hpp" +#include "rive/animation/nested_trigger.hpp" #include "rive/animation/state_machine.hpp" #include "rive/animation/state_machine_bool.hpp" #include "rive/animation/state_machine_component.hpp" @@ -137,6 +143,8 @@ namespace rive { return new NestedSimpleAnimation(); case AnimationStateBase::typeKey: return new AnimationState(); + case NestedTriggerBase::typeKey: + return new NestedTrigger(); case KeyedObjectBase::typeKey: return new KeyedObject(); case BlendAnimationDirectBase::typeKey: @@ -155,6 +163,8 @@ namespace rive { return new KeyFrameBool(); case ListenerBoolChangeBase::typeKey: return new ListenerBoolChange(); + case ListenerAlignTargetBase::typeKey: + return new ListenerAlignTarget(); case TransitionNumberConditionBase::typeKey: return new TransitionNumberCondition(); case AnyStateBase::typeKey: @@ -169,6 +179,8 @@ namespace rive { return new CubicInterpolator(); case StateTransitionBase::typeKey: return new StateTransition(); + case NestedBoolBase::typeKey: + return new NestedBool(); case KeyFrameDoubleBase::typeKey: return new KeyFrameDouble(); case KeyFrameColorBase::typeKey: @@ -189,6 +201,8 @@ namespace rive { return new NestedStateMachine(); case ExitStateBase::typeKey: return new ExitState(); + case NestedNumberBase::typeKey: + return new NestedNumber(); case BlendState1DBase::typeKey: return new BlendState1D(); case NestedRemapAnimationBase::typeKey: @@ -337,6 +351,9 @@ namespace rive { case AnimationStateBase::animationIdPropertyKey: object->as()->animationId(value); break; + case NestedInputBase::inputIdPropertyKey: + object->as()->inputId(value); + break; case KeyedObjectBase::objectIdPropertyKey: object->as()->objectId(value); break; @@ -373,6 +390,9 @@ namespace rive { case ListenerBoolChangeBase::valuePropertyKey: object->as()->value(value); break; + case ListenerAlignTargetBase::targetIdPropertyKey: + object->as()->targetId(value); + break; case TransitionValueConditionBase::opValuePropertyKey: object->as()->opValue(value); break; @@ -545,6 +565,9 @@ namespace rive { case LinearAnimationBase::speedPropertyKey: object->as()->speed(value); break; + case NestedNumberBase::nestedValuePropertyKey: + object->as()->nestedValue(value); + break; case NestedRemapAnimationBase::timePropertyKey: object->as()->time(value); break; @@ -756,6 +779,9 @@ namespace rive { case KeyFrameBoolBase::valuePropertyKey: object->as()->value(value); break; + case NestedBoolBase::nestedValuePropertyKey: + object->as()->nestedValue(value); + break; case LinearAnimationBase::enableWorkAreaPropertyKey: object->as()->enableWorkArea(value); break; @@ -840,6 +866,8 @@ namespace rive { return object->as()->inputId(); case AnimationStateBase::animationIdPropertyKey: return object->as()->animationId(); + case NestedInputBase::inputIdPropertyKey: + return object->as()->inputId(); case KeyedObjectBase::objectIdPropertyKey: return object->as()->objectId(); case BlendAnimationBase::animationIdPropertyKey: @@ -864,6 +892,8 @@ namespace rive { return object->as()->value(); case ListenerBoolChangeBase::valuePropertyKey: return object->as()->value(); + case ListenerAlignTargetBase::targetIdPropertyKey: + return object->as()->targetId(); case TransitionValueConditionBase::opValuePropertyKey: return object->as()->opValue(); case StateTransitionBase::stateToIdPropertyKey: @@ -981,6 +1011,8 @@ namespace rive { return object->as()->value(); case LinearAnimationBase::speedPropertyKey: return object->as()->speed(); + case NestedNumberBase::nestedValuePropertyKey: + return object->as()->nestedValue(); case NestedRemapAnimationBase::timePropertyKey: return object->as()->time(); case BlendAnimation1DBase::valuePropertyKey: @@ -1124,6 +1156,8 @@ namespace rive { return object->as()->isPlaying(); case KeyFrameBoolBase::valuePropertyKey: return object->as()->value(); + case NestedBoolBase::nestedValuePropertyKey: + return object->as()->nestedValue(); case LinearAnimationBase::enableWorkAreaPropertyKey: return object->as()->enableWorkArea(); case StateMachineBoolBase::valuePropertyKey: @@ -1176,6 +1210,7 @@ namespace rive { case NestedAnimationBase::animationIdPropertyKey: case ListenerInputChangeBase::inputIdPropertyKey: case AnimationStateBase::animationIdPropertyKey: + case NestedInputBase::inputIdPropertyKey: case KeyedObjectBase::objectIdPropertyKey: case BlendAnimationBase::animationIdPropertyKey: case BlendAnimationDirectBase::inputIdPropertyKey: @@ -1188,6 +1223,7 @@ namespace rive { case KeyFrameBase::interpolatorIdPropertyKey: case KeyFrameIdBase::valuePropertyKey: case ListenerBoolChangeBase::valuePropertyKey: + case ListenerAlignTargetBase::targetIdPropertyKey: case TransitionValueConditionBase::opValuePropertyKey: case StateTransitionBase::stateToIdPropertyKey: case StateTransitionBase::flagsPropertyKey: @@ -1245,6 +1281,7 @@ namespace rive { case CubicInterpolatorBase::y2PropertyKey: case KeyFrameDoubleBase::valuePropertyKey: case LinearAnimationBase::speedPropertyKey: + case NestedNumberBase::nestedValuePropertyKey: case NestedRemapAnimationBase::timePropertyKey: case BlendAnimation1DBase::valuePropertyKey: case LinearGradientBase::startXPropertyKey: @@ -1315,6 +1352,7 @@ namespace rive { case IKConstraintBase::invertDirectionPropertyKey: case NestedSimpleAnimationBase::isPlayingPropertyKey: case KeyFrameBoolBase::valuePropertyKey: + case NestedBoolBase::nestedValuePropertyKey: case LinearAnimationBase::enableWorkAreaPropertyKey: case StateMachineBoolBase::valuePropertyKey: case ShapePaintBase::isVisiblePropertyKey: diff --git a/include/rive/generated/nested_animation_base.hpp b/include/rive/generated/nested_animation_base.hpp index cb31c683..6d33c297 100644 --- a/include/rive/generated/nested_animation_base.hpp +++ b/include/rive/generated/nested_animation_base.hpp @@ -1,11 +1,11 @@ #ifndef _RIVE_NESTED_ANIMATION_BASE_HPP_ #define _RIVE_NESTED_ANIMATION_BASE_HPP_ -#include "rive/component.hpp" +#include "rive/container_component.hpp" #include "rive/core/field_types/core_uint_type.hpp" namespace rive { - class NestedAnimationBase : public Component { + class NestedAnimationBase : public ContainerComponent { protected: - typedef Component Super; + typedef ContainerComponent Super; public: static const uint16_t typeKey = 93; @@ -15,6 +15,7 @@ namespace rive { bool isTypeOf(uint16_t typeKey) const override { switch (typeKey) { case NestedAnimationBase::typeKey: + case ContainerComponentBase::typeKey: case ComponentBase::typeKey: return true; default: @@ -41,7 +42,7 @@ namespace rive { void copy(const NestedAnimationBase& object) { m_AnimationId = object.m_AnimationId; - Component::copy(object); + ContainerComponent::copy(object); } bool deserialize(uint16_t propertyKey, BinaryReader& reader) override { @@ -50,7 +51,7 @@ namespace rive { m_AnimationId = CoreUintType::deserialize(reader); return true; } - return Component::deserialize(propertyKey, reader); + return ContainerComponent::deserialize(propertyKey, reader); } protected: diff --git a/include/rive/importers/state_machine_listener_importer.hpp b/include/rive/importers/state_machine_listener_importer.hpp index 6702e441..d936ea56 100644 --- a/include/rive/importers/state_machine_listener_importer.hpp +++ b/include/rive/importers/state_machine_listener_importer.hpp @@ -6,7 +6,7 @@ namespace rive { class StateMachineListener; class StateMachine; - class ListenerInputChange; + class ListenerAction; class StateMachineListenerImporter : public ImportStackObject { private: StateMachineListener* m_StateMachineListener; @@ -14,7 +14,7 @@ namespace rive { public: StateMachineListenerImporter(StateMachineListener* listener); const StateMachineListener* stateMachineListener() const { return m_StateMachineListener; } - void addInputChange(ListenerInputChange* change); + void addAction(ListenerAction* action); StatusCode resolve() override; }; } // namespace rive diff --git a/include/rive/listener_type.hpp b/include/rive/listener_type.hpp index a2c84718..8617e4f7 100644 --- a/include/rive/listener_type.hpp +++ b/include/rive/listener_type.hpp @@ -2,11 +2,11 @@ #define _RIVE_LISTENER_TYPE_HPP_ namespace rive { enum class ListenerType : int { - updateHover = -1, enter = 0, exit = 1, down = 2, up = 3, + move = 4, }; } #endif \ No newline at end of file diff --git a/skia/viewer/build/premake5.lua b/skia/viewer/build/premake5.lua index c2d5b580..a91218ea 100644 --- a/skia/viewer/build/premake5.lua +++ b/skia/viewer/build/premake5.lua @@ -59,6 +59,7 @@ project "rive_viewer" } buildoptions {"-Wall", "-fno-exceptions", "-fno-rtti"} + defines { "RIVE_EXPERIMENTS" } filter "configurations:debug" buildoptions {"-g"} diff --git a/skia/viewer/build/windows/README.md b/skia/viewer/build/windows/README.md new file mode 100644 index 00000000..906e8804 --- /dev/null +++ b/skia/viewer/build/windows/README.md @@ -0,0 +1,20 @@ +# Rive Windows Viewer + +Main entry is [build.bat](build.bat). +Requirements: + +- Git + [Download and install](https://git-scm.com/download/win) +- CMake + - [Download and install](https://cmake.org/download/). +- Python + + - Get [Python 3](https://www.python.org/downloads/). You may need to symlink python3 to python. Make sure to do the custom install and check "install for all users." + ``` + mklink "C:\Program Files\Python310\python3.exe" "C:\Program Files\Python310\python.exe" + ``` + +- Visual Studio 2022 Community Edition + - Add clang tools + - You may need to patch up the scripts if you have a different version. +- Install Google's [Depot Tools](https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up) to build Skia. diff --git a/skia/viewer/build/windows/build.bat b/skia/viewer/build/windows/build.bat new file mode 100644 index 00000000..4592d624 --- /dev/null +++ b/skia/viewer/build/windows/build.bat @@ -0,0 +1,72 @@ +@echo off + set "DEPENDENCIES_DIR=%cd%\dependencies" +set "BAT_DIR=%cd%" + +if not exist "%DEPENDENCIES_DIR%\bin\premake5.exe" ( + pushd "%DEPENDENCIES_DIR%" + call .\get_premake5.bat || goto :error + popd +) +if not exist "%DEPENDENCIES_DIR%\skia" goto :get_skia +if "%FORCE_BUILD%"=="true" goto :get_skia +goto :got_skia + +:get_skia +pushd "%DEPENDENCIES_DIR%" +call .\get_skia.bat || goto :error +popd + +:got_skia + +if not exist "%DEPENDENCIES_DIR%\skia\out\static\skia.lib" goto :build_skia +if "%FORCE_BUILD%"=="true" goto :build_skia +goto :built_skia + +:build_skia +pushd "%DEPENDENCIES_DIR%" +call .\make_skia.bat || goto :error +popd + +:built_skia + +if not exist "%DEPENDENCIES_DIR%\skia" ( + pushd "%DEPENDENCIES_DIR%" + call .\get_skia.bat || goto :error + popd +) + +if not exist "%DEPENDENCIES_DIR%\gl3w" ( + pushd "%DEPENDENCIES_DIR%" + call .\make_gl3w.bat || goto :error + popd +) + +if not exist "%DEPENDENCIES_DIR%\imgui" ( + pushd "%DEPENDENCIES_DIR%" + call .\get_imgui.bat || goto :error + popd +) + +export "MSBuild=%ProgramFiles%\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\MSBuild.exe" + +if not exist "%DEPENDENCIES_DIR%\glfw" ( + pushd "%DEPENDENCIES_DIR%" + call .\make_glfw.bat || goto :error + popd +) + +set "PREMAKE=%DEPENDENCIES_DIR%\bin\premake5.exe" +%PREMAKE% --file=premake5_win.lua vs2022 + +call "%MSBuild%" rive.sln + +if not exist "%BAT_DIR%\..\..\..\package\Runtime\Libraries\Windows" mkdir %BAT_DIR%\..\..\..\package\Runtime\Libraries\Windows +copy .\bin\debug\rive.dll %BAT_DIR%\..\..\..\package\Runtime\Libraries\Windows\rive.dll + +goto :end + +:error +echo Failed with error #%errorlevel%. +exit /b %errorlevel% + +:end \ No newline at end of file diff --git a/skia/viewer/build/windows/dependencies/get_imgui.bat b/skia/viewer/build/windows/dependencies/get_imgui.bat new file mode 100644 index 00000000..d93b0dc3 --- /dev/null +++ b/skia/viewer/build/windows/dependencies/get_imgui.bat @@ -0,0 +1,12 @@ +@echo off +if not exist ".\imgui" ( + git clone https://github.com/ocornut/imgui imgui +) else ( + pushd imgui + git fetch + git pull + popd +) +pushd .\imgui +git checkout master +popd diff --git a/skia/viewer/build/windows/dependencies/get_premake5.bat b/skia/viewer/build/windows/dependencies/get_premake5.bat new file mode 100644 index 00000000..586fcad6 --- /dev/null +++ b/skia/viewer/build/windows/dependencies/get_premake5.bat @@ -0,0 +1,10 @@ +@echo off +if not exist ".\bin" mkdir bin +echo Downloading Premake5 +curl https://github.com/premake/premake-core/releases/download/v5.0.0-beta1/premake-5.0.0-beta1-windows.zip -L -o .\bin\premake_windows.zip +pushd bin +:: Export premake5 into bin +tar -xf premake_windows.zip +:: Delete downloaded archive +del premake_windows.zip +popd \ No newline at end of file diff --git a/skia/viewer/build/windows/dependencies/get_skia.bat b/skia/viewer/build/windows/dependencies/get_skia.bat new file mode 100644 index 00000000..d85d4e93 --- /dev/null +++ b/skia/viewer/build/windows/dependencies/get_skia.bat @@ -0,0 +1,13 @@ +@echo off +if not exist ".\skia" ( + git clone https://github.com/google/skia skia +) else ( + pushd skia + git fetch + git pull + popd +) +pushd .\skia +git checkout chrome/m99 +python3 tools/git-sync-deps +popd \ No newline at end of file diff --git a/skia/viewer/build/windows/dependencies/make_gl3w.bat b/skia/viewer/build/windows/dependencies/make_gl3w.bat new file mode 100644 index 00000000..5b2ae024 --- /dev/null +++ b/skia/viewer/build/windows/dependencies/make_gl3w.bat @@ -0,0 +1,16 @@ +@echo off +if not exist ".\gl3w" ( + git clone https://github.com/skaslev/gl3w gl3w +) else ( + cd gl3w + git fetch + git pull +) +pushd .\gl3w +if not exist ".\build" mkdir build +pushd build +cmake ../ +set "MSBuild=%ProgramFiles%\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\MSBuild.exe" +call "%MSBuild%" gl3w.sln +popd +popd \ No newline at end of file diff --git a/skia/viewer/build/windows/dependencies/make_glfw.bat b/skia/viewer/build/windows/dependencies/make_glfw.bat new file mode 100644 index 00000000..9698c907 --- /dev/null +++ b/skia/viewer/build/windows/dependencies/make_glfw.bat @@ -0,0 +1,20 @@ +@echo off +if not exist ".\glfw" ( + git clone https://github.com/glfw/glfw glfw +) else ( + pushd glfw + git fetch + git pull + popd +) +pushd .\glfw +git checkout master +popd + +mkdir glfw_build +cd glfw_build +cmake ../glfw -DBUILD_SHARED_LIBS=OFF +rem Force compile with /MT, GLFW defaults to /MDd but the rest of our libs expect /MT +set _CL_=/MT +call "%MSBuild%" GLFW.sln + diff --git a/skia/viewer/build/windows/dependencies/make_skia.bat b/skia/viewer/build/windows/dependencies/make_skia.bat new file mode 100644 index 00000000..2c5aada9 --- /dev/null +++ b/skia/viewer/build/windows/dependencies/make_skia.bat @@ -0,0 +1,99 @@ +@echo off +cd skia +set clang_win = "C:\Program Files\LLVM" +set COMPILER_FLAGS = ^ + \"-Wno-c++98-compat\",^ + \"-Wno-c++98-compat-pedantic\",^ + \"-Wno-reserved-macro-identifier\",^ + \"-Wno-newline-eof\",^ + \"-Wno-old-style-cast\",^ + \"-Wno-unused-parameter\",^ + \"-Wno-float-equal\",^ + \"-Wno-implicit-float-conversion\",^ + \"-Wno-shadow\",^ + \"-Wno-sign-conversion\",^ + \"-Wno-inconsistent-missing-destructor-override\",^ + \"-Wno-nested-anon-types\",^ + \"-Wno-suggest-destructor-override\",^ + \"-Wno-non-virtual-dtor\",^ + \"-Wno-unknown-argument\",^ + \"-Wno-gnu-anonymous-struct\",^ + \"-Wno-extra-semi\",^ + \"-Wno-cast-qual\",^ + \"-Wno-ignored-qualifiers\",^ + \"-Wno-double-promotion\",^ + \"-Wno-tautological-unsigned-zero-compare\",^ + \"-Wno-unreachable-code-break\",^ + \"-Wno-global-constructors\",^ + \"-Wno-switch-enum\",^ + \"-Wno-shorten-64-to-32\",^ + \"-Wno-missing-prototypes\",^ + \"-Wno-implicit-int-conversion\",^ + \"-Wno-unused-macros\",^ + \"-Wno-deprecated-copy-with-user-provided-dtor\",^ + \"-Wno-missing-variable-declarations\",^ + \"-Wno-ctad-maybe-unsupported\",^ + \"-Wno-vla-extension\",^ + \"-Wno-float-conversion\",^ + \"-Wno-gnu-zero-variadic-macro-arguments\",^ + \"-Wno-undef\",^ + \"-Wno-documentation\",^ + \"-Wno-documentation-pedantic\",^ + \"-Wno-documentation-unknown-command\",^ + \"-Wno-suggest-override\",^ + \"-Wno-unused-exception-parameter\",^ + \"-Wno-cast-align\",^ + \"-Wno-deprecated-declarations\",^ + \"-Wno-shadow-field\",^ + \"-Wno-nonportable-system-include-path\",^ + \"-Wno-reserved-identifier\",^ + \"-Wno-thread-safety-negative\",^ + \"-Wno-exit-time-destructors\",^ + \"-Wno-unreachable-code\",^ + \"-Wno-zero-as-null-pointer-constant\",^ + \"-Wno-pedantic\",^ + \"-Wno-sign-compare\",^ + \"-fno-rtti\",^ + \"-DSK_DISABLE_LEGACY_SHADERCONTEXT\", ^ + \"-DSK_DISABLE_LOWP_RASTER_PIPELINE\", ^ + \"-DSK_FORCE_RASTER_PIPELINE_BLITTER\", ^ + \"-DSK_DISABLE_AAA\", ^ + \"-DSK_DISABLE_EFFECT_DESERIALIZATION\", ^ + \"/MT" + +set ARGS=extra_cflags=[%COMPILER_FLAGS%] ^ + is_official_build=false^ + skia_use_gl=true^ + skia_use_zlib=true^ + skia_enable_gpu=true^ + skia_enable_fontmgr_empty=false^ + skia_use_libpng_encode=false^ + skia_use_libpng_decode=true^ + skia_enable_skgpu_v1=true^ + skia_use_dng_sdk=false^ + skia_use_egl=false^ + skia_use_expat=false^ + skia_use_fontconfig=false^ + skia_use_freetype=false^ + skia_use_icu=false^ + skia_use_libheif=false^ + skia_use_system_libpng=false^ + skia_use_libjpeg_turbo_encode=false^ + skia_use_libjpeg_turbo_decode=false^ + skia_use_libwebp_encode=false^ + skia_use_libwebp_decode=false^ + skia_use_lua=false^ + skia_use_piex=false^ + skia_use_vulkan=false^ + skia_use_metal=false^ + skia_use_angle=false^ + skia_use_direct3d=false^ + skia_use_system_zlib=false^ + skia_enable_spirv_validation=false^ + skia_enable_pdf=false^ + skia_enable_skottie=false^ + skia_enable_tools=false + +bin\gn gen out\static --type=static_library --args="%ARGS%" +ninja -C out\static +cd .. \ No newline at end of file diff --git a/skia/viewer/build/windows/premake5_win.lua b/skia/viewer/build/windows/premake5_win.lua new file mode 100644 index 00000000..d0a8975e --- /dev/null +++ b/skia/viewer/build/windows/premake5_win.lua @@ -0,0 +1,59 @@ +workspace "rive" +configurations { "debug", "release" } + +project "rive_viewer" +kind "ConsoleApp" +language "C++" +cppdialect "C++17" +toolset "clang" +targetdir "bin/%{cfg.buildcfg}" +objdir "obj/%{cfg.buildcfg}" + +skia = "dependencies/skia" +gl3w = "dependencies/gl3w/build" +rive = "../../../../" +imgui = "dependencies/imgui" +glfw_build = "dependencies/glfw_build/src" +glfw = "dependencies/glfw" + +includedirs { "../include", skia, skia .. "/include/core", skia .. "/include/effects", skia .. "/include/gpu", + skia .. "/include/config", gl3w .. "/include", rive .. "/include", rive .. "/skia/renderer/include", imgui, glfw .. "/include", "dependencies" } +libdirs { skia .. "/out/static" } + +links { "skia", "glfw3", "opengl32" } +libdirs { "../../../build/bin/%{cfg.buildcfg}", glfw_build .. "/Debug", + "../../dependencies/skia/out/static", "../../renderer/build/bin/%{cfg.buildcfg}" } + +files { "../../src/**.cpp", rive .. "/src/**.cpp", rive .. "/skia/renderer/src/**.cpp", gl3w .. "/src/gl3w.c", + imgui .. "/backends/imgui_impl_glfw.cpp", + imgui .. "/backends/imgui_impl_opengl3.cpp", imgui .. "/imgui_widgets.cpp", + imgui .. "/imgui.cpp", imgui .. "/imgui_tables.cpp", + imgui .. "/imgui_draw.cpp" } + +defines { "_USE_MATH_DEFINES", "NOMINMAX" } +architecture("x86_64") +buildoptions { "/MT", "-Wno-c++98-compat", "-Wno-unused-template", "-Wno-c++98-compat-pedantic", + "-Wno-reserved-macro-identifier", "-Wno-newline-eof", "-Wno-old-style-cast", "-Wno-unused-parameter", + "-Wno-float-equal", "-Wno-implicit-float-conversion", "-Wno-shadow", "-Wno-sign-conversion", + "-Wno-inconsistent-missing-destructor-override", "-Wno-nested-anon-types", + "-Wno-suggest-destructor-override", "-Wno-non-virtual-dtor", "-Wno-unknown-argument", + "-Wno-gnu-anonymous-struct", "-Wno-extra-semi", "-Wno-cast-qual", "-Wno-ignored-qualifiers", + "-Wno-double-promotion", "-Wno-tautological-unsigned-zero-compare", "-Wno-unreachable-code-break", + "-Wno-global-constructors", "-Wno-switch-enum", "-Wno-shorten-64-to-32", "-Wno-missing-prototypes", + "-Wno-implicit-int-conversion", "-Wno-unused-macros", "-Wno-deprecated-copy-with-user-provided-dtor", + "-Wno-missing-variable-declarations", "-Wno-ctad-maybe-unsupported", "-Wno-vla-extension", + "-Wno-float-conversion", "-Wno-gnu-zero-variadic-macro-arguments", "-Wno-undef", "-Wno-documentation", + "-Wno-documentation-pedantic", "-Wno-documentation-unknown-command", "-Wno-suggest-override", + "-Wno-unused-exception-parameter", "-Wno-cast-align", "-Wno-deprecated-declarations", "-Wno-shadow-field", + "-Wno-nonportable-system-include-path", "-Wno-reserved-identifier", "-Wno-thread-safety-negative", + "-Wno-exit-time-destructors", "-Wno-unreachable-code", "-Wno-zero-as-null-pointer-constant", + "-Wno-pedantic", "-Wno-sign-compare", "-Wall", "-fno-exceptions", "-fno-rtti", "-g" } +filter "configurations:debug" +defines { "DEBUG" } +symbols "On" + +filter "configurations:release" + +defines { "RELEASE" } +defines { "NDEBUG" } +optimize "On" diff --git a/skia/viewer/src/main.cpp b/skia/viewer/src/main.cpp index 8c379151..1fb5004e 100644 --- a/skia/viewer/src/main.cpp +++ b/skia/viewer/src/main.cpp @@ -69,6 +69,7 @@ std::vector stateMachineNames; constexpr int REQUEST_DEFAULT_SCENE = -1; +#ifdef RIVE_EXPERIMENTS #include double GetSecondsToday() { time_t m_time; @@ -90,6 +91,7 @@ double GetSecondsToday() { // printf("%g %g %g\n", secs, secs/60, secs/60/60); return secs; } +#endif // We hold onto the file's bytes for the lifetime of the file, in case we want // to change animations or state-machines, we just rebuild the rive::File from @@ -325,10 +327,12 @@ int main() { canvas->drawPaint(paint); if (currentScene) { +#ifdef RIVE_EXPERIMENTS // See if we can "set the time" e.g. clock statemachine if (auto num = currentScene->getNumber("isTime")) { num->value(GetSecondsToday()/60/60); } +#endif currentScene->advanceAndApply(elapsed); diff --git a/src/animation/listener_action.cpp b/src/animation/listener_action.cpp new file mode 100644 index 00000000..46b2ab0f --- /dev/null +++ b/src/animation/listener_action.cpp @@ -0,0 +1,19 @@ +#include "rive/animation/state_machine_listener.hpp" +#include "rive/importers/import_stack.hpp" +#include "rive/importers/state_machine_listener_importer.hpp" +#include "rive/importers/state_machine_importer.hpp" +#include "rive/animation/listener_input_change.hpp" +#include "rive/animation/state_machine.hpp" + +using namespace rive; + +StatusCode ListenerAction::import(ImportStack& importStack) { + auto stateMachineListenerImporter = + importStack.latest(StateMachineListenerBase::typeKey); + if (stateMachineListenerImporter == nullptr) { + return StatusCode::MissingObject; + } + + stateMachineListenerImporter->addAction(this); + return Super::import(importStack); +} diff --git a/src/animation/listener_align_target.cpp b/src/animation/listener_align_target.cpp new file mode 100644 index 00000000..43172272 --- /dev/null +++ b/src/animation/listener_align_target.cpp @@ -0,0 +1,24 @@ +#include "rive/animation/listener_align_target.hpp" +#include "rive/animation/state_machine_instance.hpp" +#include "rive/node.hpp" +#include "rive/constraints/constraint.hpp" + +using namespace rive; + +void ListenerAlignTarget::perform(StateMachineInstance* stateMachineInstance, + Vec2D position) const { + auto coreTarget = stateMachineInstance->artboard()->resolve(targetId()); + if (coreTarget == nullptr || !coreTarget->is()) { + return; + } + auto target = coreTarget->as(); + Mat2D targetParentWorld = getParentWorld(*target); + Mat2D inverse; + if (!targetParentWorld.invert(&inverse)) { + return; + } + + auto localPosition = inverse * position; + target->x(localPosition.x); + target->y(localPosition.y); +} diff --git a/src/animation/listener_bool_change.cpp b/src/animation/listener_bool_change.cpp index a930b28c..0745b6b4 100644 --- a/src/animation/listener_bool_change.cpp +++ b/src/animation/listener_bool_change.cpp @@ -11,7 +11,7 @@ bool ListenerBoolChange::validateInputType(const StateMachineInput* input) const return input == nullptr || input->is(); } -void ListenerBoolChange::perform(StateMachineInstance* stateMachineInstance) const { +void ListenerBoolChange::perform(StateMachineInstance* stateMachineInstance, Vec2D position) const { auto inputInstance = stateMachineInstance->input(inputId()); if (inputInstance == nullptr) { return; diff --git a/src/animation/listener_input_change.cpp b/src/animation/listener_input_change.cpp index a3e3e54a..79c04899 100644 --- a/src/animation/listener_input_change.cpp +++ b/src/animation/listener_input_change.cpp @@ -13,15 +13,8 @@ StatusCode ListenerInputChange::import(ImportStack& importStack) { return StatusCode::MissingObject; } - auto stateMachineListenerImporter = - importStack.latest(StateMachineListenerBase::typeKey); - if (stateMachineListenerImporter == nullptr) { - return StatusCode::MissingObject; - } - if (!validateInputType(stateMachineImporter->stateMachine()->input((size_t)inputId()))) { return StatusCode::InvalidObject; } - stateMachineListenerImporter->addInputChange(this); return Super::import(importStack); } diff --git a/src/animation/listener_number_change.cpp b/src/animation/listener_number_change.cpp index 33c83169..91d92685 100644 --- a/src/animation/listener_number_change.cpp +++ b/src/animation/listener_number_change.cpp @@ -12,7 +12,8 @@ bool ListenerNumberChange::validateInputType(const StateMachineInput* input) con return input == nullptr || input->is(); } -void ListenerNumberChange::perform(StateMachineInstance* stateMachineInstance) const { +void ListenerNumberChange::perform(StateMachineInstance* stateMachineInstance, + Vec2D position) const { auto inputInstance = stateMachineInstance->input(inputId()); if (inputInstance == nullptr) { return; diff --git a/src/animation/listener_trigger_change.cpp b/src/animation/listener_trigger_change.cpp index f1939e02..b601f049 100644 --- a/src/animation/listener_trigger_change.cpp +++ b/src/animation/listener_trigger_change.cpp @@ -12,7 +12,8 @@ bool ListenerTriggerChange::validateInputType(const StateMachineInput* input) co return input == nullptr || input->is(); } -void ListenerTriggerChange::perform(StateMachineInstance* stateMachineInstance) const { +void ListenerTriggerChange::perform(StateMachineInstance* stateMachineInstance, + Vec2D position) const { auto inputInstance = stateMachineInstance->input(inputId()); if (inputInstance == nullptr) { return; diff --git a/src/animation/state_machine_instance.cpp b/src/animation/state_machine_instance.cpp index d7bbe981..20625a17 100644 --- a/src/animation/state_machine_instance.cpp +++ b/src/animation/state_machine_instance.cpp @@ -267,15 +267,15 @@ void StateMachineInstance::updateListeners(Vec2D position, ListenerType hitType) // we're trying to trigger. if (hoverChange) { if (isOver && listener->listenerType() == ListenerType::enter) { - listener->performChanges(this); + listener->performChanges(this, position); markNeedsAdvance(); } else if (!isOver && listener->listenerType() == ListenerType::exit) { - listener->performChanges(this); + listener->performChanges(this, position); markNeedsAdvance(); } } if (isOver && hitType == listener->listenerType()) { - listener->performChanges(this); + listener->performChanges(this, position); markNeedsAdvance(); } } @@ -302,7 +302,7 @@ void StateMachineInstance::updateListeners(Vec2D position, ListenerType hitType) case ListenerType::up: nestedStateMachine->pointerUp(nestedPosition); break; - case ListenerType::updateHover: + case ListenerType::move: nestedStateMachine->pointerMove(nestedPosition); break; default: @@ -314,7 +314,7 @@ void StateMachineInstance::updateListeners(Vec2D position, ListenerType hitType) } void StateMachineInstance::pointerMove(Vec2D position) { - updateListeners(position, ListenerType::updateHover); + updateListeners(position, ListenerType::move); } void StateMachineInstance::pointerDown(Vec2D position) { updateListeners(position, ListenerType::down); diff --git a/src/animation/state_machine_listenable.cpp b/src/animation/state_machine_listener.cpp similarity index 81% rename from src/animation/state_machine_listenable.cpp rename to src/animation/state_machine_listener.cpp index 36e54b57..294143d4 100644 --- a/src/animation/state_machine_listenable.cpp +++ b/src/animation/state_machine_listener.cpp @@ -9,9 +9,7 @@ using namespace rive; -void StateMachineListener::addInputChange(ListenerInputChange* inputChange) { - m_InputChanges.push_back(inputChange); -} +void StateMachineListener::addAction(ListenerAction* action) { m_Actions.push_back(action); } StatusCode StateMachineListener::import(ImportStack& importStack) { auto stateMachineImporter = importStack.latest(StateMachineBase::typeKey); @@ -23,9 +21,9 @@ StatusCode StateMachineListener::import(ImportStack& importStack) { return Super::import(importStack); } -const ListenerInputChange* StateMachineListener::inputChange(size_t index) const { - if (index < m_InputChanges.size()) { - return m_InputChanges[index]; +const ListenerAction* StateMachineListener::action(size_t index) const { + if (index < m_Actions.size()) { + return m_Actions[index]; } return nullptr; } @@ -59,8 +57,9 @@ StatusCode StateMachineListener::onAddedClean(CoreContext* context) { return Super::onAddedClean(context); } -void StateMachineListener::performChanges(StateMachineInstance* stateMachineInstance) const { - for (auto inputChange : m_InputChanges) { - inputChange->perform(stateMachineInstance); +void StateMachineListener::performChanges(StateMachineInstance* stateMachineInstance, + Vec2D position) const { + for (auto action : m_Actions) { + action->perform(stateMachineInstance, position); } } \ No newline at end of file diff --git a/src/generated/animation/listener_align_target_base.cpp b/src/generated/animation/listener_align_target_base.cpp new file mode 100644 index 00000000..9da8b5bf --- /dev/null +++ b/src/generated/animation/listener_align_target_base.cpp @@ -0,0 +1,10 @@ +#include "rive/generated/animation/listener_align_target_base.hpp" +#include "rive/animation/listener_align_target.hpp" + +using namespace rive; + +Core* ListenerAlignTargetBase::clone() const { + auto cloned = new ListenerAlignTarget(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/animation/nested_bool_base.cpp b/src/generated/animation/nested_bool_base.cpp new file mode 100644 index 00000000..315ebbd7 --- /dev/null +++ b/src/generated/animation/nested_bool_base.cpp @@ -0,0 +1,10 @@ +#include "rive/generated/animation/nested_bool_base.hpp" +#include "rive/animation/nested_bool.hpp" + +using namespace rive; + +Core* NestedBoolBase::clone() const { + auto cloned = new NestedBool(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/animation/nested_number_base.cpp b/src/generated/animation/nested_number_base.cpp new file mode 100644 index 00000000..4a7fa1db --- /dev/null +++ b/src/generated/animation/nested_number_base.cpp @@ -0,0 +1,10 @@ +#include "rive/generated/animation/nested_number_base.hpp" +#include "rive/animation/nested_number.hpp" + +using namespace rive; + +Core* NestedNumberBase::clone() const { + auto cloned = new NestedNumber(); + cloned->copy(*this); + return cloned; +} diff --git a/src/generated/animation/nested_trigger_base.cpp b/src/generated/animation/nested_trigger_base.cpp new file mode 100644 index 00000000..44bb4231 --- /dev/null +++ b/src/generated/animation/nested_trigger_base.cpp @@ -0,0 +1,10 @@ +#include "rive/generated/animation/nested_trigger_base.hpp" +#include "rive/animation/nested_trigger.hpp" + +using namespace rive; + +Core* NestedTriggerBase::clone() const { + auto cloned = new NestedTrigger(); + cloned->copy(*this); + return cloned; +} diff --git a/src/importers/state_machine_listener_importer.cpp b/src/importers/state_machine_listener_importer.cpp index bf403afa..e8ac8fc2 100644 --- a/src/importers/state_machine_listener_importer.cpp +++ b/src/importers/state_machine_listener_importer.cpp @@ -6,8 +6,8 @@ using namespace rive; StateMachineListenerImporter::StateMachineListenerImporter(StateMachineListener* listener) : m_StateMachineListener(listener) {} -void StateMachineListenerImporter::addInputChange(ListenerInputChange* change) { - m_StateMachineListener->addInputChange(change); +void StateMachineListenerImporter::addAction(ListenerAction* action) { + m_StateMachineListener->addAction(action); } StatusCode StateMachineListenerImporter::resolve() { return StatusCode::Ok; } \ No newline at end of file diff --git a/test/state_machine_event_test.cpp b/test/state_machine_event_test.cpp index 5e9b4623..01e77aea 100644 --- a/test/state_machine_event_test.cpp +++ b/test/state_machine_event_test.cpp @@ -36,28 +36,31 @@ TEST_CASE("file with state machine listeners be read", "[file]") { auto target1 = artboard->resolve(listener1->targetId()); REQUIRE(target1->is()); REQUIRE(target1->as()->name() == "HandWickHit"); - REQUIRE(listener1->inputChangeCount() == 1); - auto inputChange1 = listener1->inputChange(0); + REQUIRE(listener1->actionCount() == 1); + auto inputChange1 = listener1->action(0); REQUIRE(inputChange1 != nullptr); - REQUIRE(inputChange1->inputId() == 0); + REQUIRE(inputChange1->is()); + REQUIRE(inputChange1->as()->inputId() == 0); auto listener2 = stateMachine->listener(1); auto target2 = artboard->resolve(listener2->targetId()); REQUIRE(target2->is()); REQUIRE(target2->as()->name() == "HandCannonHit"); - REQUIRE(listener2->inputChangeCount() == 1); - auto inputChange2 = listener2->inputChange(0); + REQUIRE(listener2->actionCount() == 1); + auto inputChange2 = listener2->action(0); REQUIRE(inputChange2 != nullptr); - REQUIRE(inputChange2->inputId() == 1); + REQUIRE(inputChange2->is()); + REQUIRE(inputChange2->as()->inputId() == 1); auto listener3 = stateMachine->listener(2); auto target3 = artboard->resolve(listener3->targetId()); REQUIRE(target3->is()); REQUIRE(target3->as()->name() == "HandHelmetHit"); - REQUIRE(listener3->inputChangeCount() == 1); - auto inputChange3 = listener3->inputChange(0); + REQUIRE(listener3->actionCount() == 1); + auto inputChange3 = listener3->action(0); REQUIRE(inputChange3 != nullptr); - REQUIRE(inputChange3->inputId() == 2); + REQUIRE(inputChange3->is()); + REQUIRE(inputChange3->as()->inputId() == 2); } TEST_CASE("hit testing via a state machine works", "[file]") {