add basic game object system

This commit is contained in:
hippoz 2021-02-25 23:13:05 +02:00
parent bbe6c6bdac
commit 136dceae44
Signed by: hippoz
GPG key ID: 7C52899193467641
14 changed files with 135 additions and 104 deletions

View file

@ -6,10 +6,10 @@ OBJ_DIR := obj
BIN_DIR := bin BIN_DIR := bin
EXE := $(BIN_DIR)/out EXE := $(BIN_DIR)/out
OBJ_OUT_DIRS := obj/Main obj/LuaHandler obj/Components obj/Components/Objects obj/Components/Objects/TopLevel OBJ_OUT_DIRS := obj/Main obj/Components obj/Components obj/Components/TopLevel
SRC := $(SRC_DIR)/Main/Main.cpp $(SRC_DIR)/LuaHandler/LuaHandler.cpp $(SRC_DIR)/Components/GameObject.cpp SRC := $(SRC_DIR)/Main/Main.cpp $(SRC_DIR)/Components/TopLevel/GameObject.cpp $(SRC_DIR)/Components/TopLevel/Game.cpp
OBJ := $(OBJ_DIR)/Main/Main.o $(OBJ_DIR)/LuaHandler/LuaHandler.o $(OBJ_DIR)/Components/GameObject.o OBJ := $(OBJ_DIR)/Main/Main.o $(OBJ_DIR)/Components/TopLevel/GameObject.o $(OBJ_DIR)/Components/TopLevel/Game.o
CC := g++ CC := g++ -std=c++17
CPPFLAGS := -I/usr/include/$(LUA) -Iinclude -MMD -MP CPPFLAGS := -I/usr/include/$(LUA) -Iinclude -MMD -MP
CFLAGS := -Wall CFLAGS := -Wall

View file

@ -1 +1,3 @@
libepic.say_something("lol") for i, v in pairs(program.game:GetChildren()) do
print(v.name)
end

View file

@ -1,19 +0,0 @@
#ifndef _GAMEOBJECT_H
#define _GAMEOBJECT_H
#include <vector>
struct GameObject {
const char* name;
bool is_top_level;
GameObject* parent;
std::vector<GameObject*> children;
std::map<std::string, std::vector<std::function<int(int)>>> handlers;
void add(GameObject* child);
std::vector<GameObject*>& get_children();
GameObject* get(const char* targetedName);
};
#endif

View file

@ -0,0 +1,14 @@
#ifndef _GAME_H
#define _GAME_H
struct Game : public GameObject {
Game() : GameObject("game") {
std::cout << "[+] Game" << '\n';
}
bool isGame();
};
void registerGame(lua_State* L);
#endif

View file

@ -0,0 +1,30 @@
#ifndef _GAMEOBJECT_H
#define _GAMEOBJECT_H
#include <iostream>
#include <vector>
#include <map>
#include <functional>
extern "C" {
#include <lua.h>
#include <lauxlib.h>
}
struct GameObject {
GameObject(std::string name) : name(name) {}
std::string name;
std::string type;
GameObject* parent;
std::vector<GameObject*> children;
std::map<std::string, std::function<void()>> handlers;
GameObject& Get(std::string name);
void Add(GameObject* obj);
std::vector<GameObject*>& GetChildren();
};
void registerGameObject(lua_State* L);
#endif

View file

@ -1,18 +0,0 @@
#ifndef _LUAHANDLER_H
#define _LUAHANDLER_H
extern "C"{
#include <lua.h>
#include <lauxlib.h>
}
struct LuaHandler {
lua_State* L;
LuaHandler(lua_State* L) : L(L) {};
void defineClass(const char* className);
void defineFunction(const char* className, const char* valueName, lua_CFunction func);
};
#endif

1
include/vendor/LuaBridge3 vendored Submodule

@ -0,0 +1 @@
Subproject commit d0a1debdaea96460b172c3847f0b1b7eaa6f76a2

View file

@ -1,27 +0,0 @@
// Bruh.
#include <LuaHandler/LuaHandler.hpp>
#include <Components/GameObject.hpp>
// todo: might want to make these static methods inside the gameobject class to make inheritence easier
// also see this has an example http://lua-users.org/wiki/UserDataExample
void GameObject::add(GameObject* child) {
this->children.push_back(child);
}
std::vector<GameObject*>& GameObject::get_children() {
return this->children;
}
GameObject* GameObject::get(const char* targetedName) {
// Yes, using a loop is inefficient or something
// Yes, an unsigned short can be a bit too small for this
// Eh, its fine
// FIXME: Also what if no child is found at all? Hmm well we could just return the target gameobject, that could work
for (unsigned short i = 0; i < this->children.size(); i++) {
if (this->children[i]->name == targetedName) {
return this->children[i];
}
}
}

