Add mechanism for adding callbacks to be called before/after OnControlPhase

This commit is contained in:
hispidence 2022-08-19 22:42:16 +01:00
parent 02a8d935ca
commit 44e80f88f8
8 changed files with 175 additions and 38 deletions

View file

@ -1026,16 +1026,9 @@ bool SaveGame::Save(int slot)
alternatePendulumOffset = alternatePendulumInfo.Finish();
}
std::vector<flatbuffers::Offset<Save::ScriptTable>> levelTableVec;
std::vector<flatbuffers::Offset<flatbuffers::String>> levelStringVec2;
//std::vector<savedTable> savedTables;
std::vector<std::string> savedStrings;
std::vector<SavedVar> savedVars;
g_GameScript->GetVariables(savedVars);
std::vector<flatbuffers::Offset<Save::UnionTable>> varsVec;
for (auto const& s : savedVars)
@ -1107,6 +1100,13 @@ bool SaveGame::Save(int slot)
uvb.add_members(unionVec);
auto unionVecOffset = uvb.Finish();
std::vector<std::string> callbackVecPreControl;
std::vector<std::string> callbackVecPostControl;
g_GameScript->GetCallbackStrings(callbackVecPreControl, callbackVecPostControl);
auto stringsCallbackPreControl = fbb.CreateVectorOfStrings(callbackVecPreControl);
auto stringsCallbackPostControl = fbb.CreateVectorOfStrings(callbackVecPostControl);
Save::SaveGameBuilder sgb{ fbb };
sgb.add_header(headerOffset);
@ -1150,6 +1150,8 @@ bool SaveGame::Save(int slot)
}
sgb.add_script_vars(unionVecOffset);
sgb.add_callbacks_pre_control(stringsCallbackPreControl);
sgb.add_callbacks_post_control(stringsCallbackPostControl);
auto sg = sgb.Finish();
fbb.Finish(sg);
@ -1927,6 +1929,18 @@ bool SaveGame::Load(int slot)
g_GameScript->SetVariables(loadedVars);
std::vector<std::string> callbacksPreControlVec;
auto callbacksPreControlOffsetVec = s->callbacks_pre_control();
for (auto const& s : *callbacksPreControlOffsetVec)
callbacksPreControlVec.push_back(s->str());
std::vector<std::string> callbacksPostControlVec;
auto callbacksPostControlOffsetVec = s->callbacks_post_control();
for (auto const& s : *callbacksPostControlOffsetVec)
callbacksPostControlVec.push_back(s->str());
g_GameScript->SetCallbackStrings(callbacksPreControlVec, callbacksPostControlVec);
return true;
}

View file

@ -41,6 +41,9 @@ public:
virtual void GetVariables(std::vector<SavedVar> & vars) = 0;
virtual void SetVariables(std::vector<SavedVar> const& vars) = 0;
virtual void GetCallbackStrings(std::vector<std::string> & preControl, std::vector<std::string> & postControl) const = 0;
virtual void SetCallbackStrings(std::vector<std::string> const & preControl, std::vector<std::string> const & postControl) = 0;
};
extern ScriptInterfaceGame* g_GameScript;

View file

