Entity component access and manipulation in wren scripts working!

master
Joey Pollack 3 years ago
parent 204f0d294c
commit d2608b4851

@ -10,12 +10,13 @@
foreign class VelocityComponent {
// The parameter will be used on the C++ side to set the correct C++ component
construct new(entity_id) {
super.EntityID = entity_id
}
construct new(entity_id) {}
// maybe wrap these in non-foreign methods
// to abstract pulling data out of slots?
foreign GetVelocity()
foreign GetVelocityX()
foreign GetVelocityY()
foreign SetVelocity(x, y)
}

@ -6,6 +6,8 @@
* Description - The main interface for scripts to interact with the game world
******************************************************************************/
import "Components" for VelocityComponent
// Manages all of the EntityBehaviors
class WorldInterface {
@ -46,7 +48,9 @@ class WorldInterface {
// API
/////////////////////////////////////////////////////////////////////
//foreign static GetVelocityComponent(entity_id)
static GetVelocityComponent(entity_id) {
return VelocityComponent.new(entity_id)
}
}

@ -16,6 +16,7 @@
namespace lunarium
{
std::vector<WrenState::ForeignMethodDesc> WrenState::mForeignMethods;
std::vector<WrenState::ForeignClassDesc> WrenState::mForeignClasses;
WrenState::~WrenState()
{
@ -36,6 +37,7 @@ namespace lunarium
config.writeFn = WrenState::WriteFN;
config.errorFn = WrenState::ErrorFN;
config.bindForeignMethodFn = WrenState::BindForeignMethodFN;
config.bindForeignClassFn = WrenState::BindForeignClassFN;
mpVM = wrenNewVM(&config);
@ -54,6 +56,11 @@ namespace lunarium
mForeignMethods.push_back(method_desc);
}
void WrenState::RegisterForeignClass(ForeignClassDesc class_desc)
{
mForeignClasses.push_back(class_desc);
}
/////////////////////////////////////////////////////////////////////
// HANDLES
/////////////////////////////////////////////////////////////////////
@ -185,6 +192,7 @@ namespace lunarium
{
if (FMID == (*iter))
{
Logger::Trace(mLogCat, "Successfully bound foreign method: %s::%s", class_name, signature);
return iter->FM;
}
}
@ -192,4 +200,21 @@ namespace lunarium
Logger::Error(mLogCat, "Failed to bind foreign method: %s::%s", class_name, signature);
return nullptr;
}
WrenForeignClassMethods WrenState::BindForeignClassFN(WrenVM* vm, const char* module, const char* class_name)
{
ForeignClassDesc FCD = { module, class_name };
for (auto iter = mForeignClasses.begin(); iter != mForeignClasses.end(); iter++)
{
if (FCD == (*iter))
{
Logger::Trace(mLogCat, "Successfully bound foreign class: %s in module %s", class_name, module);
return iter->FCM;
}
}
Logger::Error(mLogCat, "Could not find foreign class: %s in module %s", class_name, module);
return WrenForeignClassMethods { nullptr, nullptr };
}
}

@ -84,6 +84,7 @@ namespace lunarium
u32 GetLogCat() const;
void RegisterForeignMethod(ForeignMethodDesc method_desc);
void RegisterForeignClass(ForeignClassDesc class_desc);
void RunScript(WrenScript* script);
void RunSnippet(std::string name, std::string code);
@ -100,7 +101,7 @@ public:
static void WriteFN(WrenVM* vm, const char* text);
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 WrenForeignClassMethods BindForeignClass(WrenVM* vm, const char* module, const char* className);
static WrenForeignClassMethods BindForeignClassFN(WrenVM* vm, const char* module, const char* className);

