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 "analysis.h"
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
using namespace enum_;
|
||||
|
@ -17,7 +15,7 @@ void enum_::writeCodeForClass(std::ofstream& out, std::string headerPath, EnumAn
|
|||
out << " { " << entry.value << ", \"" << entry.name << "\" },\n";
|
||||
}
|
||||
|
||||
out << "};";
|
||||
out << "};\n\n";
|
||||
|
||||
out << "static _EnumData __data_" << state.name << " = {\n"
|
||||
<< " \"" << state.name << "\",\n"
|
||||
|
@ -26,6 +24,8 @@ void enum_::writeCodeForClass(std::ofstream& out, std::string headerPath, EnumAn
|
|||
<< "};\n\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";
|
||||
}
|
|
@ -80,7 +80,13 @@ static void processField(CXCursor cur, ClassAnalysis* state) {
|
|||
anly.flags = anly.flags | PropertyFlags::PropertyFlag_Readonly;
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ struct PropertyAnalysis {
|
|||
std::string fieldName;
|
||||
CFrameMember cframeMember = CFrameMember_None; // for cframe_position_prop etc.
|
||||
std::string backingFieldType;
|
||||
std::string backingFieldEnum;
|
||||
std::string onUpdateCallback;
|
||||
std::string category;
|
||||
PropertyFlags flags = (PropertyFlags)0;
|
||||
|
|
|
@ -89,6 +89,8 @@ static void writePropertySetHandler(std::ofstream& out, ClassAnalysis state) {
|
|||
} else if (!subtype.empty()) {
|
||||
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());";
|
||||
} else if (prop.backingFieldType == "EnumItem") {
|
||||
out << "\n this->" << prop.fieldName << " = (" << prop.backingFieldEnum << ")value.get<EnumItem>().Value();";
|
||||
} else {
|
||||
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());";
|
||||
} else if (prop.cframeMember == CFrameMember_Rotation) {
|
||||
out << "\n return Variant(" << prop.fieldName << ".ToEulerAnglesXYZ());";
|
||||
} else if (prop.backingFieldType == "EnumItem") {
|
||||
out << "\n return Variant(EnumType::" << prop.backingFieldEnum << ".FromValueInternal(" << prop.fieldName << "));";
|
||||
} else {
|
||||
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];
|
||||
if (typeInfo.empty()) typeInfo = prop.backingFieldType + "::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;
|
||||
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 << "#include \"" << state.headerPath << "\"\n\n";
|
||||
out << "#include \"datatypes/variant.h\"\n\n";
|
||||
out << "#include \"datatypes/primitives.h\"\n\n";
|
||||
out << "#include \"datatypes/variant.h\"\n";
|
||||
out << "#include \"datatypes/primitives.h\"\n";
|
||||
out << "const InstanceType " << state.name << "::TYPE = {\n"
|
||||
<< " .super = &" << state.baseClass << "::TYPE,\n"
|
||||
<< " .className = \"" << state.name << "\",\n"
|
||||
|
|
|
@ -38,11 +38,11 @@ struct InstanceType;
|
|||
struct TypeMeta {
|
||||
const TypeDesc* descriptor;
|
||||
union {
|
||||
Enum* enum_; // Applicable for EnumItem
|
||||
InstanceType* instType; // Applicable for InstanceRef
|
||||
const Enum* enum_; // Applicable for EnumItem
|
||||
const InstanceType* instType; // Applicable for InstanceRef
|
||||
};
|
||||
|
||||
inline TypeMeta(const TypeDesc* descriptor) : descriptor(descriptor) {}
|
||||
TypeMeta(Enum*);
|
||||
TypeMeta(InstanceType*);
|
||||
TypeMeta(const Enum*);
|
||||
TypeMeta(const InstanceType*);
|
||||
};
|
|
@ -4,7 +4,7 @@
|
|||
#include "error/data.h"
|
||||
#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) {}
|
||||
|
||||
|
@ -34,6 +34,12 @@ std::optional<EnumItem> Enum::FromValue(int value) const {
|
|||
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) {}
|
||||
|
||||
//
|
||||
|
|
|
@ -27,6 +27,8 @@ public:
|
|||
std::vector<EnumItem> GetEnumItems() const;
|
||||
std::optional<EnumItem> FromName(std::string) const;
|
||||
std::optional<EnumItem> FromValue(int) const;
|
||||
|
||||
EnumItem FromValueInternal(int) const;
|
||||
|
||||
std::string ToString() const;
|
||||
void PushLuaValue(lua_State*) const;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "objects/base/member.h"
|
||||
#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(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