Compare commits
2 commits
8c6f038b9f
...
4e22bbb2ad
Author | SHA1 | Date | |
---|---|---|---|
4e22bbb2ad | |||
70b164ddc2 |
19 changed files with 202 additions and 46 deletions
|
@ -121,6 +121,33 @@ static void processMethod(CXCursor cur, ClassAnalysis* state) {
|
||||||
state->methods.push_back(anly);
|
state->methods.push_back(anly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void processOperator(CXCursor cur, ClassAnalysis* state) {
|
||||||
|
std::optional<std::string> operatorDef = findAnnotation(cur, "OB::def_data_op");
|
||||||
|
if (!operatorDef) return;
|
||||||
|
|
||||||
|
OperatorAnalysis anly;
|
||||||
|
|
||||||
|
std::string symbolName = x_clang_toString(clang_getCursorSpelling(cur));
|
||||||
|
if (!symbolName.starts_with("operator"))
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string opName = symbolName.substr(8);
|
||||||
|
|
||||||
|
// Special case: Unary minus gets its own type
|
||||||
|
if (clang_Cursor_getNumArguments(cur) == 0)
|
||||||
|
opName = "-()";
|
||||||
|
|
||||||
|
anly.type = opName;
|
||||||
|
|
||||||
|
if (clang_Cursor_getNumArguments(cur) != 0) {
|
||||||
|
CXCursor arg = clang_Cursor_getArgument(cur, 0);
|
||||||
|
CXType type = clang_getCursorType(arg);
|
||||||
|
anly.param_type = x_clang_toString(clang_getTypeSpelling(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
state->operators[opName].push_back(anly);
|
||||||
|
}
|
||||||
|
|
||||||
// This processes both methods and fields
|
// This processes both methods and fields
|
||||||
static void processProperty(CXCursor cur, ClassAnalysis* state) {
|
static void processProperty(CXCursor cur, ClassAnalysis* state) {
|
||||||
std::optional<std::string> propertyDef = findAnnotation(cur, "OB::def_data_prop");
|
std::optional<std::string> propertyDef = findAnnotation(cur, "OB::def_data_prop");
|
||||||
|
@ -219,6 +246,7 @@ static void processClass(CXCursor cur, AnalysisState* state, std::string classNa
|
||||||
|
|
||||||
if (kind == CXCursor_CXXMethod) {
|
if (kind == CXCursor_CXXMethod) {
|
||||||
processMethod(cur, &anly);
|
processMethod(cur, &anly);
|
||||||
|
processOperator(cur, &anly);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CXChildVisit_Continue;
|
return CXChildVisit_Continue;
|
||||||
|
|
|
@ -19,6 +19,11 @@ struct PropertyAnalysis {
|
||||||
std::string valueType;
|
std::string valueType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OperatorAnalysis {
|
||||||
|
std::string type;
|
||||||
|
std::string param_type;
|
||||||
|
};
|
||||||
|
|
||||||
struct MethodParameter {
|
struct MethodParameter {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string type;
|
std::string type;
|
||||||
|
@ -43,6 +48,7 @@ struct ClassAnalysis {
|
||||||
std::vector<MethodAnalysis> methods;
|
std::vector<MethodAnalysis> methods;
|
||||||
std::vector<PropertyAnalysis> staticProperties;
|
std::vector<PropertyAnalysis> staticProperties;
|
||||||
std::vector<MethodAnalysis> staticMethods;
|
std::vector<MethodAnalysis> staticMethods;
|
||||||
|
std::map<std::string, std::vector<OperatorAnalysis>> operators;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AnalysisState {
|
struct AnalysisState {
|
||||||
|
|
|
@ -33,6 +33,17 @@ static std::map<std::string, std::string> LUA_PUSH_FUNCS = {
|
||||||
// { "std::string", "lua_pushstring" },
|
// { "std::string", "lua_pushstring" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::map<std::string, std::string> LUA_OP_NAME = {
|
||||||
|
{ "==", "__eq" },
|
||||||
|
{ "<", "__lt" },
|
||||||
|
{ "<=", "__le" },
|
||||||
|
{ "+", "__add" },
|
||||||
|
{ "-", "__sub" },
|
||||||
|
{ "-()", "__unm" },
|
||||||
|
{ "*", "__mul" },
|
||||||
|
{ "/", "__div" },
|
||||||
|
};
|
||||||
|
|
||||||
static std::string getLuaMethodFqn(std::string className, std::string methodName) {
|
static std::string getLuaMethodFqn(std::string className, std::string methodName) {
|
||||||
return "__lua_impl__" + className + "__" + methodName;
|
return "__lua_impl__" + className + "__" + methodName;
|
||||||
}
|
}
|
||||||
|
@ -237,14 +248,27 @@ static void writeLuaMethodImpls(std::ofstream& out, ClassAnalysis& state) {
|
||||||
static void writeLuaValueGenerator(std::ofstream& out, ClassAnalysis& state) {
|
static void writeLuaValueGenerator(std::ofstream& out, ClassAnalysis& state) {
|
||||||
std::string fqn = state.name;
|
std::string fqn = state.name;
|
||||||
|
|
||||||
|
// Insert additional operators
|
||||||
|
for (auto& [key, ops] : state.operators) {
|
||||||
|
std::string opname = LUA_OP_NAME[key];
|
||||||
|
out << "static int data_" << state.name << opname << "(lua_State*);\n";
|
||||||
|
}
|
||||||
|
|
||||||
out << "static int data_" << state.name << "_gc(lua_State*);\n"
|
out << "static int data_" << state.name << "_gc(lua_State*);\n"
|
||||||
"static int data_" << state.name << "_index(lua_State*);\n"
|
"static int data_" << state.name << "_index(lua_State*);\n"
|
||||||
"static int data_" << state.name << "_tostring(lua_State*);\n"
|
"static int data_" << state.name << "_tostring(lua_State*);\n"
|
||||||
"static const struct luaL_Reg " << state.name << "_metatable [] = {\n"
|
"static const struct luaL_Reg " << state.name << "_metatable [] = {\n"
|
||||||
" {\"__gc\", data_" << state.name << "_gc},\n"
|
" {\"__gc\", data_" << state.name << "_gc},\n"
|
||||||
" {\"__index\", data_" << state.name << "_index},\n"
|
" {\"__index\", data_" << state.name << "_index},\n"
|
||||||
" {\"__tostring\", data_" << state.name << "_tostring},\n"
|
" {\"__tostring\", data_" << state.name << "_tostring},\n";
|
||||||
" {NULL, NULL} /* end of array */\n"
|
|
||||||
|
// Insert additional operators
|
||||||
|
for (auto& [key, ops] : state.operators) {
|
||||||
|
std::string opname = LUA_OP_NAME[key];
|
||||||
|
out << " {\"" + opname + "\", data_" << state.name << opname << "},\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
out << " {NULL, NULL} /* end of array */\n"
|
||||||
"};\n\n";
|
"};\n\n";
|
||||||
|
|
||||||
out << "void " << state.name << "::PushLuaValue(lua_State* L) const {\n"
|
out << "void " << state.name << "::PushLuaValue(lua_State* L) const {\n"
|
||||||
|
@ -337,6 +361,55 @@ static void writeLuaValueGenerator(std::ofstream& out, ClassAnalysis& state) {
|
||||||
"}\n\n";
|
"}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void writeLuaOperatorImpls(std::ofstream& out, ClassAnalysis& state) {
|
||||||
|
std::string fqn = "" + state.name;
|
||||||
|
|
||||||
|
for (auto& [name, ops] : state.operators) {
|
||||||
|
out << "static int data_" << state.name << LUA_OP_NAME[name] << "(lua_State* L) {\n"
|
||||||
|
" " << fqn << "* this_ = *(" << fqn << "**)luaL_checkudata(L, 1, \"__mt_" << state.name << "\");\n"
|
||||||
|
" int n = lua_gettop(L);\n";
|
||||||
|
out << " ";
|
||||||
|
|
||||||
|
// Support multiple overloads of the same function
|
||||||
|
bool first = true;
|
||||||
|
for (OperatorAnalysis op : ops) {
|
||||||
|
if (!first) out << " else ";
|
||||||
|
first = false;
|
||||||
|
|
||||||
|
// Check to see if the arguments possibly match this implementation's parameter types
|
||||||
|
out << "if (";
|
||||||
|
|
||||||
|
// Check number of arguments
|
||||||
|
out << "n == " << std::to_string(name == "-()" ? 2 : op.param_type == "" ? 1 : 2); // Account for first argument as 'this'
|
||||||
|
|
||||||
|
if (op.param_type != "") {
|
||||||
|
out << " && ";
|
||||||
|
writeLuaTestArgument(out, op.param_type, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
out << ") {\n"; // End if condition, start if body
|
||||||
|
|
||||||
|
if (op.param_type != "") {
|
||||||
|
writeLuaGetArgument(out, op.param_type, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == "-()") {
|
||||||
|
out << " Variant(-*this_).PushLuaValue(L);\n";
|
||||||
|
} else {
|
||||||
|
out << " Variant(*this_ " << name << " arg0).PushLuaValue(L);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
out << " return 1;\n"
|
||||||
|
" }";
|
||||||
|
}
|
||||||
|
|
||||||
|
// No function implementation matched
|
||||||
|
out << "\n\n return luaL_error(L, \"Cannot apply '" << name << "' to values of type " << state.name << " and %s \", x_luaL_udatatname(L, 2));\n";
|
||||||
|
|
||||||
|
out << "}\n\n"; // End function
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void writeLuaLibraryGenerator(std::ofstream& out, ClassAnalysis& state) {
|
static void writeLuaLibraryGenerator(std::ofstream& out, ClassAnalysis& state) {
|
||||||
std::string fqn = state.name;
|
std::string fqn = state.name;
|
||||||
|
|
||||||
|
@ -451,5 +524,6 @@ void data::writeCodeForClass(std::ofstream& out, std::string headerPath, ClassAn
|
||||||
|
|
||||||
writeLuaMethodImpls(out, state);
|
writeLuaMethodImpls(out, state);
|
||||||
writeLuaValueGenerator(out, state);
|
writeLuaValueGenerator(out, state);
|
||||||
|
writeLuaOperatorImpls(out, state);
|
||||||
writeLuaLibraryGenerator(out, state);
|
writeLuaLibraryGenerator(out, state);
|
||||||
}
|
}
|
|
@ -8,6 +8,7 @@
|
||||||
#define def_data_prop(...) clang::annotate("OB::def_data_prop", #__VA_ARGS__)
|
#define def_data_prop(...) clang::annotate("OB::def_data_prop", #__VA_ARGS__)
|
||||||
#define def_data_method(...) clang::annotate("OB::def_data_method", #__VA_ARGS__)
|
#define def_data_method(...) clang::annotate("OB::def_data_method", #__VA_ARGS__)
|
||||||
#define def_data_ctor(...) clang::annotate("OB::def_data_ctor", #__VA_ARGS__)
|
#define def_data_ctor(...) clang::annotate("OB::def_data_ctor", #__VA_ARGS__)
|
||||||
|
#define def_data_op(...) clang::annotate("OB::def_data_op", #__VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define def_data(...)
|
#define def_data(...)
|
||||||
#define def_data_prop(...)
|
#define def_data_prop(...)
|
||||||
|
|
|
@ -117,6 +117,10 @@ CFrame CFrame::operator -(Vector3 vector) const {
|
||||||
return *this + -vector;
|
return *this + -vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CFrame::operator ==(CFrame other) const {
|
||||||
|
return this->Position() == other.Position() && this->rotation == other.rotation;
|
||||||
|
}
|
||||||
|
|
||||||
// Serialization
|
// Serialization
|
||||||
|
|
||||||
void CFrame::Serialize(pugi::xml_node node) const {
|
void CFrame::Serialize(pugi::xml_node node) const {
|
||||||
|
|
|
@ -72,4 +72,6 @@ public:
|
||||||
inline CFrame operator *=(CFrame otherFrame) { return *this = *this * otherFrame; }
|
inline CFrame operator *=(CFrame otherFrame) { return *this = *this * otherFrame; }
|
||||||
inline CFrame operator +=(Vector3 offset) { return *this = *this + offset; }
|
inline CFrame operator +=(Vector3 offset) { return *this = *this + offset; }
|
||||||
inline CFrame operator -=(Vector3 offset) { return *this = *this - offset; }
|
inline CFrame operator -=(Vector3 offset) { return *this = *this - offset; }
|
||||||
|
|
||||||
|
DEF_DATA_OP bool operator ==(CFrame) const;
|
||||||
};
|
};
|
|
@ -35,6 +35,10 @@ Color3 Color3::FromHex(std::string hex) {
|
||||||
return Color3(r, g, b);
|
return Color3(r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Color3::operator ==(Color3 other) const {
|
||||||
|
return this->r == other.r && this->g == other.g && this->b == other.b;
|
||||||
|
}
|
||||||
|
|
||||||
// Serialization
|
// Serialization
|
||||||
|
|
||||||
void Color3::Serialize(pugi::xml_node node) const {
|
void Color3::Serialize(pugi::xml_node node) const {
|
||||||
|
|
|
@ -31,4 +31,6 @@ public:
|
||||||
DEF_DATA_PROP inline float R() const { return r; }
|
DEF_DATA_PROP inline float R() const { return r; }
|
||||||
DEF_DATA_PROP inline float G() const { return g; }
|
DEF_DATA_PROP inline float G() const { return g; }
|
||||||
DEF_DATA_PROP inline float B() const { return b; }
|
DEF_DATA_PROP inline float B() const { return b; }
|
||||||
|
|
||||||
|
DEF_DATA_OP bool operator ==(Color3) const;
|
||||||
};
|
};
|
|
@ -40,16 +40,18 @@ EnumItem Enum::FromValueInternal(int value) const {
|
||||||
return result.value();
|
return result.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
EnumItem::EnumItem(_EnumData* parentData, std::string name, int value) : parentData(parentData), name(name), value(value) {}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
std::string Enum::ToString() const {
|
std::string Enum::ToString() const {
|
||||||
return "Enum." + this->data->name;
|
return "Enum." + this->data->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Enum::operator ==(Enum other) const {
|
||||||
|
return this->data == other.data;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
EnumItem::EnumItem(_EnumData* parentData, std::string name, int value) : parentData(parentData), name(name), value(value) {}
|
||||||
|
|
||||||
std::string EnumItem::ToString() const {
|
std::string EnumItem::ToString() const {
|
||||||
return "Enum." + parentData->name + "." + name;
|
return "Enum." + parentData->name + "." + name;
|
||||||
}
|
}
|
||||||
|
@ -69,4 +71,8 @@ result<EnumItem, DataParseError> EnumItem::FromString(std::string string, const
|
||||||
auto result = info.enum_->FromName(string);
|
auto result = info.enum_->FromName(string);
|
||||||
if (result.has_value()) return result.value();
|
if (result.has_value()) return result.value();
|
||||||
return DataParseError(string, "EnumItem");
|
return DataParseError(string, "EnumItem");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EnumItem::operator ==(EnumItem other) const {
|
||||||
|
return this->parentData == other.parentData && this->value == other.value;
|
||||||
}
|
}
|
|
@ -31,6 +31,8 @@ public:
|
||||||
|
|
||||||
EnumItem FromValueInternal(int) const;
|
EnumItem FromValueInternal(int) const;
|
||||||
|
|
||||||
|
DEF_DATA_OP bool operator ==(Enum) const;
|
||||||
|
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
void PushLuaValue(lua_State*) const;
|
void PushLuaValue(lua_State*) const;
|
||||||
static result<Variant, LuaCastError> FromLuaValue(lua_State*, int);
|
static result<Variant, LuaCastError> FromLuaValue(lua_State*, int);
|
||||||
|
@ -50,6 +52,8 @@ public:
|
||||||
inline int Value() const { return this->value; }
|
inline int Value() const { return this->value; }
|
||||||
inline Enum EnumType() const { return Enum(this->parentData); }
|
inline Enum EnumType() const { return Enum(this->parentData); }
|
||||||
|
|
||||||
|
DEF_DATA_OP bool operator ==(EnumItem) const;
|
||||||
|
|
||||||
static result<EnumItem, DataParseError> FromString(std::string, const TypeMeta);
|
static result<EnumItem, DataParseError> FromString(std::string, const TypeMeta);
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
void Serialize(pugi::xml_node) const;
|
void Serialize(pugi::xml_node) const;
|
||||||
|
|
|
@ -145,7 +145,7 @@ static int inst_index(lua_State* L) {
|
||||||
// Read property
|
// Read property
|
||||||
std::optional<PropertyMeta> meta = inst->GetPropertyMeta(key);
|
std::optional<PropertyMeta> meta = inst->GetPropertyMeta(key);
|
||||||
if (meta) {
|
if (meta) {
|
||||||
Variant value = inst->GetPropertyValue(key).expect();
|
Variant value = inst->GetProperty(key).expect();
|
||||||
value.PushLuaValue(L);
|
value.PushLuaValue(L);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ static int inst_newindex(lua_State* L) {
|
||||||
|
|
||||||
if (value.isError())
|
if (value.isError())
|
||||||
return luaL_error(L, "%s", value.errorMessage().value().c_str());
|
return luaL_error(L, "%s", value.errorMessage().value().c_str());
|
||||||
inst->SetPropertyValue(key, value.expect()).expect();
|
inst->SetProperty(key, value.expect()).expect();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,8 @@ public:
|
||||||
|
|
||||||
operator std::weak_ptr<Signal>();
|
operator std::weak_ptr<Signal>();
|
||||||
|
|
||||||
|
DEF_DATA_OP bool operator ==(SignalRef) const;
|
||||||
|
|
||||||
virtual const std::string ToString() const;
|
virtual const std::string ToString() const;
|
||||||
virtual void Serialize(pugi::xml_node node) const;
|
virtual void Serialize(pugi::xml_node node) const;
|
||||||
virtual void PushLuaValue(lua_State*) const;
|
virtual void PushLuaValue(lua_State*) const;
|
||||||
|
@ -134,6 +136,8 @@ public:
|
||||||
|
|
||||||
operator std::weak_ptr<SignalConnection>();
|
operator std::weak_ptr<SignalConnection>();
|
||||||
|
|
||||||
|
DEF_DATA_OP bool operator ==(SignalConnectionRef) const;
|
||||||
|
|
||||||
virtual const std::string ToString() const;
|
virtual const std::string ToString() const;
|
||||||
virtual void Serialize(pugi::xml_node node) const;
|
virtual void Serialize(pugi::xml_node node) const;
|
||||||
virtual void PushLuaValue(lua_State*) const;
|
virtual void PushLuaValue(lua_State*) const;
|
||||||
|
|
|
@ -72,10 +72,18 @@ bool Vector3::operator <(Vector3 other) const {
|
||||||
return X() < other.X() && Y() < other.Y() && Z() < other.Z();
|
return X() < other.X() && Y() < other.Y() && Z() < other.Z();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Vector3::operator <=(Vector3 other) const {
|
||||||
|
return X() <= other.X() && Y() <= other.Y() && Z() <= other.Z();
|
||||||
|
}
|
||||||
|
|
||||||
bool Vector3::operator >(Vector3 other) const {
|
bool Vector3::operator >(Vector3 other) const {
|
||||||
return X() > other.X() && Y() > other.Y() && Z() > other.Z();
|
return X() > other.X() && Y() > other.Y() && Z() > other.Z();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Vector3::operator >=(Vector3 other) const {
|
||||||
|
return X() >= other.X() && Y() >= other.Y() && Z() >= other.Z();
|
||||||
|
}
|
||||||
|
|
||||||
Vector3 Vector3::Cross(Vector3 other) const {
|
Vector3 Vector3::Cross(Vector3 other) const {
|
||||||
return glm::cross(this->vector, other.vector);
|
return glm::cross(this->vector, other.vector);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,8 +55,9 @@ public:
|
||||||
DEF_DATA_OP Vector3 operator -() const;
|
DEF_DATA_OP Vector3 operator -() const;
|
||||||
|
|
||||||
DEF_DATA_OP bool operator <(Vector3) const;
|
DEF_DATA_OP bool operator <(Vector3) const;
|
||||||
DEF_DATA_OP bool operator >(Vector3) const;
|
DEF_DATA_OP bool operator <=(Vector3) const;
|
||||||
|
bool operator >(Vector3) const;
|
||||||
|
bool operator >=(Vector3) const;
|
||||||
DEF_DATA_OP bool operator ==(Vector3) const;
|
DEF_DATA_OP bool operator ==(Vector3) const;
|
||||||
|
|
||||||
// Augmented shorthands
|
// Augmented shorthands
|
||||||
|
|
|
@ -4,4 +4,16 @@ extern "C" {
|
||||||
#include <lauxlib.h>
|
#include <lauxlib.h>
|
||||||
#include <lualib.h>
|
#include <lualib.h>
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const char* x_luaL_udatatname (lua_State *L, int ud) {
|
||||||
|
void *p = lua_touserdata(L, ud);
|
||||||
|
if (p != NULL) {
|
||||||
|
lua_getmetatable(L, ud);
|
||||||
|
lua_getfield(L, -1, "__name");
|
||||||
|
const char* str = lua_tostring(L, -1);
|
||||||
|
lua_pop(L, 2);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
|
@ -182,12 +182,12 @@ void Instance::OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) {
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
|
|
||||||
result<Variant, MemberNotFound> Instance::GetPropertyValue(std::string name) {
|
result<Variant, MemberNotFound> Instance::GetProperty(std::string name) {
|
||||||
name[0] = toupper(name[0]); // Ignore case of first character
|
name[0] = toupper(name[0]); // Ignore case of first character
|
||||||
return InternalGetPropertyValue(name);
|
return InternalGetPropertyValue(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
fallible<MemberNotFound, AssignToReadOnlyMember> Instance::SetPropertyValue(std::string name, Variant value, bool sendUpdateEvent) {
|
fallible<MemberNotFound, AssignToReadOnlyMember> Instance::SetProperty(std::string name, Variant value, bool sendUpdateEvent) {
|
||||||
name[0] = toupper(name[0]); // Ignore case of first character
|
name[0] = toupper(name[0]); // Ignore case of first character
|
||||||
auto result = InternalSetPropertyValue(name, value);
|
auto result = InternalSetPropertyValue(name, value);
|
||||||
if (result.isSuccess() && sendUpdateEvent) {
|
if (result.isSuccess() && sendUpdateEvent) {
|
||||||
|
@ -290,7 +290,7 @@ void Instance::Serialize(pugi::xml_node parent, RefStateSerialize state) {
|
||||||
|
|
||||||
// Update std::shared_ptr<Instance> properties using map above
|
// Update std::shared_ptr<Instance> properties using map above
|
||||||
if (meta.type.descriptor == &InstanceRef::TYPE) {
|
if (meta.type.descriptor == &InstanceRef::TYPE) {
|
||||||
std::weak_ptr<Instance> refWeak = GetPropertyValue(name).expect("Declared property is missing").get<InstanceRef>();
|
std::weak_ptr<Instance> refWeak = GetProperty(name).expect("Declared property is missing").get<InstanceRef>();
|
||||||
if (refWeak.expired()) continue;
|
if (refWeak.expired()) continue;
|
||||||
|
|
||||||
auto ref = refWeak.lock();
|
auto ref = refWeak.lock();
|
||||||
|
@ -306,7 +306,7 @@ void Instance::Serialize(pugi::xml_node parent, RefStateSerialize state) {
|
||||||
state->refsAwaitingRemap[ref] = refs;
|
state->refsAwaitingRemap[ref] = refs;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GetPropertyValue(name).expect("Declared property is missing").Serialize(propertyNode);
|
GetProperty(name).expect("Declared property is missing").Serialize(propertyNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,14 +360,14 @@ result<std::shared_ptr<Instance>, NoSuchInstance> Instance::Deserialize(pugi::xm
|
||||||
|
|
||||||
if (remappedRef) {
|
if (remappedRef) {
|
||||||
// If the instance has already been remapped, set the new value
|
// If the instance has already been remapped, set the new value
|
||||||
object->SetPropertyValue(propertyName, InstanceRef(remappedRef)).expect();
|
object->SetProperty(propertyName, InstanceRef(remappedRef)).expect();
|
||||||
} else {
|
} else {
|
||||||
// Otheriise, queue this property to be updated later, and keep its current value
|
// Otheriise, queue this property to be updated later, and keep its current value
|
||||||
auto& refs = state->refsAwaitingRemap[refId];
|
auto& refs = state->refsAwaitingRemap[refId];
|
||||||
refs.push_back(std::make_pair(object, propertyName));
|
refs.push_back(std::make_pair(object, propertyName));
|
||||||
state->refsAwaitingRemap[refId] = refs;
|
state->refsAwaitingRemap[refId] = refs;
|
||||||
|
|
||||||
object->SetPropertyValue(propertyName, InstanceRef()).expect();
|
object->SetProperty(propertyName, InstanceRef()).expect();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto valueResult = Variant::Deserialize(propertyNode, meta.type);
|
auto valueResult = Variant::Deserialize(propertyNode, meta.type);
|
||||||
|
@ -376,7 +376,7 @@ result<std::shared_ptr<Instance>, NoSuchInstance> Instance::Deserialize(pugi::xm
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto value = valueResult.expect();
|
auto value = valueResult.expect();
|
||||||
object->SetPropertyValue(propertyName, value).expect("Declared property was missing");
|
object->SetProperty(propertyName, value).expect("Declared property was missing");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,7 +386,7 @@ result<std::shared_ptr<Instance>, NoSuchInstance> Instance::Deserialize(pugi::xm
|
||||||
|
|
||||||
// Remap queued properties
|
// Remap queued properties
|
||||||
for (std::pair<std::shared_ptr<Instance>, std::string> ref : state->refsAwaitingRemap[remappedId]) {
|
for (std::pair<std::shared_ptr<Instance>, std::string> ref : state->refsAwaitingRemap[remappedId]) {
|
||||||
ref.first->SetPropertyValue(ref.second, InstanceRef(object)).expect();
|
ref.first->SetProperty(ref.second, InstanceRef(object)).expect();
|
||||||
}
|
}
|
||||||
state->refsAwaitingRemap[remappedId].clear();
|
state->refsAwaitingRemap[remappedId].clear();
|
||||||
|
|
||||||
|
@ -460,7 +460,7 @@ std::optional<std::shared_ptr<Instance>> Instance::Clone(RefStateClone state) {
|
||||||
|
|
||||||
// Update std::shared_ptr<Instance> properties using map above
|
// Update std::shared_ptr<Instance> properties using map above
|
||||||
if (meta.type.descriptor == &InstanceRef::TYPE) {
|
if (meta.type.descriptor == &InstanceRef::TYPE) {
|
||||||
std::weak_ptr<Instance> refWeak = GetPropertyValue(property).expect().get<InstanceRef>();
|
std::weak_ptr<Instance> refWeak = GetProperty(property).expect().get<InstanceRef>();
|
||||||
if (refWeak.expired()) continue;
|
if (refWeak.expired()) continue;
|
||||||
|
|
||||||
auto ref = refWeak.lock();
|
auto ref = refWeak.lock();
|
||||||
|
@ -468,18 +468,18 @@ std::optional<std::shared_ptr<Instance>> Instance::Clone(RefStateClone state) {
|
||||||
|
|
||||||
if (remappedRef) {
|
if (remappedRef) {
|
||||||
// If the instance has already been remapped, set the new value
|
// If the instance has already been remapped, set the new value
|
||||||
newInstance->SetPropertyValue(property, InstanceRef(remappedRef)).expect();
|
newInstance->SetProperty(property, InstanceRef(remappedRef)).expect();
|
||||||
} else {
|
} else {
|
||||||
// Otheriise, queue this property to be updated later, and keep its current value
|
// Otheriise, queue this property to be updated later, and keep its current value
|
||||||
auto& refs = state->refsAwaitingRemap[ref];
|
auto& refs = state->refsAwaitingRemap[ref];
|
||||||
refs.push_back(std::make_pair(newInstance, property));
|
refs.push_back(std::make_pair(newInstance, property));
|
||||||
state->refsAwaitingRemap[ref] = refs;
|
state->refsAwaitingRemap[ref] = refs;
|
||||||
|
|
||||||
newInstance->SetPropertyValue(property, InstanceRef(ref)).expect();
|
newInstance->SetProperty(property, InstanceRef(ref)).expect();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Variant value = GetPropertyValue(property).expect();
|
Variant value = GetProperty(property).expect();
|
||||||
newInstance->SetPropertyValue(property, value).expect();
|
newInstance->SetProperty(property, value).expect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +488,7 @@ std::optional<std::shared_ptr<Instance>> Instance::Clone(RefStateClone state) {
|
||||||
|
|
||||||
// Remap queued properties
|
// Remap queued properties
|
||||||
for (std::pair<std::shared_ptr<Instance>, std::string> ref : state->refsAwaitingRemap[shared_from_this()]) {
|
for (std::pair<std::shared_ptr<Instance>, std::string> ref : state->refsAwaitingRemap[shared_from_this()]) {
|
||||||
ref.first->SetPropertyValue(ref.second, InstanceRef(newInstance)).expect();
|
ref.first->SetProperty(ref.second, InstanceRef(newInstance)).expect();
|
||||||
}
|
}
|
||||||
state->refsAwaitingRemap[shared_from_this()].clear();
|
state->refsAwaitingRemap[shared_from_this()].clear();
|
||||||
|
|
||||||
|
@ -511,7 +511,7 @@ std::vector<std::pair<std::string, std::shared_ptr<Instance>>> Instance::GetRefe
|
||||||
PropertyMeta meta = GetPropertyMeta(property).expect();
|
PropertyMeta meta = GetPropertyMeta(property).expect();
|
||||||
if (meta.type.descriptor != &InstanceRef::TYPE) continue;
|
if (meta.type.descriptor != &InstanceRef::TYPE) continue;
|
||||||
|
|
||||||
std::weak_ptr<Instance> ref = GetPropertyValue(property).expect().get<InstanceRef>();
|
std::weak_ptr<Instance> ref = GetProperty(property).expect().get<InstanceRef>();
|
||||||
if (ref.expired()) continue;
|
if (ref.expired()) continue;
|
||||||
referenceProperties.push_back(std::make_pair(property, ref.lock()));
|
referenceProperties.push_back(std::make_pair(property, ref.lock()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,8 +114,8 @@ public:
|
||||||
std::string GetFullName();
|
std::string GetFullName();
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
result<Variant, MemberNotFound> GetPropertyValue(std::string name);
|
result<Variant, MemberNotFound> GetProperty(std::string name);
|
||||||
fallible<MemberNotFound, AssignToReadOnlyMember> SetPropertyValue(std::string name, Variant value, bool sendUpdateEvent = true);
|
fallible<MemberNotFound, AssignToReadOnlyMember> SetProperty(std::string name, Variant value, bool sendUpdateEvent = true);
|
||||||
result<PropertyMeta, MemberNotFound> GetPropertyMeta(std::string name);
|
result<PropertyMeta, MemberNotFound> GetPropertyMeta(std::string name);
|
||||||
// Manually trigger the update of a property. Useful internally when setting properties directly
|
// Manually trigger the update of a property. Useful internally when setting properties directly
|
||||||
void UpdateProperty(std::string name);
|
void UpdateProperty(std::string name);
|
||||||
|
|
|
@ -133,7 +133,7 @@ std::shared_ptr<DataModel> DataModel::CloneModel() {
|
||||||
|
|
||||||
// Update std::shared_ptr<Instance> properties using map above
|
// Update std::shared_ptr<Instance> properties using map above
|
||||||
if (meta.type.descriptor == &InstanceRef::TYPE) {
|
if (meta.type.descriptor == &InstanceRef::TYPE) {
|
||||||
std::weak_ptr<Instance> refWeak = GetPropertyValue(property).expect().get<InstanceRef>();
|
std::weak_ptr<Instance> refWeak = GetProperty(property).expect().get<InstanceRef>();
|
||||||
if (refWeak.expired()) continue;
|
if (refWeak.expired()) continue;
|
||||||
|
|
||||||
auto ref = refWeak.lock();
|
auto ref = refWeak.lock();
|
||||||
|
@ -141,18 +141,18 @@ std::shared_ptr<DataModel> DataModel::CloneModel() {
|
||||||
|
|
||||||
if (remappedRef) {
|
if (remappedRef) {
|
||||||
// If the instance has already been remapped, set the new value
|
// If the instance has already been remapped, set the new value
|
||||||
newModel->SetPropertyValue(property, InstanceRef(remappedRef)).expect();
|
newModel->SetProperty(property, InstanceRef(remappedRef)).expect();
|
||||||
} else {
|
} else {
|
||||||
// Otheriise, queue this property to be updated later, and keep its current value
|
// Otheriise, queue this property to be updated later, and keep its current value
|
||||||
auto& refs = state->refsAwaitingRemap[ref];
|
auto& refs = state->refsAwaitingRemap[ref];
|
||||||
refs.push_back(std::make_pair(newModel, property));
|
refs.push_back(std::make_pair(newModel, property));
|
||||||
state->refsAwaitingRemap[ref] = refs;
|
state->refsAwaitingRemap[ref] = refs;
|
||||||
|
|
||||||
newModel->SetPropertyValue(property, InstanceRef(ref)).expect();
|
newModel->SetProperty(property, InstanceRef(ref)).expect();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Variant value = GetPropertyValue(property).expect();
|
Variant value = GetProperty(property).expect();
|
||||||
newModel->SetPropertyValue(property, value).expect();
|
newModel->SetProperty(property, value).expect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ std::shared_ptr<DataModel> DataModel::CloneModel() {
|
||||||
|
|
||||||
// Remap queued properties
|
// Remap queued properties
|
||||||
for (std::pair<std::shared_ptr<Instance>, std::string> ref : state->refsAwaitingRemap[shared_from_this()]) {
|
for (std::pair<std::shared_ptr<Instance>, std::string> ref : state->refsAwaitingRemap[shared_from_this()]) {
|
||||||
ref.first->SetPropertyValue(ref.second, InstanceRef(newModel)).expect();
|
ref.first->SetProperty(ref.second, InstanceRef(newModel)).expect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone services
|
// Clone services
|
||||||
|
|
|
@ -55,7 +55,7 @@ public:
|
||||||
std::string propertyName = !isComposite ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString()
|
std::string propertyName = !isComposite ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString()
|
||||||
: view->itemFromIndex(index.parent())->data(0, Qt::DisplayRole).toString().toStdString();
|
: view->itemFromIndex(index.parent())->data(0, Qt::DisplayRole).toString().toStdString();
|
||||||
PropertyMeta meta = inst->GetPropertyMeta(propertyName).expect();
|
PropertyMeta meta = inst->GetPropertyMeta(propertyName).expect();
|
||||||
Variant currentValue = inst->GetPropertyValue(propertyName).expect();
|
Variant currentValue = inst->GetProperty(propertyName).expect();
|
||||||
|
|
||||||
if (isComposite) {
|
if (isComposite) {
|
||||||
if (meta.type.descriptor == &Vector3::TYPE) {
|
if (meta.type.descriptor == &Vector3::TYPE) {
|
||||||
|
@ -144,7 +144,7 @@ public:
|
||||||
std::string propertyName = !index.parent().parent().isValid() ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString()
|
std::string propertyName = !index.parent().parent().isValid() ? view->itemFromIndex(index)->data(0, Qt::DisplayRole).toString().toStdString()
|
||||||
: view->itemFromIndex(index.parent())->data(0, Qt::DisplayRole).toString().toStdString();
|
: view->itemFromIndex(index.parent())->data(0, Qt::DisplayRole).toString().toStdString();
|
||||||
PropertyMeta meta = inst->GetPropertyMeta(propertyName).expect();
|
PropertyMeta meta = inst->GetPropertyMeta(propertyName).expect();
|
||||||
Variant currentValue = inst->GetPropertyValue(propertyName).expect();
|
Variant currentValue = inst->GetProperty(propertyName).expect();
|
||||||
|
|
||||||
if (isComposite) {
|
if (isComposite) {
|
||||||
if (meta.type.descriptor == &Vector3::TYPE) {
|
if (meta.type.descriptor == &Vector3::TYPE) {
|
||||||
|
@ -211,12 +211,12 @@ public:
|
||||||
QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor);
|
QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor);
|
||||||
float value = spinBox->value();
|
float value = spinBox->value();
|
||||||
|
|
||||||
Vector3 prev = inst->GetPropertyValue(propertyName).expect().get<Vector3>();
|
Vector3 prev = inst->GetProperty(propertyName).expect().get<Vector3>();
|
||||||
Vector3 newVector = componentName == "X" ? Vector3(value, prev.Y(), prev.Z())
|
Vector3 newVector = componentName == "X" ? Vector3(value, prev.Y(), prev.Z())
|
||||||
: componentName == "Y" ? Vector3(prev.X(), value, prev.Z())
|
: componentName == "Y" ? Vector3(prev.X(), value, prev.Z())
|
||||||
: componentName == "Z" ? Vector3(prev.X(), prev.Y(), value) : prev;
|
: componentName == "Z" ? Vector3(prev.X(), prev.Y(), value) : prev;
|
||||||
|
|
||||||
inst->SetPropertyValue(propertyName, newVector).expect();
|
inst->SetProperty(propertyName, newVector).expect();
|
||||||
view->rebuildCompositeProperty(view->itemFromIndex(index.parent()), &Vector3::TYPE, newVector);
|
view->rebuildCompositeProperty(view->itemFromIndex(index.parent()), &Vector3::TYPE, newVector);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -227,24 +227,24 @@ public:
|
||||||
if (meta.type.descriptor == &FLOAT_TYPE) {
|
if (meta.type.descriptor == &FLOAT_TYPE) {
|
||||||
QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor);
|
QDoubleSpinBox* spinBox = dynamic_cast<QDoubleSpinBox*>(editor);
|
||||||
|
|
||||||
inst->SetPropertyValue(propertyName, (float)spinBox->value()).expect();
|
inst->SetProperty(propertyName, (float)spinBox->value()).expect();
|
||||||
model->setData(index, spinBox->value());
|
model->setData(index, spinBox->value());
|
||||||
} else if (meta.type.descriptor == &INT_TYPE) {
|
} else if (meta.type.descriptor == &INT_TYPE) {
|
||||||
QSpinBox* spinBox = dynamic_cast<QSpinBox*>(editor);
|
QSpinBox* spinBox = dynamic_cast<QSpinBox*>(editor);
|
||||||
|
|
||||||
inst->SetPropertyValue(propertyName, (int)spinBox->value()).expect();
|
inst->SetProperty(propertyName, (int)spinBox->value()).expect();
|
||||||
model->setData(index, spinBox->value());
|
model->setData(index, spinBox->value());
|
||||||
} else if (meta.type.descriptor == &STRING_TYPE) {
|
} else if (meta.type.descriptor == &STRING_TYPE) {
|
||||||
QLineEdit* lineEdit = dynamic_cast<QLineEdit*>(editor);
|
QLineEdit* lineEdit = dynamic_cast<QLineEdit*>(editor);
|
||||||
|
|
||||||
inst->SetPropertyValue(propertyName, lineEdit->text().toStdString()).expect();
|
inst->SetProperty(propertyName, lineEdit->text().toStdString()).expect();
|
||||||
model->setData(index, lineEdit->text());
|
model->setData(index, lineEdit->text());
|
||||||
} else if (meta.type.descriptor == &Color3::TYPE) {
|
} else if (meta.type.descriptor == &Color3::TYPE) {
|
||||||
QColorDialog* colorDialog = dynamic_cast<QColorDialog*>(editor);
|
QColorDialog* colorDialog = dynamic_cast<QColorDialog*>(editor);
|
||||||
|
|
||||||
QColor color = colorDialog->currentColor();
|
QColor color = colorDialog->currentColor();
|
||||||
Color3 color3(color.redF(), color.greenF(), color.blueF());
|
Color3 color3(color.redF(), color.greenF(), color.blueF());
|
||||||
inst->SetPropertyValue(propertyName, color3).expect();
|
inst->SetProperty(propertyName, color3).expect();
|
||||||
model->setData(index, QString::fromStdString(color3.ToString()), Qt::DisplayRole);
|
model->setData(index, QString::fromStdString(color3.ToString()), Qt::DisplayRole);
|
||||||
model->setData(index, color, Qt::DecorationRole);
|
model->setData(index, color, Qt::DecorationRole);
|
||||||
} else if (meta.type.descriptor == &EnumItem::TYPE) {
|
} else if (meta.type.descriptor == &EnumItem::TYPE) {
|
||||||
|
@ -252,7 +252,7 @@ public:
|
||||||
|
|
||||||
std::vector<EnumItem> siblingItems = meta.type.enum_->GetEnumItems();
|
std::vector<EnumItem> siblingItems = meta.type.enum_->GetEnumItems();
|
||||||
EnumItem newItem = siblingItems[comboBox->currentIndex()];
|
EnumItem newItem = siblingItems[comboBox->currentIndex()];
|
||||||
inst->SetPropertyValue(propertyName, newItem).expect("Failed to set enum value in properties pane");
|
inst->SetProperty(propertyName, newItem).expect("Failed to set enum value in properties pane");
|
||||||
model->setData(index, QString::fromStdString(newItem.Name()), Qt::DisplayRole);
|
model->setData(index, QString::fromStdString(newItem.Name()), Qt::DisplayRole);
|
||||||
} else if (meta.type.descriptor->fromString) {
|
} else if (meta.type.descriptor->fromString) {
|
||||||
QLineEdit* lineEdit = dynamic_cast<QLineEdit*>(editor);
|
QLineEdit* lineEdit = dynamic_cast<QLineEdit*>(editor);
|
||||||
|
@ -260,7 +260,7 @@ public:
|
||||||
result<Variant, DataParseError> parsedResult = meta.type.descriptor->fromString(lineEdit->text().toStdString(), meta.type);
|
result<Variant, DataParseError> parsedResult = meta.type.descriptor->fromString(lineEdit->text().toStdString(), meta.type);
|
||||||
if (!parsedResult) return;
|
if (!parsedResult) return;
|
||||||
Variant parsedValue = parsedResult.expect();
|
Variant parsedValue = parsedResult.expect();
|
||||||
inst->SetPropertyValue(propertyName, parsedValue).expect();
|
inst->SetProperty(propertyName, parsedValue).expect();
|
||||||
model->setData(index, QString::fromStdString(parsedValue.ToString()));
|
model->setData(index, QString::fromStdString(parsedValue.ToString()));
|
||||||
view->rebuildCompositeProperty(view->itemFromIndex(index), meta.type.descriptor, parsedValue);
|
view->rebuildCompositeProperty(view->itemFromIndex(index), meta.type.descriptor, parsedValue);
|
||||||
}
|
}
|
||||||
|
@ -342,7 +342,7 @@ void PropertiesView::setSelected(std::optional<std::shared_ptr<Instance>> instan
|
||||||
|
|
||||||
for (std::string property : properties) {
|
for (std::string property : properties) {
|
||||||
PropertyMeta meta = inst->GetPropertyMeta(property).expect();
|
PropertyMeta meta = inst->GetPropertyMeta(property).expect();
|
||||||
Variant currentValue = inst->GetPropertyValue(property).expect();
|
Variant currentValue = inst->GetProperty(property).expect();
|
||||||
|
|
||||||
if (meta.type.descriptor == &CFrame::TYPE || meta.flags & PROP_HIDDEN) continue;
|
if (meta.type.descriptor == &CFrame::TYPE || meta.flags & PROP_HIDDEN) continue;
|
||||||
|
|
||||||
|
@ -401,7 +401,7 @@ void PropertiesView::propertyChanged(QTreeWidgetItem *item, int column) {
|
||||||
PropertyMeta meta = inst->GetPropertyMeta(propertyName).expect();
|
PropertyMeta meta = inst->GetPropertyMeta(propertyName).expect();
|
||||||
|
|
||||||
if (meta.type.descriptor == &BOOL_TYPE) {
|
if (meta.type.descriptor == &BOOL_TYPE) {
|
||||||
inst->SetPropertyValue(propertyName, item->checkState(1) == Qt::Checked).expect();
|
inst->SetProperty(propertyName, item->checkState(1) == Qt::Checked).expect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ void PropertiesView::onPropertyUpdated(std::shared_ptr<Instance> inst, std::stri
|
||||||
// lastUpdateTime = std::chrono::steady_clock::now();
|
// lastUpdateTime = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
PropertyMeta meta = inst->GetPropertyMeta(property).expect();
|
PropertyMeta meta = inst->GetPropertyMeta(property).expect();
|
||||||
Variant currentValue = inst->GetPropertyValue(property).expect();
|
Variant currentValue = inst->GetProperty(property).expect();
|
||||||
|
|
||||||
if (meta.type.descriptor == &CFrame::TYPE) return;
|
if (meta.type.descriptor == &CFrame::TYPE) return;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue