array properties in lua api

This commit is contained in:
Mikulas Florek 2023-09-21 21:01:55 +02:00
parent 4eb04d2fd7
commit ee1f8f41a8
4 changed files with 119 additions and 43 deletions

View file

@ -151,6 +151,31 @@ void pushEntity(lua_State* L, EntityPtr value, World* world) {
ASSERT(!error);
}
void pushObject(lua_State* L, void* obj, StringView type_name) {
ASSERT(!type_name.empty());
LuaWrapper::DebugGuard guard(L, 1);
lua_getglobal(L, "LumixAPI");
char tmp[64];
copyString(Span(tmp), type_name);
if (LuaWrapper::getField(L, -1, tmp) != LUA_TTABLE) {
lua_pop(L, 2);
lua_newtable(L);
lua_pushlightuserdata(L, obj);
lua_setfield(L, -2, "_value");
ASSERT(false);
return;
}
lua_newtable(L); // [LumixAPI, class, obj]
lua_pushlightuserdata(L, obj); // [LumixAPI, class, obj, obj_ptr]
lua_setfield(L, -2, "_value"); // [LumixAPI, class, obj]
lua_pushvalue(L, -2); // [LumixAPI, class, obj, class]
lua_setmetatable(L, -2); // [LumixAPI, class, obj]
lua_remove(L, -2); // [LumixAPI, obj]
lua_remove(L, -2); // [obj]
}
int luaL_loadbuffer(lua_State* L, const char* buff, size_t size, const char* name) {
size_t bytecode_size;
char* bytecode = luau_compile(buff, size, nullptr, &bytecode_size);

View file

@ -56,6 +56,7 @@ LUMIX_ENGINE_API int getField(lua_State* L, int idx, const char* k);
LUMIX_ENGINE_API void luaL_unref(lua_State* L, int t, int ref);
LUMIX_ENGINE_API int luaL_ref(lua_State* L, int idx);
LUMIX_ENGINE_API int luaL_loadbuffer(lua_State* L, const char* buff, size_t size, const char* name);
LUMIX_ENGINE_API void pushObject(lua_State* L, void* obj, StringView type_name);
template <typename T> inline bool isType(lua_State* L, int index)
{

View file

@ -153,6 +153,11 @@ void ResourceManagerHub::init(FileSystem& fs)
m_file_system = &fs;
}
bool ResourceManagerHub::loadRaw(const Path& included_from, const Path& path, OutputMemoryStream& data) {
if (m_load_hook) m_load_hook->loadRaw(included_from, path);
return m_file_system->getContentSync(path, data);
}
Resource* ResourceManagerHub::load(ResourceType type, const Path& path)
{
ResourceManager* manager = get(type);

View file

@ -44,33 +44,76 @@ static const char* toString(InputSystem::Event::Type type) {
return "N/A";
}
static void convertPropertyToLuaName(const char* src, Span<char> out) {
const u32 max_size = out.length();
ASSERT(max_size > 0);
char* dest = out.begin();
while (*src && dest - out.begin() < max_size - 1) {
if (isLetter(*src)) {
*dest = isUpperCase(*src) ? *src - 'A' + 'a' : *src;
++dest;
}
else if (isNumeric(*src)) {
*dest = *src;
++dest;
}
else {
*dest = '_';
++dest;
}
++src;
}
*dest = 0;
}
struct ArrayItemSetVisitor : reflection::IPropertyVisitor {
void visit(const reflection::Property<float>& prop) override { set(prop); }
void visit(const reflection::Property<int>& prop) override { set(prop); }
void visit(const reflection::Property<u32>& prop) override { set(prop); }
void visit(const reflection::Property<EntityPtr>& prop) override { set(prop); }
void visit(const reflection::Property<Vec2>& prop) override { set(prop); }
void visit(const reflection::Property<Vec3>& prop) override { set(prop); }
void visit(const reflection::Property<IVec3>& prop) override { set(prop); }
void visit(const reflection::Property<Vec4>& prop) override { set(prop); }
void visit(const reflection::Property<Path>& prop) override { set(prop); }
void visit(const reflection::Property<bool>& prop) override { set(prop); }
void visit(const reflection::Property<const char*>& prop) override { set(prop); }
void visit(const reflection::ArrayProperty& prop) override { ASSERT(false); }
void visit(const reflection::BlobProperty& prop) override { ASSERT(false); }
void visit(const reflection::DynamicProperties& prop) override { ASSERT(false); }
template <typename T>
void set(const reflection::Property<T>& prop) {
char tmp[50];
convertPropertyToLuaName(prop.name, Span(tmp));
i32 type = lua_getfield(L, -1, tmp);
if (type == LUA_TNIL) {
lua_pop(L, 1);
return;
}
if (!LuaWrapper::isType<T>(L, -1)) {
lua_pop(L, 1);
luaL_error(L, "%s has incorrect type", tmp);
}
T val = LuaWrapper::toType<T>(L, -1);
lua_pop(L, 1);
prop.set(cmp, idx, val);
}
ComponentUID cmp;
const char* prop_name;
u32 idx;
lua_State* L;
};
static void pushObject(lua_State* L, void* obj, StringView type_name) {
ASSERT(!type_name.empty());
LuaWrapper::DebugGuard guard(L, 1);
lua_getglobal(L, "LumixAPI");
char tmp[64];
const char* c = type_name.end - 1;
while (*c != ':' && c != type_name.begin) --c;
if (*c == ':') ++c;
copyString(Span(tmp), StringView(c, u32(type_name.end - c - 2)));
if (LuaWrapper::getField(L, -1, tmp) != LUA_TTABLE) {
lua_pop(L, 2);
lua_newtable(L);
lua_pushlightuserdata(L, obj);
lua_setfield(L, -2, "_value");
ASSERT(false);
return;
}
lua_newtable(L); // [LumixAPI, class, obj]
lua_pushlightuserdata(L, obj); // [LumixAPI, class, obj, obj_ptr]
lua_setfield(L, -2, "_value"); // [LumixAPI, class, obj]
lua_pushvalue(L, -2); // [LumixAPI, class, obj, class]
lua_setmetatable(L, -2); // [LumixAPI, class, obj]
lua_remove(L, -2); // [LumixAPI, obj]
lua_remove(L, -2); // [obj]
LuaWrapper::pushObject(L, obj, StringView(c, u32(type_name.end - c - 2)));
}
static void toVariant(reflection::Variant::Type type, lua_State* L, int idx, reflection::Variant& val) {
@ -1011,28 +1054,6 @@ public:
return 1;
}
static void convertPropertyToLuaName(const char* src, Span<char> out) {
const u32 max_size = out.length();
ASSERT(max_size > 0);
char* dest = out.begin();
while (*src && dest - out.begin() < max_size - 1) {
if (isLetter(*src)) {
*dest = isUpperCase(*src) ? *src - 'A' + 'a' : *src;
++dest;
}
else if (isNumeric(*src)) {
*dest = *src;
++dest;
}
else {
*dest = '_';
++dest;
}
++src;
}
*dest = 0;
}
static bool isSameProperty(const char* name, const char* lua_name) {
char tmp[50];
convertPropertyToLuaName(name, Span(tmp));
@ -1226,7 +1247,31 @@ public:
prop.set(cmp, idx, val);
}
void visit(const reflection::ArrayProperty& prop) override {}
void set(const reflection::ArrayProperty& prop, u32 idx) {
ArrayItemSetVisitor visitor;
visitor.idx = idx;
visitor.cmp = cmp;
visitor.prop_name = prop.name;
visitor.L = L;
prop.visitChildren(visitor);
}
void visit(const reflection::ArrayProperty& prop) override {
if (!isSameProperty(prop.name, prop_name)) return;
LuaWrapper::checkTableArg(L, 3);
lua_pushnil(L);
while (prop.getCount(cmp) > 0) prop.removeItem(cmp, 0);
u32 idx = 0;
while (lua_next(L, 3)) {
prop.addItem(cmp, idx);
set(prop, idx);
++idx;
lua_pop(L, 1);
}
}
void visit(const reflection::BlobProperty& prop) override {}
ComponentUID cmp;