View file

@ -1,5 +0,0 @@
#include <Components/GameObject.cpp>
class Game : public GameObject {
}

View file

@ -0,0 +1,17 @@
#include <Components/TopLevel/GameObject.hpp>
#include <Components/TopLevel/Game.hpp>
#include <vendor/LuaBridge3/Source/LuaBridge/LuaBridge.h> // Pain
bool Game::isGame() {
return true;
}
void registerGame(lua_State* L) {
luabridge::getGlobalNamespace (L)
.beginNamespace ("Core")
.deriveClass <Game, GameObject> ("Game")
.addFunction ("isGame", &Game::isGame)
.endClass ()
.endNamespace ();
}

View file

@ -0,0 +1,35 @@
#include <Components/TopLevel/GameObject.hpp>
#include <vendor/LuaBridge3/Source/LuaBridge/LuaBridge.h> // Pain
#include <vendor/LuaBridge3/Source/LuaBridge/Vector.h> // Pain
std::vector<GameObject*>& GameObject::GetChildren() {
return this->children;
}
GameObject& GameObject::Get(std::string name) {
// NOTE(hippoz): This is a mess.
// Firstly, I should be using find_if, not a loop
// Secondly, why is this a short?
for (short i = this->children.size()-1; i >= 0; i--) {
if (this->children[i]->name == name) {
return *this->children[i];
}
}
}
void GameObject::Add(GameObject* gameObject) {
this->children.push_back(gameObject);
}
void registerGameObject(lua_State* L) {
luabridge::getGlobalNamespace (L)
.beginNamespace ("Core")
.beginClass <GameObject> ("GameObject")
.addProperty ("name", &GameObject::name)
.addFunction ("GetChildren", &GameObject::GetChildren)
.addFunction ("Add", &GameObject::Add)
.addFunction ("Get", &GameObject::Get)
.endClass ()
.endNamespace ();
}

View file

@ -1,22 +0,0 @@
#include <LuaHandler/LuaHandler.hpp>
void LuaHandler::defineClass(const char* className) {
// Create a new table and assign it to a global variable
lua_newtable(L);
lua_setglobal(L, className);
}
void LuaHandler::defineFunction(const char* className, const char* valueName, lua_CFunction func) {
// Get the table that should have been defined with LuaHandler::defineClass
lua_getglobal(L, className);
// Push the function name, as well as the function onto the stack
lua_pushstring(L, valueName);
lua_pushcfunction(L, func);
// Add the function inside the table, giving it the specified name
lua_settable(L, -3);
// Keep the stack balanced
lua_pop(L, 1);
}

View file

@ -1,20 +1,43 @@
extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
#include <iostream> #include <iostream>
#include <LuaHandler/LuaHandler.hpp> #include <vendor/LuaBridge3/Source/LuaBridge/LuaBridge.h> // Pain
#include <Components/TopLevel/GameObject.hpp>
#include <Components/TopLevel/Game.hpp>
static int say_something(lua_State* L) { static Game game;
std::cout << "something: " << lua_tostring(L, 1) << "\n";
return 1; void registerInit(lua_State* L) {
registerGameObject(L);
registerGame(L);
luabridge::getGlobalNamespace (L)
.beginNamespace ("program")
.addProperty("game", &game)
.endNamespace ();
} }
int main() { int main() {
GameObject gaming("gamer");
game.Add(&gaming);
lua_State* L = luaL_newstate(); lua_State* L = luaL_newstate();
LuaHandler handler(L); luaL_openlibs(L); // TODO: dangerous
handler.defineClass("libepic"); registerInit(L);
handler.defineFunction("libepic", "say_something", &say_something);
luaL_dofile(handler.L, "Script.lua"); int ret = luaL_dofile(L, "Script.lua");
if (ret != 0) {
std::cout << "[E] Error running main script." << '\n';
std::cout << " -> " << lua_tostring(L, -1) << '\n';
return 2;
}
return 0; return 0;
} }