Added / Updated Lua Bindings
This commit is contained in:
parent
18791713ab
commit
193dcee7d6
72
assets/scripts/backup.lua
Normal file
72
assets/scripts/backup.lua
Normal file
@ -0,0 +1,72 @@
|
||||
-- script.lua
|
||||
local itterator = 0
|
||||
local ticks = 0
|
||||
local new_rotation = 0
|
||||
local speed = 50
|
||||
|
||||
|
||||
|
||||
function OnInit()
|
||||
-- Log a message with a custom red color
|
||||
Engine.Log("This is a red message.", {1.0, 0.0, 0.0, 1.0})
|
||||
|
||||
-- Log a message with a custom green color
|
||||
Engine.Log("This is a green message.", {0.0, 1.0, 0.0, 1.0})
|
||||
|
||||
-- Log a message with a custom blue color
|
||||
Engine.Log("This is a blue message.", {0.0, 0.0, 1.0, 1.0})
|
||||
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
function OnUpdate(deltaTime)
|
||||
|
||||
-- Attempt to retrieve the GameObject with the tag "Player"
|
||||
local player = Engine.GetGameObjectByTag("Player")
|
||||
|
||||
if player ~= nil then
|
||||
-- Successfully retrieved the GameObject
|
||||
-- Call the GetName method on the GameObject
|
||||
local transform = player:GetComponent("Transform")
|
||||
|
||||
|
||||
-- Log the player's name with a white color
|
||||
-- local pos = transform:GetPosition()
|
||||
-- local x = string.format("%.2f", pos.x)
|
||||
-- local y = string.format("%.2f", pos.y)
|
||||
-- local z = string.format("%.2f", pos.z)
|
||||
|
||||
-- Engine.Log("Player Pos: (" .. x .. ", " .. y .. ", " .. z .. ")", {1, 1, 1, 1})
|
||||
|
||||
--local position = {x = 0.0, y = 2.0, z = -12.0} -- Define the new position
|
||||
--transform:SetPosition(position) -- Call the SetPosition method
|
||||
new_rotation = new_rotation + (deltaTime*speed)
|
||||
|
||||
if (new_rotation > 720) then
|
||||
new_rotation = 0
|
||||
end
|
||||
|
||||
local rotation = {x = -180, y = new_rotation, z = new_rotation} -- Define the new position
|
||||
|
||||
transform:SetRotation(rotation) -- Call the SetPosition method
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- (Optional) Perform additional operations on the player GameObject
|
||||
-- For example, you might want to move the player, change properties, etc.
|
||||
-- player:Move(newPosition)
|
||||
-- player:SetHealth(100)
|
||||
else
|
||||
-- Failed to retrieve the GameObject; it doesn't exist
|
||||
-- Log an error message with a red color
|
||||
Engine.Log("Error: Player GameObject not found!", {1, 0, 0, 1})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
@ -1,6 +1,11 @@
|
||||
-- script.lua
|
||||
local itterator = 0
|
||||
local ticks = 0
|
||||
local new_rotation = 0
|
||||
local speed = 50
|
||||
|
||||
|
||||
|
||||
function OnInit()
|
||||
-- Log a message with a custom red color
|
||||
Engine.Log("This is a red message.", {1.0, 0.0, 0.0, 1.0})
|
||||
@ -19,17 +24,44 @@ end
|
||||
|
||||
function OnUpdate(deltaTime)
|
||||
|
||||
ticks = ticks + 1
|
||||
|
||||
local timestep = 5
|
||||
if itterator >= timestep then
|
||||
Engine.Log("TPS: ".. (ticks/timestep))
|
||||
ticks = 0
|
||||
itterator = 0
|
||||
end
|
||||
|
||||
-- Attempt to retrieve the GameObject with the tag "Player"
|
||||
local player = Engine.GetGameObjectByTag("Player")
|
||||
|
||||
itterator = itterator + deltaTime
|
||||
if player ~= nil then
|
||||
-- Successfully retrieved the GameObject
|
||||
-- Call the GetName method on the GameObject
|
||||
local transform = player:GetComponent("Transform")
|
||||
|
||||
|
||||
-- Log the player's name with a white color
|
||||
-- local pos = transform:GetPosition()
|
||||
-- local x = string.format("%.2f", pos.x)
|
||||
-- local y = string.format("%.2f", pos.y)
|
||||
-- local z = string.format("%.2f", pos.z)
|
||||
|
||||
-- Engine.Log("Player Pos: (" .. x .. ", " .. y .. ", " .. z .. ")", {1, 1, 1, 1})
|
||||
|
||||
--local position = {x = 0.0, y = 2.0, z = -12.0} -- Define the new position
|
||||
--transform:SetPosition(position) -- Call the SetPosition method
|
||||
new_rotation = new_rotation + (deltaTime*speed)
|
||||
|
||||
if (new_rotation > 720) then
|
||||
new_rotation = 0
|
||||
end
|
||||
|
||||
local rotation = {x = -180, y = new_rotation, z = new_rotation} -- Define the new position
|
||||
|
||||
transform:SetRotation(rotation) -- Call the SetPosition method
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- (Optional) Perform additional operations on the player GameObject
|
||||
-- For example, you might want to move the player, change properties, etc.
|
||||
-- player:Move(newPosition)
|
||||
-- player:SetHealth(100)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
34
imgui.ini
34
imgui.ini
@ -1,6 +1,6 @@
|
||||
[Window][DockSpace]
|
||||
Pos=0,0
|
||||
Size=1920,1177
|
||||
Size=1280,720
|
||||
Collapsed=0
|
||||
|
||||
[Window][Debug##Default]
|
||||
@ -9,8 +9,8 @@ Size=400,400
|
||||
Collapsed=0
|
||||
|
||||
[Window][Inspector]
|
||||
Pos=1543,27
|
||||
Size=369,1142
|
||||
Pos=938,27
|
||||
Size=334,685
|
||||
Collapsed=0
|
||||
DockId=0x00000002,0
|
||||
|
||||
@ -21,14 +21,14 @@ Collapsed=0
|
||||
DockId=0x00000003,0
|
||||
|
||||
[Window][Performance]
|
||||
Pos=8,774
|
||||
Size=364,395
|
||||
Pos=8,475
|
||||
Size=364,237
|
||||
Collapsed=0
|
||||
DockId=0x00000006,0
|
||||
|
||||
[Window][Logger]
|
||||
Pos=374,799
|
||||
Size=1167,370
|
||||
Pos=374,392
|
||||
Size=562,320
|
||||
Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
@ -40,26 +40,32 @@ DockId=0x00000007,0
|
||||
|
||||
[Window][Scene Window]
|
||||
Pos=8,27
|
||||
Size=364,745
|
||||
Size=364,446
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
|
||||
[Window][Editor]
|
||||
Pos=374,27
|
||||
Size=1167,770
|
||||
Size=562,363
|
||||
Collapsed=0
|
||||
DockId=0x00000003,0
|
||||
|
||||
[Window][Lua Text Editor]
|
||||
Pos=374,27
|
||||
Size=1167,528
|
||||
Collapsed=0
|
||||
DockId=0x00000003,1
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x14621557 Window=0x3DA2F1DE Pos=8,27 Size=1904,1142 Split=X Selected=0xF7365A5A
|
||||
DockSpace ID=0x14621557 Window=0x3DA2F1DE Pos=8,27 Size=1264,685 Split=X Selected=0xF7365A5A
|
||||
DockNode ID=0x00000009 Parent=0x14621557 SizeRef=364,1142 Split=Y Selected=0x3DC5AC3F
|
||||
DockNode ID=0x00000005 Parent=0x00000009 SizeRef=364,745 HiddenTabBar=1 Selected=0x3DC5AC3F
|
||||
DockNode ID=0x00000006 Parent=0x00000009 SizeRef=364,395 HiddenTabBar=1 Selected=0x726D8899
|
||||
DockNode ID=0x0000000A Parent=0x14621557 SizeRef=1538,1142 Split=X
|
||||
DockNode ID=0x00000007 Parent=0x0000000A SizeRef=357,1142 Selected=0x7737E8B2
|
||||
DockNode ID=0x00000008 Parent=0x0000000A SizeRef=1545,1142 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000008 SizeRef=1167,1142 Split=Y Selected=0xF7365A5A
|
||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=1578,770 CentralNode=1 HiddenTabBar=1 Selected=0xDF0EC458
|
||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=1578,370 HiddenTabBar=1 Selected=0x9DD4E196
|
||||
DockNode ID=0x00000002 Parent=0x00000008 SizeRef=369,1142 HiddenTabBar=1 Selected=0x36DC96AB
|
||||
DockNode ID=0x00000001 Parent=0x00000008 SizeRef=1202,1142 Split=Y Selected=0xF7365A5A
|
||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=1578,820 CentralNode=1 Selected=0xDF0EC458
|
||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=1578,320 HiddenTabBar=1 Selected=0x9DD4E196
|
||||
DockNode ID=0x00000002 Parent=0x00000008 SizeRef=334,1142 HiddenTabBar=1 Selected=0x36DC96AB
|
||||
|
||||
|
@ -1,112 +1,112 @@
|
||||
Entities:
|
||||
- ID: 0
|
||||
Name: Car
|
||||
Name: Player
|
||||
Components:
|
||||
Transform:
|
||||
Position: [0, 2.79999995, -12.6000004]
|
||||
Rotation: [149.699997, -137.899994, -39.2999992]
|
||||
Scale: [1, 1, 1]
|
||||
Mesh:
|
||||
vao: 2
|
||||
indexCount: 15810
|
||||
textureID: 1
|
||||
MeshPath: assets/models/LowPolyFiatUNO.obj
|
||||
Transform:
|
||||
Position: [0, 2.79999995, -12.6000004]
|
||||
Rotation: [149.699997, -137.899994, -39.2999992]
|
||||
Scale: [1, 1, 1]
|
||||
- ID: 2
|
||||
Name: Null Texture Box
|
||||
Components:
|
||||
Transform:
|
||||
Position: [7.80000019, -8.10000038, -20.6000004]
|
||||
Rotation: [-86.3000031, 0, -66]
|
||||
Scale: [1, 1, 1]
|
||||
Mesh:
|
||||
vao: 5
|
||||
indexCount: 36
|
||||
textureID: 3
|
||||
MeshPath: assets/models/DefaultMesh.obj
|
||||
Transform:
|
||||
Position: [7.80000019, -8.10000038, -20.6000004]
|
||||
Rotation: [-86.3000031, 0, -66]
|
||||
Scale: [1, 1, 1]
|
||||
- ID: 3
|
||||
Name: Grass Box Top
|
||||
Components:
|
||||
Transform:
|
||||
Position: [-1.20000005, -3.4000001, -17.7000008]
|
||||
Rotation: [-23.5, 15.8999996, -59.9000015]
|
||||
Scale: [1, 1, 1]
|
||||
Mesh:
|
||||
vao: 5
|
||||
indexCount: 36
|
||||
textureID: 4
|
||||
MeshPath: assets/models/DefaultMesh.obj
|
||||
Transform:
|
||||
Position: [-1.20000005, -3.4000001, -17.7000008]
|
||||
Rotation: [-23.5, 15.8999996, -59.9000015]
|
||||
Scale: [1, 1, 1]
|
||||
- ID: 4
|
||||
Name: Bark Box
|
||||
Components:
|
||||
Transform:
|
||||
Position: [8.10000038, 0.800000012, -12]
|
||||
Rotation: [-17.2999992, -16.1000004, -19.2999992]
|
||||
Scale: [1, 1, 1]
|
||||
Mesh:
|
||||
vao: 5
|
||||
indexCount: 36
|
||||
textureID: 5
|
||||
MeshPath: assets/models/DefaultMesh.obj
|
||||
Transform:
|
||||
Position: [8.10000038, 0.800000012, -12]
|
||||
Rotation: [-17.2999992, -16.1000004, -19.2999992]
|
||||
Scale: [1, 1, 1]
|
||||
- ID: 5
|
||||
Name: Skybox
|
||||
Components:
|
||||
Transform:
|
||||
Position: [0, 0, 43.2000008]
|
||||
Rotation: [0, 0, 0]
|
||||
Scale: [100, 100, 100]
|
||||
Mesh:
|
||||
vao: 5
|
||||
indexCount: 36
|
||||
textureID: 6
|
||||
MeshPath: assets/models/DefaultMesh.obj
|
||||
Transform:
|
||||
Position: [0, 0, 43.2000008]
|
||||
Rotation: [0, 0, 0]
|
||||
Scale: [100, 100, 100]
|
||||
- ID: 6
|
||||
Name: Null Texture Box
|
||||
Components:
|
||||
Transform:
|
||||
Position: [-6.5, -6, -18]
|
||||
Rotation: [15.8000002, -18.2000008, -11.1000004]
|
||||
Scale: [1, 1, 1]
|
||||
Mesh:
|
||||
vao: 5
|
||||
indexCount: 36
|
||||
textureID: 3
|
||||
MeshPath: assets/models/DefaultMesh.obj
|
||||
Transform:
|
||||
Position: [-6.5, -6, -18]
|
||||
Rotation: [15.8000002, -18.2000008, -11.1000004]
|
||||
Scale: [1, 1, 1]
|
||||
- ID: 7
|
||||
Name: Grass Box Bottom
|
||||
Components:
|
||||
Transform:
|
||||
Position: [6.5999999, 1.79999995, -23.8999996]
|
||||
Rotation: [-16.1000004, -15.8999996, -35]
|
||||
Scale: [1, 1, 1]
|
||||
Mesh:
|
||||
vao: 5
|
||||
indexCount: 36
|
||||
textureID: 4
|
||||
MeshPath: assets/models/DefaultMesh.obj
|
||||
Transform:
|
||||
Position: [6.5999999, 1.79999995, -23.8999996]
|
||||
Rotation: [-16.1000004, -15.8999996, -35]
|
||||
Scale: [1, 1, 1]
|
||||
- ID: 8
|
||||
Name: Wood Box
|
||||
Components:
|
||||
Transform:
|
||||
Position: [-7.80000019, 0.200000003, -29.7999992]
|
||||
Rotation: [22.2999992, -32.7999992, 0]
|
||||
Scale: [1, 1, 1]
|
||||
Mesh:
|
||||
vao: 5
|
||||
indexCount: 36
|
||||
textureID: 1
|
||||
MeshPath: assets/models/DefaultMesh.obj
|
||||
Transform:
|
||||
Position: [-7.80000019, 0.200000003, -29.7999992]
|
||||
Rotation: [22.2999992, -32.7999992, 0]
|
||||
Scale: [1, 1, 1]
|
||||
- ID: 9
|
||||
Name: Bricks
|
||||
Components:
|
||||
Transform:
|
||||
Position: [5.5, -2.9000001, -19.5]
|
||||
Rotation: [-41.4000015, -22.6000004, -52.2999992]
|
||||
Scale: [1, 1, 1]
|
||||
Mesh:
|
||||
vao: 5
|
||||
indexCount: 36
|
||||
textureID: 2
|
||||
MeshPath: assets/models/DefaultMesh.obj
|
||||
Transform:
|
||||
Position: [5.5, -2.9000001, -19.5]
|
||||
Rotation: [-41.4000015, -22.6000004, -52.2999992]
|
||||
Scale: [1, 1, 1]
|
||||
- ID: 10
|
||||
Name: Script Handler
|
||||
Components:
|
||||
|
@ -6,13 +6,10 @@
|
||||
|
||||
#include "../Windows/LoggerWindow.h"
|
||||
|
||||
|
||||
|
||||
extern LoggerWindow *g_LoggerWindow;
|
||||
|
||||
|
||||
GameObject::GameObject(int id, const std::string &name)
|
||||
: id(id), name(name)
|
||||
: id(id), name(name)
|
||||
{
|
||||
}
|
||||
|
||||
@ -21,11 +18,17 @@ int GameObject::GetComponentCount() const
|
||||
return static_cast<int>(components.size());
|
||||
}
|
||||
|
||||
std::string GameObject::GetName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void GameObject::AddComponent(const std::shared_ptr<Component> &component)
|
||||
{
|
||||
components[component->GetName()] = component;
|
||||
//std::cout << "Added " << component->GetName() << std::endl;
|
||||
// std::cout << "Added " << component->GetName() << std::endl;
|
||||
}
|
||||
|
||||
std::shared_ptr<Component> GameObject::GetComponentByName(const std::string &name) const
|
||||
@ -59,7 +62,6 @@ YAML::Node GameObject::Serialize()
|
||||
void GameObject::Deserialize(const YAML::Node &node)
|
||||
{
|
||||
|
||||
|
||||
if (node["ID"])
|
||||
{
|
||||
id = node["ID"].as<int>();
|
||||
@ -74,7 +76,7 @@ void GameObject::Deserialize(const YAML::Node &node)
|
||||
|
||||
for (auto it = componentsNode.begin(); it != componentsNode.end(); ++it)
|
||||
{
|
||||
|
||||
|
||||
std::string compName = it->first.as<std::string>();
|
||||
YAML::Node compNode = it->second;
|
||||
|
||||
@ -100,26 +102,20 @@ void GameObject::Deserialize(const YAML::Node &node)
|
||||
{
|
||||
g_LoggerWindow->AddLog("[SceneManager] Failed to load Component: %s", compName.c_str());
|
||||
DEBUG_PRINT("[SceneManager] Failed to load Component: %s", compName.c_str());
|
||||
|
||||
}
|
||||
// Add deserialization for other components as needed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//}
|
||||
//else if (compName == MeshComponent::GetStaticName())
|
||||
// else if (compName == MeshComponent::GetStaticName())
|
||||
//{
|
||||
// auto render = std::make_shared<MeshComponent>();
|
||||
// render->Deserialize(compNode);
|
||||
// AddComponent(render);
|
||||
//}
|
||||
//else if (compName == MeshComponent::GetStaticName())
|
||||
// else if (compName == MeshComponent::GetStaticName())
|
||||
//{
|
||||
// auto render = std::make_shared<MeshComponent>();
|
||||
// render->Deserialize(compNode);
|
||||
|
@ -25,6 +25,8 @@ public:
|
||||
|
||||
GameObject(int id, const std::string &name);
|
||||
|
||||
std::string GetName() const;
|
||||
|
||||
void AddComponent(const std::shared_ptr<Component> &component);
|
||||
std::shared_ptr<Component> GetComponentByName(const std::string &name) const;
|
||||
|
||||
|
@ -73,7 +73,7 @@ bool ScriptComponent::Initialize()
|
||||
}
|
||||
|
||||
// Initialize LuaManager with the script path
|
||||
if (!m_LuaManager.init(ScriptPath))
|
||||
if (!m_LuaManager.Initialize(ScriptPath))
|
||||
{
|
||||
DEBUG_PRINT("ScriptComponent: Failed to initialize LuaManager");
|
||||
return false;
|
||||
@ -85,5 +85,5 @@ bool ScriptComponent::Initialize()
|
||||
void ScriptComponent::Update(float deltaTime)
|
||||
{
|
||||
// Call the Update method of LuaManager
|
||||
m_LuaManager.onUpdate(deltaTime);
|
||||
m_LuaManager.Update(deltaTime);
|
||||
}
|
||||
|
@ -12,6 +12,22 @@ public:
|
||||
glm::vec3 rotation;
|
||||
glm::vec3 scale;
|
||||
|
||||
glm::vec3 GetPosition() const {
|
||||
return position;
|
||||
}
|
||||
|
||||
void SetPosition(float x, float y, float z) {
|
||||
position = { x, y, z };
|
||||
}
|
||||
|
||||
glm::vec3 GetRotation() const {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
void SetRotation(float x, float y, float z) {
|
||||
rotation = { x, y, z };
|
||||
}
|
||||
|
||||
TransformComponent();
|
||||
virtual const std::string& GetName() const override;
|
||||
static const std::string& GetStaticName();
|
||||
|
@ -22,6 +22,11 @@
|
||||
#include "Windows/InspectorWindow.h"
|
||||
#include "Windows/SceneWindow.h"
|
||||
|
||||
|
||||
// Create an instance
|
||||
|
||||
// In your rendering loop
|
||||
|
||||
#include "Engine/ThemeManager.h"
|
||||
#include "Engine/SceneManager.h"
|
||||
#include "Engine/LuaAPI.h"
|
||||
@ -37,6 +42,7 @@ LoggerWindow *g_LoggerWindow;
|
||||
|
||||
SceneManager g_SceneManager;
|
||||
|
||||
|
||||
std::vector<std::shared_ptr<GameObject>> g_GameObjects;
|
||||
|
||||
int g_GPU_Triangles_drawn_to_screen = 0;
|
||||
@ -105,10 +111,11 @@ bool MyEngine::Init(int width, int height, const std::string &title)
|
||||
m_LoggerWindow = std::make_unique<LoggerWindow>();
|
||||
m_InspectorWindow = std::make_unique<InspectorWindow>();
|
||||
m_SceneWindow = std::make_unique<SceneWindow>();
|
||||
m_luaEditor = std::make_unique<LuaEditorWindow>();
|
||||
|
||||
|
||||
g_LoggerWindow = m_LoggerWindow.get();
|
||||
|
||||
|
||||
// Optionally, call 'onInit' Lua function
|
||||
|
||||
// Some initial logs
|
||||
@ -119,7 +126,6 @@ bool MyEngine::Init(int width, int height, const std::string &title)
|
||||
m_LastTime = glfwGetTime();
|
||||
DEBUG_PRINT("[OK] Engine Init ");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -243,18 +249,18 @@ void MyEngine::Run()
|
||||
|
||||
m_InspectorWindow->Show();
|
||||
|
||||
if (1)
|
||||
{
|
||||
for (auto &Gameobject : g_GameObjects)
|
||||
{
|
||||
|
||||
if (1) {
|
||||
for (auto& Gameobject : g_GameObjects) {
|
||||
|
||||
// Handle Componenets That require Updates
|
||||
|
||||
std::shared_ptr<ScriptComponent> script = Gameobject->GetComponent<ScriptComponent>();
|
||||
if (script){ // Stupid Null Checks
|
||||
if (script)
|
||||
{ // Stupid Null Checks
|
||||
script->Update(frame_delta);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,6 +274,8 @@ void MyEngine::Run()
|
||||
|
||||
m_SceneWindow->Show();
|
||||
|
||||
//m_luaEditor->Show();
|
||||
|
||||
// After rendering
|
||||
m_PerformanceWindow->UpdatePerformanceStats(-1, g_GPU_Triangles_drawn_to_screen);
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "Windows/LoggerWindow.h"
|
||||
#include "Windows/InspectorWindow.h"
|
||||
#include "Windows/SceneWindow.h"
|
||||
#include "Windows/LuaEditorWindow.h"
|
||||
|
||||
#include "Componenets/GameObject.h"
|
||||
#include "Componenets/Mesh.h"
|
||||
@ -18,11 +19,8 @@
|
||||
#include "Engine/SceneManager.h"
|
||||
#include "Engine/LuaAPI.h"
|
||||
|
||||
|
||||
|
||||
#include "TestModel.h"
|
||||
|
||||
|
||||
#include "gcml.h"
|
||||
|
||||
// Forward declaration to avoid including GLFW in the header if you prefer
|
||||
@ -43,7 +41,6 @@ private:
|
||||
void ShowDockSpace();
|
||||
|
||||
private:
|
||||
|
||||
GLFWwindow *m_Window = nullptr;
|
||||
bool m_Running = false;
|
||||
|
||||
@ -53,6 +50,7 @@ private:
|
||||
std::unique_ptr<LoggerWindow> m_LoggerWindow;
|
||||
std::unique_ptr<InspectorWindow> m_InspectorWindow;
|
||||
std::unique_ptr<SceneWindow> m_SceneWindow;
|
||||
std::unique_ptr<LuaEditorWindow> m_luaEditor;
|
||||
|
||||
double m_LastFrameTime = 0.0; // Initialize with the current time
|
||||
double m_TimeAccumulator = 0.0;
|
||||
|
@ -1,240 +1,758 @@
|
||||
// LuaManager.cpp
|
||||
// LuaAPI.cpp
|
||||
|
||||
#include "LuaAPI.h"
|
||||
#include "LuaMacros.h"
|
||||
#include "imgui.h"
|
||||
#include <iostream>
|
||||
|
||||
#include "gcml.h"
|
||||
|
||||
#include "LuaMacros.h" // Include the macros for binding
|
||||
#include "gcml.h" // Include gcml.h for DEBUG_PRINT macros
|
||||
#include "Componenets/Component.h"
|
||||
#include "Componenets/Transform.h"
|
||||
#include "Componenets/Mesh.h"
|
||||
#include "Componenets/ScriptComponent.h"
|
||||
#include "Componenets/GameObject.h"
|
||||
#include "Windows/LoggerWindow.h"
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
// External LoggerWindow instance for logging
|
||||
extern LoggerWindow *g_LoggerWindow;
|
||||
|
||||
int lua_log_message(lua_State *L);
|
||||
// External GameObjects list
|
||||
extern std::vector<std::unique_ptr<GameObject>> g_GameObjects;
|
||||
|
||||
LuaManager::LuaManager() : L(nullptr), m_firstCall(false), m_Initialized(false) {}
|
||||
// Constructor
|
||||
LuaManager::LuaManager()
|
||||
: ScriptPath(""), m_LuaState(nullptr), m_LastErrorMessage("")
|
||||
{
|
||||
}
|
||||
|
||||
// Destructor
|
||||
LuaManager::~LuaManager()
|
||||
{
|
||||
if (L)
|
||||
if (m_LuaState)
|
||||
{
|
||||
lua_close(L);
|
||||
lua_close(m_LuaState);
|
||||
m_LuaState = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool LuaManager::init(const std::string &scriptPath)
|
||||
// Initialize the LuaManager with the given script path
|
||||
bool LuaManager::Initialize(const std::string &scriptPath)
|
||||
{
|
||||
// Create a new Lua state
|
||||
L = luaL_newstate();
|
||||
if (L == nullptr)
|
||||
if (scriptPath.empty())
|
||||
{
|
||||
std::cerr << "Failed to create Lua state.\n";
|
||||
if (g_LoggerWindow)
|
||||
{
|
||||
g_LoggerWindow->AddLog("LuaManager: Script path is empty.", std::optional<ImVec4>(ImVec4(1.0f, 0.0f, 0.0f, 1.0f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT("LuaManager: Script path is empty.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ScriptPath = scriptPath;
|
||||
|
||||
// Create a new Lua state
|
||||
m_LuaState = luaL_newstate();
|
||||
if (!m_LuaState)
|
||||
{
|
||||
if (g_LoggerWindow)
|
||||
{
|
||||
g_LoggerWindow->AddLog("LuaManager: Failed to create Lua state.", std::optional<ImVec4>(ImVec4(1.0f, 0.0f, 0.0f, 1.0f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT("LuaManager: Failed to create Lua state.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Open Lua standard libraries
|
||||
luaL_openlibs(L);
|
||||
luaL_openlibs(m_LuaState);
|
||||
|
||||
// Register all necessary metatables
|
||||
RegisterAllMetatables();
|
||||
|
||||
// Create the Engine table
|
||||
CREATE_LUA_TABLE(L, Engine);
|
||||
lua_newtable(m_LuaState);
|
||||
lua_setglobal(m_LuaState, "Engine");
|
||||
|
||||
// Bind the Log function to the Engine table
|
||||
BIND_LUA_FUNCTION(L, Engine, "Log", lua_log_message);
|
||||
lua_getglobal(m_LuaState, "Engine");
|
||||
lua_pushcfunction(m_LuaState, Lua_Engine_Log);
|
||||
lua_setfield(m_LuaState, -2, "Log");
|
||||
|
||||
// Load and execute the Lua script
|
||||
if (luaL_dofile(L, scriptPath.c_str()) != LUA_OK)
|
||||
// Bind the GetGameObjectByTag function to the Engine table
|
||||
lua_pushcfunction(m_LuaState, Lua_Engine_GetGameObjectByTag);
|
||||
lua_setfield(m_LuaState, -2, "GetGameObjectByTag");
|
||||
|
||||
lua_pop(m_LuaState, 1); // Pop the Engine table from the stack
|
||||
|
||||
// Execute the Lua script
|
||||
if (luaL_dofile(m_LuaState, ScriptPath.c_str()) != LUA_OK)
|
||||
{
|
||||
g_LoggerWindow->AddLog("%s", ImVec4(1.0f, 0.0f, 0.0f, 1.0f), lua_tostring(L, -1));
|
||||
DEBUG_PRINT("%s: %s", scriptPath.c_str(), lua_tostring(L, -1));
|
||||
lua_close(L);
|
||||
L = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
m_Initialized = true;
|
||||
callLuaFunction("OnInit");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LuaManager::callLuaFunction(const std::string &funcName)
|
||||
{
|
||||
if (!m_Initialized) {
|
||||
return false;
|
||||
}
|
||||
lua_getglobal(L, funcName.c_str());
|
||||
if (!lua_isfunction(L, -1))
|
||||
{
|
||||
std::cerr << "'" << funcName << "' is not a function.\n";
|
||||
lua_pop(L, 1); // Remove non-function value
|
||||
return false;
|
||||
}
|
||||
|
||||
// Call the function with 0 arguments and 0 return values
|
||||
if (lua_pcall(L, 0, 0, 0) != LUA_OK)
|
||||
{
|
||||
std::cerr << "Error calling '" << funcName << "': " << lua_tostring(L, -1) << "\n";
|
||||
lua_pop(L, 1); // Remove error message
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LuaManager::onUpdate(float deltaTime)
|
||||
{
|
||||
if (!m_Initialized) {
|
||||
return false;
|
||||
}
|
||||
// Push the 'OnUpdate' function onto the stack
|
||||
lua_getglobal(L, "OnUpdate"); // Ensure correct case
|
||||
if (!lua_isfunction(L, -1))
|
||||
{
|
||||
std::cerr << "'OnUpdate' is not a function.\n";
|
||||
lua_pop(L, 1); // Remove non-function value
|
||||
return false;
|
||||
}
|
||||
|
||||
// Push the deltaTime argument
|
||||
lua_pushnumber(L, deltaTime);
|
||||
|
||||
m_firstCall = true;
|
||||
|
||||
// Call the function with 1 argument and 0 return values
|
||||
if (lua_pcall(L, 1, 0, 0) != LUA_OK)
|
||||
{
|
||||
// Retrieve the error message from Lua
|
||||
const char *luaError = lua_tostring(L, -1);
|
||||
const char *luaError = lua_tostring(m_LuaState, -1);
|
||||
if (luaError)
|
||||
{
|
||||
std::string errorMsg(luaError);
|
||||
|
||||
// Check if this error message has already been logged
|
||||
// Prevent duplicate error logs
|
||||
if (errorMsg != m_LastErrorMessage)
|
||||
{
|
||||
// Log the error to the in-game terminal in red
|
||||
if (g_LoggerWindow)
|
||||
{
|
||||
g_LoggerWindow->AddLog(errorMsg.c_str(), ImVec4(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
std::string formattedError = "LuaManager Error: " + errorMsg;
|
||||
ImVec4 redColor = ImVec4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
g_LoggerWindow->AddLog(formattedError.c_str(), std::optional<ImVec4>(redColor));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "LoggerWindow is not initialized.\n";
|
||||
DEBUG_PRINT("LuaManager Error: %s", errorMsg.c_str());
|
||||
}
|
||||
|
||||
// Update the last error message
|
||||
m_LastErrorMessage = errorMsg;
|
||||
}
|
||||
|
||||
// Optionally, print to std::cerr once if LoggerWindow is unavailable
|
||||
if (!g_LoggerWindow)
|
||||
{
|
||||
std::cerr << "Error calling 'OnUpdate': " << luaError << "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Unknown error calling 'OnUpdate'.\n";
|
||||
if (g_LoggerWindow)
|
||||
{
|
||||
g_LoggerWindow->AddLog("LuaManager: Unknown error executing script.", std::optional<ImVec4>(ImVec4(1.0f, 0.0f, 0.0f, 1.0f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT("LuaManager: Unknown error executing script.");
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(L, 1); // Remove error message
|
||||
|
||||
lua_pop(m_LuaState, 1); // Remove error message from stack
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reset last error message on successful script execution
|
||||
m_LastErrorMessage.clear();
|
||||
|
||||
// Log successful initialization
|
||||
DEBUG_PRINT("LuaManager initialized successfully with script: %s", ScriptPath.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Update function called every frame
|
||||
void LuaManager::Update(float deltaTime)
|
||||
{
|
||||
if (!m_LuaState)
|
||||
{
|
||||
if (g_LoggerWindow)
|
||||
{
|
||||
g_LoggerWindow->AddLog("LuaManager: Lua state is not initialized.", std::optional<ImVec4>(ImVec4(1.0f, 0.0f, 0.0f, 1.0f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT("LuaManager: Lua state is not initialized.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Push the 'OnUpdate' function onto the stack
|
||||
lua_getglobal(m_LuaState, "OnUpdate");
|
||||
if (!lua_isfunction(m_LuaState, -1))
|
||||
{
|
||||
if (g_LoggerWindow)
|
||||
{
|
||||
g_LoggerWindow->AddLog("LuaManager: 'OnUpdate' is not a function.", std::optional<ImVec4>(ImVec4(1.0f, 0.0f, 0.0f, 1.0f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT("LuaManager: 'OnUpdate' is not a function.");
|
||||
}
|
||||
lua_pop(m_LuaState, 1); // Remove non-function value from stack
|
||||
return;
|
||||
}
|
||||
|
||||
// Push the deltaTime argument
|
||||
lua_pushnumber(m_LuaState, deltaTime);
|
||||
|
||||
// Call the 'OnUpdate' function with 1 argument and 0 return values
|
||||
if (lua_pcall(m_LuaState, 1, 0, 0) != LUA_OK)
|
||||
{
|
||||
const char *luaError = lua_tostring(m_LuaState, -1);
|
||||
if (luaError)
|
||||
{
|
||||
std::string errorMsg(luaError);
|
||||
// Prevent duplicate error logs
|
||||
if (errorMsg != m_LastErrorMessage)
|
||||
{
|
||||
if (g_LoggerWindow)
|
||||
{
|
||||
std::string formattedError = "LuaManager Error in OnUpdate: " + errorMsg;
|
||||
ImVec4 redColor = ImVec4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
g_LoggerWindow->AddLog(formattedError.c_str(), std::optional<ImVec4>(redColor));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT("LuaManager Error in OnUpdate: %s", errorMsg.c_str());
|
||||
}
|
||||
m_LastErrorMessage = errorMsg;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_LoggerWindow)
|
||||
{
|
||||
g_LoggerWindow->AddLog("LuaManager: Unknown error in OnUpdate.", std::optional<ImVec4>(ImVec4(1.0f, 0.0f, 0.0f, 1.0f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_PRINT("LuaManager: Unknown error in OnUpdate.");
|
||||
}
|
||||
}
|
||||
|
||||
lua_pop(m_LuaState, 1); // Remove error message from stack
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset the last error message if the call was successful
|
||||
// Reset last error message on successful call
|
||||
m_LastErrorMessage.clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LuaManager::onDrawGui()
|
||||
{
|
||||
return callLuaFunction("onDrawGui");
|
||||
}
|
||||
|
||||
bool LuaManager::callFunction(const std::string &funcName, int args, int returns)
|
||||
{
|
||||
if (!m_Initialized) {
|
||||
return false;
|
||||
}
|
||||
lua_getglobal(L, funcName.c_str());
|
||||
if (!lua_isfunction(L, -1))
|
||||
{
|
||||
std::cerr << "'" << funcName << "' is not a function.\n";
|
||||
lua_pop(L, 1); // Remove non-function value
|
||||
return false;
|
||||
}
|
||||
|
||||
// For simplicity, this example doesn't handle arguments and return values.
|
||||
// You can extend this method to push arguments and retrieve returns as needed.
|
||||
|
||||
if (lua_pcall(L, args, returns, 0) != LUA_OK)
|
||||
{
|
||||
std::cerr << "Error calling '" << funcName << "': " << lua_tostring(L, -1) << "\n";
|
||||
lua_pop(L, 1); // Remove error message
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Binding function to log messages from Lua
|
||||
int lua_log_message(lua_State *L)
|
||||
int LuaManager::Lua_Engine_Log(lua_State *L)
|
||||
{
|
||||
// Check and retrieve the message string
|
||||
int argc = lua_gettop(L);
|
||||
if (argc < 1 || !lua_isstring(L, 1))
|
||||
{
|
||||
lua_pushstring(L, "Engine.Log expects at least one string argument.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
std::string message = lua_tostring(L, 1);
|
||||
ImVec4 color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // Default white
|
||||
|
||||
// Optional color table
|
||||
if (argc >= 2 && lua_istable(L, 2))
|
||||
{
|
||||
lua_getfield(L, 2, "r");
|
||||
if (lua_isnumber(L, -1))
|
||||
color.x = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 2, "g");
|
||||
if (lua_isnumber(L, -1))
|
||||
color.y = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 2, "b");
|
||||
if (lua_isnumber(L, -1))
|
||||
color.z = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, 2, "a");
|
||||
if (lua_isnumber(L, -1))
|
||||
color.w = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
// Log the message
|
||||
if (g_LoggerWindow)
|
||||
{
|
||||
g_LoggerWindow->AddLog(message.c_str(), std::optional<ImVec4>(color));
|
||||
}
|
||||
|
||||
return 0; // No return values
|
||||
}
|
||||
|
||||
// Binding function to retrieve a GameObject by tag from Lua
|
||||
int LuaManager::Lua_Engine_GetGameObjectByTag(lua_State *L)
|
||||
{
|
||||
// Reuse the existing Lua_GetGameObjectByTag function
|
||||
return Lua_GetGameObjectByTag(L);
|
||||
}
|
||||
|
||||
// Binding function to retrieve a GameObject by tag
|
||||
int LuaManager::Lua_GetGameObjectByTag(lua_State *L)
|
||||
{
|
||||
// Check if the first argument is a string
|
||||
if (!lua_isstring(L, 1))
|
||||
{
|
||||
lua_pushstring(L, "Incorrect argument to 'Engine.Log'. Expected string as first argument.");
|
||||
lua_error(L);
|
||||
return 0; // Never reached, lua_error long jumps
|
||||
lua_pushstring(L, "GetGameObjectByTag expects a string argument.");
|
||||
lua_error(L); // Raises a Lua error and does not return
|
||||
return 0; // This line won't be reached
|
||||
}
|
||||
const char *message = lua_tostring(L, 1);
|
||||
|
||||
// Initialize default color
|
||||
ImVec4 color(1.0f, 1.0f, 1.0f, 1.0f); // Default white color
|
||||
std::string tag = lua_tostring(L, 1);
|
||||
|
||||
// Check if a second argument (color) is provided
|
||||
if (lua_gettop(L) >= 2)
|
||||
// Search for the GameObject with the matching tag
|
||||
GameObject *foundObject = nullptr;
|
||||
for (auto &obj : g_GameObjects)
|
||||
{
|
||||
if (lua_istable(L, 2))
|
||||
if (obj->name == tag)
|
||||
{
|
||||
// Retrieve color components from the table
|
||||
lua_pushnumber(L, 1); // Push key 1 (r)
|
||||
lua_gettable(L, 2);
|
||||
float r = lua_isnumber(L, -1) ? lua_tonumber(L, -1) : 1.0f;
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_pushnumber(L, 2); // Push key 2 (g)
|
||||
lua_gettable(L, 2);
|
||||
float g = lua_isnumber(L, -1) ? lua_tonumber(L, -1) : 1.0f;
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_pushnumber(L, 3); // Push key 3 (b)
|
||||
lua_gettable(L, 2);
|
||||
float b = lua_isnumber(L, -1) ? lua_tonumber(L, -1) : 1.0f;
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_pushnumber(L, 4); // Push key 4 (a)
|
||||
lua_gettable(L, 2);
|
||||
float a = lua_isnumber(L, -1) ? lua_tonumber(L, -1) : 1.0f;
|
||||
lua_pop(L, 1);
|
||||
|
||||
color = ImVec4(r, g, b, a);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L, "Incorrect argument to 'Engine.Log'. Expected table for color.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
foundObject = obj.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure LoggerWindow is valid
|
||||
if (foundObject == nullptr)
|
||||
{
|
||||
lua_pushnil(L); // Push nil to the stack if not found
|
||||
return 1; // Return 1 (nil on Lua stack)
|
||||
}
|
||||
|
||||
g_LoggerWindow->AddLog(message, color);
|
||||
// Create userdata to hold the GameObject pointer
|
||||
GameObject **udata = (GameObject **)lua_newuserdata(L, sizeof(GameObject *));
|
||||
*udata = foundObject;
|
||||
|
||||
return 0; // Number of return values
|
||||
// Set the metatable
|
||||
luaL_getmetatable(L, "GameObjectMetaTable");
|
||||
if (!lua_istable(L, -1)) // Check if the metatable was successfully found
|
||||
{
|
||||
DEBUG_PRINT("LuaManager: Metatable 'GameObjectMetaTable' not found.");
|
||||
lua_pop(L, 1); // Remove the invalid metatable from the stack
|
||||
lua_pushnil(L); // Return nil to indicate failure
|
||||
return 1; // Return 1 (nil on Lua stack)
|
||||
}
|
||||
|
||||
lua_setmetatable(L, -2); // Set the metatable for the userdata
|
||||
|
||||
return 1; // Return the GameObject userdata
|
||||
}
|
||||
|
||||
|
||||
// Binding function to retrieve a Component by name from a GameObject
|
||||
int LuaManager::Lua_GameObject_GetComponent(lua_State *L)
|
||||
{
|
||||
// Ensure the first argument is a userdata with the correct metatable
|
||||
GameObject **udata = (GameObject **)luaL_checkudata(L, 1, "GameObjectMetaTable");
|
||||
if (udata == nullptr || *udata == nullptr)
|
||||
{
|
||||
lua_pushstring(L, "Invalid GameObject.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Ensure the second argument is a string representing the component name
|
||||
if (!lua_isstring(L, 2))
|
||||
{
|
||||
lua_pushstring(L, "GetComponent expects a string as the second argument.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *componentNameStr = lua_tostring(L, 2);
|
||||
|
||||
// Retrieve the component by name
|
||||
Component *component = (*udata)->GetComponentByName(componentNameStr).get();
|
||||
|
||||
if (component == nullptr)
|
||||
{
|
||||
lua_pushnil(L); // Return nil if component not found
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// Determine which metatable to use based on the component type
|
||||
if (strcmp(componentNameStr, "Transform") == 0)
|
||||
{
|
||||
luaL_getmetatable(L, "TransformMetaTable");
|
||||
}
|
||||
else if (strcmp(componentNameStr, "Mesh") == 0)
|
||||
{
|
||||
luaL_getmetatable(L, "MeshMetaTable");
|
||||
}
|
||||
else if (strcmp(componentNameStr, "Script") == 0)
|
||||
{
|
||||
luaL_getmetatable(L, "ScriptMetaTable");
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L, "Unknown ComponentType specified.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if the metatable was successfully retrieved
|
||||
std::string metatableName = std::string(componentNameStr) + "MetaTable";
|
||||
|
||||
if (!lua_istable(L, -1))
|
||||
{
|
||||
DEBUG_PRINT("LuaManager: Metatable '%s' not found.", std::string(metatableName).c_str());
|
||||
lua_pop(L, 1); // Remove the invalid metatable from the stack
|
||||
lua_pushnil(L); // Return nil to indicate failure
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create userdata for the Component
|
||||
Component **compUdata = (Component **)lua_newuserdata(L, sizeof(Component *));
|
||||
*compUdata = component;
|
||||
|
||||
// Retrieve and push the metatable onto the stack
|
||||
luaL_getmetatable(L, std::string(metatableName).c_str());
|
||||
if (lua_isnil(L, -1))
|
||||
{
|
||||
luaL_error(L, "Metatable '%s' not found", std::string(metatableName).c_str());
|
||||
}
|
||||
|
||||
// Set the metatable for the userdata
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
|
||||
return 1; // Return the Component userdata
|
||||
}
|
||||
|
||||
// Binding function to retrieve a Component's name
|
||||
int LuaManager::Lua_Component_GetName(lua_State *L)
|
||||
{
|
||||
// Ensure the first argument is a userdata with ComponentMetaTable
|
||||
Component **udata = (Component **)luaL_checkudata(L, 1, "ComponentMetaTable");
|
||||
if (udata == nullptr || *udata == nullptr)
|
||||
{
|
||||
lua_pushstring(L, "Invalid Component.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Push the name of the Component
|
||||
lua_pushstring(L, (*udata)->GetName().c_str());
|
||||
|
||||
return 1; // Return the name
|
||||
}
|
||||
|
||||
// Binding function to retrieve a TransformComponent's position
|
||||
int LuaManager::Lua_TransformComponent_GetPosition(lua_State *L)
|
||||
{
|
||||
// Ensure the first argument is a userdata with TransformMetaTable
|
||||
TransformComponent **udata = (TransformComponent **)luaL_checkudata(L, 1, "TransformMetaTable");
|
||||
if (udata == nullptr || *udata == nullptr)
|
||||
{
|
||||
lua_pushstring(L, "Invalid TransformComponent.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Assuming TransformComponent has a GetPosition method returning a glm::vec3
|
||||
glm::vec3 position = (*udata)->GetPosition(); // Example using glm::vec3
|
||||
|
||||
// Push position as a Lua table
|
||||
lua_newtable(L);
|
||||
lua_pushnumber(L, position.x);
|
||||
lua_setfield(L, -2, "x");
|
||||
lua_pushnumber(L, position.y);
|
||||
lua_setfield(L, -2, "y");
|
||||
lua_pushnumber(L, position.z);
|
||||
lua_setfield(L, -2, "z");
|
||||
|
||||
return 1; // Return the position table
|
||||
}
|
||||
|
||||
// Binding function to set a TransformComponent's position
|
||||
int LuaManager::Lua_TransformComponent_SetPosition(lua_State *L)
|
||||
{
|
||||
// Ensure the first argument is a userdata with TransformMetaTable
|
||||
TransformComponent **udata = (TransformComponent **)luaL_checkudata(L, 1, "TransformMetaTable");
|
||||
if (udata == nullptr || *udata == nullptr)
|
||||
{
|
||||
lua_pushstring(L, "Invalid TransformComponent.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Ensure the second argument is a table with x, y, z
|
||||
if (!lua_istable(L, 2))
|
||||
{
|
||||
lua_pushstring(L, "SetPosition expects a table with x, y, z fields.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_getfield(L, 2, "x");
|
||||
lua_getfield(L, 2, "y");
|
||||
lua_getfield(L, 2, "z");
|
||||
|
||||
if (!lua_isnumber(L, -3) || !lua_isnumber(L, -2) || !lua_isnumber(L, -1))
|
||||
{
|
||||
lua_pushstring(L, "SetPosition expects numerical x, y, z fields.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
float x = lua_tonumber(L, -3);
|
||||
float y = lua_tonumber(L, -2);
|
||||
float z = lua_tonumber(L, -1);
|
||||
|
||||
lua_pop(L, 3); // Remove x, y, z from stack
|
||||
|
||||
(*udata)->SetPosition(x, y, z); // Corrected to match the method signature
|
||||
|
||||
return 0; // No return values
|
||||
}
|
||||
|
||||
// Binding function to retrieve a TransformComponent's position
|
||||
int LuaManager::Lua_TransformComponent_GetRotation(lua_State *L)
|
||||
{
|
||||
// Ensure the first argument is a userdata with TransformMetaTable
|
||||
TransformComponent **udata = (TransformComponent **)luaL_checkudata(L, 1, "TransformMetaTable");
|
||||
if (udata == nullptr || *udata == nullptr)
|
||||
{
|
||||
lua_pushstring(L, "Invalid TransformComponent.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Assuming TransformComponent has a GetPosition method returning a glm::vec3
|
||||
glm::vec3 rotation = (*udata)->GetRotation(); // Example using glm::vec3
|
||||
|
||||
// Push position as a Lua table
|
||||
lua_newtable(L);
|
||||
lua_pushnumber(L, rotation.x);
|
||||
lua_setfield(L, -2, "x");
|
||||
lua_pushnumber(L, rotation.y);
|
||||
lua_setfield(L, -2, "y");
|
||||
lua_pushnumber(L, rotation.z);
|
||||
lua_setfield(L, -2, "z");
|
||||
|
||||
return 1; // Return the position table
|
||||
}
|
||||
|
||||
|
||||
// Binding function to set a TransformComponent's position
|
||||
int LuaManager::Lua_TransformComponent_SetRotation(lua_State *L)
|
||||
{
|
||||
// Ensure the first argument is a userdata with TransformMetaTable
|
||||
TransformComponent **udata = (TransformComponent **)luaL_checkudata(L, 1, "TransformMetaTable");
|
||||
if (udata == nullptr || *udata == nullptr)
|
||||
{
|
||||
lua_pushstring(L, "Invalid TransformComponent.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Ensure the second argument is a table with x, y, z
|
||||
if (!lua_istable(L, 2))
|
||||
{
|
||||
lua_pushstring(L, "SetRotation expects a table with x, y, z fields.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_getfield(L, 2, "x");
|
||||
lua_getfield(L, 2, "y");
|
||||
lua_getfield(L, 2, "z");
|
||||
|
||||
if (!lua_isnumber(L, -3) || !lua_isnumber(L, -2) || !lua_isnumber(L, -1))
|
||||
{
|
||||
lua_pushstring(L, "SetRotation expects numerical x, y, z fields.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
float x = lua_tonumber(L, -3);
|
||||
float y = lua_tonumber(L, -2);
|
||||
float z = lua_tonumber(L, -1);
|
||||
|
||||
lua_pop(L, 3); // Remove x, y, z from stack
|
||||
|
||||
(*udata)->SetRotation(x, y, z); // Corrected to match the method signature
|
||||
|
||||
return 0; // No return values
|
||||
}
|
||||
|
||||
// Binding function to retrieve a MeshComponent's mesh data
|
||||
int LuaManager::Lua_MeshComponent_GetMeshData(lua_State *L)
|
||||
{
|
||||
// Ensure the first argument is a userdata with MeshComponentMetaTable
|
||||
MeshComponent **udata = (MeshComponent **)luaL_checkudata(L, 1, "MeshComponentMetaTable");
|
||||
if (udata == nullptr || *udata == nullptr)
|
||||
{
|
||||
lua_pushstring(L, "Invalid MeshComponent.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Example: Push mesh data as a table
|
||||
// Ensure MeshData is defined appropriately in MeshComponent
|
||||
GLuint ID = (*udata)->textureID; // Assume MeshData is a struct with relevant fields
|
||||
|
||||
lua_newtable(L);
|
||||
lua_pushnumber(L, ID);
|
||||
lua_setfield(L, -2, "vertexData");
|
||||
// lua_pushstring(L, ID.indexData.c_str());
|
||||
// lua_setfield(L, -2, "indexData");
|
||||
// Add more mesh data fields as needed
|
||||
|
||||
return 1; // Return the mesh data table
|
||||
}
|
||||
|
||||
// Binding function to retrieve a ScriptComponent's script path
|
||||
int LuaManager::Lua_ScriptComponent_GetScriptPath(lua_State *L)
|
||||
{
|
||||
// Ensure the first argument is a userdata with ScriptComponentMetaTable
|
||||
ScriptComponent **udata = (ScriptComponent **)luaL_checkudata(L, 1, "ScriptComponentMetaTable");
|
||||
if (udata == nullptr || *udata == nullptr)
|
||||
{
|
||||
lua_pushstring(L, "Invalid ScriptComponent.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Push the script path
|
||||
lua_pushstring(L, (*udata)->ScriptPath.c_str());
|
||||
|
||||
return 1; // Return the script path
|
||||
}
|
||||
|
||||
// Binding function to retrieve a GameObject's name
|
||||
int LuaManager::Lua_GameObject_GetName(lua_State *L)
|
||||
{
|
||||
// Ensure the first argument is a userdata with GameObjectMetaTable
|
||||
GameObject **udata = (GameObject **)luaL_checkudata(L, 1, "GameObjectMetaTable");
|
||||
if (udata == nullptr || *udata == nullptr)
|
||||
{
|
||||
lua_pushstring(L, "Invalid GameObject.");
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Push the name of the GameObject
|
||||
lua_pushstring(L, (*udata)->GetName().c_str());
|
||||
|
||||
return 1; // Return the name
|
||||
}
|
||||
|
||||
// Function to register all metatables
|
||||
void LuaManager::RegisterAllMetatables()
|
||||
{
|
||||
RegisterComponentMetaTable();
|
||||
RegisterTransformComponentMetaTable();
|
||||
RegisterMeshComponentMetaTable();
|
||||
RegisterScriptComponentMetaTable();
|
||||
RegisterGameObjectMetatable();
|
||||
}
|
||||
|
||||
// Function to register the base ComponentMetaTable
|
||||
void LuaManager::RegisterComponentMetaTable()
|
||||
{
|
||||
luaL_newmetatable(m_LuaState, "ComponentMetaTable");
|
||||
|
||||
// __index
|
||||
lua_pushstring(m_LuaState, "__index");
|
||||
lua_newtable(m_LuaState);
|
||||
|
||||
// Add methods to the metatable
|
||||
lua_pushcfunction(m_LuaState, Lua_Component_GetName);
|
||||
lua_setfield(m_LuaState, -2, "GetName");
|
||||
|
||||
// Add more common methods as needed
|
||||
|
||||
lua_settable(m_LuaState, -3); // Set __index to the table with methods
|
||||
|
||||
lua_pop(m_LuaState, 1); // Pop the metatable
|
||||
}
|
||||
|
||||
// Function to register the TransformMetaTable
|
||||
void LuaManager::RegisterTransformComponentMetaTable()
|
||||
{
|
||||
luaL_newmetatable(m_LuaState, "TransformMetaTable");
|
||||
|
||||
// __index
|
||||
lua_pushstring(m_LuaState, "__index");
|
||||
lua_newtable(m_LuaState);
|
||||
|
||||
// Inherit from ComponentMetaTable
|
||||
luaL_getmetatable(m_LuaState, "ComponentMetaTable");
|
||||
lua_setfield(m_LuaState, -2, "__base");
|
||||
|
||||
// Add methods specific to TransformComponent
|
||||
lua_pushcfunction(m_LuaState, Lua_TransformComponent_GetPosition);
|
||||
lua_setfield(m_LuaState, -2, "GetPosition");
|
||||
|
||||
lua_pushcfunction(m_LuaState, Lua_TransformComponent_SetPosition);
|
||||
lua_setfield(m_LuaState, -2, "SetPosition");
|
||||
|
||||
// Add methods specific to TransformComponent
|
||||
lua_pushcfunction(m_LuaState, Lua_TransformComponent_GetRotation);
|
||||
lua_setfield(m_LuaState, -2, "GetRotation");
|
||||
|
||||
lua_pushcfunction(m_LuaState, Lua_TransformComponent_SetRotation);
|
||||
lua_setfield(m_LuaState, -2, "SetRotation");
|
||||
|
||||
// Add more Transform-specific methods as needed
|
||||
|
||||
lua_settable(m_LuaState, -3); // Set __index to the table with methods
|
||||
|
||||
lua_pop(m_LuaState, 1); // Pop the metatable
|
||||
}
|
||||
|
||||
// Function to register the MeshComponentMetaTable
|
||||
void LuaManager::RegisterMeshComponentMetaTable()
|
||||
{
|
||||
luaL_newmetatable(m_LuaState, "MeshMetaTable");
|
||||
|
||||
// __index
|
||||
lua_pushstring(m_LuaState, "__index");
|
||||
lua_newtable(m_LuaState);
|
||||
|
||||
// Inherit from ComponentMetaTable
|
||||
luaL_getmetatable(m_LuaState, "ComponentMetaTable");
|
||||
lua_setfield(m_LuaState, -2, "__base");
|
||||
|
||||
// Add methods specific to MeshComponent
|
||||
lua_pushcfunction(m_LuaState, Lua_MeshComponent_GetMeshData);
|
||||
lua_setfield(m_LuaState, -2, "GetMeshData");
|
||||
|
||||
// Add more Mesh-specific methods as needed
|
||||
|
||||
lua_settable(m_LuaState, -3); // Set __index to the table with methods
|
||||
|
||||
lua_pop(m_LuaState, 1); // Pop the metatable
|
||||
}
|
||||
|
||||
// Function to register the ScriptComponentMetaTable
|
||||
void LuaManager::RegisterScriptComponentMetaTable()
|
||||
{
|
||||
luaL_newmetatable(m_LuaState, "ScriptMetaTable");
|
||||
|
||||
// __index
|
||||
lua_pushstring(m_LuaState, "__index");
|
||||
lua_newtable(m_LuaState);
|
||||
|
||||
// Inherit from ComponentMetaTable
|
||||
luaL_getmetatable(m_LuaState, "ComponentMetaTable");
|
||||
lua_setfield(m_LuaState, -2, "__base");
|
||||
|
||||
// Add methods specific to ScriptComponent
|
||||
lua_pushcfunction(m_LuaState, Lua_ScriptComponent_GetScriptPath);
|
||||
lua_setfield(m_LuaState, -2, "GetScriptPath");
|
||||
|
||||
// Add more Script-specific methods as needed
|
||||
|
||||
lua_settable(m_LuaState, -3); // Set __index to the table with methods
|
||||
|
||||
lua_pop(m_LuaState, 1); // Pop the metatable
|
||||
}
|
||||
|
||||
// Function to register the GameObjectMetaTable
|
||||
void LuaManager::RegisterGameObjectMetatable()
|
||||
{
|
||||
luaL_newmetatable(m_LuaState, "GameObjectMetaTable");
|
||||
|
||||
// __index
|
||||
lua_pushstring(m_LuaState, "__index");
|
||||
lua_newtable(m_LuaState);
|
||||
|
||||
// Add methods to the metatable
|
||||
lua_pushcfunction(m_LuaState, Lua_GameObject_GetName);
|
||||
lua_setfield(m_LuaState, -2, "GetName");
|
||||
|
||||
lua_pushcfunction(m_LuaState, Lua_GameObject_GetComponent);
|
||||
lua_setfield(m_LuaState, -2, "GetComponent");
|
||||
|
||||
// Add more methods as needed
|
||||
|
||||
lua_settable(m_LuaState, -3); // Set __index to the table with methods
|
||||
|
||||
lua_pop(m_LuaState, 1); // Pop the metatable
|
||||
}
|
||||
|
@ -1,36 +1,98 @@
|
||||
// LuaAPI.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "lua.hpp"
|
||||
#include <string>
|
||||
// Include Lua headers
|
||||
extern "C"
|
||||
{
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
}
|
||||
|
||||
class LuaManager {
|
||||
// Include standard libraries
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
// Forward declarations to avoid circular dependencies
|
||||
class Component;
|
||||
class TransformComponent;
|
||||
class MeshComponent;
|
||||
class ScriptComponent;
|
||||
class GameObject;
|
||||
class LoggerWindow;
|
||||
|
||||
// LuaManager class definition
|
||||
class LuaManager
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
LuaManager();
|
||||
|
||||
// Destructor
|
||||
~LuaManager();
|
||||
|
||||
// Initialize the Lua state and load the script
|
||||
bool init(const std::string& scriptPath);
|
||||
/**
|
||||
* @brief Initializes the LuaManager with the specified Lua script.
|
||||
*
|
||||
* This function creates a new Lua state, opens standard libraries,
|
||||
* registers all necessary metatables, binds essential functions to Lua,
|
||||
* and executes the provided Lua script.
|
||||
*
|
||||
* @param scriptPath The file path to the Lua script to execute.
|
||||
* @return true if initialization is successful; false otherwise.
|
||||
*/
|
||||
bool Initialize(const std::string &scriptPath);
|
||||
|
||||
// Call the 'onUpdate' function in Lua
|
||||
bool onUpdate(float deltaTime);
|
||||
|
||||
// Call the 'onDrawGui' function in Lua
|
||||
bool onDrawGui();
|
||||
|
||||
// Optionally, call other Lua functions as needed
|
||||
bool callFunction(const std::string& funcName, int args = 0, int returns = 0);
|
||||
/**
|
||||
* @brief Updates the LuaManager each frame.
|
||||
*
|
||||
* This function calls the Lua `OnUpdate` function, passing the
|
||||
* delta time since the last frame. It handles any errors that
|
||||
* occur during the execution of the Lua function.
|
||||
*
|
||||
* @param deltaTime The time elapsed since the last frame.
|
||||
*/
|
||||
void Update(float deltaTime);
|
||||
|
||||
private:
|
||||
lua_State* L;
|
||||
std::string m_LastErrorMessage; // Stores the last error message
|
||||
// Lua state
|
||||
std::string ScriptPath;
|
||||
|
||||
bool m_firstCall;
|
||||
lua_State *m_LuaState;
|
||||
|
||||
bool m_Initialized;
|
||||
// Last error message to prevent duplicate logging
|
||||
std::string m_LastErrorMessage;
|
||||
void RegisterAllMetatables();
|
||||
void RegisterComponentMetaTable();
|
||||
|
||||
void RegisterTransformComponentMetaTable();
|
||||
void RegisterMeshComponentMetaTable();
|
||||
void RegisterScriptComponentMetaTable();
|
||||
void RegisterGameObjectMetatable();
|
||||
|
||||
// Helper function to call a Lua function with no arguments and no return values
|
||||
// Binding functions for Component
|
||||
static int Lua_Component_GetName(lua_State *L);
|
||||
|
||||
bool callLuaFunction(const std::string& funcName);
|
||||
// Binding functions for TransformComponent
|
||||
static int Lua_TransformComponent_GetPosition(lua_State *L);
|
||||
static int Lua_TransformComponent_SetPosition(lua_State *L);
|
||||
|
||||
static int Lua_TransformComponent_GetRotation(lua_State *L);
|
||||
static int Lua_TransformComponent_SetRotation(lua_State *L);
|
||||
|
||||
// Binding functions for MeshComponent
|
||||
static int Lua_MeshComponent_GetMeshData(lua_State *L);
|
||||
|
||||
// Binding functions for ScriptComponent
|
||||
static int Lua_ScriptComponent_GetScriptPath(lua_State *L);
|
||||
|
||||
// Binding functions for GameObject
|
||||
static int Lua_GameObject_GetName(lua_State *L);
|
||||
static int Lua_GameObject_GetComponent(lua_State *L);
|
||||
static int Lua_GetGameObjectByTag(lua_State *L);
|
||||
|
||||
// Binding functions for Engine table
|
||||
static int Lua_Engine_Log(lua_State *L);
|
||||
static int Lua_Engine_GetGameObjectByTag(lua_State *L);
|
||||
};
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
#include "./Componenets/GameObject.h"
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "Componenets/GameObject.h"
|
||||
|
||||
|
||||
class SceneManager
|
||||
|
208
src/Windows/LuaEditorWindow.cpp
Normal file
208
src/Windows/LuaEditorWindow.cpp
Normal file
@ -0,0 +1,208 @@
|
||||
#include <vector>
|
||||
#include "LuaEditorWindow.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
// Lua keywords for highlighting
|
||||
const std::unordered_set<std::string> luaKeywords = {
|
||||
"and", "break", "do", "else", "elseif", "end", "false", "for", "function",
|
||||
"if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true",
|
||||
"until", "while"
|
||||
};
|
||||
|
||||
bool IsLuaKeyword(const std::string& word) {
|
||||
return luaKeywords.find(word) != luaKeywords.end();
|
||||
}
|
||||
|
||||
|
||||
LuaEditorWindow::LuaEditorWindow() {
|
||||
m_FilePath = "assets/scripts/script.lua";
|
||||
m_EditorContent.resize(BUFFER_SIZE, '\0'); // Initialize buffer
|
||||
std::string initialText = "-- Lua Text Editor Example\nprint('Hello, World!')";
|
||||
std::copy(initialText.begin(), initialText.end(), m_EditorContent.begin());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void LuaEditorWindow::Show() {
|
||||
if (m_EditorContent.empty()) {
|
||||
ImGui::Text("Editor content not initialized.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui::Begin("Lua Text Editor");
|
||||
|
||||
// Toolbar buttons
|
||||
if (ImGui::Button("Save")) {
|
||||
if (!m_FilePath.empty()) {
|
||||
SaveToFile(m_FilePath);
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Load")) {
|
||||
if (!m_FilePath.empty()) {
|
||||
LoadFromFile(m_FilePath);
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Clear")) {
|
||||
Clear();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
// Editable text input
|
||||
float contentHeight = ImGui::GetContentRegionAvail().y;
|
||||
ImVec2 inputBoxSize(-FLT_MIN, contentHeight);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); // Reduce spacing for overlay
|
||||
ImGui::BeginChild("##editor_background", inputBoxSize, true, ImGuiWindowFlags_NoScrollbar);
|
||||
|
||||
// Syntax highlighting overlay
|
||||
ImGui::SetCursorPos(ImVec2(0, 0));
|
||||
std::istringstream stream(GetText());
|
||||
std::string line;
|
||||
|
||||
while (std::getline(stream, line)) {
|
||||
const char* cursor = line.c_str();
|
||||
const char* end = cursor + line.size();
|
||||
std::string inlineText;
|
||||
while (cursor < end) {
|
||||
// Handle comments
|
||||
if (*cursor == '-' && (cursor + 1 < end) && *(cursor + 1) == '-') {
|
||||
if (!inlineText.empty()) {
|
||||
ImGui::TextUnformatted(inlineText.c_str());
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
inlineText.clear();
|
||||
}
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 0.5f, 0.5f, 1.0f)); // Gray for comments
|
||||
ImGui::TextUnformatted(cursor);
|
||||
ImGui::PopStyleColor();
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle strings
|
||||
if (*cursor == '"' || *cursor == '\'') {
|
||||
char stringDelimiter = *cursor;
|
||||
if (!inlineText.empty()) {
|
||||
ImGui::TextUnformatted(inlineText.c_str());
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
inlineText.clear();
|
||||
}
|
||||
const char* stringStart = cursor++;
|
||||
while (cursor < end && *cursor != stringDelimiter) {
|
||||
if (*cursor == '\\' && (cursor + 1 < end) && *(cursor + 1) == stringDelimiter) {
|
||||
cursor++;
|
||||
}
|
||||
cursor++;
|
||||
}
|
||||
if (cursor < end) {
|
||||
cursor++;
|
||||
}
|
||||
std::string stringToken(stringStart, cursor);
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 1.0f, 0.0f, 1.0f)); // Green for strings
|
||||
ImGui::TextUnformatted(stringToken.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle keywords
|
||||
const char* wordStart = cursor;
|
||||
while (cursor < end && (isalnum(*cursor) || *cursor == '_')) {
|
||||
cursor++;
|
||||
}
|
||||
std::string word(wordStart, cursor);
|
||||
if (IsLuaKeyword(word)) {
|
||||
if (!inlineText.empty()) {
|
||||
ImGui::TextUnformatted(inlineText.c_str());
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
inlineText.clear();
|
||||
}
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.0f, 0.5f, 1.0f, 1.0f)); // Blue for keywords
|
||||
ImGui::TextUnformatted(word.c_str());
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
} else {
|
||||
inlineText += word;
|
||||
}
|
||||
|
||||
// Handle symbols
|
||||
if (cursor < end && !isalnum(*cursor) && *cursor != '_') {
|
||||
if (!inlineText.empty()) {
|
||||
ImGui::TextUnformatted(inlineText.c_str());
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
inlineText.clear();
|
||||
}
|
||||
ImGui::TextUnformatted(std::string(1, *cursor).c_str());
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
cursor++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inlineText.empty()) {
|
||||
ImGui::TextUnformatted(inlineText.c_str());
|
||||
}
|
||||
ImGui::NewLine();
|
||||
}
|
||||
|
||||
ImGui::EndChild(); // End background overlay
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
// Editable content area
|
||||
ImGui::InputTextMultiline("##editor", m_EditorContent.data(), m_EditorContent.size(),
|
||||
inputBoxSize, ImGuiInputTextFlags_AllowTabInput);
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void LuaEditorWindow::SetText(const std::string& text) {
|
||||
if (text.size() >= BUFFER_SIZE) {
|
||||
m_EditorContent.resize(text.size() + 1); // Resize if needed
|
||||
}
|
||||
std::copy(text.begin(), text.end(), m_EditorContent.begin());
|
||||
m_EditorContent[text.size()] = '\0'; // Ensure null termination
|
||||
}
|
||||
|
||||
std::string LuaEditorWindow::GetText() const {
|
||||
return std::string(m_EditorContent.data());
|
||||
}
|
||||
|
||||
void LuaEditorWindow::Clear() {
|
||||
std::fill(m_EditorContent.begin(), m_EditorContent.end(), '\0');
|
||||
}
|
||||
|
||||
bool LuaEditorWindow::SaveToFile(const std::string& filePath) {
|
||||
std::ofstream file(filePath);
|
||||
if (!file.is_open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file << m_EditorContent.data();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LuaEditorWindow::LoadFromFile(const std::string& filePath) {
|
||||
std::ifstream file(filePath);
|
||||
if (!file.is_open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::stringstream buffer;
|
||||
buffer << file.rdbuf();
|
||||
SetText(buffer.str());
|
||||
m_FilePath = filePath;
|
||||
return true;
|
||||
}
|
||||
|
24
src/Windows/LuaEditorWindow.h
Normal file
24
src/Windows/LuaEditorWindow.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "imgui.h"
|
||||
|
||||
class LuaEditorWindow {
|
||||
public:
|
||||
LuaEditorWindow();
|
||||
~LuaEditorWindow() = default;
|
||||
|
||||
void Show(); // Renders the Lua editor window
|
||||
void SetText(const std::string& text); // Sets the editor content
|
||||
std::string GetText() const; // Gets the editor content
|
||||
void Clear(); // Clears the editor content
|
||||
bool LoadFromFile(const std::string& filePath); // Loads content from a file
|
||||
bool SaveToFile(const std::string& filePath); // Saves content to a file
|
||||
|
||||
private:
|
||||
|
||||
std::vector<char> m_EditorContent; // Buffer for the editor's content
|
||||
static constexpr size_t BUFFER_SIZE = 1024 * 16; // 16 KB default size
|
||||
std::string m_FilePath; // Path to the loaded file
|
||||
bool m_ScrollToBottom = false; // Flag to auto-scroll to the bottom
|
||||
};
|
Loading…
Reference in New Issue
Block a user