Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 8 additions & 43 deletions editor/Editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,53 +160,18 @@ void Editor::reloadScriptLib()
[](const auto& e) -> bool { return e.template get<0>().instance == nullptr; }
));

m_listScriptNames = {};
m_listScriptParameters = {};
m_makeScriptInstance = {};

if (m_project.scriptLib().empty())
m_scriptLibHandle.reset();
else
m_scriptLibHandle.reset(dlLoad(m_project.scriptLib().string().c_str()));

if (m_scriptLibHandle == nullptr)
throw std::runtime_error(std::format("unable to load shared lib : {}", m_project.scriptLib().string()));

void* listScriptNamesSym = getSym(m_scriptLibHandle.get(), "listScriptNames");
void* listScriptParametersSym = getSym(m_scriptLibHandle.get(), "listScriptParameters");
void* makeScriptInstanceSym = getSym(m_scriptLibHandle.get(), "makeScriptInstance");

if (listScriptNamesSym == nullptr || listScriptParametersSym == nullptr || makeScriptInstanceSym == nullptr)
{
m_scriptLibHandle.reset();
throw std::runtime_error(std::format("unable to get symbols in lib : {}", m_project.scriptLib().string()));
m_listScriptNames = {};
m_listScriptParameters = {};
m_makeScriptInstance = {};
return;
}

m_listScriptNames = [listScriptNamesSym]() -> std::vector<std::string> {
const char** names = nullptr;
unsigned long count = 0;
reinterpret_cast<GE::ListScriptNamesFn>(listScriptNamesSym)(&names, &count);
std::vector<std::string> output;
for (unsigned long i = 0; i < count; i++)
if (names[i] != nullptr)
output.emplace_back(names[i]);
return output;
};

m_listScriptParameters = [listScriptParametersSym](const std::string& name) -> std::vector<GE::ScriptParameterDescriptor> {
const GE::ScriptParameterDescriptor* parameters = nullptr;
unsigned long count = 0;
reinterpret_cast<GE::ListScriptParametersFn>(listScriptParametersSym)(name.c_str(), &parameters, &count);
std::vector<GE::ScriptParameterDescriptor> output;
output.reserve(count);
for (unsigned long i = 0; i < count; i++)
output.emplace_back(parameters[i]);
return output;
};

m_makeScriptInstance = [makeScriptInstanceSym](const std::string& name) -> std::shared_ptr<GE::Script> {
return std::shared_ptr<GE::Script>(reinterpret_cast<GE::MakeScriptInstanceFn>(makeScriptInstanceSym)(name.c_str()));
};
GE::ScriptLibraryManager manager(m_project.scriptLib());
m_listScriptNames = manager.listScriptNamesFunction();
m_listScriptParameters = manager.listScriptParametersFunction();
m_makeScriptInstance = manager.makeScriptInstanceFunction();
}

void Editor::startGame()
Expand Down
28 changes: 5 additions & 23 deletions editor/Editor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,15 @@
#include <Game-Engine/FrameGraph.hpp>
#include <Game-Engine/InputContext.hpp>
#include <Game-Engine/Input.hpp>
#include <Game-Engine/Script.hpp>
#include <Game-Engine/ScriptLibraryManager.hpp>
#include <Game-Engine/Scene.hpp>

#include <dlLoad/dlLoad.h>

#include <imgui.h>

#include <cstdint>
#include <filesystem>
#include <memory>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include <functional>

