Compare commits
4 Commits
cd0d7bfea0
...
a012aff7f8
Author | SHA1 | Date |
---|---|---|
bog | a012aff7f8 | |
bog | 49aa9be3dd | |
bog | aacc650741 | |
bog | 1b72ba842c |
|
@ -29,6 +29,11 @@ executable('d2d',
|
||||||
'src/Game.cpp',
|
'src/Game.cpp',
|
||||||
'src/Scene.cpp',
|
'src/Scene.cpp',
|
||||||
|
|
||||||
|
# ecs
|
||||||
|
'src/ECS.cpp',
|
||||||
|
'src/BaseComponent.cpp',
|
||||||
|
'src/BaseSystem.cpp',
|
||||||
|
|
||||||
# graphics
|
# graphics
|
||||||
'src/Shader.cpp',
|
'src/Shader.cpp',
|
||||||
'src/Shape.cpp',
|
'src/Shape.cpp',
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
#include "BaseComponent.hpp"
|
||||||
|
|
||||||
|
namespace d2
|
||||||
|
{
|
||||||
|
/*explicit*/ BaseComponent::BaseComponent(size_t id)
|
||||||
|
: m_id { id }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ BaseComponent::~BaseComponent()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef d2_BASECOMPONENT_HPP
|
||||||
|
#define d2_BASECOMPONENT_HPP
|
||||||
|
|
||||||
|
#include "commons.hpp"
|
||||||
|
|
||||||
|
namespace d2
|
||||||
|
{
|
||||||
|
class BaseComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit BaseComponent(size_t id);
|
||||||
|
virtual ~BaseComponent();
|
||||||
|
|
||||||
|
size_t id() const { return m_id; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t m_id;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,19 @@
|
||||||
|
#include "BaseSystem.hpp"
|
||||||
|
|
||||||
|
namespace d2
|
||||||
|
{
|
||||||
|
/*explicit*/ BaseSystem::BaseSystem(size_t id)
|
||||||
|
: m_id { id }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ BaseSystem::~BaseSystem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BaseSystem::add_signature(BaseComponent const& component)
|
||||||
|
{
|
||||||
|
m_signature |= (1 << component.id());
|
||||||
|
return m_signature;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef d2_BASESYSTEM_HPP
|
||||||
|
#define d2_BASESYSTEM_HPP
|
||||||
|
|
||||||
|
#include "commons.hpp"
|
||||||
|
#include "src/BaseComponent.hpp"
|
||||||
|
|
||||||
|
namespace d2
|
||||||
|
{
|
||||||
|
class BaseSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit BaseSystem(size_t id);
|
||||||
|
virtual ~BaseSystem();
|
||||||
|
|
||||||
|
size_t id() const { return m_id; }
|
||||||
|
size_t signature() const { return m_signature; }
|
||||||
|
size_t add_signature(BaseComponent const& component);
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t m_id = 0;
|
||||||
|
size_t m_signature = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,59 @@
|
||||||
|
#include "ECS.hpp"
|
||||||
|
|
||||||
|
namespace d2
|
||||||
|
{
|
||||||
|
/*explicit*/ ECS::ECS()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ ECS::~ECS()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ECS::spawn(std::vector<std::unique_ptr<BaseComponent>>& components)
|
||||||
|
{
|
||||||
|
size_t entity = m_entity_counter;
|
||||||
|
|
||||||
|
for (auto& component: components)
|
||||||
|
{
|
||||||
|
m_entities[entity][component->id()] = std::move(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_entity_counter++;
|
||||||
|
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseComponent const& ECS::getc(size_t entity,
|
||||||
|
size_t component) const
|
||||||
|
{
|
||||||
|
return *m_entities.at(entity).at(component).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseComponent& ECS::getc(size_t entity,
|
||||||
|
size_t component)
|
||||||
|
{
|
||||||
|
return *m_entities.at(entity).at(component).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ECS::esig(size_t entity) const
|
||||||
|
{
|
||||||
|
size_t sig = 0;
|
||||||
|
|
||||||
|
for (size_t i=0; i<MAX_COMPONENTS; i++)
|
||||||
|
{
|
||||||
|
if (m_entities[entity][i] != nullptr)
|
||||||
|
{
|
||||||
|
sig |= (1 << m_entities[entity][i]->id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ECS::sig_match(size_t system_signature,
|
||||||
|
size_t entity_signature) const
|
||||||
|
{
|
||||||
|
return (system_signature & entity_signature) == system_signature;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef d2_ECS_HPP
|
||||||
|
#define d2_ECS_HPP
|
||||||
|
|
||||||
|
#include "commons.hpp"
|
||||||
|
#include "BaseComponent.hpp"
|
||||||
|
|
||||||
|
namespace d2
|
||||||
|
{
|
||||||
|
constexpr size_t MAX_ENTITIES = 1024;
|
||||||
|
constexpr size_t MAX_COMPONENTS = 256;
|
||||||
|
|
||||||
|
class ECS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ECS();
|
||||||
|
virtual ~ECS();
|
||||||
|
|
||||||
|
size_t spawn(std::vector<std::unique_ptr<BaseComponent>>& components);
|
||||||
|
|
||||||
|
size_t entity_count() const { return m_entity_counter; }
|
||||||
|
|
||||||
|
BaseComponent const& getc(size_t entity,
|
||||||
|
size_t component) const;
|
||||||
|
|
||||||
|
BaseComponent& getc(size_t entity,
|
||||||
|
size_t component);
|
||||||
|
|
||||||
|
size_t esig(size_t entity) const;
|
||||||
|
bool sig_match(size_t system_signature,
|
||||||
|
size_t entity_signature) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t m_entity_counter = 0;
|
||||||
|
std::array<std::array<std::unique_ptr<BaseComponent>,
|
||||||
|
MAX_COMPONENTS>,
|
||||||
|
MAX_ENTITIES> m_entities;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
74
src/Game.cpp
74
src/Game.cpp
|
@ -1,5 +1,7 @@
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include "Game.hpp"
|
#include "Game.hpp"
|
||||||
|
#include "SDL_events.h"
|
||||||
|
#include "SDL_keyboard.h"
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
namespace d2
|
namespace d2
|
||||||
|
@ -105,4 +107,76 @@ namespace d2
|
||||||
m_scenes.pop_back();
|
m_scenes.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Game::is_key_pressed(std::string const& keyname) const
|
||||||
|
{
|
||||||
|
SDL_Keycode key = SDL_GetKeyFromName(keyname.c_str());
|
||||||
|
SDL_Scancode scan = SDL_GetScancodeFromKey(key);
|
||||||
|
Uint8 const* keys = SDL_GetKeyboardState(nullptr);
|
||||||
|
|
||||||
|
return keys[scan];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Game::is_key_just_pressed(std::string const& keyname) const
|
||||||
|
{
|
||||||
|
static bool prev = false;
|
||||||
|
|
||||||
|
bool pressed = is_key_pressed(keyname);
|
||||||
|
|
||||||
|
if (pressed != prev)
|
||||||
|
{
|
||||||
|
prev = pressed;
|
||||||
|
return pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Game::is_mouse_pressed(std::string const& btn_name) const
|
||||||
|
{
|
||||||
|
Uint32 btns = SDL_GetMouseState(nullptr, nullptr);
|
||||||
|
|
||||||
|
if (btn_name == "left")
|
||||||
|
{
|
||||||
|
return btns & SDL_BUTTON(SDL_BUTTON_LEFT);
|
||||||
|
}
|
||||||
|
else if (btn_name == "middle")
|
||||||
|
{
|
||||||
|
return btns & SDL_BUTTON(SDL_BUTTON_MIDDLE);
|
||||||
|
}
|
||||||
|
else if (btn_name == "right")
|
||||||
|
{
|
||||||
|
return btns & SDL_BUTTON(SDL_BUTTON_RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw game_error {"Unknown mosue button '" + btn_name + "'."};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Game::is_mouse_just_pressed(std::string const& btn_name) const
|
||||||
|
{
|
||||||
|
static bool prev = false;
|
||||||
|
bool new_val = is_mouse_pressed(btn_name);
|
||||||
|
|
||||||
|
if (new_val != prev)
|
||||||
|
{
|
||||||
|
prev = new_val;
|
||||||
|
return new_val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Game::mouse_x() const
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
SDL_GetMouseState(&x, nullptr);
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Game::mouse_y() const
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
SDL_GetMouseState(nullptr, &y);
|
||||||
|
return y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
13
src/Game.hpp
13
src/Game.hpp
|
@ -5,6 +5,7 @@
|
||||||
#include "commons.hpp"
|
#include "commons.hpp"
|
||||||
#include "Renderer.hpp"
|
#include "Renderer.hpp"
|
||||||
#include "Scene.hpp"
|
#include "Scene.hpp"
|
||||||
|
#include "ECS.hpp"
|
||||||
|
|
||||||
namespace d2
|
namespace d2
|
||||||
{
|
{
|
||||||
|
@ -18,6 +19,9 @@ namespace d2
|
||||||
unsigned height);
|
unsigned height);
|
||||||
virtual ~Game();
|
virtual ~Game();
|
||||||
|
|
||||||
|
ECS const& ecs() const { return m_ecs; }
|
||||||
|
ECS& ecs() { return m_ecs; }
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
void queue_draw(std::unique_ptr<Object> obj);
|
void queue_draw(std::unique_ptr<Object> obj);
|
||||||
|
|
||||||
|
@ -25,12 +29,21 @@ namespace d2
|
||||||
void push(Args... args);
|
void push(Args... args);
|
||||||
void pop();
|
void pop();
|
||||||
|
|
||||||
|
bool is_key_pressed(std::string const& keyname) const;
|
||||||
|
bool is_key_just_pressed(std::string const& keyname) const;
|
||||||
|
|
||||||
|
bool is_mouse_pressed(std::string const& btn_name) const;
|
||||||
|
bool is_mouse_just_pressed(std::string const& btn_name) const;
|
||||||
|
int mouse_x() const;
|
||||||
|
int mouse_y() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_Window* m_window = nullptr;
|
SDL_Window* m_window = nullptr;
|
||||||
SDL_GLContext m_context;
|
SDL_GLContext m_context;
|
||||||
std::unique_ptr<Renderer> m_renderer;
|
std::unique_ptr<Renderer> m_renderer;
|
||||||
std::vector<std::unique_ptr<Object>> m_draw_queue;
|
std::vector<std::unique_ptr<Object>> m_draw_queue;
|
||||||
std::vector<std::unique_ptr<Scene>> m_scenes;
|
std::vector<std::unique_ptr<Scene>> m_scenes;
|
||||||
|
ECS m_ecs;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
|
|
321
src/Script.cpp
321
src/Script.cpp
|
@ -1,15 +1,37 @@
|
||||||
#include "Script.hpp"
|
#include "Script.hpp"
|
||||||
|
#include "libguile/list.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace d2
|
namespace d2
|
||||||
{
|
{
|
||||||
|
// Script
|
||||||
|
// ------
|
||||||
|
|
||||||
/*static*/ std::unique_ptr<Game> Script::game = nullptr;
|
/*static*/ std::unique_ptr<Game> Script::game = nullptr;
|
||||||
/*static*/ glm::vec4 Script::color = {0.0f, 0.0f, 0.0f, 255.0f};
|
/*static*/ glm::vec4 Script::color = {0.0f, 0.0f, 0.0f, 255.0f};
|
||||||
|
|
||||||
|
// ECS
|
||||||
|
// ----
|
||||||
|
|
||||||
|
/*static*/ std::unordered_map<size_t, std::unique_ptr<ScriptComponent>>
|
||||||
|
ScriptComponent::components;
|
||||||
|
|
||||||
|
/*static*/ size_t ScriptSystem::system_id = 0;
|
||||||
|
/*static*/ std::unordered_map<size_t, std::unique_ptr<ScriptSystem>>
|
||||||
|
ScriptSystem::systems;
|
||||||
|
|
||||||
|
/*static*/ size_t ScriptComponent::comp_id = 0;
|
||||||
|
|
||||||
/*static*/ void Script::init()
|
/*static*/ void Script::init()
|
||||||
{
|
{
|
||||||
scm_init_guile();
|
scm_init_guile();
|
||||||
scm_c_define_gsubr("winconf", 3, 0, 0,
|
scm_c_define_gsubr("winconf", 3, 0, 0,
|
||||||
reinterpret_cast<void*>(&fn_winconf));
|
reinterpret_cast<void*>(&fn_winconf));
|
||||||
|
// Drawing
|
||||||
|
// -------
|
||||||
|
scm_c_define_gsubr("rect", 4, 0, 0, reinterpret_cast<void*>(&fn_rect));
|
||||||
|
scm_c_define_gsubr("color!", 4, 0, 0,
|
||||||
|
reinterpret_cast<void*>(&fn_set_color));
|
||||||
|
|
||||||
// Scenes
|
// Scenes
|
||||||
// ------
|
// ------
|
||||||
|
@ -19,11 +41,44 @@ namespace d2
|
||||||
scm_c_define_gsubr("scene:pop", 0, 0, 0,
|
scm_c_define_gsubr("scene:pop", 0, 0, 0,
|
||||||
reinterpret_cast<void*>(&fn_scene__pop));
|
reinterpret_cast<void*>(&fn_scene__pop));
|
||||||
|
|
||||||
// Drawing
|
// Inputs
|
||||||
// -------
|
// ------
|
||||||
scm_c_define_gsubr("rect", 4, 0, 0, reinterpret_cast<void*>(&fn_rect));
|
scm_c_define_gsubr("pressed?", 2, 0, 0,
|
||||||
scm_c_define_gsubr("color!", 4, 0, 0,
|
reinterpret_cast<void*>(&fn_is_pressed));
|
||||||
reinterpret_cast<void*>(&fn_set_color));
|
scm_c_define_gsubr("just-pressed?", 2, 0, 0,
|
||||||
|
reinterpret_cast<void*>(&fn_is_just_pressed));
|
||||||
|
|
||||||
|
scm_c_define_gsubr("mouse-x", 0, 0, 0,
|
||||||
|
reinterpret_cast<void*>(&fn_mouse_x));
|
||||||
|
scm_c_define_gsubr("mouse-y", 0, 0, 0,
|
||||||
|
reinterpret_cast<void*>(&fn_mouse_y));
|
||||||
|
|
||||||
|
// Filesystem
|
||||||
|
// ----------
|
||||||
|
scm_c_define_gsubr("rootdir", 0, 0, 1,
|
||||||
|
reinterpret_cast<void*>(&fn_rootdir));
|
||||||
|
|
||||||
|
// ECS
|
||||||
|
// ----------
|
||||||
|
scm_c_define_gsubr("world:system", 0, 0, 1,
|
||||||
|
reinterpret_cast<void*>(&fn_world__system));
|
||||||
|
scm_c_define_gsubr("world:component", 0, 0, 1,
|
||||||
|
reinterpret_cast<void*>(&fn_world__component));
|
||||||
|
scm_c_define_gsubr("world:spawn", 0, 0, 1,
|
||||||
|
reinterpret_cast<void*>(&fn_world__spawn));
|
||||||
|
scm_c_define_gsubr("world:esig", 1, 0, 0,
|
||||||
|
reinterpret_cast<void*>(&fn_world__esig));
|
||||||
|
scm_c_define_gsubr("world:ssig", 1, 0, 0,
|
||||||
|
reinterpret_cast<void*>(&fn_world__ssig));
|
||||||
|
scm_c_define_gsubr("world:getc", 3, 0, 0,
|
||||||
|
reinterpret_cast<void*>(&fn_world__getc));
|
||||||
|
scm_c_define_gsubr("world:setc!", 4, 0, 0,
|
||||||
|
reinterpret_cast<void*>(&fn_world__setc));
|
||||||
|
scm_c_define_gsubr("world:match?", 2, 0, 0,
|
||||||
|
reinterpret_cast<void*>(&fn_world__match));
|
||||||
|
scm_c_define_gsubr("world:process", 1, 0, 0,
|
||||||
|
reinterpret_cast<void*>(&fn_world__process));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ void Script::terminate()
|
/*static*/ void Script::terminate()
|
||||||
|
@ -56,27 +111,7 @@ namespace d2
|
||||||
return SCM_BOOL_T;
|
return SCM_BOOL_T;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ SCM Script::fn_scene__push(SCM scm_function, SCM scm_ctx)
|
/*static*/ SCM Script::fn_rect(SCM scm_x, SCM scm_y, SCM scm_w, SCM scm_h)
|
||||||
{
|
|
||||||
if (scm_is_null(scm_ctx))
|
|
||||||
{
|
|
||||||
Script::game->push<ScriptScene>(scm_function);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Script::game->push<ScriptScene>(scm_function, scm_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SCM_BOOL_T;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*static*/ SCM Script::fn_scene__pop()
|
|
||||||
{
|
|
||||||
Script::game->pop();
|
|
||||||
return SCM_BOOL_T;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*static*/ SCM Script::fn_rect(SCM scm_x, SCM scm_y, SCM scm_w, SCM scm_h)
|
|
||||||
{
|
{
|
||||||
float x = scm_to_double(scm_x);
|
float x = scm_to_double(scm_x);
|
||||||
float y = scm_to_double(scm_y);
|
float y = scm_to_double(scm_y);
|
||||||
|
@ -116,4 +151,238 @@ namespace d2
|
||||||
|
|
||||||
return SCM_BOOL_T;
|
return SCM_BOOL_T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_scene__push(SCM scm_function, SCM scm_ctx)
|
||||||
|
{
|
||||||
|
if (scm_is_null(scm_ctx))
|
||||||
|
{
|
||||||
|
Script::game->push<ScriptScene>(scm_function);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Script::game->push<ScriptScene>(scm_function, scm_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SCM_BOOL_T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_scene__pop()
|
||||||
|
{
|
||||||
|
Script::game->pop();
|
||||||
|
return SCM_BOOL_T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_is_pressed(SCM scm_device, SCM scm_keyname)
|
||||||
|
{
|
||||||
|
std::string device =
|
||||||
|
scm_to_locale_string(scm_symbol_to_string(scm_device));
|
||||||
|
std::string keyname = scm_to_locale_string(scm_keyname);
|
||||||
|
|
||||||
|
if (device == "key")
|
||||||
|
{
|
||||||
|
bool result = Script::game->is_key_pressed(keyname);
|
||||||
|
return scm_from_bool(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device == "mouse")
|
||||||
|
{
|
||||||
|
bool result = Script::game->is_mouse_pressed(keyname);
|
||||||
|
return scm_from_bool(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw script_error {"Unknown device '" + device + "'."};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_is_just_pressed(SCM scm_device, SCM scm_keyname)
|
||||||
|
{
|
||||||
|
std::string device =
|
||||||
|
scm_to_locale_string(scm_symbol_to_string(scm_device));
|
||||||
|
std::string keyname = scm_to_locale_string(scm_keyname);
|
||||||
|
|
||||||
|
if (device == "key")
|
||||||
|
{
|
||||||
|
bool result = Script::game->is_key_just_pressed(keyname);
|
||||||
|
return scm_from_bool(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device == "mouse")
|
||||||
|
{
|
||||||
|
bool result = Script::game->is_mouse_just_pressed(keyname);
|
||||||
|
return scm_from_bool(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw script_error {"Unknown device '" + device + "'."};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_mouse_x()
|
||||||
|
{
|
||||||
|
return scm_from_int32(Script::game->mouse_x());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_mouse_y()
|
||||||
|
{
|
||||||
|
return scm_from_int32(Script::game->mouse_y());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_rootdir(SCM scm_args)
|
||||||
|
{
|
||||||
|
std::filesystem::path path =
|
||||||
|
std::filesystem::current_path();
|
||||||
|
|
||||||
|
size_t sz = scm_to_int32(scm_length(scm_args));
|
||||||
|
|
||||||
|
for (size_t i=0; i<sz; i++)
|
||||||
|
{
|
||||||
|
SCM scm_value = scm_list_ref(scm_args, scm_from_uint64(i));
|
||||||
|
auto value = scm_to_locale_string(scm_value);
|
||||||
|
path = path / value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scm_from_locale_string(path.string().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_world__system(SCM scm_args)
|
||||||
|
{
|
||||||
|
size_t len = scm_to_uint64(scm_length(scm_args));
|
||||||
|
SCM function = scm_list_ref(scm_args, scm_from_uint64(0));
|
||||||
|
auto system = std::make_unique<ScriptSystem>(function);
|
||||||
|
|
||||||
|
for (size_t i=1; i<len; i++)
|
||||||
|
{
|
||||||
|
SCM scm_value = scm_list_ref(scm_args, scm_from_uint64(i));
|
||||||
|
size_t value = scm_to_uint64(scm_value);
|
||||||
|
system->add_signature(*ScriptComponent::components[value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t id = system->id();
|
||||||
|
ScriptSystem::systems[id] = std::move(system);
|
||||||
|
|
||||||
|
return scm_from_uint64(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_world__component(SCM scm_args)
|
||||||
|
{
|
||||||
|
auto component =
|
||||||
|
std::make_unique<ScriptComponent>(ScriptComponent::comp_id);
|
||||||
|
ScriptComponent::comp_id++;
|
||||||
|
|
||||||
|
size_t len = scm_to_uint64(scm_length(scm_args));
|
||||||
|
|
||||||
|
for (size_t i=0; i<len; i+=2)
|
||||||
|
{
|
||||||
|
SCM scm_name =
|
||||||
|
scm_symbol_to_string(scm_list_ref(scm_args, scm_from_uint64(i)));
|
||||||
|
|
||||||
|
std::string name = scm_to_locale_string(scm_name);
|
||||||
|
|
||||||
|
SCM value = scm_list_ref(scm_args, scm_from_uint64(i + 1));
|
||||||
|
component->add(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t id = component->id();
|
||||||
|
|
||||||
|
ScriptComponent::components[id] = std::move(component);
|
||||||
|
return scm_from_uint64(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_world__spawn(SCM scm_args)
|
||||||
|
{
|
||||||
|
size_t len = scm_to_uint64(scm_length(scm_args));
|
||||||
|
std::vector<std::unique_ptr<BaseComponent>> comps;
|
||||||
|
|
||||||
|
for (size_t i=0; i<len; i++)
|
||||||
|
{
|
||||||
|
SCM comp_scm = scm_list_ref(scm_args, scm_from_uint64(i));
|
||||||
|
size_t comp = scm_to_uint64(comp_scm);
|
||||||
|
auto& model = ScriptComponent::components[comp];
|
||||||
|
comps.push_back(std::make_unique<ScriptComponent>(*model));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t entity = Script::game->ecs().spawn(comps);
|
||||||
|
|
||||||
|
return scm_from_uint64(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_world__esig(SCM scm_entity)
|
||||||
|
{
|
||||||
|
size_t entity = scm_to_uint64(scm_entity);
|
||||||
|
size_t sig = Script::game->ecs().esig(entity);
|
||||||
|
|
||||||
|
return scm_from_uint64(sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_world__ssig(SCM scm_system)
|
||||||
|
{
|
||||||
|
size_t id = scm_to_uint64(scm_system);
|
||||||
|
auto const& system = ScriptSystem::systems[id];
|
||||||
|
|
||||||
|
size_t signature = system->signature();
|
||||||
|
return scm_from_uint64(signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM
|
||||||
|
Script::fn_world__getc(SCM scm_entity, SCM scm_comp, SCM scm_field)
|
||||||
|
{
|
||||||
|
size_t entity = scm_to_uint64(scm_entity);
|
||||||
|
size_t comp = scm_to_uint64(scm_comp);
|
||||||
|
std::string field =
|
||||||
|
scm_to_locale_string(scm_symbol_to_string(scm_field));
|
||||||
|
|
||||||
|
auto const& component = Script::game->ecs().getc(entity, comp);
|
||||||
|
auto& script_comp = static_cast<ScriptComponent const&>(component);
|
||||||
|
|
||||||
|
if (script_comp.values.find(field) == std::end(script_comp.values))
|
||||||
|
{
|
||||||
|
throw script_error {"Cannot find field '" + field + "'"};
|
||||||
|
}
|
||||||
|
|
||||||
|
return script_comp.values.at(field);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM
|
||||||
|
Script::fn_world__setc(SCM scm_entity, SCM scm_comp, SCM scm_field,
|
||||||
|
SCM scm_value)
|
||||||
|
{
|
||||||
|
size_t entity = scm_to_uint64(scm_entity);
|
||||||
|
size_t comp = scm_to_uint64(scm_comp);
|
||||||
|
std::string field =
|
||||||
|
scm_to_locale_string(scm_symbol_to_string(scm_field));
|
||||||
|
|
||||||
|
auto& component = Script::game->ecs().getc(entity, comp);
|
||||||
|
auto& script_comp = static_cast<ScriptComponent&>(component);
|
||||||
|
|
||||||
|
script_comp.values[field] = scm_value;
|
||||||
|
|
||||||
|
return scm_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_world__match(SCM scm_system, SCM scm_entity)
|
||||||
|
{
|
||||||
|
size_t sys_sig =
|
||||||
|
ScriptSystem::systems[scm_to_uint64(scm_system)]->signature();
|
||||||
|
|
||||||
|
size_t entity_sig =
|
||||||
|
Script::game->ecs().esig(scm_to_uint64(scm_entity));
|
||||||
|
|
||||||
|
return
|
||||||
|
scm_from_bool(Script::game->ecs().sig_match(sys_sig, entity_sig));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static*/ SCM Script::fn_world__process(SCM scm_system)
|
||||||
|
{
|
||||||
|
auto const& system = ScriptSystem::systems[scm_to_uint64(scm_system)];
|
||||||
|
SCM function = system->function;
|
||||||
|
size_t entities = Script::game->ecs().entity_count();
|
||||||
|
|
||||||
|
for (size_t i=0; i<entities; i++)
|
||||||
|
{
|
||||||
|
if (Script::game->ecs().sig_match(system->signature(),
|
||||||
|
Script::game->ecs().esig(i)))
|
||||||
|
{
|
||||||
|
scm_call_1(function, scm_from_uint64(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SCM_BOOL_T;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,14 @@
|
||||||
|
|
||||||
#include "commons.hpp"
|
#include "commons.hpp"
|
||||||
#include "Game.hpp"
|
#include "Game.hpp"
|
||||||
|
#include "BaseComponent.hpp"
|
||||||
|
#include "BaseSystem.hpp"
|
||||||
#include "libguile/numbers.h"
|
#include "libguile/numbers.h"
|
||||||
|
|
||||||
namespace d2
|
namespace d2
|
||||||
{
|
{
|
||||||
|
D2_ERROR(script_error);
|
||||||
|
|
||||||
struct Script
|
struct Script
|
||||||
{
|
{
|
||||||
static void init();
|
static void init();
|
||||||
|
@ -21,6 +25,25 @@ namespace d2
|
||||||
static SCM fn_scene__push(SCM scm_function, SCM scm_ctx);
|
static SCM fn_scene__push(SCM scm_function, SCM scm_ctx);
|
||||||
static SCM fn_scene__pop();
|
static SCM fn_scene__pop();
|
||||||
|
|
||||||
|
static SCM fn_is_pressed(SCM scm_device, SCM scm_keyname);
|
||||||
|
static SCM fn_is_just_pressed(SCM scm_device, SCM scm_keyname);
|
||||||
|
|
||||||
|
static SCM fn_mouse_x();
|
||||||
|
static SCM fn_mouse_y();
|
||||||
|
|
||||||
|
static SCM fn_rootdir(SCM scm_args);
|
||||||
|
|
||||||
|
static SCM fn_world__system(SCM scm_args);
|
||||||
|
static SCM fn_world__component(SCM scm_args);
|
||||||
|
static SCM fn_world__spawn(SCM scm_args);
|
||||||
|
static SCM fn_world__esig(SCM scm_entity);
|
||||||
|
static SCM fn_world__ssig(SCM scm_system);
|
||||||
|
static SCM fn_world__getc(SCM scm_entity, SCM scm_comp, SCM scm_field);
|
||||||
|
static SCM fn_world__setc(SCM scm_entity, SCM scm_comp,
|
||||||
|
SCM scm_field, SCM scm_value);
|
||||||
|
static SCM fn_world__match(SCM scm_system, SCM scm_entity);
|
||||||
|
static SCM fn_world__process(SCM scm_system);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::unique_ptr<Game> game;
|
static std::unique_ptr<Game> game;
|
||||||
static glm::vec4 color;
|
static glm::vec4 color;
|
||||||
|
@ -46,6 +69,45 @@ namespace d2
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ScriptComponent: public BaseComponent
|
||||||
|
{
|
||||||
|
static size_t comp_id;
|
||||||
|
static std::unordered_map<size_t, std::unique_ptr<ScriptComponent>>
|
||||||
|
components;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, SCM> values;
|
||||||
|
|
||||||
|
explicit ScriptComponent(ScriptComponent const& other)
|
||||||
|
: BaseComponent(other.id())
|
||||||
|
, values { other.values }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit ScriptComponent(size_t id)
|
||||||
|
: BaseComponent(id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(std::string const& name, SCM scm_value)
|
||||||
|
{
|
||||||
|
values.insert({name, scm_value});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScriptSystem: public BaseSystem
|
||||||
|
{
|
||||||
|
static size_t system_id;
|
||||||
|
static std::unordered_map<size_t, std::unique_ptr<ScriptSystem>>
|
||||||
|
systems;
|
||||||
|
SCM function;
|
||||||
|
|
||||||
|
explicit ScriptSystem(SCM p_function)
|
||||||
|
: BaseSystem(ScriptSystem::system_id++)
|
||||||
|
, function { p_function }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "conf.hpp"
|
#include "conf.hpp"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue