diff --git a/_IDAScripts/ExportClassH/HeaderGen.py b/_IDAScripts/ExportClassH/HeaderGen.py index 182f49b..e530dd7 100644 --- a/_IDAScripts/ExportClassH/HeaderGen.py +++ b/_IDAScripts/ExportClassH/HeaderGen.py @@ -1,4 +1,5 @@ import os +from typing import Optional from ExportClassH import JSONGen, Utils, Config from ExportClassH.ClassDefs import ParsedClass, ParsedFunction, ParsedClassVar @@ -123,16 +124,18 @@ def GenerateClassContent(targetClass: ParsedClass, indentLevel: str) -> list[str hasAnyContent = bool(contentLines) # Insert access specifier if needed - if not firstVarOrFuncAccess and targetClass.type == "class": + if not firstVarOrFuncAccess and targetClass.type == "class" and hasAnyContent: contentLines.insert(1, f"{indentLevel}public:") childClassDefinitions: list[str] = [] - for parsedClass in targetClass.childClasses.values(): - classDefinition = GenerateClassDefinition(parsedClass, indentLevel + "\t") - classContent = GenerateClassContent(parsedClass, indentLevel + "\t") + childClassesLen = len(targetClass.childClasses.values()) + for i, parsedClass in enumerate(targetClass.childClasses.values()): + childClassDefinition = GenerateClassDefinition(parsedClass, indentLevel + "\t") + childClasSContent = GenerateClassContent(parsedClass, indentLevel + "\t") + if i != 0 and (i != childClassesLen or hasAnyContent): + childClassDefinitions.append("") - childClassDefinitions.extend(classDefinition[:len(classDefinition) - 1] + classContent + classDefinition[len(classDefinition) - 1:]) - childClassDefinitions.append("") + childClassDefinitions.extend(childClassDefinition[:len(childClassDefinition) - 1] + childClasSContent + childClassDefinition[len(childClassDefinition) - 1:]) if (hasAnyContent): contentLines.insert(0, "#pragma region GENERATED by ExportClassToCPPH.py") @@ -154,11 +157,49 @@ def GenerateClassDefinition(targetClass: ParsedClass, indentLevel: str, forwardD classDefLines.append(f"{indentLevel}}};") return classDefLines +def GenerateClassDependencyDefinition(classDependency: str, indentLevel: str, parsedClassesDict: dict[str, ParsedClass]) -> list[str]: + """Generate a class definition from a list of methods.""" + classDependencyList = Utils.SplitByClassSeparatorOutsideTemplates(classDependency) + classDependencyListLen = len(classDependencyList) + + alreadyCheckedDependenciesList: list[str] = [] + currentClassDependency: Optional[ParsedClass] = None + + classDefLines: list[str] = [] + classDefBracketClosingLines: list[str] = [] + for i, dependency in enumerate(classDependencyList, 1): + alreadyCheckedDependenciesList.append(dependency) + if not currentClassDependency: + currentClassDependency = parsedClassesDict.get(dependency) + if not currentClassDependency: + continue + else: + currentClassDependency = currentClassDependency.childClasses.get("::".join(alreadyCheckedDependenciesList)) + if not currentClassDependency: + continue + + canCurrentClassHaveEnclosure = currentClassDependency.type != "enum" and classDependencyListLen > 1 and i != classDependencyListLen + classDefLines.append(f"{indentLevel}{currentClassDependency.type} {currentClassDependency.name}{' {' if canCurrentClassHaveEnclosure else ';'}") + + if canCurrentClassHaveEnclosure: + if currentClassDependency.type == "class": + classDefLines.append(f"{indentLevel}public:") + classDefBracketClosingLines.append(f"{indentLevel}}};") + indentLevel += "\t" + + classDefLines.extend(classDefBracketClosingLines) + return classDefLines + def GenerateHeaderCode(targetClass: ParsedClass, parsedClassesDict: dict[str, ParsedClass]) -> list[str]: """Generate header code for a standard class (not nested).""" global indentLevel fullClassDefinition: list[str] = [] + for classDependency in targetClass.classDependencies: + classDependencyDefinition = GenerateClassDependencyDefinition(classDependency, indentLevel, parsedClassesDict) + fullClassDefinition.extend(classDependencyDefinition) + fullClassDefinition.append("") + for namespace in targetClass.parentNamespaces: fullClassDefinition.append(f"{indentLevel}namespace {namespace} {{") indentLevel += "\t" @@ -241,10 +282,10 @@ def ExportClassHeaders(): parsedClassesDict = JSONGen.GetAllParsedClasses() JSONGen.MoveChildClasses(parsedClassesDict) - for (parsedClassName, parsedClass) in parsedClassesDict.items(): + for parsedClass in parsedClassesDict.values(): headerCodeLines = GenerateHeaderCode(parsedClass, parsedClassesDict) + headerCode: str = "\n".join(headerCodeLines) - WriteHeaderToFile(parsedClass, headerCode, f"{parsedClass.name}.h" if parsedClass.type != "namespace" else "") # classDefinition = GenerateClassDefinition(parsedClass, indentLevel) # classContent = GenerateClassContent(parsedClass, indentLevel) diff --git a/_IDAScripts/generated/cbs.h b/_IDAScripts/generated/cbs.h index 4c78ba4..2f4b511 100644 --- a/_IDAScripts/generated/cbs.h +++ b/_IDAScripts/generated/cbs.h @@ -1,6 +1,72 @@ #pragma once #include +namespace cbs { + class CPcidPath; +}; + +namespace cbs { + class CEntity; +}; + +namespace cbs { + class CEntityPointer; +}; + +namespace cbs { + class CPointer; +}; + +namespace cbs { + class CPcidPathView; +}; + +namespace cbs { + enum pcid_t; +}; + +namespace ttl { + class string_const; +}; + +class SpawnContext; + +class ILevel; + +class mtx34; + +namespace Replication { + class CreateObjectOptions; +}; + +struct PresetId; + +namespace ttl { + class set; +}; + +class CRTTIField; + +namespace cbs { + struct WorldIndex; +}; + +namespace ttl { + class string_base; +}; + +namespace cbs { + class PrefabEntityComponent; +}; + +namespace ttl { + class span; +}; + +namespace ttl { + class vector; +}; + namespace cbs { #pragma region GENERATED by ExportClassToCPPH.py enum pcid_t; @@ -95,10 +161,8 @@ namespace cbs { #pragma endregion }; - public: class CPointer; - public: class CSystemWorldData; class CBaseObject { @@ -675,7 +739,6 @@ namespace cbs { public: #pragma region GENERATED by ExportClassToCPPH.py struct ResultType; - GAME_IMPORT CEntityGenerator(cbs::CEntityGenerator&&); GAME_IMPORT CEntityGenerator(cbs::Prefab const*, SpawnContext&); GAME_IMPORT CEntityGenerator(); @@ -1723,7 +1786,6 @@ namespace cbs { struct SVirtualField; enum ESavePrefabHierarchy; - GAME_IMPORT static char const* const EXTDTL_FLT_POSTFIX; GAME_IMPORT static char const* const EXT_FLT_POSTFIX; GAME_IMPORT static char const* const FLT_POSTFIX; @@ -2658,7 +2720,6 @@ namespace cbs { GAME_IMPORT bool IsEmpty(); #pragma endregion }; - GAME_IMPORT static uint32_t const UNAVAILABLE_IDX; GAME_IMPORT static bool __INTERNAL_crtti_fields_initialized_field; GAME_IMPORT static class rtti::Type& m_RTTI; @@ -2885,7 +2946,6 @@ namespace cbs { #pragma endregion }; - public: class ICallable; struct WorldIndex; @@ -3230,7 +3290,6 @@ namespace cbs { struct SAudioHook; struct SPlayingEventParams; - GAME_IMPORT static bool __INTERNAL_crtti_fields_initialized_field; GAME_IMPORT static class rtti::Type& m_RTTI; GAME_IMPORT static class cbs::CComponentSystem>& s_System; @@ -3726,7 +3785,6 @@ namespace cbs { public: #pragma region GENERATED by ExportClassToCPPH.py struct PinnedPointer; - GAME_IMPORT class cbs::CBaseObject* AllocateComponent(cbs::WorldIndex, cbs::SystemIndex); GAME_IMPORT void DeallocateComponent(cbs::detail::Handle); GAME_IMPORT class cbs::CBaseObject* GetComponentImpl(cbs::detail::Handle); @@ -4006,7 +4064,6 @@ namespace cbs { #pragma endregion }; - public: class ComponentPoolEnumerator; enum ComponentPoolEnumeratorMode; @@ -4638,7 +4695,6 @@ namespace cbs { #pragma endregion }; - public: class CAbstractSystem; class CEntityMgr { @@ -4665,17 +4721,14 @@ namespace cbs { #pragma endregion }; - public: class CComponentSystem; - public: class CComponentBaseSystem; struct SPrefabConfigurationOverrideInfo; enum VisitResult; - public: class CSystem; class PrefabAreaComponent { @@ -6009,7 +6062,6 @@ namespace cbs { GAME_IMPORT virtual enum cbs::VisitResult Visit(cbs::PrefabEntityComponentHierarchy const&); #pragma endregion }; - GAME_IMPORT PrefabDataRetrieval(cbs::Prefab const*, cbs::CPcidPath const&); GAME_IMPORT void DumpResults(fs::ifile&) const; GAME_IMPORT bool Execute(); @@ -9504,11 +9556,9 @@ namespace cbs { GAME_IMPORT void Send() const; #pragma endregion }; - }; namespace msg { - public: class SingleMessagePipeOut; class IMessageData { @@ -10331,7 +10381,6 @@ namespace cbs { #pragma endregion }; - public: class MessagePipeId; class MessageTransmitterPipe { @@ -10427,14 +10476,11 @@ namespace cbs { GAME_IMPORT virtual void OnReceive(CRTTIObject*, cbs::msg::Message const&); #pragma endregion }; - }; namespace detail { struct MessagePipeReceiver; - }; - }; namespace ps { @@ -10524,7 +10570,6 @@ namespace cbs { public: #pragma region GENERATED by ExportClassToCPPH.py enum GUARD_STATE; - GAME_IMPORT static bool s_ForceBakeData; GAME_IMPORT static enum cbs::ps::CStorage::GUARD_STATE s_Guard; GAME_IMPORT static int s_StaticEntitiesRestoreDefaultsCounter; @@ -10872,16 +10917,13 @@ namespace cbs { struct FromStringOptions; enum EStringPathFormat; - GAME_IMPORT static class cbs::ps::IStorage* GetInstance(); #pragma endregion }; enum ReplicationRule; - public: class CStorageReplicator; - }; namespace prefabs { @@ -10890,7 +10932,6 @@ namespace cbs { public: #pragma region GENERATED by ExportClassToCPPH.py struct ValueView; - private: GAME_IMPORT GamePrefabValuesContainer(void*); public: @@ -10936,11 +10977,9 @@ namespace cbs { namespace impl { #pragma region GENERATED by ExportClassToCPPH.py struct MemoryDesc; - GAME_IMPORT void DumpPrefabElementPaths(CLevel const*); #pragma endregion }; - GAME_IMPORT uint64_t GTotalApplyValuesTime; GAME_IMPORT uint64_t GTotalCreatePVCTime; @@ -10973,7 +11012,6 @@ namespace cbs { #pragma endregion }; - public: class IPropertySet; class IProperty { @@ -10994,13 +11032,11 @@ namespace cbs { }; struct PropertyId; - }; namespace Call { #pragma region GENERATED by ExportClassToCPPH.py enum TYPE; - GAME_IMPORT static class IRTTIEnumerationTyped const* GetRTTI(); #pragma endregion }; @@ -11031,62 +11067,47 @@ namespace cbs { namespace EAreaType { #pragma region GENERATED by ExportClassToCPPH.py enum TYPE; - GAME_IMPORT static class IRTTIEnumerationTyped const* GetRTTI(); #pragma endregion }; namespace FRendering { enum TYPE; - }; - }; namespace contracts { - public: class ApiFindComponent; - public: class ApiFindComponentExact; - public: class ApiGatherComponents; - public: class ApiGetInterface; - public: class ApiInvalidatePointer; - public: class ApiComponentOnEntityChanged; - public: class ApiModifyMessagePipeReceivers; - public: class ApiEntityInterfaceChainAccess; - }; namespace EActivityState { #pragma region GENERATED by ExportClassToCPPH.py enum TYPE; - GAME_IMPORT static class IRTTIEnumerationTyped const* GetRTTI(); #pragma endregion }; namespace detail { enum Handle; - }; namespace FComponent { #pragma region GENERATED by ExportClassToCPPH.py enum TYPE; - GAME_IMPORT static class IRTTIEnumerationTyped const* GetRTTI(); #pragma endregion }; @@ -11094,7 +11115,6 @@ namespace cbs { namespace FEntity { #pragma region GENERATED by ExportClassToCPPH.py enum TYPE; - GAME_IMPORT static class IRTTIEnumerationTyped const* GetRTTI(); #pragma endregion }; @@ -11109,9 +11129,7 @@ namespace cbs { GAME_IMPORT void* Reallocate(cbs::memory::Category, void*, uint64_t); #pragma endregion }; - }; - GAME_IMPORT class cbs::PrefabManager* g_PrefabManager; GAME_IMPORT bool operator==(cbs::CPcidPath const&, cbs::CPcidPath const&);