We can properly use range based for loops with view and interaction with Lua is significantly improved

This commit is contained in:
2020-05-13 01:17:25 +02:00
parent de5af0a5aa
commit c9f05af6c9
8 changed files with 234 additions and 172 deletions

View File

@@ -7,9 +7,9 @@
#include <utility>
namespace ecs::lua {
struct Wrapper : Component {
struct LuaComponent : Component {
// @todo Figure out a more elegant way
Wrapper() {}
LuaComponent() {}
sol::table table;
};

View File

@@ -18,8 +18,80 @@ namespace ecs::lua {
preload["ecs"] = [&lua] {
sol::table ecs = lua.create_table();
ecs.set_function("register", [&lua] (std::string name, sol::table table) {
size_t id = ComponentID::regist(name);
ecs.new_usertype<Entity>("Entity",
"__tostring", [] (Entity* thiz) {
return uuids::to_string(thiz->uuid);
},
"add_component", [] (Entity* thiz, size_t id, Component* component) {
return thiz->add_component(id, component);
},
"has_components", [] (Entity* thiz, sol::variadic_args args) {
std::vector<size_t> ids;
for (sol::table table : args) {
// @todo Check that the table has id and convert()
ids.push_back(table["_id"]);
}
return thiz->has_components(ids);
},
"get_component", [&lua] (Entity* thiz, sol::table table) -> sol::object {
// @todo Check that the table has id and convert()
Component* component = thiz->get_component(table["_id"]);
auto f1 = table["_convert"];
if (f1.valid()) {
return f1(component);
}
throw std::runtime_error("Unknown component");
}
);
ecs.new_usertype<View<>>("View",
"for_each", &View<>::for_each
);
ecs.new_usertype<Manager>("Manager",
"create_entity", [] (Manager* thiz) {
// @todo Allow to construct with given uuid
return thiz->create_entity();
},
"remove_entity", &Manager::remove_entity,
"has_entity", [] (Manager* thiz, std::string uuid) {
// @todo Check if valid
return thiz->has_entity(uuids::uuid::from_string(uuid).value());
},
"get_entity", [] (Manager* thiz, std::string uuid) {
// @todo Check if valid
return thiz->get_entity(uuids::uuid::from_string(uuid).value());
},
"view", [] (Manager* thiz, sol::variadic_args args) {
std::vector<size_t> ids;
for (sol::table table : args) {
// @todo Check that the table has id and convert()
ids.push_back(table["_id"]);
}
return thiz->view(ids);
}
);
return ecs;
};
preload["ecs.LuaComponent"] = [&lua] {
lua.new_usertype<LuaComponent>("LuaComponent",
"__index", [] (LuaComponent* thiz, std::string key) {
return thiz->table[key];
},
"__newindex", [] (LuaComponent* thiz, std::string key, sol::object value) {
thiz->table[key] = value;
},
sol::base_classes, sol::bases<ecs::Component>()
);
sol::table comp = lua.create_table();
comp.set_function("create", [&lua] (std::string name, sol::table table) {
std::cout << "Creating new component: " << name << '\n';
size_t id = ComponentID::add(name);
std::cout << "ID: " << id << '\n';
std::unordered_map<std::string, sol::type> map;
@@ -38,8 +110,7 @@ namespace ecs::lua {
#ifdef _OPTIONAL_ECS_SERIAL
auto serialize = [map, name] (std::ostream& os, ecs::Component* component) {
std::cout << "SERIALIZE: " << name << '\n';
Wrapper* wrapper = (Wrapper*)component;
LuaComponent* wrapper = (LuaComponent*)component;
// Write each of the entries
io::write<size_t>(os, map.size());
@@ -65,9 +136,7 @@ namespace ecs::lua {
};
auto deserialize = [map] (std::istream& is, Component* component) {
std::cout << "DESERIALIZE\n";
Wrapper* wrapper = (Wrapper*)component;
LuaComponent* wrapper = (LuaComponent*)component;
// Write each of the entries
size_t size = io::read<size_t>(is);
@@ -80,17 +149,14 @@ namespace ecs::lua {
switch (type) {
case sol::type::string:
std::cout << "STRING\n";
wrapper->table[key] = io::read<std::string>(is);
break;
case sol::type::number:
std::cout << "NUMBER\n";
wrapper->table[key] = io::read<float>(is);
break;
case sol::type::boolean:
std::cout << "BOOL\n";
wrapper->table[key] = io::read<bool>(is);
break;
@@ -101,8 +167,7 @@ namespace ecs::lua {
};
auto create = [&lua, map] {
std::cout << "CREATE\n";
Wrapper* wrapper = new Wrapper();
LuaComponent* wrapper = new LuaComponent();
wrapper->table = lua.create_table();
for (auto [key, type] : map) {
@@ -130,14 +195,11 @@ namespace ecs::lua {
ecs::serial::register_component_custom(id, serialize, deserialize, create);
#endif
lua.set_function("_internal_to_" + name, [] (ecs::Component* component) {
return (Wrapper*)component;
});
sol::table component = lua.create_table();
component["_id"] = id;
component.set_function("new", sol::factories([&lua, id, map] (sol::table table) {
Wrapper* wrapper = new Wrapper();
LuaComponent* wrapper = new LuaComponent();
wrapper->table = lua.create_table();
for (auto [key, type] : map) {
@@ -147,75 +209,14 @@ namespace ecs::lua {
return std::make_pair(id, wrapper);
}));
component.set_function("_convert", [] (ecs::Component* component) {
return (LuaComponent*)component;
});
return component;
});
ecs.new_usertype<Entity>("Entity",
"__tostring", [] (Entity* thiz) {
return uuids::to_string(thiz->uuid);
},
"add_component", [] (Entity* thiz, size_t id, Component* component) {
return thiz->add_component(id, component);
},
"has_components", [] (Entity* thiz, sol::variadic_args args) {
std::vector<std::string> names;
for (std::string name : args) {
names.push_back(name);
}
return thiz->has_components(ComponentID::resolve(names));
},
"get_component", [&lua] (Entity* thiz, std::string name) -> sol::object {
// Convert to the correct component type
Component* component = thiz->get_component(ComponentID::resolve(name));
// @todo Figure out a more elegant way to convert
auto f1 = lua["_internal_to_" + name];
if (f1.valid()) {
return f1(component);
}
throw std::runtime_error("Unknown component");
}
);
ecs.new_usertype<View<>>("View",
"for_each", &View<>::for_each
);
ecs.new_usertype<Manager>("Manager",
"create_entity", [] (Manager* thiz) {
// @todo Allow to construct with given uuid
return thiz->create_entity();
},
"remove_entity", &Manager::remove_entity,
"has_entity", [] (Manager* thiz, std::string uuid) {
// @todo Check if valid
return thiz->has_entity(uuids::uuid::from_string(uuid).value());
},
"get_entity", [] (Manager* thiz, std::string uuid) {
// @todo Check if valid
return thiz->get_entity(uuids::uuid::from_string(uuid).value());
},
"view", [] (Manager* thiz, sol::variadic_args args) {
std::vector<std::string> names;
for (std::string name : args) {
names.push_back(name);
}
return thiz->view(ComponentID::resolve(names));
}
);
return ecs;
};
preload["ecs.Wrapper"] = [&lua] {
lua.new_usertype<Wrapper>("Wrapper",
"__index", [] (Wrapper* thiz, std::string key) {
return thiz->table[key];
},
"__newindex", [] (Wrapper* thiz, std::string key, sol::object value) {
thiz->table[key] = value;
},
sol::base_classes, sol::bases<ecs::Component>()
);
return comp;
};
}
}