mirror of
https://github.com/rive-app/rive-cpp.git
synced 2026-01-18 21:21:17 +01:00
305 lines
10 KiB
C++
305 lines
10 KiB
C++
#ifndef _RIVE_FILE_HPP_
|
|
#define _RIVE_FILE_HPP_
|
|
|
|
#include "rive/artboard.hpp"
|
|
#include "rive/backboard.hpp"
|
|
#include "rive/factory.hpp"
|
|
#include "rive/file_asset_loader.hpp"
|
|
#include "rive/assets/manifest_asset.hpp"
|
|
#include "rive/viewmodel/data_enum.hpp"
|
|
#include "rive/viewmodel/viewmodel_component.hpp"
|
|
#include "rive/viewmodel/viewmodel_instance.hpp"
|
|
#include "rive/viewmodel/viewmodel_instance_value.hpp"
|
|
#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 "rive/data_resolver.hpp"
|
|
#include <vector>
|
|
#include <set>
|
|
#include <unordered_map>
|
|
|
|
#ifdef WITH_RIVE_SCRIPTING
|
|
struct lua_State;
|
|
#endif
|
|
|
|
///
|
|
/// Default namespace for Rive Cpp runtime code.
|
|
///
|
|
namespace rive
|
|
{
|
|
#ifdef WITH_RIVE_TOOLS
|
|
class ViewModelInstance;
|
|
typedef void (*ViewModelInstanceCreated)(ViewModelInstance* instance);
|
|
#endif
|
|
class BinaryReader;
|
|
class DataBind;
|
|
class RuntimeHeader;
|
|
class Factory;
|
|
class ScrollPhysics;
|
|
class ViewModelRuntime;
|
|
class BindableArtboard;
|
|
#ifdef WITH_RIVE_SCRIPTING
|
|
class CPPRuntimeScriptingContext;
|
|
class ScriptingVM;
|
|
#endif
|
|
|
|
///
|
|
/// Tracks the success/failure result when importing a Rive file.
|
|
///
|
|
enum class ImportResult
|
|
{
|
|
/// Indicates that a file's been successfully imported.
|
|
success,
|
|
/// Indicates that the Rive file is not supported by this runtime.
|
|
unsupportedVersion,
|
|
/// Indicates that the there is a formatting problem in the file itself.
|
|
malformed
|
|
};
|
|
|
|
///
|
|
/// A Rive file.
|
|
///
|
|
class File : public RefCnt<File>
|
|
{
|
|
public:
|
|
/// Major version number supported by the runtime.
|
|
static const int majorVersion = 7;
|
|
/// Minor version number supported by the runtime.
|
|
static const int minorVersion = 0;
|
|
|
|
File(Factory*, rcp<FileAssetLoader>);
|
|
|
|
public:
|
|
~File();
|
|
#if defined(DEBUG) && defined(WITH_RIVE_TOOLS)
|
|
static size_t debugTotalFileCount;
|
|
#endif
|
|
///
|
|
/// Imports a Rive file from a binary buffer.
|
|
/// @param data the raw date of the file.
|
|
/// @param result is an optional status result.
|
|
/// @param assetLoader is an optional helper to load assets which
|
|
/// cannot be found in-band.
|
|
/// @returns a pointer to the file, or null on failure.
|
|
static rcp<File> import(Span<const uint8_t> data,
|
|
Factory* factory,
|
|
ImportResult* result = nullptr,
|
|
FileAssetLoader* assetLoader = nullptr)
|
|
{
|
|
return import(data, factory, result, ref_rcp(assetLoader));
|
|
}
|
|
|
|
static rcp<File> import(Span<const uint8_t> data,
|
|
Factory*,
|
|
ImportResult* result,
|
|
rcp<FileAssetLoader> assetLoader);
|
|
|
|
/// @returns the file's backboard. All files have exactly one backboard.
|
|
Backboard* backboard() const { return m_backboard; }
|
|
|
|
/// @returns the number of artboards in the file.
|
|
size_t artboardCount() const { return m_artboards.size(); }
|
|
std::string artboardNameAt(size_t index) const;
|
|
|
|
Span<const rcp<FileAsset>> assets() const;
|
|
|
|
// Instances
|
|
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;
|
|
|
|
/// @returns the named artboard. If no artboard is found with that name,
|
|
/// the null pointer is returned.
|
|
Artboard* artboard(std::string name) const;
|
|
|
|
/// @returns the artboard at the specified index, or the nullptr if the
|
|
/// index is out of range.
|
|
Artboard* artboard(size_t index) const;
|
|
|
|
/// @returns a view model instance of the view model with the specified
|
|
/// name.
|
|
rcp<ViewModelInstance> createViewModelInstance(std::string name) const;
|
|
|
|
/// @returns a view model instance attached to the artboard if it exists.
|
|
rcp<ViewModelInstance> createViewModelInstance(Artboard* artboard) const;
|
|
|
|
/// @returns a view model instance of the viewModel.
|
|
rcp<ViewModelInstance> createViewModelInstance(ViewModel* viewModel) const;
|
|
|
|
/// @returns the default view model instance of the viewModel, or returns an
|
|
/// empty one if there is no default.
|
|
rcp<ViewModelInstance> createDefaultViewModelInstance(
|
|
ViewModel* viewModel) const;
|
|
|
|
/// @returns the default view model instance of the viewModel, or returns an
|
|
/// empty one if there is no default.
|
|
rcp<ViewModelInstance> createDefaultViewModelInstance(
|
|
Artboard* artboard) const;
|
|
|
|
/// @returns a view model instance of the viewModel by name and instance
|
|
/// name.
|
|
rcp<ViewModelInstance> createViewModelInstance(
|
|
std::string name,
|
|
std::string instanceName) const;
|
|
|
|
/// @returns a view model instance of the viewModel by their indexes.
|
|
rcp<ViewModelInstance> createViewModelInstance(size_t index,
|
|
size_t instanceIndex) const;
|
|
|
|
size_t viewModelCount() const { return m_ViewModels.size(); }
|
|
ViewModel* viewModel(std::string name);
|
|
ViewModel* viewModel(size_t index);
|
|
ViewModelRuntime* defaultArtboardViewModel(Artboard* artboard) const;
|
|
ViewModelRuntime* viewModelByIndex(size_t index) const;
|
|
ViewModelRuntime* viewModelByName(std::string name) const;
|
|
ViewModelInstanceListItem* viewModelInstanceListItem(
|
|
rcp<ViewModelInstance> viewModelInstance);
|
|
ViewModelInstanceListItem* viewModelInstanceListItem(
|
|
rcp<ViewModelInstance> viewModelInstance,
|
|
Artboard* artboard);
|
|
void completeViewModelInstance(
|
|
rcp<ViewModelInstance> viewModelInstance,
|
|
std::unordered_map<ViewModelInstance*, rcp<ViewModelInstance>>&
|
|
instancesMap) const;
|
|
void completeViewModelInstance(
|
|
rcp<ViewModelInstance> viewModelInstance) const;
|
|
const std::vector<DataEnum*>& enums() const;
|
|
rcp<FileAsset> asset(size_t index);
|
|
|
|
std::vector<Artboard*> artboards() { return m_artboards; };
|
|
|
|
// When the runtime is hosted in the editor, we get a pointer
|
|
// to the VM that we can use. If this is nullptr, we can assume
|
|
// we are running in the runtime and should instance our own VMs
|
|
// and pass them down to the root
|
|
#ifdef WITH_RIVE_SCRIPTING
|
|
void scriptingVM(lua_State* vm)
|
|
{
|
|
cleanupScriptingVM();
|
|
m_luaState = vm;
|
|
}
|
|
lua_State* scriptingVM()
|
|
{
|
|
// For now, if we don't have a vm, create one. In the future, we
|
|
// may need a way to create multiple vms in parallel
|
|
if (m_luaState == nullptr)
|
|
{
|
|
makeScriptingVM();
|
|
}
|
|
return m_luaState;
|
|
}
|
|
#ifdef WITH_RIVE_TOOLS
|
|
void clearScriptingVM() { cleanupScriptingVM(); }
|
|
bool hasVM() { return m_luaState != nullptr; }
|
|
#endif
|
|
#endif
|
|
|
|
DataResolver* dataResolver()
|
|
{
|
|
if (m_manifest)
|
|
{
|
|
return m_manifest.get()->as<ManifestAsset>();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
#ifdef WITH_RIVE_TOOLS
|
|
/// Strips FileAssetContents for FileAssets of given typeKeys.
|
|
/// @param data the raw data of the file.
|
|
/// @param result is an optional status result.
|
|
/// @returns the data buffer of the file with the FileAssetContents objects
|
|
/// stripped out.
|
|
static const std::vector<uint8_t> stripAssets(
|
|
Span<const uint8_t> data,
|
|
std::set<uint16_t> typeKeys,
|
|
ImportResult* result = nullptr);
|
|
#endif
|
|
|
|
#ifdef TESTING
|
|
FileAssetLoader* testing_getAssetLoader() const
|
|
{
|
|
return m_assetLoader.get();
|
|
}
|
|
#endif
|
|
#ifdef WITH_RIVE_TOOLS
|
|
void onViewModelInstanceCreated(ViewModelInstanceCreated callback)
|
|
{
|
|
m_viewmodelInstanceCreatedCallback = callback;
|
|
}
|
|
void triggerViewModelCreatedCallback(bool value)
|
|
{
|
|
m_triggerViewModelCreatedCallback = value;
|
|
}
|
|
#endif
|
|
|
|
private:
|
|
ImportResult read(BinaryReader&, const RuntimeHeader&);
|
|
|
|
/// The file's backboard. All Rive files have a single backboard
|
|
/// where the artboards live.
|
|
Backboard* m_backboard;
|
|
|
|
/// We just keep these alive for the life of this File
|
|
std::vector<rcp<FileAsset>> m_fileAssets;
|
|
|
|
std::vector<DataConverter*> m_DataConverters;
|
|
|
|
std::vector<KeyFrameInterpolator*> m_keyframeInterpolators;
|
|
std::vector<ScrollPhysics*> m_scrollPhysics;
|
|
|
|
/// List of artboards in the file. Each artboard encapsulates a set of
|
|
/// Rive components and animations.
|
|
std::vector<Artboard*> m_artboards;
|
|
|
|
/// List of view models in the file. They may outlive the file if viewmodel
|
|
/// instances are still needed after the file is destroyed
|
|
std::vector<ViewModel*> m_ViewModels;
|
|
|
|
/// List of view models instances in the file. We keep this list to keep
|
|
/// them alive during the lifetime of this file. This list does not hold a
|
|
/// reference to instances created by users.
|
|
std::vector<ViewModelInstance*> m_ViewModelInstances;
|
|
|
|
mutable std::vector<rcp<ViewModelRuntime>> m_viewModelRuntimes;
|
|
std::vector<DataEnum*> m_Enums;
|
|
|
|
Factory* m_factory;
|
|
|
|
/// The helper used to load assets when they're not provided in-band
|
|
/// with the file.
|
|
rcp<FileAssetLoader> m_assetLoader;
|
|
|
|
#ifdef WITH_RIVE_SCRIPTING
|
|
lua_State* m_luaState = nullptr;
|
|
std::unique_ptr<CPPRuntimeScriptingContext> m_scriptingContext;
|
|
std::unique_ptr<ScriptingVM> m_scriptingVM;
|
|
void makeScriptingVM();
|
|
void cleanupScriptingVM();
|
|
void registerScripts();
|
|
#endif
|
|
|
|
rcp<ViewModelInstance> copyViewModelInstance(
|
|
ViewModelInstance* viewModelInstance,
|
|
std::unordered_map<ViewModelInstance*, rcp<ViewModelInstance>>&
|
|
instancesMap) const;
|
|
|
|
rcp<ViewModelRuntime> createViewModelRuntime(ViewModel* viewModel) const;
|
|
|
|
uint32_t findViewModelId(ViewModel* search) const;
|
|
#ifdef WITH_RIVE_TOOLS
|
|
ViewModelInstanceCreated m_viewmodelInstanceCreatedCallback = nullptr;
|
|
bool m_triggerViewModelCreatedCallback = false;
|
|
#endif
|
|
|
|
rcp<FileAsset> m_manifest = nullptr;
|
|
};
|
|
} // namespace rive
|
|
#endif
|