namespace GE_Editor
{
Expand All @@ -53,16 +46,6 @@ class Editor : public GE::Application
~Editor() override = default;

private:
struct DlHandleDeleter
{
void operator()(DlHandle handle) const
{
if (handle != nullptr)
dlFree(handle);
}
};
using UniqueDlHandle = std::unique_ptr<std::remove_pointer_t<DlHandle>, DlHandleDeleter>;

void loadProject(const std::filesystem::path&);
void saveEditedScene();
void saveProject();
Expand All @@ -76,11 +59,6 @@ class Editor : public GE::Application
void rebuildFrameGraph();
void renderImgui();

UniqueDlHandle m_scriptLibHandle; // need to be before m_edited scene so it is destroyed after
std::function<std::vector<std::string>()> m_listScriptNames;
std::function<std::vector<GE::ScriptParameterDescriptor>(const std::string&)> m_listScriptParameters;
std::function<std::shared_ptr<GE::Script>(const std::string&)> m_makeScriptInstance;

std::filesystem::path m_projectFilePath;
Project m_project;

Expand All @@ -97,6 +75,10 @@ class Editor : public GE::Application
std::pair<uint32_t, uint32_t> m_viewportSize = {0, 0};
GE::FrameGraph m_frameGraph; // TODO move into render (something like render->setGraph())

GE::ListScriptNamesFn m_listScriptNames;
GE::ListScriptParametersFn m_listScriptParameters;
GE::MakeScriptInstanceFn m_makeScriptInstance;

public:
Editor& operator=(const Editor&) = delete;
Editor& operator=(Editor&&) = delete;
Expand Down
13 changes: 8 additions & 5 deletions editor/UI/EntityInspectorPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <Game-Engine/Components.hpp>
#include <Game-Engine/ECSWorld.hpp>
#include <Game-Engine/Entity.hpp>
#include <Game-Engine/Script.hpp>
#include <Game-Engine/ScriptLibraryManager.hpp>

#include <imgui.h>

Expand Down Expand Up @@ -92,19 +92,22 @@ template<>
void EntityInspectorPanel::componentEditWidget<GE::ScriptComponent>()
{
GE::ScriptComponent& scriptComponent = m_entity.get<GE::ScriptComponent>();
if (!m_listScriptNames || !m_listScriptParameters)
{
ImGui::TextDisabled("No script library loaded");
return;
}

const char* previewValue = scriptComponent.name.empty() ? "none" : scriptComponent.name.c_str();
if (ImGui::BeginCombo("Script##ScriptComponent_name", previewValue))
{
assert(m_listScriptNames);
for (const std::string& scriptName : m_listScriptNames())
{
const bool isSelected = scriptComponent.name == scriptName;
if (ImGui::Selectable(scriptName.c_str(), isSelected))
{
scriptComponent.name = scriptName;
scriptComponent.parameters.clear();
assert(m_listScriptParameters);
for (const GE::ScriptParameterDescriptor& parameter : m_listScriptParameters(scriptName))
{
auto [parameterIt, inserted] = scriptComponent.parameters.try_emplace(parameter.name, parameter.defaultValue);
Expand Down Expand Up @@ -150,8 +153,8 @@ void EntityInspectorPanel::componentEditWidget<GE::ScriptComponent>()

EntityInspectorPanel::EntityInspectorPanel(
const GE::Entity& entity,
std::function<std::vector<std::string>()> listScriptNames,
std::function<std::vector<GE::ScriptParameterDescriptor>(const std::string&)> listScriptParameters
GE::ListScriptNamesFn listScriptNames,
GE::ListScriptParametersFn listScriptParameters
)
: m_entity(entity)
, m_listScriptNames(std::move(listScriptNames))
Expand Down
13 changes: 6 additions & 7 deletions editor/UI/EntityInspectorPanel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@
#define ENTITYINSPECTORPANEL_HPP

#include <Game-Engine/Entity.hpp>
#include <Game-Engine/Script.hpp>
#include <Game-Engine/ScriptLibraryManager.hpp>

#include <functional>
#include <string>
#include <vector>

namespace GE_Editor
{
Expand All @@ -28,8 +27,8 @@ class EntityInspectorPanel

EntityInspectorPanel(
const GE::Entity& entity,
std::function<std::vector<std::string>()> listScriptNames,
std::function<std::vector<GE::ScriptParameterDescriptor>(const std::string&)> listScriptParameters
GE::ListScriptNamesFn listScriptNames,
GE::ListScriptParametersFn listScriptParameters
);

EntityInspectorPanel& onEntityDelete(std::function<void()>&& f) { return m_onEntityDelete = std::move(f), *this; }
Expand All @@ -44,8 +43,8 @@ class EntityInspectorPanel
void addComponentPopUp();

GE::Entity m_entity;
std::function<std::vector<std::string>()> m_listScriptNames;
std::function<std::vector<GE::ScriptParameterDescriptor>(const std::string&)> m_listScriptParameters;
GE::ListScriptNamesFn m_listScriptNames;
GE::ListScriptParametersFn m_listScriptParameters;

std::function<void()> m_onEntityDelete;

Expand Down
13 changes: 5 additions & 8 deletions include/Game-Engine/Game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,10 @@
#include "Game-Engine/InputContext.hpp"
#include "Game-Engine/Scene.hpp"
#include "Game-Engine/AssetManager.hpp"
#include "Game-Engine/Script.hpp"
#include "Game-Engine/ScriptLibraryManager.hpp"

#include <map>
#include <memory>
#include <string>
#include <functional>
#include <vector>

namespace GE
{
Expand All @@ -41,8 +38,8 @@ class GE_API Game

Game(
AssetManager* assetManager,
std::function<std::shared_ptr<GE::Script>(const std::string&)> makeScriptInstance,
std::function<std::vector<GE::ScriptParameterDescriptor>(const std::string&)> listScriptParameters,
MakeScriptInstanceFn makeScriptInstance,
ListScriptParametersFn listScriptParameters,
const Descriptor& descriptor
);

Expand All @@ -54,8 +51,8 @@ class GE_API Game
~Game();

private:
std::function<std::shared_ptr<GE::Script>(const std::string&)> m_makeScriptInstance;
std::function<std::vector<GE::ScriptParameterDescriptor>(const std::string&)> m_listScriptParameters;
MakeScriptInstanceFn m_makeScriptInstance;
ListScriptParametersFn m_listScriptParameters;
std::map<std::string, Scene> m_scenes;
Scene* m_activeScene = nullptr;
InputContext m_inputContext;
Expand Down
4 changes: 0 additions & 4 deletions include/Game-Engine/Script.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ class GE_API Script
template<typename T>
concept ScriptClass = std::derived_from<T, Script>;

using MakeScriptInstanceFn = Script* (*)(const char*);
using ListScriptNamesFn = void (*)(const char***, unsigned long*);
using ListScriptParametersFn = void (*)(const char*, const ScriptParameterDescriptor**, unsigned long*);

class GE_API ScriptRegistry
{
public:
Expand Down
60 changes: 60 additions & 0 deletions include/Game-Engine/ScriptLibraryManager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* ---------------------------------------------------
* ScriptLibraryManager.hpp
*
* Author: Thomas Choquet <thomas.publique@icloud.com>
* ---------------------------------------------------
*/

#ifndef SCRIPT_LIBRARY_MANAGER_HPP
#define SCRIPT_LIBRARY_MANAGER_HPP

#include "Game-Engine/Export.hpp"
#include "Game-Engine/Script.hpp"

#include <filesystem>
#include <functional>
#include <memory>
#include <string>
#include <vector>

namespace GE
{


using ListScriptNamesFn = std::function<std::vector<std::string>()>;
using ListScriptParametersFn = std::function<std::vector<ScriptParameterDescriptor>(const std::string&)>;
using MakeScriptInstanceFn = std::function<std::shared_ptr<Script>(const std::string&)>;

class GE_API ScriptLibraryManager
{
public:

ScriptLibraryManager(const std::filesystem::path& path);
ScriptLibraryManager(const ScriptLibraryManager&) = delete;
ScriptLibraryManager(ScriptLibraryManager&&) = default;

ListScriptNamesFn listScriptNamesFunction() const;
ListScriptParametersFn listScriptParametersFunction() const;
MakeScriptInstanceFn makeScriptInstanceFunction() const;

~ScriptLibraryManager();

ScriptLibraryManager& operator=(const ScriptLibraryManager&) = delete;
ScriptLibraryManager& operator=(ScriptLibraryManager&&) = default;

private:
using MakeScriptInstanceSym = Script* (*)(const char*);
using ListScriptNamesSym = void (*)(const char***, unsigned long*);
using ListScriptParametersSym = void (*)(const char*, const ScriptParameterDescriptor**, unsigned long*);

std::shared_ptr<void> m_libraryHandle;

ListScriptNamesSym m_listScriptNames = nullptr;
ListScriptParametersSym m_listScriptParameters = nullptr;
MakeScriptInstanceSym m_makeScriptInstance = nullptr;
};

} // namespace GE

#endif // SCRIPT_LIBRARY_MANAGER_HPP
15 changes: 9 additions & 6 deletions src/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@
*/

#include "Game-Engine/Game.hpp"
#include "Game-Engine/ScriptLibraryManager.hpp"
#include "Game-Engine/ECSView.hpp"
#include "Game-Engine/Scene.hpp"
#include "Game-Engine/AssetManager.hpp"

#include <format>
#include <cassert>
#include <ranges>
#include <stdexcept>
#include <utility>

namespace GE
Expand All @@ -24,17 +27,17 @@ namespace
void setupScene(
Game& game,
Scene& scene,
const std::function<std::shared_ptr<Script>(const std::string&)>& makeScriptInstance,
const std::function<std::vector<ScriptParameterDescriptor>(const std::string&)>& listScriptParameters
const MakeScriptInstanceFn& makeScriptInstance,
const ListScriptParametersFn& listScriptParameters
)
{
scene.load();
for (Entity entity : scene.ecsWorld()
| ECSView<ScriptComponent>()
| std::views::transform([&](auto id) { return Entity{ &scene.ecsWorld(), id }; }))
{
assert(makeScriptInstance);
assert(listScriptParameters);
if (!makeScriptInstance || !listScriptParameters)
throw std::runtime_error(std::format("unable to create script '{}' without a loaded script library", entity.get<ScriptComponent>().name));
ScriptComponent& scriptComponent = entity.get<ScriptComponent>();
scriptComponent.instance = makeScriptInstance(scriptComponent.name);
assert(scriptComponent.instance);
Expand Down Expand Up @@ -65,8 +68,8 @@ void tearDownScene(Game& game, Scene& scene)

Game::Game(
AssetManager* assetManager,
std::function<std::shared_ptr<Script>(const std::string&)> makeScriptInstance,
std::function<std::vector<ScriptParameterDescriptor>(const std::string&)> listScriptParameters,
MakeScriptInstanceFn makeScriptInstance,
ListScriptParametersFn listScriptParameters,
const Descriptor& descriptor
)
: m_makeScriptInstance(std::move(makeScriptInstance))
Expand Down
Loading