@ -19,6 +19,7 @@ static constexpr char ScriptReserved_SoundSource[] = "SoundSource";
static constexpr char ScriptReserved_AIObject[] = "AIObject";
static constexpr char ScriptReserved_DisplayString[] = "DisplayString";
static constexpr char ScriptReserved_Vec3[] = "Vec3";
static constexpr char ScriptReserved_Rotation[] = "Rotation";
// Member functions
static constexpr char ScriptReserved_New[] = "New";
@ -92,8 +93,6 @@ static constexpr char ScriptReserved_SetTitleScreenImagePath[] = "SetTitleScreen
static constexpr char ScriptReserved_SetFarView[] = "SetFarView";
static constexpr char ScriptReserved_SetSettings[] = "SetSettings";
static constexpr char ScriptReserved_SetAnimations[] = "SetAnimations";
// Flow Functions
static constexpr char ScriptReserved_SetStrings[] = "SetStrings";
static constexpr char ScriptReserved_GetString[] = "GetString";
static constexpr char ScriptReserved_SetLanguageNames[] = "SetLanguageNames";
@ -129,6 +128,9 @@ static constexpr char ScriptReserved_ScreenToPercent[] = "ScreenToPercent";
static constexpr char ScriptReserved_PercentToScreen[] = "PercentToScreen";
static constexpr char ScriptReserved_HasLineOfSight[] = "HasLineOfSight";
static constexpr char ScriptReserved_AddCallback[] = "AddCallback";
static constexpr char ScriptReserved_RemoveCallback[] = "RemoveCallback";
static constexpr char ScriptReserved_EmitParticle[] = "EmitParticle";
static constexpr char ScriptReserved_EmitLightningArc[] = "EmitLightningArc";
static constexpr char ScriptReserved_EmitShockwave[] = "EmitShockwave";
@ -154,6 +156,7 @@ static constexpr char ScriptReserved_KeyClear[] = "KeyClear";
static constexpr char ScriptReserved_ObjID[] = "ObjID";
static constexpr char ScriptReserved_BlendID[] = "BlendID";
static constexpr char ScriptReserved_DisplayStringOption[] = "DisplayStringOption";
static constexpr char ScriptReserved_CallbackPoint[] = "CallbackPoint";
static constexpr char ScriptReserved_LevelVars[] = "LevelVars";
static constexpr char ScriptReserved_GameVars[] = "GameVars";

View file

