feat(lua): added Instance.new for object creation
This commit is contained in:
parent
9f97a90c12
commit
74b8bca10a
4 changed files with 80 additions and 1 deletions
77
core/src/lua/instancelib.cpp
Normal file
77
core/src/lua/instancelib.cpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#include "objects/base/instance.h"
|
||||||
|
#include "datatypes/ref.h"
|
||||||
|
#include "luaapis.h" // IWYU pragma: keep
|
||||||
|
#include "objects/meta.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
static int lib_Instance_index(lua_State*);
|
||||||
|
static int lib_Instance_tostring(lua_State*);
|
||||||
|
static const struct luaL_Reg lib_Instance_metatable [] = {
|
||||||
|
{"__index", lib_Instance_index},
|
||||||
|
{"__tostring", lib_Instance_tostring},
|
||||||
|
{NULL, NULL} /* end of array */
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __lua_impl__Instance__new(lua_State* L) {
|
||||||
|
int n = lua_gettop(L);
|
||||||
|
|
||||||
|
// First argument (className)
|
||||||
|
std::string className = luaL_checkstring(L, 1);
|
||||||
|
|
||||||
|
// [Optional] Second argument (parent)
|
||||||
|
std::shared_ptr<Instance> parent;
|
||||||
|
if (n > 1) {
|
||||||
|
parent = **(std::shared_ptr<Instance>**)luaL_checkudata(L, 2, "__mt_instance");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look up class name
|
||||||
|
if (INSTANCE_MAP.count(className) == 0)
|
||||||
|
return luaL_error(L, "Attempt to create instance of unknown type '%s'", className.c_str());
|
||||||
|
|
||||||
|
const InstanceType* type = INSTANCE_MAP[className];
|
||||||
|
|
||||||
|
if (type->flags & (INSTANCE_NOTCREATABLE | INSTANCE_SERVICE) || type->constructor == nullptr)
|
||||||
|
return luaL_error(L, "Attempt to create Instance of type '%s', which is not creatable", className.c_str());
|
||||||
|
|
||||||
|
std::shared_ptr<Instance> object = type->constructor();
|
||||||
|
|
||||||
|
if (parent != nullptr)
|
||||||
|
object->SetParent(parent);
|
||||||
|
|
||||||
|
InstanceRef(object).PushLuaValue(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Instance::PushLuaLibrary(lua_State* L) {
|
||||||
|
lua_getglobal(L, "_G");
|
||||||
|
lua_pushstring(L, "Instance");
|
||||||
|
|
||||||
|
lua_newuserdata(L, 0);
|
||||||
|
|
||||||
|
// Create the library's metatable
|
||||||
|
luaL_newmetatable(L, "__mt_lib_Instance");
|
||||||
|
luaL_register(L, NULL, lib_Instance_metatable);
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
|
||||||
|
lua_rawset(L, -3);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int lib_Instance_tostring(lua_State* L) {
|
||||||
|
lua_pushstring(L, "Instance");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lib_Instance_index(lua_State* L) {
|
||||||
|
std::string key(lua_tostring(L, 2));
|
||||||
|
lua_pop(L, 2);
|
||||||
|
|
||||||
|
if (key == "new") {
|
||||||
|
lua_pushcfunction(L, __lua_impl__Instance__new);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return luaL_error(L, "%s is not a valid member of %s\n", key.c_str(), "Instance");
|
||||||
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ public:
|
||||||
|
|
||||||
// Instance is abstract, so it should not implement GetClass directly
|
// Instance is abstract, so it should not implement GetClass directly
|
||||||
virtual const InstanceType* GetClass() = 0;
|
virtual const InstanceType* GetClass() = 0;
|
||||||
|
static void PushLuaLibrary(lua_State*); // Defined in lua/instancelib.cpp
|
||||||
bool SetParent(std::optional<std::shared_ptr<Instance>> newParent);
|
bool SetParent(std::optional<std::shared_ptr<Instance>> newParent);
|
||||||
std::optional<std::shared_ptr<Instance>> GetParent();
|
std::optional<std::shared_ptr<Instance>> GetParent();
|
||||||
bool IsParentLocked();
|
bool IsParentLocked();
|
||||||
|
|
|
@ -46,6 +46,7 @@ void ScriptContext::InitService() {
|
||||||
Vector3::PushLuaLibrary(state);
|
Vector3::PushLuaLibrary(state);
|
||||||
CFrame::PushLuaLibrary(state);
|
CFrame::PushLuaLibrary(state);
|
||||||
Color3::PushLuaLibrary(state);
|
Color3::PushLuaLibrary(state);
|
||||||
|
Instance::PushLuaLibrary(state);
|
||||||
|
|
||||||
// TODO: custom os library
|
// TODO: custom os library
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ class ObLuaLexer : public QsciLexerLua {
|
||||||
//"foreach foreachi getn "
|
//"foreach foreachi getn "
|
||||||
|
|
||||||
// Openblocks extensions
|
// Openblocks extensions
|
||||||
"shared require game workspace "
|
"shared require game workspace Instance Instance.new "
|
||||||
|
|
||||||
"_G _VERSION getfenv getmetatable ipairs loadstring "
|
"_G _VERSION getfenv getmetatable ipairs loadstring "
|
||||||
"next pairs pcall rawequal rawget rawset select "
|
"next pairs pcall rawequal rawget rawset select "
|
||||||
|
|
Loading…
Add table
Reference in a new issue