diff --git a/autogen/CMakeLists.txt b/autogen/CMakeLists.txt index 994b2df..4d1c2d2 100644 --- a/autogen/CMakeLists.txt +++ b/autogen/CMakeLists.txt @@ -4,7 +4,6 @@ find_package(Clang REQUIRED) add_executable(autogen src/main.cpp src/util.cpp - src/cache.cpp src/analysis.cpp src/codegen.cpp ) diff --git a/autogen/src/analysis.cpp b/autogen/src/analysis.cpp index 6a8d204..05978ac 100644 --- a/autogen/src/analysis.cpp +++ b/autogen/src/analysis.cpp @@ -282,6 +282,9 @@ bool analyzeClasses(std::string path, std::string srcRoot, AnalysisState* state) CXCursorKind kind = clang_getCursorKind(cur); if (kind != CXCursor_ClassDecl) return CXChildVisit_Continue; + CXSourceLocation loc = clang_getCursorLocation(cur); + if (!clang_Location_isFromMainFile(loc)) return CXChildVisit_Continue; // This class is not from this header. Skip + std::string className = x_clang_toString(clang_getCursorDisplayName(cur)); // Forward-decls can slip through the cracks, this prevents that, but also allows us to filter non-instance classes in the src/objects directory if (!findInstanceAnnotation(cur)) return CXChildVisit_Continue; // Class is not "primary" declaration/is not instance, skip diff --git a/autogen/src/codegen.cpp b/autogen/src/codegen.cpp index 11d3af8..f5b8c1c 100644 --- a/autogen/src/codegen.cpp +++ b/autogen/src/codegen.cpp @@ -17,8 +17,6 @@ std::map MAPPED_TYPE = { { "int", "Data::Int" }, { "float", "Data::Float" }, { "std::string", "Data::String" }, - { "std::weak_ptr", "Data::InstanceRef" }, - { "std::weak_ptr", "Data::InstanceRef" }, { "glm::vec3", "Vector3" }, }; @@ -26,6 +24,16 @@ std::map ENUM_TYPES = { { "SurfaceType", std::monostate() } }; +std::string parseWeakPtr(std::string weakPtrType) { + if (!weakPtrType.starts_with("std::weak_ptr")) return ""; + + int pos0 = weakPtrType.find("<"); + int pos1 = weakPtrType.find(">"); + + std::string subtype = weakPtrType.substr(pos0+1, pos1-pos0-1); + return subtype; +} + std::string castFromVariant(std::string valueStr, std::string fieldType) { // Manual exception for now, enums will get their own system eventually if (fieldType == "SurfaceType") { @@ -42,6 +50,12 @@ std::string castToVariant(std::string valueStr, std::string fieldType) { return "Data::Int((int)" + valueStr + ")"; } + // InstanceRef + std::string subtype = parseWeakPtr(fieldType); + if (!subtype.empty()) { + return "Data::Variant(" + valueStr + ".expired() ? Data::InstanceRef() : Data::InstanceRef(std::dynamic_pointer_cast(" + valueStr + ".lock())))"; + } + std::string mappedType = MAPPED_TYPE[fieldType]; if (!mappedType.empty()) { return mappedType + "(" + valueStr + ")"; @@ -56,6 +70,8 @@ void writePropertySetHandler(std::ofstream& out, ClassAnalysis state) { bool first = true; for (auto& prop : state.properties) { out << (first ? "" : " else ") << "if (name == \"" << prop.name << "\") {"; + // InstanceRef + std::string subtype = parseWeakPtr(prop.backingFieldType); if (prop.flags & PropertyFlag_Readonly) { out << "\n return AssignToReadOnlyMember(GetClass()->className, name)"; @@ -63,6 +79,9 @@ void writePropertySetHandler(std::ofstream& out, ClassAnalysis state) { out << "\n this->" << prop.fieldName << " = this->" << prop.fieldName << ".Rotation() + value.get();"; } else if (prop.cframeMember == CFrameMember_Rotation) { out << "\n this->" << prop.fieldName << " = CFrame::FromEulerAnglesXYZ(value.get()) + this->" << prop.fieldName << ".Position();"; + } else if (!subtype.empty()) { + out << "\n std::weak_ptr ref = value.get();" + << "\n this->" << prop.fieldName << " = ref.expired() ? std::weak_ptr<" << subtype << ">() : std::dynamic_pointer_cast<" << subtype << ">(ref.lock());"; } else { out << "\n this->" << prop.fieldName << " = " << castFromVariant("value", prop.backingFieldType) << ";"; if (!prop.onUpdateCallback.empty()) @@ -106,13 +125,15 @@ void writePropertyGetHandler(std::ofstream& out, ClassAnalysis state) { } void writePropertiesList(std::ofstream& out, ClassAnalysis state) { - out << "std::vector " << state.name << "::InternalGetProperties() {\n"; - out << " std::vector properties = " << state.baseClass << "::InternalGetProperties();\n"; + out << "std::vector " << state.name << "::InternalGetProperties() {\n"; + out << " std::vector properties = " << state.baseClass << "::InternalGetProperties();\n"; for (auto& prop : state.properties) { - out << " properties.push_back(\"" << prop.name << "\")l\n"; + out << " properties.push_back(\"" << prop.name << "\");\n"; } + out << " return properties;\n"; + out << "};\n\n"; } @@ -127,6 +148,7 @@ void writePropertyMetaHandler(std::ofstream& out, ClassAnalysis state) { std::string type = MAPPED_TYPE[prop.backingFieldType]; if (type.empty()) type = prop.backingFieldType; if (type == "SurfaceType") type = "Data::Int"; + if (!parseWeakPtr(prop.backingFieldType).empty()) type = "Data::InstanceRef"; std::string strFlags; if (prop.flags & PropertyFlag_Readonly) @@ -174,6 +196,7 @@ void writeCodeForClass(std::ofstream& out, ClassAnalysis& state) { if (state.abstract) constructorStr = "nullptr"; else constructorStr = "&" + state.name + "::Create"; + out << "#define __AUTOGEN_EXTRA_INCLUDES__\n"; out << "#include \"" << state.headerPath << "\"\n\n"; out << "const InstanceType " << state.name << "::TYPE = {\n" << " .super = &" << state.baseClass << "::TYPE,\n" @@ -193,4 +216,5 @@ void writeCodeForClass(std::ofstream& out, ClassAnalysis& state) { writePropertySetHandler(out, state); writePropertyGetHandler(out, state); writePropertyMetaHandler(out, state); + writePropertiesList(out, state); } \ No newline at end of file diff --git a/autogen/src/main.cpp b/autogen/src/main.cpp index 82adfa0..a157312 100644 --- a/autogen/src/main.cpp +++ b/autogen/src/main.cpp @@ -5,11 +5,8 @@ #include #include #include -#include -#include #include #include "analysis.h" -#include "cache.h" #include "codegen.h" namespace fs = std::filesystem; @@ -32,9 +29,6 @@ int main(int argc, char** argv) { fs::create_directories(outPath.parent_path()); // Make sure generated dir exists before we try writing to it - if (state.classes.empty()) - return 0; - printf("[AUTOGEN] Generating file %s...\n", relpath.c_str()); std::ofstream outStream(outPath); diff --git a/core/src/objects/joint/jointinstance.h b/core/src/objects/joint/jointinstance.h index 99d0459..033b99e 100644 --- a/core/src/objects/joint/jointinstance.h +++ b/core/src/objects/joint/jointinstance.h @@ -5,6 +5,11 @@ #include #include +//this is necessary ebcause we use std::weak_ptr without including it in this file +#ifdef __AUTOGEN_EXTRA_INCLUDES__ +#include "../part.h" +#endif + class Part; class Workspace;