Refactors the World Scripting API into it's own class

master
Joey Pollack 3 years ago
parent 6b03a758d2
commit 204f0d294c

@ -98,6 +98,7 @@ set(LUNARIUM_SRC
"src/scripting/wren_script.cpp" "src/scripting/wren_script.cpp"
"src/scripting/coreAPI.cpp" "src/scripting/coreAPI.cpp"
"src/world/world.cpp" "src/world/world.cpp"
"src/world/world_api.cpp"
"src/world/entity.cpp" "src/world/entity.cpp"
) )

@ -6,14 +6,8 @@
* Description - The foreign classes for components * Description - The foreign classes for components
******************************************************************************/ ******************************************************************************/
class Component {
EntityID { _EntityID }
EntityID=(value) {
_EntityID = value
}
}
foreign class VelocityComponent is Component { foreign class VelocityComponent {
// The parameter will be used on the C++ side to set the correct C++ component // The parameter will be used on the C++ side to set the correct C++ component
construct new(entity_id) { construct new(entity_id) {

@ -6,15 +6,6 @@
* Description - The main interface for scripts to interact with the game world * Description - The main interface for scripts to interact with the game world
******************************************************************************/ ******************************************************************************/
class Component {
Tag { 1 }
Transform { 2 }
Velocity { 3 }
Camera { 4 }
BlockOut { 5 }
Script { 6 }
}
// Manages all of the EntityBehaviors // Manages all of the EntityBehaviors
class WorldInterface { class WorldInterface {
@ -55,7 +46,7 @@ class WorldInterface {
// API // API
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
//foreign static GetComponent(entity_id, component_id) //foreign static GetVelocityComponent(entity_id)
} }

@ -43,6 +43,7 @@ namespace lunarium
class WrenScript; class WrenScript;
typedef WrenForeignMethodFn ForeignMethod; typedef WrenForeignMethodFn ForeignMethod;
typedef WrenFinalizerFn Finalizer;
class WrenState class WrenState
{ {
@ -61,6 +62,20 @@ namespace lunarium
} }
}; };
struct ForeignClassDesc
{
std::string Module;
std::string Class;
u32 ForeignDataSize;
WrenForeignClassMethods FCM;
bool operator==(const ForeignClassDesc& rhs)
{
return (Module == rhs.Module && Class == rhs.Class);
}
};
public: public:
~WrenState(); ~WrenState();
@ -85,6 +100,7 @@ public:
static void WriteFN(WrenVM* vm, const char* text); static void WriteFN(WrenVM* vm, const char* text);
static void ErrorFN(WrenVM* vm, WrenErrorType type, const char* module, int line, const char* message); static void ErrorFN(WrenVM* vm, WrenErrorType type, const char* module, int line, const char* message);
static WrenForeignMethodFn BindForeignMethodFN(WrenVM* vm, const char* module, const char* className, bool isStatic, const char* signature); static WrenForeignMethodFn BindForeignMethodFN(WrenVM* vm, const char* module, const char* className, bool isStatic, const char* signature);
static WrenForeignClassMethods BindForeignClass(WrenVM* vm, const char* module, const char* className);
@ -92,6 +108,7 @@ public:
static u32 mLogCat; static u32 mLogCat;
WrenVM* mpVM; WrenVM* mpVM;
static std::vector<ForeignMethodDesc> mForeignMethods; static std::vector<ForeignMethodDesc> mForeignMethods;
static std::vector<ForeignClassDesc> mForeignClasses;
}; };
} }