@ -17,6 +17,18 @@ Saving data, triggering functions, and callbacks for level-specific scripts.
@pragma nostrip
*/
enum class CallbackPoint
{
PreControl,
PostControl,
};
static const std::unordered_map<std::string, CallbackPoint> kCallbackPoints
{
{"PreControlPhase", CallbackPoint::PreControl},
{"PostControlPhase", CallbackPoint::PostControl},
};
void SetVariable(sol::table tab, sol::object key, sol::object value)
{
switch (value.get_type())
@ -63,6 +75,16 @@ sol::object GetVariable(sol::table tab, sol::object key)
LogicHandler::LogicHandler(sol::state* lua, sol::table & parent) : m_handler{ lua }
{
m_handler.GetState()->set_function("print", &LogicHandler::LogPrint, this);
sol::table table_logic{ m_handler.GetState()->lua_state(), sol::create };
parent.set(ScriptReserved_Logic, table_logic);
table_logic.set_function(ScriptReserved_AddCallback, &LogicHandler::AddCallback, this);
table_logic.set_function(ScriptReserved_RemoveCallback, &LogicHandler::RemoveCallback, this);
m_handler.MakeReadOnlyTable(table_logic, ScriptReserved_CallbackPoint, kCallbackPoints);
ResetScripts(true);
}
@ -71,6 +93,33 @@ void LogicHandler::ResetGameTables()
MakeSpecialTable(m_handler.GetState(), ScriptReserved_GameVars, &GetVariable, &SetVariable);
}
void LogicHandler::AddCallback(CallbackPoint point, std::string const & name)
{
switch(point)
{
case CallbackPoint::PreControl:
m_callbacksPreControl.insert(name);
break;
case CallbackPoint::PostControl:
m_callbacksPostControl.insert(name);
break;
}
}
void LogicHandler::RemoveCallback(CallbackPoint point, std::string const & name)
{
switch(point)
{
case CallbackPoint::PreControl:
m_callbacksPreControl.erase(name);
break;
case CallbackPoint::PostControl:
m_callbacksPostControl.erase(name);
break;
}
}
void LogicHandler::ResetLevelTables()
{
@ -121,6 +170,9 @@ void LogicHandler::ResetScripts(bool clearGameVars)
{
FreeLevelScripts();
m_callbacksPreControl.clear();
m_callbacksPostControl.clear();
auto currentPackage = m_handler.GetState()->get<sol::table>("package");
auto currentLoaded = currentPackage.get<sol::table>("loaded");
@ -347,6 +399,24 @@ void LogicHandler::GetVariables(std::vector<SavedVar> & vars)
populate(tab);
}
void LogicHandler::GetCallbackStrings(std::vector<std::string>& preControl, std::vector<std::string>& postControl) const
{
for (auto const& s : m_callbacksPreControl)
preControl.push_back(s);
for (auto const& s : m_callbacksPostControl)
postControl.push_back(s);
}
void LogicHandler::SetCallbackStrings(std::vector<std::string> const & preControl, std::vector<std::string> const & postControl)
{
for (auto const& s : preControl)
m_callbacksPreControl.insert(s);
for (auto const& s : postControl)
m_callbacksPostControl.insert(s);
}
template <typename R, char const * S, typename mapType>
std::unique_ptr<R> GetByName(std::string const & type, std::string const & name, mapType const & map)
{
@ -428,9 +498,25 @@ void LogicHandler::OnLoad()
void LogicHandler::OnControlPhase(float dt)
{
sol::table levelFuncs = (*m_handler.GetState())[ScriptReserved_LevelFuncs];
auto tryCall = [dt, &levelFuncs](std::string const& name)
{
if (!levelFuncs[name].valid())
ScriptAssertF(false, "Callback {} not valid", name);
else
levelFuncs[name].call(dt);
};
for (auto& name : m_callbacksPreControl)
tryCall(name);
lua_gc(m_handler.GetState()->lua_state(), LUA_GCCOLLECT, 0);
if(m_onControlPhase.valid())
doCallback(m_onControlPhase, dt);
for (auto& name : m_callbacksPostControl)
tryCall(name);
}
void LogicHandler::OnSave()

View file

@ -5,28 +5,7 @@
#include <unordered_set>
#include "Strings/StringsHandler.h"
struct LuaFunction {
std::string Name;
std::string Code;
bool Executed;
};
struct GameScriptVector3 {
float x;
float y;
float z;
};
struct LuaVariable
{
bool IsGlobal;
std::string Name;
int Type;
float FloatValue;
int IntValue;
std::string StringValue;
bool BoolValue;
};
enum class CallbackPoint;
class LogicHandler : public ScriptInterfaceGame
{
@ -38,6 +17,9 @@ private:
sol::protected_function m_onSave{};
sol::protected_function m_onEnd{};
std::unordered_set<std::string> m_callbacksPreControl;
std::unordered_set<std::string> m_callbacksPostControl;
void ResetLevelTables();
void ResetGameTables();
LuaHandler m_handler;
@ -49,6 +31,10 @@ public:
void LogPrint(sol::variadic_args va);
bool SetLevelFunc(sol::table tab, std::string const& luaName, sol::object value);
void AddCallback(CallbackPoint point, std::string const& name);
void RemoveCallback(CallbackPoint point, std::string const & name);
void ResetScripts(bool clearGameVars) override;
sol::protected_function GetLevelFunc(sol::table tab, std::string const& luaName);
@ -59,13 +45,17 @@ public:
void ExecuteFunction(std::string const& name, short idOne, short idTwo) override;
void GetVariables(std::vector<SavedVar>& vars) override;
void SetVariables(std::vector<SavedVar> const& vars) override;
void ResetVariables();
void SetVariables(std::vector<SavedVar> const& vars) override;
void SetCallbackStrings(std::vector<std::string> const& preControl, std::vector<std::string> const& postControl) override;
void GetCallbackStrings(std::vector<std::string>& preControl, std::vector<std::string>& postControl) const override;
void InitCallbacks() override;
void OnStart() override;
void OnLoad() override;
void OnControlPhase(float dt) override;
void OnSave() override;
void OnEnd() override;
};

View file

@ -1,5 +1,6 @@
#include "framework.h"
#include "Rotation.h"
#include "ReservedScriptNames.h"
#include "Specific/phd_global.h"
/*** Represents a rotation.
@ -13,7 +14,7 @@ All values will be clamped to [-32768, 32767].
void Rotation::Register(sol::table & parent)
{
using ctors = sol::constructors<Rotation(int, int, int)>;
parent.new_usertype<Rotation>("Rotation",
parent.new_usertype<Rotation>(ScriptReserved_Rotation,
ctors(),
sol::call_constructor, ctors(),
sol::meta_function::to_string, &Rotation::ToString,

View file

@ -5849,6 +5849,8 @@ struct SaveGameT : public flatbuffers::NativeTable {
std::vector<std::unique_ptr<TEN::Save::VolumeStateT>> volume_states{};
std::vector<std::unique_ptr<TEN::Save::EventSetCallCountersT>> call_counters{};
std::unique_ptr<TEN::Save::UnionVecT> script_vars{};
std::vector<std::string> callbacks_pre_control{};
std::vector<std::string> callbacks_post_control{};
};
struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@ -5891,7 +5893,9 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_ALTERNATE_PENDULUM = 68,
VT_VOLUME_STATES = 70,
VT_CALL_COUNTERS = 72,
VT_SCRIPT_VARS = 74
VT_SCRIPT_VARS = 74,
VT_CALLBACKS_PRE_CONTROL = 76,
VT_CALLBACKS_POST_CONTROL = 78
};
const TEN::Save::SaveGameHeader *header() const {
return GetPointer<const TEN::Save::SaveGameHeader *>(VT_HEADER);
@ -6001,6 +6005,12 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const TEN::Save::UnionVec *script_vars() const {
return GetPointer<const TEN::Save::UnionVec *>(VT_SCRIPT_VARS);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *callbacks_pre_control() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_CALLBACKS_PRE_CONTROL);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *callbacks_post_control() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_CALLBACKS_POST_CONTROL);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyOffset(verifier, VT_HEADER) &&
@ -6079,6 +6089,12 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
verifier.VerifyVectorOfTables(call_counters()) &&
VerifyOffset(verifier, VT_SCRIPT_VARS) &&
verifier.VerifyTable(script_vars()) &&
VerifyOffset(verifier, VT_CALLBACKS_PRE_CONTROL) &&
verifier.VerifyVector(callbacks_pre_control()) &&
verifier.VerifyVectorOfStrings(callbacks_pre_control()) &&
VerifyOffset(verifier, VT_CALLBACKS_POST_CONTROL) &&
verifier.VerifyVector(callbacks_post_control()) &&
verifier.VerifyVectorOfStrings(callbacks_post_control()) &&
verifier.EndTable();
}
SaveGameT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
@ -6198,6 +6214,12 @@ struct SaveGameBuilder {
void add_script_vars(flatbuffers::Offset<TEN::Save::UnionVec> script_vars) {
fbb_.AddOffset(SaveGame::VT_SCRIPT_VARS, script_vars);
}
void add_callbacks_pre_control(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> callbacks_pre_control) {
fbb_.AddOffset(SaveGame::VT_CALLBACKS_PRE_CONTROL, callbacks_pre_control);
}
void add_callbacks_post_control(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> callbacks_post_control) {
fbb_.AddOffset(SaveGame::VT_CALLBACKS_POST_CONTROL, callbacks_post_control);
}
explicit SaveGameBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
@ -6246,10 +6268,14 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGame(
flatbuffers::Offset<TEN::Save::Pendulum> alternate_pendulum = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TEN::Save::VolumeState>>> volume_states = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TEN::Save::EventSetCallCounters>>> call_counters = 0,
flatbuffers::Offset<TEN::Save::UnionVec> script_vars = 0) {
flatbuffers::Offset<TEN::Save::UnionVec> script_vars = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> callbacks_pre_control = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> callbacks_post_control = 0) {
SaveGameBuilder builder_(_fbb);
builder_.add_oneshot_position(oneshot_position);
builder_.add_ambient_position(ambient_position);
builder_.add_callbacks_post_control(callbacks_post_control);
builder_.add_callbacks_pre_control(callbacks_pre_control);
builder_.add_script_vars(script_vars);
builder_.add_call_counters(call_counters);
builder_.add_volume_states(volume_states);
@ -6329,7 +6355,9 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGameDirect(
flatbuffers::Offset<TEN::Save::Pendulum> alternate_pendulum = 0,
const std::vector<flatbuffers::Offset<TEN::Save::VolumeState>> *volume_states = nullptr,
const std::vector<flatbuffers::Offset<TEN::Save::EventSetCallCounters>> *call_counters = nullptr,
flatbuffers::Offset<TEN::Save::UnionVec> script_vars = 0) {
flatbuffers::Offset<TEN::Save::UnionVec> script_vars = 0,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *callbacks_pre_control = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *callbacks_post_control = nullptr) {
auto items__ = items ? _fbb.CreateVector<flatbuffers::Offset<TEN::Save::Item>>(*items) : 0;
auto room_items__ = room_items ? _fbb.CreateVector<int32_t>(*room_items) : 0;
auto fxinfos__ = fxinfos ? _fbb.CreateVector<flatbuffers::Offset<TEN::Save::FXInfo>>(*fxinfos) : 0;
@ -6349,6 +6377,8 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGameDirect(
auto cd_flags__ = cd_flags ? _fbb.CreateVector<int32_t>(*cd_flags) : 0;
auto volume_states__ = volume_states ? _fbb.CreateVector<flatbuffers::Offset<TEN::Save::VolumeState>>(*volume_states) : 0;
auto call_counters__ = call_counters ? _fbb.CreateVector<flatbuffers::Offset<TEN::Save::EventSetCallCounters>>(*call_counters) : 0;
auto callbacks_pre_control__ = callbacks_pre_control ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*callbacks_pre_control) : 0;
auto callbacks_post_control__ = callbacks_post_control ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*callbacks_post_control) : 0;
return TEN::Save::CreateSaveGame(
_fbb,
header,
@ -6386,7 +6416,9 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGameDirect(
alternate_pendulum,
volume_states__,
call_counters__,
script_vars);
script_vars,
callbacks_pre_control__,
callbacks_post_control__);
}
flatbuffers::Offset<SaveGame> CreateSaveGame(flatbuffers::FlatBufferBuilder &_fbb, const SaveGameT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
@ -8117,6 +8149,8 @@ inline void SaveGame::UnPackTo(SaveGameT *_o, const flatbuffers::resolver_functi
{ auto _e = volume_states(); if (_e) { _o->volume_states.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->volume_states[_i] = std::unique_ptr<TEN::Save::VolumeStateT>(_e->Get(_i)->UnPack(_resolver)); } } }
{ auto _e = call_counters(); if (_e) { _o->call_counters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->call_counters[_i] = std::unique_ptr<TEN::Save::EventSetCallCountersT>(_e->Get(_i)->UnPack(_resolver)); } } }
{ auto _e = script_vars(); if (_e) _o->script_vars = std::unique_ptr<TEN::Save::UnionVecT>(_e->UnPack(_resolver)); }
{ auto _e = callbacks_pre_control(); if (_e) { _o->callbacks_pre_control.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->callbacks_pre_control[_i] = _e->Get(_i)->str(); } } }
{ auto _e = callbacks_post_control(); if (_e) { _o->callbacks_post_control.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->callbacks_post_control[_i] = _e->Get(_i)->str(); } } }
}
inline flatbuffers::Offset<SaveGame> SaveGame::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SaveGameT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@ -8163,6 +8197,8 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGame(flatbuffers::FlatBufferBuild
auto _volume_states = _fbb.CreateVector<flatbuffers::Offset<TEN::Save::VolumeState>> (_o->volume_states.size(), [](size_t i, _VectorArgs *__va) { return CreateVolumeState(*__va->__fbb, __va->__o->volume_states[i].get(), __va->__rehasher); }, &_va );
auto _call_counters = _fbb.CreateVector<flatbuffers::Offset<TEN::Save::EventSetCallCounters>> (_o->call_counters.size(), [](size_t i, _VectorArgs *__va) { return CreateEventSetCallCounters(*__va->__fbb, __va->__o->call_counters[i].get(), __va->__rehasher); }, &_va );
auto _script_vars = _o->script_vars ? CreateUnionVec(_fbb, _o->script_vars.get(), _rehasher) : 0;
auto _callbacks_pre_control = _fbb.CreateVectorOfStrings(_o->callbacks_pre_control);
auto _callbacks_post_control = _fbb.CreateVectorOfStrings(_o->callbacks_post_control);
return TEN::Save::CreateSaveGame(
_fbb,
_header,
@ -8200,7 +8236,9 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGame(flatbuffers::FlatBufferBuild
_alternate_pendulum,
_volume_states,
_call_counters,
_script_vars);
_script_vars,
_callbacks_pre_control,
_callbacks_post_control);
}
inline bool VerifyVarUnion(flatbuffers::Verifier &verifier, const void *obj, VarUnion type) {

View file

@ -458,6 +458,8 @@ table SaveGame {
volume_states: [VolumeState];
call_counters: [EventSetCallCounters];
script_vars: UnionVec;
callbacks_pre_control: [string];
callbacks_post_control: [string];
}
root_type TEN.Save.SaveGame;