Skip to content
Open
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
1 change: 1 addition & 0 deletions bindings/lua/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ set(LUA_BINDINGS_SOURCE
"src/plugin.cpp"
"src/systems.cpp"
"src/logging.cpp"
"src/depends.cpp"
)

# ------------------------ Configure lua bindings target -------------------------
Expand Down
1 change: 1 addition & 0 deletions bindings/lua/samples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,4 @@ endfunction()
make_sample(DIR "hello_world" ASSETS)
make_sample(DIR "modules" ASSETS)
make_sample(DIR "systems" ASSETS)
make_sample(DIR "depends" ASSETS)
24 changes: 24 additions & 0 deletions bindings/lua/samples/depends/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <cubos/bindings/lua/plugin.hpp>

#include <cubos/engine/prelude.hpp>
#include <cubos/engine/settings/plugin.hpp>
#include <cubos/engine/transform/plugin.hpp>

using namespace cubos::engine;
using namespace cubos::bindings::lua;

int main(int argc, char** argv)
{
Cubos cubos{argc, argv};

cubos.plugin(settingsPlugin);
cubos.plugin(luaBindingsPlugin);
cubos.plugin(transformPlugin);

cubos.startupSystem("configure Assets").before(settingsTag).call([](Settings& settings) {
settings.setString("scripts.lua.app.osPath", APP_SCRIPTS_PATH);
});

cubos.run();
return 0;
}
8 changes: 8 additions & 0 deletions bindings/lua/samples/depends/scripts/depends.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
transform = cubos.depends("cubos::engine::transformPlugin")

for i, v in pairs(transform) do
cubos.info(i)
end

cubos.info("Type of position:", transform.Position.__kind)
cubos.info("Type of childof:", transform.ChildOf.__kind)
22 changes: 22 additions & 0 deletions bindings/lua/src/cubos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "cubos.hpp"
#include "systems.hpp"
#include "logging.hpp"
#include "depends.hpp"

using cubos::engine::Cubos;

Expand All @@ -24,14 +25,35 @@ void cubos::bindings::lua::injectCubos(lua_State* state, Cubos* cubos)
lua_settable(state, LUA_REGISTRYINDEX);

lua_newtable(state);

// Ecs
pushFunction(state, "startupSystem", startupSystem);
pushFunction(state, "system", system);
pushFunction(state, "depends", depends);

// Logging
pushFunction(state, "info", logInfo);
pushFunction(state, "warn", logWarn);
pushFunction(state, "error", logError);

lua_setglobal(state, "cubos");


// Create metatables for types
luaL_newmetatable(state, "component");
lua_pushstring(state, "Component");
lua_setfield(state, -2, "__kind");
lua_setfield(state, -1, "__index");

luaL_newmetatable(state, "resource");
lua_pushstring(state, "Resource");
lua_setfield(state, -2, "__kind");
lua_setfield(state, -1, "__index");

luaL_newmetatable(state, "relation");
lua_pushstring(state, "Relation");
lua_setfield(state, -2, "__kind");
lua_setfield(state, -1, "__index");
}

Cubos* cubos::bindings::lua::getCubos(lua_State* state)
Expand Down
107 changes: 107 additions & 0 deletions bindings/lua/src/depends.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#include "systems.hpp"

#include "cubos.hpp"
#include "logging.hpp"

#include <cubos/core/ecs/cubos.hpp>
#include <cubos/core/ecs/plugin_queue.hpp>
#include <cubos/core/ecs/types.hpp>
#include <cubos/core/ecs/world.hpp>

#include <cubos/core/tel/logging.hpp>
#include <cubos/core/tel/level.hpp>

#include <unordered_map>
#include <vector>
#include <string>

using namespace cubos::core::ecs;
using namespace cubos::core::reflection;


static Plugin findPlugin(Cubos* cubos, const char* pluginName) {
for (auto& entry : cubos->installedPlugins())
{
if (entry.second.name == pluginName)
{
return entry.first;
}
}

return nullptr;
}

static PluginInfo getPluginInfo(Cubos* cubos, Plugin plugin) {
return cubos->installedPlugins().at(plugin);
}

/*
* Gets the contents of a plugin and its subplugins
*/
static void registerPlugin(Cubos* cubos, Plugin plugin, std::vector<const Type*>& pluginContent)
{
PluginInfo pluginInfo = getPluginInfo(cubos, plugin);

for (Plugin subplugin : pluginInfo.subPlugins)
{
registerPlugin(cubos, subplugin, pluginContent);
}

for (auto& type : pluginInfo.types)
{
pluginContent.push_back(type);
}
}

namespace cubos::bindings::lua {
int depends(lua_State *state)
{
Cubos* cubos = getCubos(state);
World* world = cubos->world();
Types types = world->types();
std::vector<const Type*> pluginContent;

const char* pluginName = luaL_checkstring(state, 1);
Plugin plugin = findPlugin(cubos, pluginName);

if (plugin == nullptr)
{
logLua(state, cubos::core::tel::Level::Error, "Unable to find plugin named " + std::string(pluginName));
lua_pushnil(state);
return 1;
}

registerPlugin(cubos, plugin, pluginContent);

// The plugin is defined as a table with each type being a field.
// Each type is defined as a userdata with a metatable corresponding
// to its kind (Component/Resource/Relation).
lua_newtable(state);

for (auto& type : pluginContent)
{
const Type** instance = (const Type**) lua_newuserdata(state, sizeof(Type*));
Comment thread
mcanais marked this conversation as resolved.
*instance = type;

DataTypeId id = types.id(*type);

if (types.isComponent(id))
{
luaL_getmetatable(state, "component");
}
else if (types.isResource(id))
{
luaL_getmetatable(state, "resource");
}
else if (types.isRelation(id))
{
luaL_getmetatable(state, "relation");
}

lua_setmetatable(state, -2);
lua_setfield(state, -2, type->shortName().c_str());
}

return 1;
}
}
21 changes: 21 additions & 0 deletions bindings/lua/src/depends.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/// @dir
/// @brief @ref lua-bindings-plugin plugin directory.

/// @file
/// @brief Logging lua api.
/// @ingroup lua-bindings-plugin
#pragma once

#include <cstdint>

#include <lua.hpp>

namespace cubos::bindings::lua
{
/// @brief Lua api function that gets the components, resources and relations of a given plugin
// and its subplugins.
/// @param state The current lua state.
/// @ingroup lua-bindings-plugin
int depends(lua_State* state);

} // namespace cubos::bindings::lua
37 changes: 19 additions & 18 deletions bindings/lua/src/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

#include <string>
#include <cmath>
#include <utility>

#include <cubos/engine/prelude.hpp>
#include <cubos/core/tel/logging.hpp>
#include <cubos/core/tel/level.hpp>

Comment thread
mcanais marked this conversation as resolved.
using namespace cubos::core::tel;

Expand Down Expand Up @@ -64,42 +66,41 @@ static std::string formatArgs(lua_State *state)
return str;
}

static void log(lua_State* state, Level logLevel)
namespace cubos::bindings::lua
{
std::string formattedArgs = formatArgs(state);
Logger::Location location;
lua_Debug debugInfo;

if (lua_getstack(state, 1, &debugInfo))
void logLua(lua_State* state, Level logLevel, std::string message)
{
if (lua_getinfo(state, "nSl", &debugInfo))
Logger::Location location;
lua_Debug debugInfo;

if (lua_getstack(state, 1, &debugInfo))
Comment thread
mcanais marked this conversation as resolved.
{
location.function = debugInfo.name ? debugInfo.name : "undefined";
location.file = debugInfo.short_src;
location.line = debugInfo.currentline;
if (lua_getinfo(state, "nSl", &debugInfo))
Comment thread
mcanais marked this conversation as resolved.
{
location.function = debugInfo.name ? debugInfo.name : "undefined";
Comment thread
mcanais marked this conversation as resolved.
location.file = debugInfo.short_src;
location.line = debugInfo.currentline;

Logger::write(logLevel, location, formattedArgs);
Logger::write(logLevel, location, std::move(message));
}
}
}
}

namespace cubos::bindings::lua
{
int logInfo(lua_State* state)
{
log(state, Level::Info);
logLua(state, Level::Info, formatArgs(state));
return 0;
};

int logWarn(lua_State* state)
{
log(state, Level::Warn);
logLua(state, Level::Warn, formatArgs(state));
return 0;
};

int logError(lua_State* state)
{
log(state, Level::Error);
logLua(state, Level::Error, formatArgs(state));
return 0;
};
} // namespace cubos::bindings::lua
9 changes: 9 additions & 0 deletions bindings/lua/src/logging.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,20 @@
#pragma once

#include <cstdint>
#include <string>
#include <cubos/core/tel/level.hpp>

#include <lua.hpp>

namespace cubos::bindings::lua
{
/// @brief Logs a message showing lua specific info.
/// @param state The current lua state.
/// @param level Logging level.
/// @param message Message to print.
/// @ingroup lua-bindings-plugin
void logLua(lua_State* state, cubos::core::tel::Level level, std::string message);

/// @brief Lua api function to log information.
/// @param state The current lua state.
/// @ingroup lua-bindings-plugin
Expand Down
2 changes: 1 addition & 1 deletion bindings/lua/src/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ void cubos::bindings::lua::luaBindingsPlugin(Cubos& cubos)
}
(void)plugins;
plugins.add([](Cubos& other) {
auto& state = other.world().resource<State>();
auto& state = other.world()->resource<State>();
loadScripts(ScriptsMountPoint, state.luaState);
});
}
Expand Down
Loading
Loading