@ -10,6 +10,7 @@
******************************************************************************/ ******************************************************************************/
#include "world.h" #include "world.h"
#include "world_api.h"
#include <LunariumConfig.h> #include <LunariumConfig.h>
#include <utils/logger.h> #include <utils/logger.h>
#include <utils/helpers.h> #include <utils/helpers.h>
@ -43,29 +44,34 @@ namespace lunarium
void World::InitScriptState() void World::InitScriptState()
{ {
mScriptState.Initialize().LogIfFailed(LogCategory::GAME_SYSTEM, "Failed to initialize the world script state"); // mScriptState.Initialize().LogIfFailed(LogCategory::GAME_SYSTEM, "Failed to initialize the world script state");
// Load the world interface script // // Register foreign methods
mWorldInterface.SetModuleName("WorldInterface"); // mScriptState.RegisterForeignMethod({"WorldInterface", "WorldInterface", true, "GetComponent(_,_)", (WrenForeignMethodFn)&World::GetVelocityComponent});
std::string code = File::ReadTextFile("world_interface.wren"); // This will eventually move to internal data
mWorldInterface.SetScriptCode(code);
mScriptState.RunScript(&mWorldInterface); // // Load the world interface script
// mWorldInterface.SetModuleName("WorldInterface");
// std::string code = File::ReadTextFile("world_interface.wren"); // This will eventually move to internal data
// mWorldInterface.SetScriptCode(code);
// Get class and method handles // mScriptState.RunScript(&mWorldInterface);
mWIHandle = mScriptState.GetWrenClassHandle("WorldInterface", "WorldInterface");
mWIInitMethod = mScriptState.GetWrenMethodHandle("Init()");
mWIDoOnLoadMethod = mScriptState.GetWrenMethodHandle("DoOnLoad()");
mWIDoOnUnloadMethod = mScriptState.GetWrenMethodHandle("DoOnUnload()");
mWIUpdateMethod = mScriptState.GetWrenMethodHandle("Update(_)");
// Init the interface // // Get class and method handles
mScriptState.CallWrenMethod(mWIInitMethod, mWIHandle, {}, "WorldInterface.Init()"); // mWIHandle = mScriptState.GetWrenClassHandle("WorldInterface", "WorldInterface");
// mWIInitMethod = mScriptState.GetWrenMethodHandle("Init()");
// mWIDoOnLoadMethod = mScriptState.GetWrenMethodHandle("DoOnLoad()");
// mWIDoOnUnloadMethod = mScriptState.GetWrenMethodHandle("DoOnUnload()");
// mWIUpdateMethod = mScriptState.GetWrenMethodHandle("Update(_)");
// // Init the interface
// mScriptState.CallWrenMethod(mWIInitMethod, mWIHandle, {}, "WorldInterface.Init()");
} }
void World::OnLoad() void World::OnLoad()
{ {
InitScriptState(); // InitScriptState();
WorldAPI::Initialize(this).LogIfFailed(LogCategory::GAME_SYSTEM, "Failed to initialized the world scripting api");
// Load scripts from all ScriptComponents in the world // Load scripts from all ScriptComponents in the world
auto group_scripts = mECSRegistry.view<ScriptComponent>(); auto group_scripts = mECSRegistry.view<ScriptComponent>();
@ -78,19 +84,24 @@ namespace lunarium
editor::Script* pScript = (editor::Script*) editor::ContentManager::GetInstance().GetAsset(script_comp.ScriptID); editor::Script* pScript = (editor::Script*) editor::ContentManager::GetInstance().GetAsset(script_comp.ScriptID);
WrenScript script(pScript->GetScriptFile().filename().string().c_str(), pScript->GetScript()); WrenScript script(pScript->GetScriptFile().filename().string().c_str(), pScript->GetScript());
mScriptState.RunScript(&script); // mScriptState.RunScript(&script);
WorldAPI::RunScript(script);
#endif #endif
} }
// Call OnLoad for each registered EntityBehavior class object // Call OnLoad for each registered EntityBehavior class object
mScriptState.CallWrenMethod(mWIDoOnLoadMethod, mWIHandle, {}, "WorldInterface.DoOnLoad()"); //mScriptState.CallWrenMethod(mWIDoOnLoadMethod, mWIHandle, {}, "WorldInterface.DoOnLoad()");
WorldAPI::InvokeEvent(WorldAPI::Event::ON_LOAD);
} }
void World::OnUnload() void World::OnUnload()
{ {
// TODO: Call OnUnLoad for each registered EntityBehavior class object // TODO: Call OnUnLoad for each registered EntityBehavior class object
mScriptState.CallWrenMethod(mWIDoOnUnloadMethod, mWIHandle, {}, "WorldInterface.DoOnUnload()"); //mScriptState.CallWrenMethod(mWIDoOnUnloadMethod, mWIHandle, {}, "WorldInterface.DoOnUnload()");
mScriptState.Shutdown(); WorldAPI::InvokeEvent(WorldAPI::Event::ON_UNLOAD);
//mScriptState.Shutdown();
WorldAPI::Shutdown();
} }
void World::SetRunMode(RunMode mode) void World::SetRunMode(RunMode mode)
@ -107,7 +118,8 @@ namespace lunarium
{ {
// Update all scripts // Update all scripts
// Call Update for each registered EntityBehavior class object // Call Update for each registered EntityBehavior class object
mScriptState.CallWrenMethod(mWIUpdateMethod, mWIHandle, { {WrenParamType::WPT_DOUBLE, (double)dt} }, "WorldInterface.Update(dt)"); //mScriptState.CallWrenMethod(mWIUpdateMethod, mWIHandle, { {WrenParamType::WPT_DOUBLE, (double)dt} }, "WorldInterface.Update(dt)");
WorldAPI::InvokeEvent(WorldAPI::Event::ON_UPDATE, dt);
// Update Transforms for any enity with a velocity // Update Transforms for any enity with a velocity
@ -226,6 +238,8 @@ namespace lunarium
return iter == mEntities.end(); return iter == mEntities.end();
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
// RUN MODE HELPERS // RUN MODE HELPERS
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
@ -308,7 +322,7 @@ namespace lunarium
mEntities.clear(); mEntities.clear();
mEntitiesByUUID.clear(); mEntitiesByUUID.clear();
Deserialize(state.State); Deserialize(state.State).LogIfFailed(LogCategory::GAME_SYSTEM, "Failed to deserialize the world state");
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////

@ -107,13 +107,7 @@ namespace lunarium
private: private:
LUUID mUUID; LUUID mUUID;
std::string mName; std::string mName;
WrenState mScriptState;
WrenScript mWorldInterface;
WrenHandle* mWIHandle;
WrenHandle* mWIInitMethod;
WrenHandle* mWIDoOnLoadMethod;
WrenHandle* mWIDoOnUnloadMethod;
WrenHandle* mWIUpdateMethod;
// State critical Data // State critical Data
entt::registry mECSRegistry; entt::registry mECSRegistry;
@ -134,8 +128,7 @@ namespace lunarium
// TEST STUFF // TEST STUFF
//bool mGetAssetsFromEditor; // This is for testing until we get a proper asset manager //bool mGetAssetsFromEditor; // This is for testing until we get a proper asset manager
private: // SCRIPTING API
static void GetComponent(WrenVM* vm);
private: // HELPERS private: // HELPERS
void InitScriptState(); void InitScriptState();

@ -0,0 +1,97 @@
/******************************************************************************
* File - world_api.cpp
* Author - Joey Pollack
* Date - 2022/11/21 (y/m/d)
* Mod Date - 2022/11/21 (y/m/d)
* Description - The scripting api for the world interface
******************************************************************************/
#include "world_api.h"
#include "world.h"
#include <utils/logger.h>
#include <utils/helpers.h>
#include <cstdarg>
namespace lunarium
{
WrenState WorldAPI::mScriptState;
World* WorldAPI::mpWorld = nullptr;
WorldAPI::ScriptEventHandles WorldAPI::mEventHandles;
OpRes WorldAPI::Initialize(World* pWorld)
{
mpWorld = pWorld;
mScriptState.Initialize().LogIfFailed(LogCategory::GAME_SYSTEM, "Failed to initialize the world script state");
// Register foreign methods
mScriptState.RegisterForeignMethod({"WorldInterface", "WorldInterface", true, "GetComponent(_,_)", (WrenForeignMethodFn)&WorldAPI::GetVelocityComponent});
// Load the world interface script
WrenScript world_interface;
world_interface.SetModuleName("WorldInterface");
std::string code = File::ReadTextFile("world_interface.wren"); // This will eventually move to internal data
world_interface.SetScriptCode(code);
mScriptState.RunScript(&world_interface);
// Get class and method handles
mEventHandles.mWIHandle = mScriptState.GetWrenClassHandle("WorldInterface", "WorldInterface");
mEventHandles.mWIInitMethod = mScriptState.GetWrenMethodHandle("Init()");
mEventHandles.mWIDoOnLoadMethod = mScriptState.GetWrenMethodHandle("DoOnLoad()");
mEventHandles.mWIDoOnUnloadMethod = mScriptState.GetWrenMethodHandle("DoOnUnload()");
mEventHandles.mWIUpdateMethod = mScriptState.GetWrenMethodHandle("Update(_)");
// Init the interface
mScriptState.CallWrenMethod(mEventHandles.mWIInitMethod, mEventHandles.mWIHandle, {}, "WorldInterface.Init()");
return OpRes::OK();
}
void WorldAPI::Shutdown()
{
mpWorld = nullptr;
}
void WorldAPI::RunScript(WrenScript& script)
{
mScriptState.RunScript(&script);
}
void WorldAPI::InvokeEvent(Event e, ...)
{
switch (e)
{
case Event::ON_LOAD: mScriptState.CallWrenMethod(mEventHandles.mWIDoOnLoadMethod, mEventHandles.mWIHandle, {}, "WorldInterface.DoOnLoad()"); break;
case Event::ON_UNLOAD: mScriptState.CallWrenMethod(mEventHandles.mWIDoOnUnloadMethod, mEventHandles.mWIHandle, {}, "WorldInterface.DoOnUnload()"); break;
case Event::ON_UPDATE:
{
va_list args;
va_start(args, e);
double dt = va_arg(args, double);
mScriptState.CallWrenMethod(mEventHandles.mWIUpdateMethod, mEventHandles.mWIHandle, { {WrenParamType::WPT_DOUBLE, (double)dt} }, "WorldInterface.Update(dt)" );
va_end(args);
}
break;
}
}
/////////////////////////////////////////////////////////////////////
// SCRIPT API
/////////////////////////////////////////////////////////////////////
void WorldAPI::GetVelocityComponent(WrenVM* vm)
{
std::string str_entity_id = wrenGetSlotString(vm, 1);
LUUID entity_id = std::stoull(str_entity_id);
// More examples of creating foreign class instances
// https://github.com/wren-lang/wren/issues/1062
}
}

@ -0,0 +1,58 @@
/******************************************************************************
* File - world_api.h
* Author - Joey Pollack
* Date - 2022/11/21 (y/m/d)
* Mod Date - 2022/11/21 (y/m/d)
* Description - The scripting api for the world interface
******************************************************************************/
#ifndef LUNARIUM_WORLD_API_H_
#define LUNARIUM_WORLD_API_H_
#include <core/common_defs.h>
#include <scripting/wren_state.h>
#include <scripting/wren_script.h>
#include <utils/op_res.h>
namespace lunarium
{
class WorldAPI
{
friend class World;
public:
struct ScriptEventHandles
{
WrenHandle* mWIHandle;
WrenHandle* mWIInitMethod;
WrenHandle* mWIDoOnLoadMethod;
WrenHandle* mWIDoOnUnloadMethod;
WrenHandle* mWIUpdateMethod;
};
enum class Event
{
ON_LOAD,
ON_UNLOAD,
ON_UPDATE,
};
public:
static OpRes Initialize(World* pWorld);
static void Shutdown();
static void RunScript(WrenScript& script);
static void InvokeEvent(Event e, ...);
private: // SCRIPTING API
static void GetVelocityComponent(WrenVM* vm);
private:
static WrenState mScriptState;
static World* mpWorld;
static ScriptEventHandles mEventHandles;
};
}
#endif // LUNARIUM_WORLD_API_H_
Loading…
Cancel
Save