mirror of
https://github.com/rive-app/rive-cpp.git
synced 2026-01-18 13:11:19 +01:00
data bind artboards rcp file (#10214) c542b9b7ac
* make file ref counted * migrate File to refcnt * add bindable artboard class to keep file reference * feat(unity): support rcp file and BindableArtboard class (#10228) * refactor(apple): use updated file bindable artboard apis (#10229) * update command queue to support bindable artboards * use bindable artboards on command queue * self manage view model instances in js runtime * change remaining viewModelInstanceRuntimes to rcp * refactor(apple): update view model instances to use rcp (#10298) * refactor(unity): support rcp ViewModelInstanceRuntime (#10309) * rebase fix * deprecate getArtboard in favor of getBindableArtboard * fix merge * remove unused lambda capture * fix rive binding * feat(Android): RCP File, VMI, and add bindable artboards (#10456) * refactor: C++ refactors - Import from long (incorrect) -> jlong - Header clang-tidy fix - Use reinterpret_cast instead of C-style cast - Break out some variables instead of long one liners - Use auto - Remove unused env and thisObj # Conflicts: # packages/runtime_android/kotlin/src/main/cpp/src/helpers/general.cpp * docs: Improve documentation on the File class * feat: Support bindable artboard type and RCP VMIs # Conflicts: # packages/runtime_android/kotlin/src/androidTest/java/app/rive/runtime/kotlin/core/RiveDataBindingTest.kt * feat: Support RCP files * refactor: Change from +1/-1 ref to just release * fix: Moved to the more appropriate null pointer for GetStringUTFChars * replace unref with release Co-authored-by: Adam <67035612+damzobridge@users.noreply.github.com> Co-authored-by: David Skuza <david@rive.app> Co-authored-by: Erik <erik@rive.app> Co-authored-by: hernan <hernan@rive.app>
This commit is contained in:
@@ -1 +1 @@
|
||||
f7613dbf3542cf1d666612856728d70ba1715521
|
||||
c542b9b7ac7ac5cd96f798f3fbe7dd5411beecd3
|
||||
|
||||
@@ -38,6 +38,7 @@ class DataBind;
|
||||
class BindableProperty;
|
||||
class HitDrawable;
|
||||
class ListenerViewModel;
|
||||
typedef void (*DataBindChanged)();
|
||||
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
class StateMachineInstance;
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
#include "rive/animation/linear_animation.hpp"
|
||||
#include "rive/animation/state_machine.hpp"
|
||||
#include "rive/core_context.hpp"
|
||||
#include "rive/data_bind/data_bind.hpp"
|
||||
#include "rive/data_bind/data_context.hpp"
|
||||
#include "rive/data_bind/data_bind_context.hpp"
|
||||
#include "rive/viewmodel/viewmodel_instance_value.hpp"
|
||||
#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp"
|
||||
#include "rive/generated/artboard_base.hpp"
|
||||
@@ -48,6 +46,7 @@ class SMIBool;
|
||||
class SMIInput;
|
||||
class SMINumber;
|
||||
class SMITrigger;
|
||||
class DataBind;
|
||||
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
typedef void (*ArtboardCallback)(void*);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "rive/artboard.hpp"
|
||||
#include "rive/constraints/constrainable_list.hpp"
|
||||
#include "rive/property_recorder.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include "rive/artboard_host.hpp"
|
||||
#include "rive/data_bind/data_bind_list_item_consumer.hpp"
|
||||
#include "rive/layout/layout_node_provider.hpp"
|
||||
@@ -17,7 +18,6 @@
|
||||
#include <unordered_map>
|
||||
namespace rive
|
||||
{
|
||||
class File;
|
||||
class LayoutComponent;
|
||||
class ScrollConstraint;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef _RIVE_ARTBOARD_HOST_HPP_
|
||||
#define _RIVE_ARTBOARD_HOST_HPP_
|
||||
#include "rive/refcnt.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include <stdio.h>
|
||||
namespace rive
|
||||
{
|
||||
@@ -8,7 +9,6 @@ class ArtboardInstance;
|
||||
class DataBind;
|
||||
class DataContext;
|
||||
class ViewModelInstance;
|
||||
class File;
|
||||
|
||||
class ArtboardHost
|
||||
{
|
||||
|
||||
23
include/rive/bindable_artboard.hpp
Normal file
23
include/rive/bindable_artboard.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef _RIVE_BINDABLE_ARTBOARD_HPP_
|
||||
#define _RIVE_BINDABLE_ARTBOARD_HPP_
|
||||
#include "rive/refcnt.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include "rive/artboard.hpp"
|
||||
|
||||
namespace rive
|
||||
{
|
||||
|
||||
class BindableArtboard : public RefCnt<BindableArtboard>
|
||||
{
|
||||
public:
|
||||
BindableArtboard(rcp<const File> file,
|
||||
std::unique_ptr<ArtboardInstance> artboard);
|
||||
ArtboardInstance* artboard() { return m_artboard.get(); }
|
||||
|
||||
private:
|
||||
rcp<const File> m_file;
|
||||
std::unique_ptr<ArtboardInstance> m_artboard;
|
||||
};
|
||||
} // namespace rive
|
||||
|
||||
#endif
|
||||
@@ -29,6 +29,7 @@ public:
|
||||
AudioSource* getAudioSource(AudioSourceHandle) const;
|
||||
Font* getFont(FontHandle) const;
|
||||
ArtboardInstance* getArtboardInstance(ArtboardHandle) const;
|
||||
rcp<BindableArtboard> getBindableArtboard(ArtboardHandle) const;
|
||||
StateMachineInstance* getStateMachineInstance(StateMachineHandle) const;
|
||||
ViewModelInstanceRuntime* getViewModelInstance(
|
||||
ViewModelInstanceHandle) const;
|
||||
@@ -187,8 +188,7 @@ private:
|
||||
std::unordered_map<FontHandle, rcp<Font>> m_fonts;
|
||||
std::unordered_map<RenderImageHandle, rcp<RenderImage>> m_images;
|
||||
std::unordered_map<AudioSourceHandle, rcp<AudioSource>> m_audioSources;
|
||||
std::unordered_map<ArtboardHandle, std::unique_ptr<ArtboardInstance>>
|
||||
m_artboards;
|
||||
std::unordered_map<ArtboardHandle, rcp<BindableArtboard>> m_artboards;
|
||||
std::unordered_map<ViewModelInstanceHandle, rcp<ViewModelInstanceRuntime>>
|
||||
m_viewModels;
|
||||
std::unordered_map<StateMachineHandle,
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
#include "rive/refcnt.hpp"
|
||||
#include "rive/viewmodel/viewmodel.hpp"
|
||||
#include "rive/viewmodel/viewmodel_instance_list_item.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include <stdio.h>
|
||||
namespace rive
|
||||
{
|
||||
class File;
|
||||
|
||||
class DataConverterNumberToList : public DataConverterNumberToListBase
|
||||
{
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
#include "rive/data_bind/converters/data_converter.hpp"
|
||||
#include "rive/data_bind/data_values/data_type.hpp"
|
||||
#include "rive/dirtyable.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include <stdio.h>
|
||||
namespace rive
|
||||
{
|
||||
class File;
|
||||
class DataBindContextValue;
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
class DataBind;
|
||||
@@ -43,8 +43,8 @@ public:
|
||||
bool sourceToTargetRunsFirst();
|
||||
bool advance(float elapsedTime);
|
||||
void suppressDirt(bool value) { m_suppressDirt = value; };
|
||||
void file(File* value) { m_file = value; };
|
||||
File* file() const { return m_file; };
|
||||
void file(File* value);
|
||||
File* file() const;
|
||||
DataType outputType();
|
||||
DataType sourceOutputType();
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "rive/viewmodel/viewmodel_instance_viewmodel.hpp"
|
||||
#include "rive/viewmodel/viewmodel_instance_list_item.hpp"
|
||||
#include "rive/animation/keyframe_interpolator.hpp"
|
||||
#include "rive/data_bind/converters/data_converter.hpp"
|
||||
#include "rive/refcnt.hpp"
|
||||
#include <vector>
|
||||
#include <set>
|
||||
@@ -23,10 +24,12 @@
|
||||
namespace rive
|
||||
{
|
||||
class BinaryReader;
|
||||
class DataBind;
|
||||
class RuntimeHeader;
|
||||
class Factory;
|
||||
class ScrollPhysics;
|
||||
class ViewModelRuntime;
|
||||
class BindableArtboard;
|
||||
|
||||
///
|
||||
/// Tracks the success/failure result when importing a Rive file.
|
||||
@@ -92,6 +95,9 @@ public:
|
||||
std::unique_ptr<ArtboardInstance> artboardDefault() const;
|
||||
std::unique_ptr<ArtboardInstance> artboardAt(size_t index) const;
|
||||
std::unique_ptr<ArtboardInstance> artboardNamed(std::string name) const;
|
||||
rcp<BindableArtboard> bindableArtboardNamed(std::string name) const;
|
||||
rcp<BindableArtboard> bindableArtboardDefault() const;
|
||||
rcp<BindableArtboard> internalBindableArtboardFromArtboard(Artboard*) const;
|
||||
|
||||
Artboard* artboard() const;
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "rive/viewmodel/viewmodel_instance_artboard.hpp"
|
||||
#include "rive/refcnt.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
namespace rive
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <stdint.h>
|
||||
#include "rive/viewmodel/runtime/viewmodel_instance_value_runtime.hpp"
|
||||
#include "rive/viewmodel/viewmodel_instance_artboard.hpp"
|
||||
#include "rive/bindable_artboard.hpp"
|
||||
|
||||
namespace rive
|
||||
{
|
||||
@@ -17,11 +18,11 @@ public:
|
||||
ViewModelInstanceArtboard* viewModelInstance) :
|
||||
ViewModelInstanceValueRuntime(viewModelInstance)
|
||||
{}
|
||||
void value(Artboard* artboard);
|
||||
void value(rcp<BindableArtboard> bindableArtboard);
|
||||
const DataType dataType() override { return DataType::artboard; }
|
||||
|
||||
#ifdef TESTING
|
||||
Artboard* testing_value();
|
||||
rcp<BindableArtboard> testing_value();
|
||||
#endif
|
||||
};
|
||||
} // namespace rive
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
ViewModelInstanceListRuntime(ViewModelInstanceList* viewModelInstance) :
|
||||
ViewModelInstanceValueRuntime(viewModelInstance)
|
||||
{}
|
||||
ViewModelInstanceRuntime* instanceAt(int index);
|
||||
rcp<ViewModelInstanceRuntime> instanceAt(int index);
|
||||
void addInstance(ViewModelInstanceRuntime*);
|
||||
bool addInstanceAt(ViewModelInstanceRuntime*, int);
|
||||
void removeInstance(ViewModelInstanceRuntime*);
|
||||
|
||||
@@ -43,7 +43,8 @@ public:
|
||||
ViewModelInstanceTriggerRuntime* propertyTrigger(
|
||||
const std::string& path) const;
|
||||
ViewModelInstanceListRuntime* propertyList(const std::string& path) const;
|
||||
ViewModelInstanceRuntime* propertyViewModel(const std::string& path) const;
|
||||
rcp<ViewModelInstanceRuntime> propertyViewModel(
|
||||
const std::string& path) const;
|
||||
ViewModelInstanceAssetImageRuntime* propertyImage(
|
||||
const std::string& path) const;
|
||||
ViewModelInstanceArtboardRuntime* propertyArtboard(
|
||||
|
||||
@@ -27,11 +27,11 @@ public:
|
||||
const std::string& name() const;
|
||||
size_t instanceCount() const;
|
||||
size_t propertyCount() const;
|
||||
ViewModelInstanceRuntime* createInstanceFromIndex(size_t index) const;
|
||||
ViewModelInstanceRuntime* createInstanceFromName(
|
||||
rcp<ViewModelInstanceRuntime> createInstanceFromIndex(size_t index) const;
|
||||
rcp<ViewModelInstanceRuntime> createInstanceFromName(
|
||||
const std::string& name) const;
|
||||
ViewModelInstanceRuntime* createDefaultInstance() const;
|
||||
ViewModelInstanceRuntime* createInstance() const;
|
||||
rcp<ViewModelInstanceRuntime> createDefaultInstance() const;
|
||||
rcp<ViewModelInstanceRuntime> createInstance() const;
|
||||
std::vector<PropertyData> properties();
|
||||
static std::vector<PropertyData> buildPropertiesData(
|
||||
std::vector<rive::ViewModelProperty*>& properties);
|
||||
@@ -40,9 +40,7 @@ public:
|
||||
private:
|
||||
ViewModel* m_viewModel;
|
||||
const File* m_file;
|
||||
mutable std::vector<rcp<ViewModelInstanceRuntime>>
|
||||
m_viewModelInstanceRuntimes;
|
||||
ViewModelInstanceRuntime* createRuntimeInstance(
|
||||
rcp<ViewModelInstanceRuntime> createRuntimeInstance(
|
||||
rcp<ViewModelInstance> instance) const;
|
||||
};
|
||||
} // namespace rive
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef _RIVE_VIEW_MODEL_INSTANCE_ARTBOARD_HPP_
|
||||
#define _RIVE_VIEW_MODEL_INSTANCE_ARTBOARD_HPP_
|
||||
#include "rive/generated/viewmodel/viewmodel_instance_artboard_base.hpp"
|
||||
#include "rive/bindable_artboard.hpp"
|
||||
#include <stdio.h>
|
||||
namespace rive
|
||||
{
|
||||
@@ -15,11 +16,11 @@ protected:
|
||||
void propertyValueChanged() override;
|
||||
|
||||
public:
|
||||
void asset(Artboard* value);
|
||||
Artboard* asset() { return m_artboard; }
|
||||
void asset(rcp<BindableArtboard> value);
|
||||
rcp<BindableArtboard> asset() { return m_bindableArtboard; }
|
||||
|
||||
private:
|
||||
Artboard* m_artboard = nullptr;
|
||||
rcp<BindableArtboard> m_bindableArtboard = nullptr;
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
public:
|
||||
void onChanged(ViewModelArtboardChanged callback)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "rive/math/simd.hpp"
|
||||
#include "rive/artboard.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include "rive/refcnt.hpp"
|
||||
#include "rive/layout.hpp"
|
||||
#include "rive/animation/state_machine_instance.hpp"
|
||||
#include "rive/static_scene.hpp"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "rive/artboard.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include "rive/refcnt.hpp"
|
||||
#include "rive/animation/linear_animation_instance.hpp"
|
||||
#include "rive/animation/state_machine_instance.hpp"
|
||||
#include "rive/animation/state_machine_input_instance.hpp"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "rive/animation/state_machine_layer.hpp"
|
||||
#include "rive/animation/state_machine_input.hpp"
|
||||
#include "rive/animation/state_machine_listener.hpp"
|
||||
#include "rive/data_bind/data_bind.hpp"
|
||||
|
||||
using namespace rive;
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "rive/viewmodel/viewmodel_instance_trigger.hpp"
|
||||
#include "rive/artboard_component_list.hpp"
|
||||
#include "rive/constraints/draggable_constraint.hpp"
|
||||
#include "rive/data_bind/data_bind_context.hpp"
|
||||
#include "rive/data_bind/data_bind.hpp"
|
||||
#include "rive/data_bind_flags.hpp"
|
||||
#include "rive/event_report.hpp"
|
||||
#include "rive/gesture_click_phase.hpp"
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "rive/nested_artboard_leaf.hpp"
|
||||
#include "rive/nested_artboard_layout.hpp"
|
||||
#include "rive/joystick.hpp"
|
||||
#include "rive/data_bind/data_bind.hpp"
|
||||
#include "rive/data_bind_flags.hpp"
|
||||
#include "rive/animation/nested_bool.hpp"
|
||||
#include "rive/animation/nested_number.hpp"
|
||||
@@ -1666,7 +1667,7 @@ void Artboard::bindViewModelInstance(rcp<ViewModelInstance> viewModelInstance,
|
||||
|
||||
bool Artboard::isAncestor(const Artboard* artboard)
|
||||
{
|
||||
if (m_artboardSource == artboard)
|
||||
if (artboard != nullptr && m_artboardSource == artboard->artboardSource())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
8
src/bindable_artboard.cpp
Normal file
8
src/bindable_artboard.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "rive/bindable_artboard.hpp"
|
||||
|
||||
using namespace rive;
|
||||
|
||||
BindableArtboard::BindableArtboard(rcp<const File> file,
|
||||
std::unique_ptr<ArtboardInstance> artboard) :
|
||||
m_file(file), m_artboard(std::move(artboard))
|
||||
{}
|
||||
@@ -293,7 +293,15 @@ ArtboardInstance* CommandServer::getArtboardInstance(
|
||||
{
|
||||
assert(std::this_thread::get_id() == m_threadID);
|
||||
auto it = m_artboards.find(handle);
|
||||
return it != m_artboards.end() ? it->second.get() : nullptr;
|
||||
return it != m_artboards.end() ? it->second.get()->artboard() : nullptr;
|
||||
}
|
||||
|
||||
rcp<BindableArtboard> CommandServer::getBindableArtboard(
|
||||
ArtboardHandle handle) const
|
||||
{
|
||||
assert(std::this_thread::get_id() == m_threadID);
|
||||
auto it = m_artboards.find(handle);
|
||||
return it != m_artboards.end() ? it->second : nullptr;
|
||||
}
|
||||
|
||||
StateMachineInstance* CommandServer::getStateMachineInstance(
|
||||
@@ -519,7 +527,7 @@ bool CommandServer::processCommands()
|
||||
if (file != nullptr)
|
||||
{
|
||||
m_fileDependencies[handle] = {};
|
||||
m_files[handle] = std::move(file);
|
||||
m_files[handle] = file;
|
||||
|
||||
std::unique_lock<std::mutex> messageLock(
|
||||
m_commandQueue->m_messageMutex);
|
||||
@@ -823,12 +831,9 @@ bool CommandServer::processCommands()
|
||||
if (rive::File* file = getFile(fileHandle))
|
||||
{
|
||||
if (auto artboard = name.empty()
|
||||
? file->artboardDefault()
|
||||
: file->artboardNamed(name))
|
||||
? file->bindableArtboardDefault()
|
||||
: file->bindableArtboardNamed(name))
|
||||
{
|
||||
assert(m_fileDependencies.find(fileHandle) !=
|
||||
m_fileDependencies.end());
|
||||
m_fileDependencies[fileHandle].push_back(handle);
|
||||
m_artboardDependencies[handle] = {};
|
||||
m_artboards[handle] = std::move(artboard);
|
||||
}
|
||||
@@ -984,8 +989,7 @@ bool CommandServer::processCommands()
|
||||
{
|
||||
if (viewModelInstanceName.empty())
|
||||
{
|
||||
instance =
|
||||
ref_rcp(viewModel->createDefaultInstance());
|
||||
instance = viewModel->createDefaultInstance();
|
||||
if (instance == nullptr)
|
||||
{
|
||||
ErrorReporter<FileHandle>(
|
||||
@@ -1000,9 +1004,8 @@ bool CommandServer::processCommands()
|
||||
}
|
||||
else
|
||||
{
|
||||
instance =
|
||||
ref_rcp(viewModel->createInstanceFromName(
|
||||
viewModelInstanceName));
|
||||
instance = viewModel->createInstanceFromName(
|
||||
viewModelInstanceName);
|
||||
if (instance == nullptr)
|
||||
{
|
||||
ErrorReporter<FileHandle>(
|
||||
@@ -1019,7 +1022,7 @@ bool CommandServer::processCommands()
|
||||
}
|
||||
else
|
||||
{
|
||||
instance = ref_rcp(viewModel->createInstance());
|
||||
instance = viewModel->createInstance();
|
||||
if (instance == nullptr)
|
||||
{
|
||||
ErrorReporter<FileHandle>(
|
||||
@@ -1313,8 +1316,7 @@ bool CommandServer::processCommands()
|
||||
if (auto nestedViewModel =
|
||||
rootViewInstance->propertyViewModel(path))
|
||||
{
|
||||
m_viewModels[nestedViewHandle] =
|
||||
ref_rcp(nestedViewModel);
|
||||
m_viewModels[nestedViewHandle] = nestedViewModel;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1365,8 +1367,7 @@ bool CommandServer::processCommands()
|
||||
auto viewModelInstance = list->instanceAt(index);
|
||||
if (viewModelInstance)
|
||||
{
|
||||
m_viewModels[listViewHandle] =
|
||||
ref_rcp(viewModelInstance);
|
||||
m_viewModels[listViewHandle] = viewModelInstance;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2244,14 +2245,14 @@ bool CommandServer::processCommands()
|
||||
}
|
||||
case DataType::artboard:
|
||||
{
|
||||
if (auto artboard =
|
||||
getArtboardInstance(artboadHandle))
|
||||
if (auto bindableArtboard =
|
||||
getBindableArtboard(artboadHandle))
|
||||
{
|
||||
if (auto artboardProperty =
|
||||
viewModelInstance->propertyArtboard(
|
||||
value.metaData.name))
|
||||
{
|
||||
artboardProperty->value(artboard);
|
||||
artboardProperty->value(bindableArtboard);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -392,3 +392,7 @@ bool DataBind::advance(float elapsedTime)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DataBind::file(File* value) { m_file = value; };
|
||||
|
||||
File* DataBind::file() const { return m_file; };
|
||||
23
src/file.cpp
23
src/file.cpp
@@ -1,4 +1,5 @@
|
||||
#include "rive/file.hpp"
|
||||
#include "rive/bindable_artboard.hpp"
|
||||
#include "rive/runtime_header.hpp"
|
||||
#include "rive/animation/animation.hpp"
|
||||
#include "rive/artboard_component_list.hpp"
|
||||
@@ -38,6 +39,7 @@
|
||||
#include "rive/animation/blend_state_direct.hpp"
|
||||
#include "rive/animation/transition_property_viewmodel_comparator.hpp"
|
||||
#include "rive/constraints/scrolling/scroll_physics.hpp"
|
||||
#include "rive/data_bind/data_bind.hpp"
|
||||
#include "rive/data_bind/bindable_property.hpp"
|
||||
#include "rive/data_bind/bindable_property_artboard.hpp"
|
||||
#include "rive/data_bind/bindable_property_asset.hpp"
|
||||
@@ -589,6 +591,27 @@ std::unique_ptr<ArtboardInstance> File::artboardNamed(std::string name) const
|
||||
return ab ? ab->instance() : nullptr;
|
||||
}
|
||||
|
||||
rcp<BindableArtboard> File::bindableArtboardNamed(std::string name) const
|
||||
{
|
||||
auto ab = this->artboardNamed(name);
|
||||
return ab ? make_rcp<BindableArtboard>(ref_rcp(this), std::move(ab))
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
rcp<BindableArtboard> File::bindableArtboardDefault() const
|
||||
{
|
||||
auto ab = this->artboardDefault();
|
||||
return ab ? make_rcp<BindableArtboard>(ref_rcp(this), std::move(ab))
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
rcp<BindableArtboard> File::internalBindableArtboardFromArtboard(
|
||||
Artboard* artboard) const
|
||||
{
|
||||
auto ab = artboard ? artboard->instance() : nullptr;
|
||||
return ab ? make_rcp<BindableArtboard>(nullptr, std::move(ab)) : nullptr;
|
||||
}
|
||||
|
||||
void File::completeViewModelInstance(
|
||||
rcp<ViewModelInstance> viewModelInstance) const
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "rive/constraints/scrolling/scroll_physics.hpp"
|
||||
#include "rive/viewmodel/viewmodel.hpp"
|
||||
#include "rive/viewmodel/viewmodel_instance.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include "rive/data_bind/converters/data_converter.hpp"
|
||||
#include "rive/data_bind/converters/data_converter_group_item.hpp"
|
||||
#include "rive/data_bind/converters/data_converter_range_mapper.hpp"
|
||||
|
||||
@@ -64,9 +64,10 @@ Artboard* NestedArtboard::findArtboard(
|
||||
}
|
||||
if (viewModelInstanceArtboard->asset() != nullptr)
|
||||
{
|
||||
if (!parentArtboard()->isAncestor(viewModelInstanceArtboard->asset()))
|
||||
if (!parentArtboard()->isAncestor(
|
||||
viewModelInstanceArtboard->asset()->artboard()))
|
||||
{
|
||||
return viewModelInstanceArtboard->asset();
|
||||
return viewModelInstanceArtboard->asset()->artboard();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -4,13 +4,15 @@
|
||||
// Default namespace for Rive Cpp code
|
||||
using namespace rive;
|
||||
|
||||
void ViewModelInstanceArtboardRuntime::value(Artboard* artboard)
|
||||
void ViewModelInstanceArtboardRuntime::value(
|
||||
rcp<BindableArtboard> bindableArtboard)
|
||||
{
|
||||
m_viewModelInstanceValue->as<ViewModelInstanceArtboard>()->asset(artboard);
|
||||
m_viewModelInstanceValue->as<ViewModelInstanceArtboard>()->asset(
|
||||
bindableArtboard);
|
||||
}
|
||||
|
||||
#ifdef TESTING
|
||||
Artboard* ViewModelInstanceArtboardRuntime::testing_value()
|
||||
rcp<BindableArtboard> ViewModelInstanceArtboardRuntime::testing_value()
|
||||
{
|
||||
return m_viewModelInstanceValue->as<ViewModelInstanceArtboard>()->asset();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
// Default namespace for Rive Cpp code
|
||||
using namespace rive;
|
||||
|
||||
ViewModelInstanceRuntime* ViewModelInstanceListRuntime::instanceAt(int index)
|
||||
rcp<ViewModelInstanceRuntime> ViewModelInstanceListRuntime::instanceAt(
|
||||
int index)
|
||||
{
|
||||
auto listItems =
|
||||
m_viewModelInstanceValue->as<ViewModelInstanceList>()->listItems();
|
||||
@@ -22,12 +23,12 @@ ViewModelInstanceRuntime* ViewModelInstanceListRuntime::instanceAt(int index)
|
||||
auto it = m_itemsMap.find(listItem);
|
||||
if (it != m_itemsMap.end())
|
||||
{
|
||||
return it->second.get();
|
||||
return rcp<ViewModelInstanceRuntime>(it->second);
|
||||
}
|
||||
auto instanceRuntime =
|
||||
make_rcp<ViewModelInstanceRuntime>(listItem->viewModelInstance());
|
||||
m_itemsMap[listItem] = instanceRuntime;
|
||||
return instanceRuntime.get();
|
||||
return rcp<ViewModelInstanceRuntime>(instanceRuntime);
|
||||
}
|
||||
|
||||
void ViewModelInstanceListRuntime::addInstance(
|
||||
|
||||
@@ -296,14 +296,14 @@ rcp<ViewModelInstanceRuntime> ViewModelInstanceRuntime::instanceRuntime(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ViewModelInstanceRuntime* ViewModelInstanceRuntime::propertyViewModel(
|
||||
rcp<ViewModelInstanceRuntime> ViewModelInstanceRuntime::propertyViewModel(
|
||||
const std::string& path) const
|
||||
{
|
||||
const auto propertyName = getPropertyNameFromPath(path);
|
||||
auto viewModelInstance = viewModelInstanceFromFullPath(path);
|
||||
if (viewModelInstance != nullptr)
|
||||
{
|
||||
return viewModelInstance->instanceRuntime(propertyName).get();
|
||||
return viewModelInstance->instanceRuntime(propertyName);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ std::vector<std::string> ViewModelRuntime::instanceNames() const
|
||||
return names;
|
||||
}
|
||||
|
||||
ViewModelInstanceRuntime* ViewModelRuntime::createInstanceFromIndex(
|
||||
rcp<ViewModelInstanceRuntime> ViewModelRuntime::createInstanceFromIndex(
|
||||
const size_t index) const
|
||||
{
|
||||
auto viewModelInstance = m_viewModel->instance(index);
|
||||
@@ -129,7 +129,7 @@ ViewModelInstanceRuntime* ViewModelRuntime::createInstanceFromIndex(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ViewModelInstanceRuntime* ViewModelRuntime::createInstanceFromName(
|
||||
rcp<ViewModelInstanceRuntime> ViewModelRuntime::createInstanceFromName(
|
||||
const std::string& name) const
|
||||
{
|
||||
auto viewModelInstance = m_viewModel->instance(name);
|
||||
@@ -151,7 +151,7 @@ ViewModelInstanceRuntime* ViewModelRuntime::createInstanceFromName(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ViewModelInstanceRuntime* ViewModelRuntime::createDefaultInstance() const
|
||||
rcp<ViewModelInstanceRuntime> ViewModelRuntime::createDefaultInstance() const
|
||||
{
|
||||
auto viewModelInstance =
|
||||
m_file->createDefaultViewModelInstance(m_viewModel);
|
||||
@@ -164,21 +164,20 @@ ViewModelInstanceRuntime* ViewModelRuntime::createDefaultInstance() const
|
||||
return createInstance();
|
||||
}
|
||||
|
||||
ViewModelInstanceRuntime* ViewModelRuntime::createInstance() const
|
||||
rcp<ViewModelInstanceRuntime> ViewModelRuntime::createInstance() const
|
||||
{
|
||||
auto instance = m_file->createViewModelInstance(m_viewModel);
|
||||
return createRuntimeInstance(instance);
|
||||
}
|
||||
|
||||
ViewModelInstanceRuntime* ViewModelRuntime::createRuntimeInstance(
|
||||
rcp<ViewModelInstanceRuntime> ViewModelRuntime::createRuntimeInstance(
|
||||
rcp<ViewModelInstance> instance) const
|
||||
{
|
||||
if (instance != nullptr)
|
||||
{
|
||||
auto viewModelInstanceRuntime = rcp<ViewModelInstanceRuntime>(
|
||||
new ViewModelInstanceRuntime(instance));
|
||||
m_viewModelInstanceRuntimes.push_back(viewModelInstanceRuntime);
|
||||
return viewModelInstanceRuntime.get();
|
||||
return viewModelInstanceRuntime;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -10,7 +10,7 @@ using namespace rive;
|
||||
|
||||
void ViewModelInstanceArtboard::propertyValueChanged()
|
||||
{
|
||||
m_artboard = nullptr;
|
||||
m_bindableArtboard = nullptr;
|
||||
addDirt(ComponentDirt::Bindings);
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
if (m_changedCallback != nullptr)
|
||||
@@ -21,9 +21,9 @@ void ViewModelInstanceArtboard::propertyValueChanged()
|
||||
onValueChanged();
|
||||
}
|
||||
|
||||
void ViewModelInstanceArtboard::asset(Artboard* value)
|
||||
void ViewModelInstanceArtboard::asset(rcp<BindableArtboard> value)
|
||||
{
|
||||
propertyValue(-1);
|
||||
m_artboard = value;
|
||||
m_bindableArtboard = value;
|
||||
addDirt(ComponentDirt::Bindings);
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "rive/artboard.hpp"
|
||||
#include "rive/factory.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include "rive/refcnt.hpp"
|
||||
|
||||
struct AutoClose
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "rive/artboard.hpp"
|
||||
#include "rive/renderer.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include "rive/refcnt.hpp"
|
||||
#include "rive/animation/state_machine_instance.hpp"
|
||||
#include "rive/static_scene.hpp"
|
||||
#include <filesystem>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "common/test_harness.hpp"
|
||||
#include "common/testing_window.hpp"
|
||||
#include "rive/artboard.hpp"
|
||||
#include "rive/refcnt.hpp"
|
||||
#include "rive/animation/state_machine_instance.hpp"
|
||||
#include "rive/file.hpp"
|
||||
#include "rive/text/font_hb.hpp"
|
||||
|
||||
@@ -175,9 +175,8 @@ TEST_CASE("artboard management", "[CommandQueue]")
|
||||
|
||||
// Deleting the file first should now delete the artboard as well.
|
||||
commandQueue->deleteFile(fileHandle);
|
||||
commandQueue->runOnce([fileHandle, artboardHandle1](CommandServer* server) {
|
||||
commandQueue->runOnce([fileHandle](CommandServer* server) {
|
||||
CHECK(server->getFile(fileHandle) == nullptr);
|
||||
CHECK(server->getArtboardInstance(artboardHandle1) == nullptr);
|
||||
});
|
||||
|
||||
commandQueue->deleteArtboard(artboardHandle1);
|
||||
@@ -792,7 +791,7 @@ TEST_CASE("View Models", "[CommandQueue]")
|
||||
auto list =
|
||||
server->getViewModelInstance(bviewModel)->propertyList("Test List");
|
||||
CHECK(list != nullptr);
|
||||
CHECK(list->instanceAt(0) ==
|
||||
CHECK(list->instanceAt(0).get() ==
|
||||
server->getViewModelInstance(listViewModel));
|
||||
});
|
||||
|
||||
@@ -1628,7 +1627,7 @@ public:
|
||||
CHECK(nested != nullptr);
|
||||
auto property = instance->propertyViewModel(name);
|
||||
CHECK(property != nullptr);
|
||||
CHECK(property == nested);
|
||||
CHECK(property.get() == nested);
|
||||
});
|
||||
|
||||
// There is no requesting for nested view models
|
||||
@@ -1807,20 +1806,24 @@ TEST_CASE("View Model Property Set/Get", "[CommandQueue]")
|
||||
});
|
||||
|
||||
// Same for artboards.
|
||||
auto bindableArtboardHandle =
|
||||
commandQueue->instantiateDefaultArtboard(fileHandle);
|
||||
commandQueue->setViewModelInstanceArtboard(tester.m_handle,
|
||||
"Test Artboard",
|
||||
artboardHandle);
|
||||
bindableArtboardHandle);
|
||||
|
||||
commandQueue->runOnce([artboardHandle,
|
||||
commandQueue->runOnce([bindableArtboardHandle,
|
||||
handle = tester.m_handle](CommandServer* server) {
|
||||
auto artboard = server->getArtboardInstance(artboardHandle);
|
||||
CHECK(artboard != nullptr);
|
||||
auto bindableArtboard =
|
||||
server->getBindableArtboard(bindableArtboardHandle);
|
||||
CHECK(bindableArtboard != nullptr);
|
||||
auto viewModel = server->getViewModelInstance(handle);
|
||||
CHECK(viewModel != nullptr);
|
||||
auto artboardProperty = viewModel->propertyArtboard("Test Artboard");
|
||||
CHECK(artboardProperty != nullptr);
|
||||
CHECK(artboardProperty->testing_value() == artboard);
|
||||
CHECK(artboardProperty->testing_value() == bindableArtboard);
|
||||
});
|
||||
commandQueue->deleteArtboard(bindableArtboardHandle);
|
||||
|
||||
auto badImageHandle =
|
||||
commandQueue->decodeImage(std::vector<uint8_t>(1024 * 1024, {}));
|
||||
@@ -2512,8 +2515,8 @@ public:
|
||||
CHECK(value2Instance != nullptr);
|
||||
auto property = instance->propertyList(name);
|
||||
CHECK(property != nullptr);
|
||||
CHECK(property->instanceAt(index) == value1Instance);
|
||||
CHECK(property->instanceAt(index2) == value2Instance);
|
||||
CHECK(property->instanceAt(index).get() == value1Instance);
|
||||
CHECK(property->instanceAt(index2).get() == value2Instance);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2532,23 +2535,23 @@ public:
|
||||
auto property = instance->propertyList(name);
|
||||
CHECK(property != nullptr);
|
||||
auto valueModel = server->getViewModelInstance(value);
|
||||
CHECK(property->instanceAt(index) == valueModel);
|
||||
CHECK(property->instanceAt(index).get() == valueModel);
|
||||
});
|
||||
}
|
||||
|
||||
void pushExpectation(std::string name, ViewModelInstanceHandle value)
|
||||
{
|
||||
m_queue->appendViewModelInstanceListViewModel(m_handle, name, value);
|
||||
m_queue->runOnce(
|
||||
[handle = m_handle, name, value](CommandServer* server) {
|
||||
auto instance = server->getViewModelInstance(handle);
|
||||
CHECK(instance != nullptr);
|
||||
auto property = instance->propertyList(name);
|
||||
CHECK(property != nullptr);
|
||||
auto valueModel = server->getViewModelInstance(value);
|
||||
CHECK(property->instanceAt(static_cast<int>(property->size()) -
|
||||
1) == valueModel);
|
||||
});
|
||||
m_queue->runOnce([handle = m_handle, name, value](
|
||||
CommandServer* server) {
|
||||
auto instance = server->getViewModelInstance(handle);
|
||||
CHECK(instance != nullptr);
|
||||
auto property = instance->propertyList(name);
|
||||
CHECK(property != nullptr);
|
||||
auto valueModel = server->getViewModelInstance(value);
|
||||
CHECK(property->instanceAt(static_cast<int>(property->size()) - 1)
|
||||
.get() == valueModel);
|
||||
});
|
||||
}
|
||||
|
||||
void pushBadExpectation(std::string name,
|
||||
|
||||
@@ -68,7 +68,7 @@ TEST_CASE("Test data binding artboards from same and different sources",
|
||||
|
||||
// Change source to local artboard at index 1
|
||||
|
||||
auto ch1Source = file->artboard("ch1");
|
||||
auto ch1Source = file->bindableArtboardNamed("ch1");
|
||||
vmiArtboard->asset(ch1Source);
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
@@ -76,14 +76,14 @@ TEST_CASE("Test data binding artboards from same and different sources",
|
||||
|
||||
// Change source to local artboard at index 2
|
||||
|
||||
auto ch2Source = file->artboard("ch2");
|
||||
auto ch2Source = file->bindableArtboardNamed("ch2");
|
||||
vmiArtboard->asset(ch2Source);
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
artboard->draw(renderer.get());
|
||||
|
||||
// Change source to external artboard "source_1"
|
||||
auto source1 = sourceFile->artboard("source_1");
|
||||
auto source1 = sourceFile->bindableArtboardNamed("source_1");
|
||||
vmiArtboard->asset(source1);
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
@@ -102,7 +102,7 @@ TEST_CASE("Test data binding artboards from same and different sources",
|
||||
artboard->draw(renderer.get());
|
||||
|
||||
// Change source to external artboard "source_2"
|
||||
auto source2 = sourceFile->artboard("source_2");
|
||||
auto source2 = sourceFile->bindableArtboardNamed("source_2");
|
||||
vmiArtboard->asset(source2);
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
@@ -166,7 +166,7 @@ TEST_CASE("Test recursive data binding artboards is skipped", "[data binding]")
|
||||
artboard->draw(renderer.get());
|
||||
|
||||
// Change source to artboard "recursive-grand-child-1"
|
||||
auto child1Source = file->artboard("recursive-grand-child-1");
|
||||
auto child1Source = file->bindableArtboardNamed("recursive-grand-child-1");
|
||||
vmiArtboard->asset(child1Source);
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
@@ -174,7 +174,7 @@ TEST_CASE("Test recursive data binding artboards is skipped", "[data binding]")
|
||||
|
||||
// Changing source to artboard "recursive-parent" does not change the
|
||||
// content because it's an ancestor of itself
|
||||
auto parentSource = file->artboard("recursive-parent");
|
||||
auto parentSource = file->bindableArtboardNamed("recursive-parent");
|
||||
vmiArtboard->asset(parentSource);
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
@@ -182,14 +182,15 @@ TEST_CASE("Test recursive data binding artboards is skipped", "[data binding]")
|
||||
|
||||
// Changing source to artboard "recursive-grand-parent" does not change the
|
||||
// content because it's an ancestor of itself
|
||||
auto grandParentSource = file->artboard("recursive-grand-parent");
|
||||
auto grandParentSource =
|
||||
file->bindableArtboardNamed("recursive-grand-parent");
|
||||
vmiArtboard->asset(grandParentSource);
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
artboard->draw(renderer.get());
|
||||
|
||||
// Change source to artboard "recursive-grand-child-2"
|
||||
auto child2Source = file->artboard("recursive-grand-child-2");
|
||||
auto child2Source = file->bindableArtboardNamed("recursive-grand-child-2");
|
||||
vmiArtboard->asset(child2Source);
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
@@ -197,3 +198,58 @@ TEST_CASE("Test recursive data binding artboards is skipped", "[data binding]")
|
||||
|
||||
CHECK(silver.matches("data_binding_artboards_test_recursive"));
|
||||
}
|
||||
|
||||
TEST_CASE("Test default data binding artboard from different source",
|
||||
"[data binding]")
|
||||
{
|
||||
// Note: the data_binding_artboards_source_test has a view model created
|
||||
// that matches the view model the original artboards have. This is a
|
||||
// temporary "hack" to validate that the artboard gets correctly bound
|
||||
SerializingFactory silver;
|
||||
auto file = ReadRiveFile("assets/data_binding_artboards_test.riv", &silver);
|
||||
auto sourceFile =
|
||||
ReadRiveFile("assets/data_binding_artboards_source_test.riv", &silver);
|
||||
|
||||
auto artboard = file->artboardDefault();
|
||||
silver.frameSize(artboard->width(), artboard->height());
|
||||
|
||||
REQUIRE(artboard != nullptr);
|
||||
auto stateMachine = artboard->stateMachineAt(0);
|
||||
int viewModelId = artboard.get()->viewModelId();
|
||||
|
||||
auto vmi = viewModelId == -1
|
||||
? file->createViewModelInstance(artboard.get())
|
||||
: file->createViewModelInstance(viewModelId, 0);
|
||||
|
||||
stateMachine->bindViewModelInstance(vmi);
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
auto renderer = silver.makeRenderer();
|
||||
artboard->draw(renderer.get());
|
||||
|
||||
auto vmiArtboard =
|
||||
vmi->propertyValue("ab")->as<ViewModelInstanceArtboard>();
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
artboard->draw(renderer.get());
|
||||
// Change source to local artboard at index 1
|
||||
|
||||
auto ch1Source = file->bindableArtboardNamed("ch1");
|
||||
vmiArtboard->asset(ch1Source);
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
artboard->draw(renderer.get());
|
||||
// Change source to local artboard at index 2
|
||||
|
||||
auto ch2Source = file->bindableArtboardNamed("ch2");
|
||||
vmiArtboard->asset(ch2Source);
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
artboard->draw(renderer.get());
|
||||
// Change source to default bindable artboard
|
||||
auto source1 = sourceFile->bindableArtboardDefault();
|
||||
vmiArtboard->asset(source1);
|
||||
silver.addFrame();
|
||||
stateMachine->advanceAndApply(0.1f);
|
||||
artboard->draw(renderer.get());
|
||||
CHECK(silver.matches("data_binding_artboards_default_test"));
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user