Major - Adds Lua scripting component support - V14.0.0

Adds a Lua scripting component to the engine, allowing users to attach Lua scripts to entities.

Includes necessary Lua headers and library files.

Also integrates the Lua scripting component into the editor, allowing it to be added via ImGui.
This commit is contained in:
2025-09-17 23:20:50 +02:00
parent 76fdd3c76e
commit f3039f22ed
16 changed files with 1764 additions and 62 deletions

View File

@@ -9,6 +9,7 @@
#include "component.h"
#include "components/audio_component.h"
#include "components/identity_component.h"
#include "components/lua_script_component.h"
#include "components/render_component.h"
#include "components/transform_component.h"
#include "components/physics_component.h"
@@ -52,5 +53,6 @@ inline void EnregistrerTousLesComposants() {
factory.EnregistrerComposant<ecs::IdentityComponent>("IdentityComponent");
factory.EnregistrerComposant<ecs::RenderComponent>("RenderComponent");
factory.EnregistrerComposant<ecs::AudioComponent>("AudioComponent");
factory.EnregistrerComposant<ecs::LuaScriptComponent>("LuaScriptComponent");
// Ajouter d'autres composants ici
}

View File

@@ -0,0 +1,100 @@
#pragma once
#include "../component.h"
#include "Lua/lua.hpp"
#include <string>
#include <fstream>
#include <sstream>
#include <imgui.h>
#include <filesystem>
namespace ecs {
class LuaScriptComponent : public Component {
public:
LuaScriptComponent() : scriptCreated(false), popupOpen(true) {
L = luaL_newstate();
luaL_openlibs(L);
}
~LuaScriptComponent() override {
if (L) {
lua_close(L);
L = nullptr;
}
}
void OnImGuiRender() override {
if (popupOpen) {
ImGui::OpenPopup("Nouveau Script Lua");
if (ImGui::BeginPopupModal("Nouveau Script Lua", NULL, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::InputText("Nom du Script", scriptNameBuffer, sizeof(scriptNameBuffer));
if (ImGui::Button("Annuler")) {
scriptCreated = false;
popupOpen = false;
// Signal pour retirer ce component (<28> g<>rer par l'entity)
}
ImGui::SameLine();
if (ImGui::Button("Valider")) {
if (CreateScriptFile()) {
scriptCreated = true;
popupOpen = false;
} else {
// Gestion d'erreur possible (imprimer popup message)
}
}
ImGui::EndPopup();
}
}
if (scriptCreated) {
ImGui::TextWrapped("Script associe: %s", scriptName.c_str());
}
}
bool HasScript() const { return scriptCreated; }
const std::string& GetScriptName() const { return scriptName; }
private:
lua_State* L = nullptr;
char scriptNameBuffer[128] = {0};
std::string scriptName;
bool scriptCreated = false;
bool popupOpen = false;
bool CreateScriptFile() {
if (strlen(scriptNameBuffer) == 0)
return false;
scriptName = scriptNameBuffer;
if (scriptName.length() < 4 || scriptName.substr(scriptName.length() - 4) != ".lua") {
scriptName += ".lua";
}
// Dossier standard des scripts
std::string execFolder = std::filesystem::current_path().string();
std::string scriptFolder = execFolder + "/assets/Script/";
// Cr<43>er dossiers s'ils manquent
std::error_code ec;
std::filesystem::create_directories(scriptFolder, ec);
if (ec) {
// Log erreur
return false;
}
std::string fullPath = scriptFolder + scriptName;
// Cr<43>er un fichier script vide ou template simple
std::ofstream ofs(fullPath);
if (!ofs) return false;
ofs << "-- Script Lua vide pour ECS\n\nfunction on_update(dt)\n -- Code ici\nend\n";
ofs.close();
return true;
}
};
} // namespace ecs

View File

@@ -31,6 +31,11 @@ struct widget_entry
std::function<void()> func;
};
struct ComponentEntry {
const char* name;
std::function<void()> addFunc;
};
class imguiManager
{
public:

View File

@@ -555,64 +555,33 @@ void imguiManager::WidgetInspectorWindow()
}
ImGui::SameLine();
if (ImGui::Button("Add Component"))
{
if (ImGui::Button("Add Component")) {
ImGui::OpenPopup("AddComponentPopup");
}
if (ImGui::BeginPopup("AddComponentPopup"))
{
if (ImGui::BeginPopup("AddComponentPopup")) {
ImGui::Text("Select Component to Add:");
ImGui::Separator();
if (ImGui::MenuItem("Transform Component"))
{
if (!entity->HasComponent<ecs::TransformComponent>())
{
entity->AddComponent<ecs::TransformComponent>();
ComponentEntry componentsEntry[] = {
{"Transform Component", [&]() { if (!entity->HasComponent<ecs::TransformComponent>()) entity->AddComponent<ecs::TransformComponent>(); }},
{"Model Path Component", [&]() { if (!entity->HasComponent<ecs::ModelPathComponent>()) entity->AddComponent<ecs::ModelPathComponent>(); }},
{"Audio Component", [&]() { if (!entity->HasComponent<ecs::AudioComponent>()) entity->AddComponent<ecs::AudioComponent>(); }},
{"Physics Component", [&]() { if (!entity->HasComponent<ecs::PhysicsComponent>()) entity->AddComponent<ecs::PhysicsComponent>(); }},
{"Render Component", [&]() { if (!entity->HasComponent<ecs::RenderComponent>()) entity->AddComponent<ecs::RenderComponent>(); }},
{"Shader Component", [&]() { if (!entity->HasComponent<ecs::ShaderComponent>()) entity->AddComponent<ecs::ShaderComponent>(); }},
{"Lua Script Component", [&]() { if (!entity->HasComponent<ecs::LuaScriptComponent>()) entity->AddComponent<ecs::LuaScriptComponent>(); }},
{"Identity Component", [&]() { if (!entity->HasComponent<ecs::IdentityComponent>()) entity->AddComponent<ecs::IdentityComponent>(); }}
// Ajouter d'autres composants ici
};
for (auto& comp : componentsEntry) {
if (ImGui::MenuItem(comp.name)) {
comp.addFunc();
ImGui::CloseCurrentPopup();
}
ImGui::CloseCurrentPopup();
}
if (ImGui::MenuItem("Model Path Component"))
{
if (!entity->HasComponent<ecs::ModelPathComponent>())
{
entity->AddComponent<ecs::ModelPathComponent>();
}
ImGui::CloseCurrentPopup();
}
if (ImGui::MenuItem("Audio Component"))
{
if (!entity->HasComponent<ecs::AudioComponent>())
{
entity->AddComponent<ecs::AudioComponent>();
}
ImGui::CloseCurrentPopup();
}
if (ImGui::MenuItem("Physics Component"))
{
if (!entity->HasComponent<ecs::PhysicsComponent>())
{
entity->AddComponent<ecs::PhysicsComponent>();
}
ImGui::CloseCurrentPopup();
}
if (ImGui::MenuItem("Render Component"))
{
if (!entity->HasComponent<ecs::RenderComponent>())
{
entity->AddComponent<ecs::RenderComponent>();
}
ImGui::CloseCurrentPopup();
}
if (ImGui::MenuItem("Shader Component"))
{
if (!entity->HasComponent<ecs::ShaderComponent>())
{
entity->AddComponent<ecs::ShaderComponent>();
}
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}