feat(autogen): enum integration with objects
This commit is contained in:
parent
46856a06e2
commit
1f296e5fe4
9 changed files with 36 additions and 14 deletions
|
@ -1,9 +1,7 @@
|
||||||
#include "codegen.h"
|
#include "codegen.h"
|
||||||
#include "analysis.h"
|
#include "analysis.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <map>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <variant>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace enum_;
|
using namespace enum_;
|
||||||
|
@ -17,7 +15,7 @@ void enum_::writeCodeForClass(std::ofstream& out, std::string headerPath, EnumAn
|
||||||
out << " { " << entry.value << ", \"" << entry.name << "\" },\n";
|
out << " { " << entry.value << ", \"" << entry.name << "\" },\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "};";
|
out << "};\n\n";
|
||||||
|
|
||||||
out << "static _EnumData __data_" << state.name << " = {\n"
|
out << "static _EnumData __data_" << state.name << " = {\n"
|
||||||
<< " \"" << state.name << "\",\n"
|
<< " \"" << state.name << "\",\n"
|
||||||
|
@ -26,6 +24,8 @@ void enum_::writeCodeForClass(std::ofstream& out, std::string headerPath, EnumAn
|
||||||
<< "};\n\n";
|
<< "};\n\n";
|
||||||
|
|
||||||
out << "namespace EnumType {\n"
|
out << "namespace EnumType {\n"
|
||||||
<< " const Enum " << state.name << "(&__data_" << state.name << ");\n"
|
// extern is necessary here too to prevent "const" from marking Enum as implicitly static
|
||||||
|
// https://stackoverflow.com/questions/2190919/mixing-extern-and-const#comment2509591_2190981
|
||||||
|
<< " extern const Enum " << state.name << "(&__data_" << state.name << ");\n"
|
||||||
<< "}\n\n";
|
<< "}\n\n";
|
||||||
}
|
}
|
|
@ -80,7 +80,13 @@ static void processField(CXCursor cur, ClassAnalysis* state) {
|
||||||
anly.flags = anly.flags | PropertyFlags::PropertyFlag_Readonly;
|
anly.flags = anly.flags | PropertyFlags::PropertyFlag_Readonly;
|
||||||
|
|
||||||
CXType type = clang_getCursorType(cur);
|
CXType type = clang_getCursorType(cur);
|
||||||
anly.backingFieldType = x_clang_toString(clang_getTypeSpelling(type)).c_str();
|
anly.backingFieldType = x_clang_toString(clang_getTypeSpelling(type));
|
||||||
|
CXCursor typeCur = clang_getTypeDeclaration(type);
|
||||||
|
bool isEnum = findAnnotation(typeCur, "OB::def_enum").has_value();
|
||||||
|
if (isEnum) {
|
||||||
|
anly.backingFieldType = "EnumItem";
|
||||||
|
anly.backingFieldEnum = x_clang_toString(clang_getTypeSpelling(type));
|
||||||
|
}
|
||||||
|
|
||||||
state->properties.push_back(anly);
|
state->properties.push_back(anly);
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct PropertyAnalysis {
|
||||||
std::string fieldName;
|
std::string fieldName;
|
||||||
CFrameMember cframeMember = CFrameMember_None; // for cframe_position_prop etc.
|
CFrameMember cframeMember = CFrameMember_None; // for cframe_position_prop etc.
|
||||||
std::string backingFieldType;
|
std::string backingFieldType;
|
||||||
|
std::string backingFieldEnum;
|
||||||
std::string onUpdateCallback;
|
std::string onUpdateCallback;
|
||||||
std::string category;
|
std::string category;
|
||||||
PropertyFlags flags = (PropertyFlags)0;
|
PropertyFlags flags = (PropertyFlags)0;
|
||||||
|
|
|
@ -89,6 +89,8 @@ static void writePropertySetHandler(std::ofstream& out, ClassAnalysis state) {
|
||||||
} else if (!subtype.empty()) {
|
} else if (!subtype.empty()) {
|
||||||
out << "\n std::weak_ptr<Instance> ref = value.get<InstanceRef>();"
|
out << "\n std::weak_ptr<Instance> ref = value.get<InstanceRef>();"
|
||||||
<< "\n this->" << prop.fieldName << " = ref.expired() ? std::weak_ptr<" << subtype << ">() : std::dynamic_pointer_cast<" << subtype << ">(ref.lock());";
|
<< "\n this->" << prop.fieldName << " = ref.expired() ? std::weak_ptr<" << subtype << ">() : std::dynamic_pointer_cast<" << subtype << ">(ref.lock());";
|
||||||
|
} else if (prop.backingFieldType == "EnumItem") {
|
||||||
|
out << "\n this->" << prop.fieldName << " = (" << prop.backingFieldEnum << ")value.get<EnumItem>().Value();";
|
||||||
} else {
|
} else {
|
||||||
out << "\n this->" << prop.fieldName << " = " << castFromVariant("value", prop.backingFieldType) << ";";
|
out << "\n this->" << prop.fieldName << " = " << castFromVariant("value", prop.backingFieldType) << ";";
|
||||||
}
|
}
|
||||||
|
@ -143,6 +145,8 @@ static void writePropertyGetHandler(std::ofstream& out, ClassAnalysis state) {
|
||||||
out << "\n return Variant(" << prop.fieldName << ".Position());";
|
out << "\n return Variant(" << prop.fieldName << ".Position());";
|
||||||
} else if (prop.cframeMember == CFrameMember_Rotation) {
|
} else if (prop.cframeMember == CFrameMember_Rotation) {
|
||||||
out << "\n return Variant(" << prop.fieldName << ".ToEulerAnglesXYZ());";
|
out << "\n return Variant(" << prop.fieldName << ".ToEulerAnglesXYZ());";
|
||||||
|
} else if (prop.backingFieldType == "EnumItem") {
|
||||||
|
out << "\n return Variant(EnumType::" << prop.backingFieldEnum << ".FromValueInternal(" << prop.fieldName << "));";
|
||||||
} else {
|
} else {
|
||||||
out << "\n return Variant(" << castToVariant(prop.fieldName, prop.backingFieldType) << ");";
|
out << "\n return Variant(" << castToVariant(prop.fieldName, prop.backingFieldType) << ");";
|
||||||
}
|
}
|
||||||
|
@ -193,7 +197,7 @@ static void writePropertyMetaHandler(std::ofstream& out, ClassAnalysis state) {
|
||||||
std::string typeInfo = TYPEINFO_REFS[prop.backingFieldType];
|
std::string typeInfo = TYPEINFO_REFS[prop.backingFieldType];
|
||||||
if (typeInfo.empty()) typeInfo = prop.backingFieldType + "::TYPE";
|
if (typeInfo.empty()) typeInfo = prop.backingFieldType + "::TYPE";
|
||||||
if (!parseWeakPtr(prop.backingFieldType).empty()) typeInfo = "InstanceRef::TYPE";
|
if (!parseWeakPtr(prop.backingFieldType).empty()) typeInfo = "InstanceRef::TYPE";
|
||||||
if (prop.backingFieldType == "SurfaceType") typeInfo = "INT_TYPE";
|
if (prop.backingFieldType == "EnumItem") typeInfo = "EnumType::" + prop.backingFieldEnum;
|
||||||
|
|
||||||
std::string strFlags;
|
std::string strFlags;
|
||||||
if (prop.flags & PropertyFlag_Readonly)
|
if (prop.flags & PropertyFlag_Readonly)
|
||||||
|
@ -256,8 +260,8 @@ void object::writeCodeForClass(std::ofstream& out, std::string headerPath, Class
|
||||||
|
|
||||||
out << "#define __AUTOGEN_EXTRA_INCLUDES__\n";
|
out << "#define __AUTOGEN_EXTRA_INCLUDES__\n";
|
||||||
out << "#include \"" << state.headerPath << "\"\n\n";
|
out << "#include \"" << state.headerPath << "\"\n\n";
|
||||||
out << "#include \"datatypes/variant.h\"\n\n";
|
out << "#include \"datatypes/variant.h\"\n";
|
||||||
out << "#include \"datatypes/primitives.h\"\n\n";
|
out << "#include \"datatypes/primitives.h\"\n";
|
||||||
out << "const InstanceType " << state.name << "::TYPE = {\n"
|
out << "const InstanceType " << state.name << "::TYPE = {\n"
|
||||||
<< " .super = &" << state.baseClass << "::TYPE,\n"
|
<< " .super = &" << state.baseClass << "::TYPE,\n"
|
||||||
<< " .className = \"" << state.name << "\",\n"
|
<< " .className = \"" << state.name << "\",\n"
|
||||||
|
|
|
@ -38,11 +38,11 @@ struct InstanceType;
|
||||||
struct TypeMeta {
|
struct TypeMeta {
|
||||||
const TypeDesc* descriptor;
|
const TypeDesc* descriptor;
|
||||||
union {
|
union {
|
||||||
Enum* enum_; // Applicable for EnumItem
|
const Enum* enum_; // Applicable for EnumItem
|
||||||
InstanceType* instType; // Applicable for InstanceRef
|
const InstanceType* instType; // Applicable for InstanceRef
|
||||||
};
|
};
|
||||||
|
|
||||||
inline TypeMeta(const TypeDesc* descriptor) : descriptor(descriptor) {}
|
inline TypeMeta(const TypeDesc* descriptor) : descriptor(descriptor) {}
|
||||||
TypeMeta(Enum*);
|
TypeMeta(const Enum*);
|
||||||
TypeMeta(InstanceType*);
|
TypeMeta(const InstanceType*);
|
||||||
};
|
};
|
|
@ -4,7 +4,7 @@
|
||||||
#include "error/data.h"
|
#include "error/data.h"
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
TypeMeta::TypeMeta(Enum* enum_) : enum_(enum_), descriptor(&EnumItem::TYPE) {}
|
TypeMeta::TypeMeta(const Enum* enum_) : enum_(enum_), descriptor(&EnumItem::TYPE) {}
|
||||||
|
|
||||||
Enum::Enum(_EnumData* data) : data(data) {}
|
Enum::Enum(_EnumData* data) : data(data) {}
|
||||||
|
|
||||||
|
@ -34,6 +34,12 @@ std::optional<EnumItem> Enum::FromValue(int value) const {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EnumItem Enum::FromValueInternal(int value) const {
|
||||||
|
auto result = this->FromValue(value);
|
||||||
|
if (!result) return EnumItem(data, "", value);
|
||||||
|
return result.value();
|
||||||
|
}
|
||||||
|
|
||||||
EnumItem::EnumItem(_EnumData* parentData, std::string name, int value) : parentData(parentData), name(name), value(value) {}
|
EnumItem::EnumItem(_EnumData* parentData, std::string name, int value) : parentData(parentData), name(name), value(value) {}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -27,6 +27,8 @@ public:
|
||||||
std::vector<EnumItem> GetEnumItems() const;
|
std::vector<EnumItem> GetEnumItems() const;
|
||||||
std::optional<EnumItem> FromName(std::string) const;
|
std::optional<EnumItem> FromName(std::string) const;
|
||||||
std::optional<EnumItem> FromValue(int) const;
|
std::optional<EnumItem> FromValue(int) const;
|
||||||
|
|
||||||
|
EnumItem FromValueInternal(int) const;
|
||||||
|
|
||||||
std::string ToString() const;
|
std::string ToString() const;
|
||||||
void PushLuaValue(lua_State*) const;
|
void PushLuaValue(lua_State*) const;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include "objects/base/member.h"
|
#include "objects/base/member.h"
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
TypeMeta::TypeMeta(InstanceType* instType) : instType(instType), descriptor(&InstanceRef::TYPE) {}
|
TypeMeta::TypeMeta(const InstanceType* instType) : instType(instType), descriptor(&InstanceRef::TYPE) {}
|
||||||
|
|
||||||
InstanceRef::InstanceRef() {};
|
InstanceRef::InstanceRef() {};
|
||||||
InstanceRef::InstanceRef(std::weak_ptr<Instance> instance) : ref(instance) {};
|
InstanceRef::InstanceRef(std::weak_ptr<Instance> instance) : ref(instance) {};
|
||||||
|
|
3
core/src/enum/meta.h
Normal file
3
core/src/enum/meta.h
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "surface.h"
|
Loading…
Add table
Reference in a new issue