@ -42,34 +42,8 @@ namespace lunarium
}
void World::InitScriptState()
{
// mScriptState.Initialize().LogIfFailed(LogCategory::GAME_SYSTEM, "Failed to initialize the world script state");
// // Register foreign methods
// mScriptState.RegisterForeignMethod({"WorldInterface", "WorldInterface", true, "GetComponent(_,_)", (WrenForeignMethodFn)&World::GetVelocityComponent});
// // 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);
// mScriptState.RunScript(&mWorldInterface);
// // Get class and method handles
// 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()
{
// InitScriptState();
WorldAPI::Initialize(this).LogIfFailed(LogCategory::GAME_SYSTEM, "Failed to initialized the world scripting api");
@ -90,17 +64,13 @@ namespace lunarium
}
// Call OnLoad for each registered EntityBehavior class object
//mScriptState.CallWrenMethod(mWIDoOnLoadMethod, mWIHandle, {}, "WorldInterface.DoOnLoad()");
WorldAPI::InvokeEvent(WorldAPI::Event::ON_LOAD);
}
void World::OnUnload()
{
// TODO: Call OnUnLoad for each registered EntityBehavior class object
//mScriptState.CallWrenMethod(mWIDoOnUnloadMethod, mWIHandle, {}, "WorldInterface.DoOnUnload()");
// Call OnUnLoad for each registered EntityBehavior class object
WorldAPI::InvokeEvent(WorldAPI::Event::ON_UNLOAD);
//mScriptState.Shutdown();
WorldAPI::Shutdown();
}
@ -118,7 +88,6 @@ namespace lunarium
{
// Update all scripts
// Call Update for each registered EntityBehavior class object
//mScriptState.CallWrenMethod(mWIUpdateMethod, mWIHandle, { {WrenParamType::WPT_DOUBLE, (double)dt} }, "WorldInterface.Update(dt)");
WorldAPI::InvokeEvent(WorldAPI::Event::ON_UPDATE, dt);
@ -176,6 +145,10 @@ namespace lunarium
mpActiveCamera = pCam;
}
/////////////////////////////////////////////////////////////////////
// ENTITY API
/////////////////////////////////////////////////////////////////////
entt::registry* World::GetEntityRegistry()
{
return &mECSRegistry;
@ -245,37 +218,37 @@ namespace lunarium
/////////////////////////////////////////////////////////////////////
void World::DrawHeirarchy(lunarium::Renderer2D* g, entt::entity& entity, TransformComponent& my_trans, BlockOutComponent& bo_comp, glm::mat4 current_transform)
{
// Draw current entity
Rectangle rect(my_trans.Position.x, my_trans.Position.y, bo_comp.Size.x, bo_comp.Size.y);
Color color(bo_comp.Color.x, bo_comp.Color.y, bo_comp.Color.z, bo_comp.Color.w);
g->DrawQuad(rect, color, nullptr, -my_trans.Rotation.z, Rectangle(-1, -1, -1, -1), current_transform);
// Apply transform to children's transforms
current_transform *= my_trans.GetTransform();
// Iterate and draw children
if (mECSRegistry.all_of<ChildrenComponent>(entity))
{
ChildrenComponent& children_comp = mECSRegistry.get<ChildrenComponent>(entity);
for (int i = 0; i < children_comp.Children.size(); i++)
{
Entity* pEnt = GetEntity(children_comp.Children[i]);
entt::entity handle = pEnt->GetEnttHandle();
if (pEnt->HasComponent<TransformComponent>() && pEnt->HasComponent<BlockOutComponent>())
{
TransformComponent& trans_comp = pEnt->GetComponent<TransformComponent>();
BlockOutComponent& bo_comp = pEnt->GetComponent<BlockOutComponent>();
DrawHeirarchy(g, handle, trans_comp, bo_comp, current_transform);
}
}
}
// void World::DrawHeirarchy(lunarium::Renderer2D* g, entt::entity& entity, TransformComponent& my_trans, BlockOutComponent& bo_comp, glm::mat4 current_transform)
// {
// // Draw current entity
// Rectangle rect(my_trans.Position.x, my_trans.Position.y, bo_comp.Size.x, bo_comp.Size.y);
// Color color(bo_comp.Color.x, bo_comp.Color.y, bo_comp.Color.z, bo_comp.Color.w);
// g->DrawQuad(rect, color, nullptr, -my_trans.Rotation.z, Rectangle(-1, -1, -1, -1), current_transform);
// // Apply transform to children's transforms
// current_transform *= my_trans.GetTransform();
// // Iterate and draw children
// if (mECSRegistry.all_of<ChildrenComponent>(entity))
// {
// ChildrenComponent& children_comp = mECSRegistry.get<ChildrenComponent>(entity);
// for (int i = 0; i < children_comp.Children.size(); i++)
// {
// Entity* pEnt = GetEntity(children_comp.Children[i]);
// entt::entity handle = pEnt->GetEnttHandle();
// if (pEnt->HasComponent<TransformComponent>() && pEnt->HasComponent<BlockOutComponent>())
// {
// TransformComponent& trans_comp = pEnt->GetComponent<TransformComponent>();
// BlockOutComponent& bo_comp = pEnt->GetComponent<BlockOutComponent>();
// DrawHeirarchy(g, handle, trans_comp, bo_comp, current_transform);
// }
// }
// }
}
// }
glm::mat4 World::GetParentTransform(LUUID parent)
{

@ -134,7 +134,7 @@ namespace lunarium
void InitScriptState();
void RenderEditor(lunarium::Renderer2D* pGraphics) const;
glm::mat4 GetParentTransform(LUUID parent);
void DrawHeirarchy(lunarium::Renderer2D* g, entt::entity& entity, TransformComponent& my_trans, BlockOutComponent& bo_comp, glm::mat4 current_transform);
//void DrawHeirarchy(lunarium::Renderer2D* g, entt::entity& entity, TransformComponent& my_trans, BlockOutComponent& bo_comp, glm::mat4 current_transform);
};
}

@ -8,6 +8,7 @@
#include "world_api.h"
#include "world.h"
#include "entity.h"
#include <utils/logger.h>
#include <utils/helpers.h>
@ -26,16 +27,27 @@ namespace lunarium
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});
//mScriptState.RegisterForeignMethod({"WorldInterface", "WorldInterface", true, "GetComponent(_,_)", (WrenForeignMethodFn)&WorldAPI::GetVelocityComponent});
// Register foreign classes
SetupForeignClassVelocityComp();
// Load the component script
WrenScript components;
components.SetModuleName("Components");
std::string code = File::ReadTextFile("components.wren"); // This will eventually move to internal data
components.SetScriptCode(code);
mScriptState.RunScript(&components);
// 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
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()");
@ -94,4 +106,62 @@ namespace lunarium
}
/////////////////////////////////////////////////////////////////////
// FOREIGN CLASSES
/////////////////////////////////////////////////////////////////////
void WorldAPI::SetupForeignClassVelocityComp()
{
mScriptState.RegisterForeignClass({"Components", "VelocityComponent", sizeof(VelocityComponent*),
{(WrenForeignMethodFn)&WorldAPI::VelocityCompAllocate, &WorldAPI::VelocityCompFinalise}});
mScriptState.RegisterForeignMethod({"Components", "VelocityComponent", false, "GetVelocityX()",&WorldAPI::GetVelocityXFM});
mScriptState.RegisterForeignMethod({"Components", "VelocityComponent", false, "GetVelocityY()",(WrenForeignMethodFn)&WorldAPI::GetVelocityYFM});
mScriptState.RegisterForeignMethod({"Components", "VelocityComponent", false, "SetVelocity(_,_)", (WrenForeignMethodFn)&WorldAPI::SetVelocityFM});
}
void WorldAPI::VelocityCompAllocate(WrenVM* vm)
{
VelocityComponent** vcp = (VelocityComponent**)wrenSetSlotNewForeign(vm, 0, 0, sizeof(VelocityComponent*));
std::string str_entity_id = wrenGetSlotString(vm, 1);
LUUID entity_id = std::stoull(str_entity_id);
Entity* pEnt = mpWorld->GetEntity(entity_id);
if (!pEnt->HasComponent<VelocityComponent>())
{
Logger::Error(LogCategory::SCRIPTING, "Cannot allocate foreign class VelocityComponent - the entity does not have the component");
(*vcp) = nullptr;
}
(*vcp) = &pEnt->GetComponent<VelocityComponent>();
}
void WorldAPI::VelocityCompFinalise(void* data)
{
// Nothing to clean up
}
void WorldAPI::GetVelocityXFM(WrenVM* vm)
{
VelocityComponent** vcp = (VelocityComponent**)wrenGetSlotForeign(vm, 0);
wrenEnsureSlots(vm, 1);
wrenSetSlotDouble(vm, 0, (*vcp)->Velocity.x);
}
void WorldAPI::GetVelocityYFM(WrenVM* vm)
{
VelocityComponent** vcp = (VelocityComponent**)wrenGetSlotForeign(vm, 0);
wrenEnsureSlots(vm, 1);
wrenSetSlotDouble(vm, 0, (*vcp)->Velocity.y);
}
void WorldAPI::SetVelocityFM(WrenVM* vm)
{
VelocityComponent** vcp = (VelocityComponent**)wrenGetSlotForeign(vm, 0);
double x = wrenGetSlotDouble(vm, 1);
double y = wrenGetSlotDouble(vm, 2);
(*vcp)->Velocity.x = x;
(*vcp)->Velocity.y = y;
}
}

@ -48,6 +48,14 @@ namespace lunarium
private: // SCRIPTING API
static void GetVelocityComponent(WrenVM* vm);
// Foreign classes
static void SetupForeignClassVelocityComp();
static void VelocityCompAllocate(WrenVM* vm);
static void VelocityCompFinalise(void* data);
static void GetVelocityXFM(WrenVM* vm);
static void GetVelocityYFM(WrenVM* vm);
static void SetVelocityFM(WrenVM* vm);
private:
static WrenState mScriptState;
static World* mpWorld;

Loading…
Cancel
Save