mirror of
https://github.com/rive-app/rive-cpp.git
synced 2026-01-18 13:11:19 +01:00
No double deref luau (#11448) 62fcec60de
Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
This commit is contained in:
@@ -1 +1 @@
|
||||
9b416a02f6fffdcb2210cbb674ef7d746466e2d1
|
||||
62fcec60de0eea68dceb64758f284ef5b5e20c00
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
#include "rive/generated/assets/script_asset_base.hpp"
|
||||
#include "rive/simple_array.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
struct lua_State;
|
||||
#endif
|
||||
|
||||
namespace rive
|
||||
{
|
||||
class Artboard;
|
||||
@@ -24,7 +29,6 @@ enum ScriptProtocol
|
||||
};
|
||||
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
class LuaState;
|
||||
class ScriptAssetImporter;
|
||||
#endif
|
||||
|
||||
@@ -65,7 +69,7 @@ private:
|
||||
|
||||
protected:
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
bool verifyImplementation(ScriptedObject* object, LuaState* luaState);
|
||||
bool verifyImplementation(ScriptedObject* object, lua_State* state);
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -173,7 +177,7 @@ public:
|
||||
void file(File* value) { m_file = value; }
|
||||
File* file() const { return m_file; }
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
LuaState* vm();
|
||||
lua_State* vm();
|
||||
void registrationComplete(int ref) override;
|
||||
#endif
|
||||
std::string moduleName() override
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
struct lua_State;
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Default namespace for Rive Cpp runtime code.
|
||||
///
|
||||
@@ -39,7 +43,6 @@ class BindableArtboard;
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
class CPPRuntimeScriptingContext;
|
||||
class ScriptingVM;
|
||||
class LuaState;
|
||||
#endif
|
||||
|
||||
///
|
||||
@@ -177,12 +180,12 @@ public:
|
||||
// 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(LuaState* vm)
|
||||
void scriptingVM(lua_State* vm)
|
||||
{
|
||||
cleanupScriptingVM();
|
||||
m_luaState = vm;
|
||||
}
|
||||
LuaState* scriptingVM()
|
||||
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
|
||||
@@ -192,6 +195,10 @@ public:
|
||||
}
|
||||
return m_luaState;
|
||||
}
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
void clearScriptingVM() { cleanupScriptingVM(); }
|
||||
bool hasVM() { return m_luaState != nullptr; }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
DataResolver* dataResolver()
|
||||
@@ -270,7 +277,7 @@ private:
|
||||
rcp<FileAssetLoader> m_assetLoader;
|
||||
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
LuaState* m_luaState = nullptr;
|
||||
lua_State* m_luaState = nullptr;
|
||||
std::unique_ptr<CPPRuntimeScriptingContext> m_scriptingContext;
|
||||
std::unique_ptr<ScriptingVM> m_scriptingVM;
|
||||
void makeScriptingVM();
|
||||
|
||||
@@ -9,18 +9,10 @@
|
||||
namespace rive
|
||||
{
|
||||
class ViewModel;
|
||||
class LuaState
|
||||
{
|
||||
public:
|
||||
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
|
||||
LuaState(lua_State* state) : state(state) {}
|
||||
~LuaState() { state = nullptr; }
|
||||
void initializeData(std::vector<ViewModel*>&);
|
||||
|
||||
lua_State* state;
|
||||
void initializeLuaData(lua_State* state, std::vector<ViewModel*>& viewModels);
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace rive
|
||||
#endif
|
||||
@@ -1,8 +1,5 @@
|
||||
#ifndef _RIVE_SCRIPTED_DATA_CONVERTER_HPP_
|
||||
#define _RIVE_SCRIPTED_DATA_CONVERTER_HPP_
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
#include "rive/lua/rive_lua_libs.hpp"
|
||||
#endif
|
||||
#include "rive/generated/scripted/scripted_data_converter_base.hpp"
|
||||
#include "rive/advancing_component.hpp"
|
||||
#include "rive/scripted/scripted_object.hpp"
|
||||
@@ -41,7 +38,7 @@ private:
|
||||
public:
|
||||
~ScriptedDataConverter();
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
bool scriptInit(LuaState* state) override;
|
||||
bool scriptInit(lua_State* state) override;
|
||||
DataValue* convert(DataValue* value, DataBind* dataBind) override;
|
||||
DataValue* reverseConvert(DataValue* value, DataBind* dataBind) override;
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#ifndef _RIVE_SCRIPTED_DRAWABLE_HPP_
|
||||
#define _RIVE_SCRIPTED_DRAWABLE_HPP_
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
#include "rive/lua/rive_lua_libs.hpp"
|
||||
#endif
|
||||
#include "rive/generated/scripted/scripted_drawable_base.hpp"
|
||||
#include "rive/animation/state_machine_instance.hpp"
|
||||
#include "rive/advancing_component.hpp"
|
||||
@@ -24,7 +21,7 @@ class ScriptedDrawable : public ScriptedDrawableBase,
|
||||
{
|
||||
public:
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
bool scriptInit(LuaState* state) override;
|
||||
bool scriptInit(lua_State* state) override;
|
||||
#endif
|
||||
void draw(Renderer* renderer) override;
|
||||
void update(ComponentDirt value) override;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#ifndef _RIVE_SCRIPTED_LAYOUT_HPP_
|
||||
#define _RIVE_SCRIPTED_LAYOUT_HPP_
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
#include "rive/lua/rive_lua_libs.hpp"
|
||||
#endif
|
||||
#include "rive/layout/layout_enums.hpp"
|
||||
#include "rive/layout/layout_measure_mode.hpp"
|
||||
#include "rive/generated/scripted/scripted_layout_base.hpp"
|
||||
@@ -19,7 +16,7 @@ private:
|
||||
|
||||
public:
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
bool scriptInit(LuaState* luaState) override;
|
||||
bool scriptInit(lua_State* state) override;
|
||||
#endif
|
||||
Vec2D measureLayout(float width,
|
||||
LayoutMeasureMode widthMode,
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
#ifndef _RIVE_SCRIPTED_OBJECT_HPP_
|
||||
#define _RIVE_SCRIPTED_OBJECT_HPP_
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
#include "rive/lua/rive_lua_libs.hpp"
|
||||
#endif
|
||||
#include "rive/assets/file_asset_referencer.hpp"
|
||||
#include "rive/assets/script_asset.hpp"
|
||||
#include "rive/custom_property.hpp"
|
||||
@@ -10,6 +7,11 @@
|
||||
#include "rive/refcnt.hpp"
|
||||
#include "rive/generated/assets/script_asset_base.hpp"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
struct lua_State;
|
||||
#endif
|
||||
|
||||
namespace rive
|
||||
{
|
||||
class Artboard;
|
||||
@@ -26,7 +28,10 @@ protected:
|
||||
int m_context = 0;
|
||||
virtual void disposeScriptInputs();
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
LuaState* m_state = nullptr;
|
||||
lua_State* m_state = nullptr;
|
||||
#endif
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
bool hasValidVM();
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -45,8 +50,8 @@ public:
|
||||
virtual void markNeedsUpdate();
|
||||
virtual DataContext* dataContext() { return nullptr; }
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
virtual bool scriptInit(LuaState* state);
|
||||
LuaState* state() { return m_state; }
|
||||
virtual bool scriptInit(lua_State* state);
|
||||
lua_State* state() { return m_state; }
|
||||
#endif
|
||||
void scriptDispose();
|
||||
virtual bool addScriptedDirt(ComponentDirt value, bool recurse = false) = 0;
|
||||
|
||||
@@ -25,7 +25,7 @@ class ScriptedPathEffect : public ScriptedPathEffectBase,
|
||||
{
|
||||
public:
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
bool scriptInit(LuaState* state) override;
|
||||
bool scriptInit(lua_State* state) override;
|
||||
#endif
|
||||
void addProperty(CustomProperty* prop) override;
|
||||
StatusCode onAddedClean(CoreContext* context) override;
|
||||
|
||||
@@ -45,9 +45,8 @@ void ScriptInput::initScriptedValue() {}
|
||||
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
bool OptionalScriptedMethods::verifyImplementation(ScriptedObject* object,
|
||||
LuaState* luaState)
|
||||
lua_State* state)
|
||||
{
|
||||
auto state = luaState->state;
|
||||
lua_pushvalue(state, -1);
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(state, 0, 1)) != LUA_OK)
|
||||
{
|
||||
@@ -161,7 +160,7 @@ bool OptionalScriptedMethods::verifyImplementation(ScriptedObject* object,
|
||||
return true;
|
||||
}
|
||||
|
||||
LuaState* ScriptAsset::vm()
|
||||
lua_State* ScriptAsset::vm()
|
||||
{
|
||||
if (m_file == nullptr)
|
||||
{
|
||||
@@ -203,7 +202,8 @@ void ScriptAsset::registrationComplete(int ref)
|
||||
bool ScriptAsset::initScriptedObjectWith(ScriptedObject* object)
|
||||
{
|
||||
#if defined(WITH_RIVE_SCRIPTING)
|
||||
if (vm() == nullptr)
|
||||
auto state = vm();
|
||||
if (state == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -214,23 +214,22 @@ bool ScriptAsset::initScriptedObjectWith(ScriptedObject* object)
|
||||
name().c_str());
|
||||
return false;
|
||||
}
|
||||
auto vmState = vm()->state;
|
||||
rive_lua_pushRef(vmState, generatorFunctionRef());
|
||||
rive_lua_pushRef(state, generatorFunctionRef());
|
||||
|
||||
if (!m_initted)
|
||||
{
|
||||
if (!verifyImplementation(object, vm()))
|
||||
if (!verifyImplementation(object, state))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"ScriptAsset failed to verify method implementation %s\n",
|
||||
name().c_str());
|
||||
rive_lua_pop(vmState, 1);
|
||||
rive_lua_pop(state, 1);
|
||||
return false;
|
||||
}
|
||||
m_initted = true;
|
||||
}
|
||||
object->implementedMethods(implementedMethods());
|
||||
return object->scriptInit(vm());
|
||||
return object->scriptInit(state);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "rive/importers/import_stack.hpp"
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
#include "rive/lua/rive_lua_libs.hpp"
|
||||
#include "rive/lua/lua_state.hpp"
|
||||
#endif
|
||||
#include "rive/importers/keyed_object_importer.hpp"
|
||||
#include "rive/importers/keyed_property_importer.hpp"
|
||||
@@ -639,16 +640,15 @@ void File::makeScriptingVM()
|
||||
m_scriptingContext =
|
||||
rivestd::make_unique<CPPRuntimeScriptingContext>(m_factory);
|
||||
m_scriptingVM = rivestd::make_unique<ScriptingVM>(m_scriptingContext.get());
|
||||
m_luaState = new LuaState(m_scriptingVM->state());
|
||||
m_luaState->initializeData(m_ViewModels);
|
||||
m_luaState = m_scriptingVM->state();
|
||||
initializeLuaData(m_luaState, m_ViewModels);
|
||||
}
|
||||
|
||||
void File::cleanupScriptingVM()
|
||||
{
|
||||
m_luaState = nullptr;
|
||||
if (m_scriptingVM != nullptr)
|
||||
{
|
||||
delete m_luaState;
|
||||
m_luaState = nullptr;
|
||||
m_scriptingVM.reset();
|
||||
m_scriptingContext.reset();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@ static int viewmodel_new(lua_State* L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LuaState::initializeData(std::vector<ViewModel*>& viewModels)
|
||||
void rive::initializeLuaData(lua_State* state,
|
||||
std::vector<ViewModel*>& viewModels)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
|
||||
@@ -41,7 +41,7 @@ void ScriptedDataConverter::disposeScriptInputs()
|
||||
}
|
||||
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
bool ScriptedDataConverter::scriptInit(LuaState* state)
|
||||
bool ScriptedDataConverter::scriptInit(lua_State* state)
|
||||
{
|
||||
ScriptedObject::scriptInit(state);
|
||||
addScriptedDirt(ComponentDirt::Bindings);
|
||||
@@ -50,34 +50,33 @@ bool ScriptedDataConverter::scriptInit(LuaState* state)
|
||||
|
||||
bool ScriptedDataConverter::pushDataValue(DataValue* value)
|
||||
{
|
||||
auto state = m_state->state;
|
||||
// Stack: [self, field, self]
|
||||
if (value->is<DataValueNumber>())
|
||||
{
|
||||
lua_newrive<ScriptedDataValueNumber>(
|
||||
state,
|
||||
state,
|
||||
m_state,
|
||||
m_state,
|
||||
value->as<DataValueNumber>()->value());
|
||||
}
|
||||
else if (value->is<DataValueString>())
|
||||
{
|
||||
lua_newrive<ScriptedDataValueString>(
|
||||
state,
|
||||
state,
|
||||
m_state,
|
||||
m_state,
|
||||
value->as<DataValueString>()->value());
|
||||
}
|
||||
else if (value->is<DataValueBoolean>())
|
||||
{
|
||||
lua_newrive<ScriptedDataValueBoolean>(
|
||||
state,
|
||||
state,
|
||||
m_state,
|
||||
m_state,
|
||||
value->as<DataValueBoolean>()->value());
|
||||
}
|
||||
else if (value->is<DataValueColor>())
|
||||
{
|
||||
lua_newrive<ScriptedDataValueColor>(
|
||||
state,
|
||||
state,
|
||||
m_state,
|
||||
m_state,
|
||||
value->as<DataValueColor>()->value());
|
||||
}
|
||||
else
|
||||
@@ -94,21 +93,27 @@ DataValue* ScriptedDataConverter::applyConversion(DataValue* value,
|
||||
{
|
||||
return value;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
if (!hasValidVM())
|
||||
{
|
||||
return value;
|
||||
}
|
||||
#endif
|
||||
// Stack: []
|
||||
rive_lua_pushRef(state, m_self);
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
// Stack: [self]
|
||||
lua_getfield(state, -1, method.c_str());
|
||||
lua_getfield(m_state, -1, method.c_str());
|
||||
|
||||
// Stack: [self, field]
|
||||
lua_pushvalue(state, -2);
|
||||
lua_pushvalue(m_state, -2);
|
||||
// Stack: [self, field, self]
|
||||
if (pushDataValue(value))
|
||||
{
|
||||
// Stack: [self, field, self, ScriptedData]
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(state, 2, 1)) == LUA_OK)
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(m_state, 2, 1)) == LUA_OK)
|
||||
{
|
||||
auto result = (ScriptedDataValue*)lua_touserdata(state, -1);
|
||||
auto result = (ScriptedDataValue*)lua_touserdata(m_state, -1);
|
||||
if (result->isNumber())
|
||||
{
|
||||
storeData<DataValueNumber>(result->dataValue());
|
||||
@@ -127,12 +132,12 @@ DataValue* ScriptedDataConverter::applyConversion(DataValue* value,
|
||||
}
|
||||
}
|
||||
// Stack: [self, status] or [self, result]
|
||||
rive_lua_pop(state, 2);
|
||||
rive_lua_pop(m_state, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stack: [self, field, self]
|
||||
rive_lua_pop(state, 3);
|
||||
rive_lua_pop(m_state, 3);
|
||||
}
|
||||
if (!m_dataValue)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
using namespace rive;
|
||||
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
bool ScriptedDrawable::scriptInit(LuaState* state)
|
||||
bool ScriptedDrawable::scriptInit(lua_State* state)
|
||||
{
|
||||
ScriptedObject::scriptInit(state);
|
||||
addDirt(ComponentDirt::Paint);
|
||||
@@ -17,11 +17,17 @@ bool ScriptedDrawable::scriptInit(LuaState* state)
|
||||
|
||||
void ScriptedDrawable::draw(Renderer* renderer)
|
||||
{
|
||||
if (!draws())
|
||||
if (!draws() || !m_state)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
if (!hasValidVM())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_needsSaveOperation)
|
||||
{
|
||||
@@ -38,24 +44,24 @@ void ScriptedDrawable::draw(Renderer* renderer)
|
||||
|
||||
renderer->transform(worldTransform());
|
||||
// Stack: []
|
||||
auto scriptedRenderer = lua_newrive<ScriptedRenderer>(state, renderer);
|
||||
auto scriptedRenderer = lua_newrive<ScriptedRenderer>(m_state, renderer);
|
||||
// Stack: [scriptedRenderer]
|
||||
rive_lua_pushRef(state, m_self);
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
// Stack: [scriptedRenderer, self]
|
||||
lua_getfield(state, -1, "draw");
|
||||
lua_getfield(m_state, -1, "draw");
|
||||
// Stack: [scriptedRenderer, self, "draw"]
|
||||
lua_pushvalue(state, -2);
|
||||
lua_pushvalue(m_state, -2);
|
||||
// Stack: [scriptedRenderer, self, "draw", self]
|
||||
lua_pushvalue(state, -4);
|
||||
lua_pushvalue(m_state, -4);
|
||||
// Stack: [scriptedRenderer, self, "draw", self, scriptedRenderer]
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(state, 2, 0)) != LUA_OK)
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(m_state, 2, 0)) != LUA_OK)
|
||||
{
|
||||
// Stack: [scriptedRenderer, self, status]
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pop(m_state, 1);
|
||||
}
|
||||
scriptedRenderer->end();
|
||||
// Stack: [scriptedRenderer, self]
|
||||
rive_lua_pop(state, 2);
|
||||
rive_lua_pop(m_state, 2);
|
||||
|
||||
if (needsOpacitySave)
|
||||
{
|
||||
@@ -87,8 +93,8 @@ HitResult HitScriptedDrawable::processEvent(Vec2D position,
|
||||
{
|
||||
HitResult hitResult = HitResult::none;
|
||||
auto scriptAsset = m_drawable->scriptAsset();
|
||||
auto vm = m_drawable->state();
|
||||
if (vm == nullptr || scriptAsset == nullptr ||
|
||||
auto state = m_drawable->state();
|
||||
if (state == nullptr || scriptAsset == nullptr ||
|
||||
!handlesEvent(canHit, hitType))
|
||||
{
|
||||
return HitResult::none;
|
||||
@@ -99,7 +105,6 @@ HitResult HitScriptedDrawable::processEvent(Vec2D position,
|
||||
{
|
||||
return hitResult;
|
||||
}
|
||||
auto state = vm->state;
|
||||
rive_lua_pushRef(state, m_drawable->self());
|
||||
auto mName = methodName(canHit, hitType);
|
||||
if (static_cast<lua_Type>(lua_getfield(state, -1, mName.c_str())) !=
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
using namespace rive;
|
||||
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
bool ScriptedLayout::scriptInit(LuaState* state)
|
||||
bool ScriptedLayout::scriptInit(lua_State* state)
|
||||
{
|
||||
ScriptedDrawable::scriptInit(state);
|
||||
if (parent() != nullptr && parent()->is<LayoutComponent>())
|
||||
@@ -24,25 +24,24 @@ void ScriptedLayout::callScriptedResize(Vec2D size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
rive_lua_pushRef(state, m_self);
|
||||
if (static_cast<lua_Type>(lua_getfield(state, -1, "resize")) !=
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
if (static_cast<lua_Type>(lua_getfield(m_state, -1, "resize")) !=
|
||||
LUA_TFUNCTION)
|
||||
{
|
||||
fprintf(stderr, "expected resize to be a function\n");
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pop(m_state, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushvalue(state, -2);
|
||||
lua_pushvec2d(state, size);
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(state, 2, 0)) != LUA_OK)
|
||||
lua_pushvalue(m_state, -2);
|
||||
lua_pushvec2d(m_state, size);
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(m_state, 2, 0)) != LUA_OK)
|
||||
{
|
||||
fprintf(stderr, "resize failed\n");
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pop(m_state, 1);
|
||||
}
|
||||
}
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pop(m_state, 1);
|
||||
}
|
||||
|
||||
Vec2D ScriptedLayout::measureLayout(float width,
|
||||
@@ -56,37 +55,36 @@ Vec2D ScriptedLayout::measureLayout(float width,
|
||||
}
|
||||
auto measuredWidth = std::numeric_limits<float>::max();
|
||||
auto measuredHeight = std::numeric_limits<float>::max();
|
||||
auto state = m_state->state;
|
||||
rive_lua_pushRef(state, m_self);
|
||||
if (static_cast<lua_Type>(lua_getfield(state, -1, "measure")) !=
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
if (static_cast<lua_Type>(lua_getfield(m_state, -1, "measure")) !=
|
||||
LUA_TFUNCTION)
|
||||
{
|
||||
fprintf(stderr, "expected measure to be a function\n");
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pop(m_state, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushvalue(state, -2);
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(state, 1, 1)) != LUA_OK)
|
||||
lua_pushvalue(m_state, -2);
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(m_state, 1, 1)) != LUA_OK)
|
||||
{
|
||||
fprintf(stderr, "measure failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (static_cast<lua_Type>(lua_type(state, -1)) != LUA_TVECTOR)
|
||||
if (static_cast<lua_Type>(lua_type(m_state, -1)) != LUA_TVECTOR)
|
||||
{
|
||||
fprintf(stderr, "expected measure to return a Vec2D\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto size = lua_tovec2d(state, -1);
|
||||
auto size = lua_tovec2d(m_state, -1);
|
||||
measuredWidth = size->x;
|
||||
measuredHeight = size->y;
|
||||
}
|
||||
}
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pop(m_state, 1);
|
||||
}
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pop(m_state, 1);
|
||||
|
||||
return Vec2D(std::min((widthMode == LayoutMeasureMode::undefined
|
||||
? std::numeric_limits<float>::max()
|
||||
|
||||
@@ -37,16 +37,15 @@ void ScriptedObject::setArtboardInput(std::string name, Artboard* artboard)
|
||||
return;
|
||||
}
|
||||
|
||||
auto state = m_state->state;
|
||||
rive_lua_pushRef(state, m_self);
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
auto artboardInstance = artboard->instance();
|
||||
artboardInstance->frameOrigin(false);
|
||||
lua_newrive<ScriptedArtboard>(state,
|
||||
state,
|
||||
lua_newrive<ScriptedArtboard>(m_state,
|
||||
m_state,
|
||||
ref_rcp(scriptAsset()->file()),
|
||||
std::move(artboardInstance));
|
||||
lua_setfield(state, -2, name.c_str());
|
||||
rive_lua_pop(state, 1);
|
||||
lua_setfield(m_state, -2, name.c_str());
|
||||
rive_lua_pop(m_state, 1);
|
||||
addScriptedDirt(ComponentDirt::ScriptUpdate);
|
||||
}
|
||||
|
||||
@@ -56,11 +55,10 @@ void ScriptedObject::setBooleanInput(std::string name, bool value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
rive_lua_pushRef(state, m_self);
|
||||
lua_pushboolean(state, value);
|
||||
lua_setfield(state, -2, name.c_str());
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
lua_pushboolean(m_state, value);
|
||||
lua_setfield(m_state, -2, name.c_str());
|
||||
rive_lua_pop(m_state, 1);
|
||||
addScriptedDirt(ComponentDirt::ScriptUpdate);
|
||||
}
|
||||
|
||||
@@ -70,11 +68,10 @@ void ScriptedObject::setNumberInput(std::string name, float value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
rive_lua_pushRef(state, m_self);
|
||||
lua_pushnumber(state, value);
|
||||
lua_setfield(state, -2, name.c_str());
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
lua_pushnumber(m_state, value);
|
||||
lua_setfield(m_state, -2, name.c_str());
|
||||
rive_lua_pop(m_state, 1);
|
||||
addScriptedDirt(ComponentDirt::ScriptUpdate);
|
||||
}
|
||||
|
||||
@@ -84,11 +81,10 @@ void ScriptedObject::setIntegerInput(std::string name, int value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
rive_lua_pushRef(state, m_self);
|
||||
lua_pushunsigned(state, value);
|
||||
lua_setfield(state, -2, name.c_str());
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
lua_pushunsigned(m_state, value);
|
||||
lua_setfield(m_state, -2, name.c_str());
|
||||
rive_lua_pop(m_state, 1);
|
||||
addScriptedDirt(ComponentDirt::ScriptUpdate);
|
||||
}
|
||||
|
||||
@@ -98,11 +94,10 @@ void ScriptedObject::setStringInput(std::string name, std::string value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
rive_lua_pushRef(state, m_self);
|
||||
lua_pushstring(state, value.c_str());
|
||||
lua_setfield(state, -2, name.c_str());
|
||||
rive_lua_pop(state, 1);
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
lua_pushstring(m_state, value.c_str());
|
||||
lua_setfield(m_state, -2, name.c_str());
|
||||
rive_lua_pop(m_state, 1);
|
||||
addScriptedDirt(ComponentDirt::ScriptUpdate);
|
||||
}
|
||||
|
||||
@@ -113,8 +108,7 @@ void ScriptedObject::setViewModelInput(std::string name,
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
rive_lua_pushRef(state, m_self);
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
switch (value->coreType())
|
||||
{
|
||||
case ViewModelInstanceViewModelBase::typeKey:
|
||||
@@ -130,8 +124,8 @@ void ScriptedObject::setViewModelInput(std::string name,
|
||||
return;
|
||||
}
|
||||
|
||||
lua_newrive<ScriptedViewModel>(state,
|
||||
state,
|
||||
lua_newrive<ScriptedViewModel>(m_state,
|
||||
m_state,
|
||||
ref_rcp(vmi->viewModel()),
|
||||
vmi);
|
||||
break;
|
||||
@@ -139,8 +133,8 @@ void ScriptedObject::setViewModelInput(std::string name,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
lua_setfield(state, -2, name.c_str());
|
||||
rive_lua_pop(state, 1);
|
||||
lua_setfield(m_state, -2, name.c_str());
|
||||
rive_lua_pop(m_state, 1);
|
||||
addScriptedDirt(ComponentDirt::ScriptUpdate);
|
||||
}
|
||||
|
||||
@@ -150,38 +144,64 @@ void ScriptedObject::trigger(std::string name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
rive_lua_pushRef(state, m_self);
|
||||
if (static_cast<lua_Type>(lua_getfield(state, -1, name.c_str())) !=
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
if (static_cast<lua_Type>(lua_getfield(m_state, -1, name.c_str())) !=
|
||||
LUA_TFUNCTION)
|
||||
{
|
||||
rive_lua_pop(state, 2);
|
||||
rive_lua_pop(m_state, 2);
|
||||
return;
|
||||
}
|
||||
lua_pushvalue(state, -2);
|
||||
rive_lua_pcall(state, 1, 0);
|
||||
rive_lua_pop(state, 1);
|
||||
lua_pushvalue(m_state, -2);
|
||||
rive_lua_pcall(m_state, 1, 0);
|
||||
rive_lua_pop(m_state, 1);
|
||||
addScriptedDirt(ComponentDirt::ScriptUpdate);
|
||||
}
|
||||
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
bool ScriptedObject::hasValidVM()
|
||||
{
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
if (!m_state)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (asset())
|
||||
{
|
||||
auto scriptAsset = asset()->as<ScriptAsset>();
|
||||
if (!scriptAsset->file() || !scriptAsset->file()->hasVM())
|
||||
{
|
||||
m_state = nullptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ScriptedObject::scriptAdvance(float elapsedSeconds)
|
||||
{
|
||||
if (!advances() || m_state == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
rive_lua_pushRef(state, m_self);
|
||||
lua_getfield(state, -1, "advance");
|
||||
lua_pushvalue(state, -2);
|
||||
lua_pushnumber(state, elapsedSeconds);
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(state, 2, 1)) != LUA_OK)
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
if (!hasValidVM())
|
||||
{
|
||||
rive_lua_pop(state, 2);
|
||||
return false;
|
||||
}
|
||||
bool result = lua_toboolean(state, -1);
|
||||
rive_lua_pop(state, 2);
|
||||
#endif
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
lua_getfield(m_state, -1, "advance");
|
||||
lua_pushvalue(m_state, -2);
|
||||
lua_pushnumber(m_state, elapsedSeconds);
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(m_state, 2, 1)) != LUA_OK)
|
||||
{
|
||||
rive_lua_pop(m_state, 2);
|
||||
return false;
|
||||
}
|
||||
bool result = lua_toboolean(m_state, -1);
|
||||
rive_lua_pop(m_state, 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -191,35 +211,39 @@ void ScriptedObject::scriptUpdate()
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
// Stack: []
|
||||
rive_lua_pushRef(state, m_self);
|
||||
// Stack: [self]
|
||||
lua_getfield(state, -1, "update");
|
||||
// Stack: [self, field] Swap self and field
|
||||
lua_insert(state, -2);
|
||||
// Stack: [field, self]
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(state, 1, 0)) != LUA_OK)
|
||||
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
if (!hasValidVM())
|
||||
{
|
||||
rive_lua_pop(state, 1);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// Stack: []
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
// Stack: [self]
|
||||
lua_getfield(m_state, -1, "update");
|
||||
// Stack: [self, field] Swap self and field
|
||||
lua_insert(m_state, -2);
|
||||
// Stack: [field, self]
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(m_state, 1, 0)) != LUA_OK)
|
||||
{
|
||||
rive_lua_pop(m_state, 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool ScriptedObject::scriptInit(LuaState* luaState)
|
||||
bool ScriptedObject::scriptInit(lua_State* state)
|
||||
{
|
||||
auto state = luaState->state;
|
||||
|
||||
// Clean up old references if reinitializing
|
||||
if (m_state != nullptr && (m_self != 0 || m_context != 0))
|
||||
{
|
||||
if (m_self != 0)
|
||||
{
|
||||
lua_unref(m_state->state, m_self);
|
||||
lua_unref(m_state, m_self);
|
||||
m_self = 0;
|
||||
}
|
||||
if (m_context != 0)
|
||||
{
|
||||
lua_unref(m_state->state, m_context);
|
||||
lua_unref(m_state, m_context);
|
||||
m_context = 0;
|
||||
}
|
||||
}
|
||||
@@ -251,7 +275,7 @@ bool ScriptedObject::scriptInit(LuaState* luaState)
|
||||
rive_lua_pop(state, 1);
|
||||
// Stack: [self]
|
||||
m_self = lua_ref(state, -1);
|
||||
m_state = luaState;
|
||||
m_state = state;
|
||||
for (auto prop : m_customProperties)
|
||||
{
|
||||
auto scriptInput = ScriptInput::from(prop);
|
||||
@@ -332,12 +356,12 @@ void ScriptedObject::scriptDispose()
|
||||
|
||||
if (m_state != nullptr)
|
||||
{
|
||||
lua_unref(m_state->state, m_self);
|
||||
lua_unref(m_state->state, m_context);
|
||||
lua_unref(m_state, m_self);
|
||||
lua_unref(m_state, m_context);
|
||||
#ifdef TESTING
|
||||
// Force GC to collect any ScriptedArtboard instances created via
|
||||
// instance()
|
||||
lua_gc(m_state->state, LUA_GCCOLLECT, 0);
|
||||
lua_gc(m_state, LUA_GCCOLLECT, 0);
|
||||
#endif
|
||||
}
|
||||
m_state = nullptr;
|
||||
|
||||
@@ -11,7 +11,7 @@ using namespace rive;
|
||||
void ScriptedEffectPath::invalidateEffect() { m_path.rewind(); }
|
||||
|
||||
#ifdef WITH_RIVE_SCRIPTING
|
||||
bool ScriptedPathEffect::scriptInit(LuaState* state)
|
||||
bool ScriptedPathEffect::scriptInit(lua_State* state)
|
||||
{
|
||||
ScriptedObject::scriptInit(state);
|
||||
addScriptedDirt(ComponentDirt::Paint, true);
|
||||
@@ -26,6 +26,13 @@ void ScriptedPathEffect::updateEffect(PathProvider* pathProvider,
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef WITH_RIVE_TOOLS
|
||||
if (!hasValidVM())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
auto effectPathIt = m_effectPaths.find(pathProvider);
|
||||
if (effectPathIt != m_effectPaths.end())
|
||||
{
|
||||
@@ -43,35 +50,34 @@ void ScriptedPathEffect::updateEffect(PathProvider* pathProvider,
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto state = m_state->state;
|
||||
// Stack: []
|
||||
rive_lua_pushRef(state, m_self);
|
||||
rive_lua_pushRef(m_state, m_self);
|
||||
// Stack: [self]
|
||||
lua_getfield(state, -1, "update");
|
||||
lua_getfield(m_state, -1, "update");
|
||||
// Stack: [self, "update"]
|
||||
lua_pushvalue(state, -2);
|
||||
lua_pushvalue(m_state, -2);
|
||||
// Stack: [self, "update", self]
|
||||
lua_newrive<ScriptedPathData>(state, source->rawPath());
|
||||
lua_newrive<ScriptedPathData>(m_state, source->rawPath());
|
||||
// Stack: [self, "update", self, pathData]
|
||||
lua_newrive<ScriptedNode>(state,
|
||||
lua_newrive<ScriptedNode>(m_state,
|
||||
nullptr,
|
||||
shapePaint->parentTransformComponent());
|
||||
auto scriptedNode = lua_torive<ScriptedNode>(state, -1);
|
||||
auto scriptedNode = lua_torive<ScriptedNode>(m_state, -1);
|
||||
scriptedNode->shapePaint(shapePaint);
|
||||
// Stack: [self, "update", self, pathData, node]
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(state, 3, 1)) != LUA_OK)
|
||||
if (static_cast<lua_Status>(rive_lua_pcall(m_state, 3, 1)) != LUA_OK)
|
||||
{
|
||||
fprintf(stderr, "update function failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stack: [self, outputPathData]
|
||||
auto scriptedPath = (ScriptedPathData*)lua_touserdata(state, -1);
|
||||
auto scriptedPath = (ScriptedPathData*)lua_touserdata(m_state, -1);
|
||||
auto rawPath = path->mutableRawPath();
|
||||
rawPath->addPath(scriptedPath->rawPath);
|
||||
}
|
||||
// Stack: [self, status] or [self, outputPathData]
|
||||
rive_lua_pop(state, 2);
|
||||
rive_lua_pop(m_state, 2);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
@@ -513,7 +513,7 @@ end
|
||||
ScriptedDrawable drawable;
|
||||
|
||||
// Create LuaState from ScriptingTest's VM state
|
||||
LuaState luaState(L);
|
||||
lua_State* luaState = L;
|
||||
|
||||
// Manually set the inits flag since we're not using ScriptAsset
|
||||
// The inits flag indicates that the script has an init function
|
||||
@@ -524,7 +524,7 @@ end
|
||||
// ScriptingTest already left it there, so we can call scriptInit directly
|
||||
// Call ScriptedObject::scriptInit directly to avoid addDirt which requires
|
||||
// an artboard
|
||||
CHECK(drawable.ScriptedObject::scriptInit(&luaState));
|
||||
CHECK(drawable.ScriptedObject::scriptInit(luaState));
|
||||
|
||||
// Manually set implemented methods flags since we're not using ScriptAsset
|
||||
// Check if advance function exists and set the flag
|
||||
@@ -597,7 +597,7 @@ end
|
||||
ScriptedLayout layout;
|
||||
|
||||
// Create LuaState from ScriptingTest's VM state
|
||||
LuaState luaState(L);
|
||||
lua_State* luaState = L;
|
||||
|
||||
// Manually set the inits flag since we're not using ScriptAsset
|
||||
layout.implementedMethods(layout.implementedMethods() |
|
||||
@@ -606,7 +606,7 @@ end
|
||||
// scriptInit expects the factory function on the stack
|
||||
// Call ScriptedObject::scriptInit directly to avoid addDirt which requires
|
||||
// an artboard
|
||||
CHECK(layout.ScriptedObject::scriptInit(&luaState));
|
||||
CHECK(layout.ScriptedObject::scriptInit(luaState));
|
||||
|
||||
// Manually set implemented methods flags
|
||||
// After scriptInit, the self table is stored in m_self
|
||||
@@ -708,22 +708,22 @@ end
|
||||
// Create LuaState from ScriptingTest's VM state
|
||||
// Keep it in scope for the entire test since converter stores a pointer to
|
||||
// it
|
||||
LuaState luaState(L);
|
||||
lua_State* luaState = L;
|
||||
|
||||
// Manually set the inits flag since we're not using ScriptAsset
|
||||
converter->implementedMethods(converter->implementedMethods() |
|
||||
(1 << 9)); // m_initsBit
|
||||
|
||||
// Verify LuaState is valid before using it
|
||||
REQUIRE(luaState.state != nullptr);
|
||||
REQUIRE(luaState.state == L);
|
||||
REQUIRE(luaState != nullptr);
|
||||
REQUIRE(luaState == L);
|
||||
|
||||
// scriptInit expects the factory function on the stack
|
||||
// Verify stack state before calling scriptInit
|
||||
REQUIRE(lua_gettop(L) == stackTop);
|
||||
REQUIRE(lua_type(L, -1) == LUA_TFUNCTION);
|
||||
|
||||
REQUIRE(converter->ScriptedObject::scriptInit(&luaState));
|
||||
REQUIRE(converter->ScriptedObject::scriptInit(luaState));
|
||||
converter->addScriptedDirt(ComponentDirt::Bindings);
|
||||
|
||||
// Verify self() is valid before using it
|
||||
|
||||
Reference in New Issue
Block a user