From 81b721c755d12887d73ff8e5609db041e45781c4 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Fri, 24 Nov 2023 14:05:55 -0600 Subject: [PATCH 1/8] wipwork for adding a gui driven class callback method prototyper with command and variable reporting --- .../game/data/Prototyping/Prototyping.tscript | 3 + .../UI/classPrototyping.asset.taml | 5 + .../data/Prototyping/UI/classPrototyping.gui | 122 +++++++++++++++ .../Prototyping/UI/classPrototyping.tscript | 142 ++++++++++++++++++ 4 files changed, 272 insertions(+) create mode 100644 Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.asset.taml create mode 100644 Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui create mode 100644 Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript diff --git a/Templates/BaseGame/game/data/Prototyping/Prototyping.tscript b/Templates/BaseGame/game/data/Prototyping/Prototyping.tscript index c053fd2cf..abdf546be 100644 --- a/Templates/BaseGame/game/data/Prototyping/Prototyping.tscript +++ b/Templates/BaseGame/game/data/Prototyping/Prototyping.tscript @@ -37,6 +37,9 @@ function Prototyping::onDestroyGameServer(%this) //This is called when the client is initially set up by the game application function Prototyping::initClient(%this) { + //class method prototyping + %this.queueExec("./UI/classPrototyping"); + %this.queueExec("./UI/classPrototyping.gui"); } //This is called when a client connects to a server diff --git a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.asset.taml b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.asset.taml new file mode 100644 index 000000000..a269f2329 --- /dev/null +++ b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.asset.taml @@ -0,0 +1,5 @@ + diff --git a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui new file mode 100644 index 000000000..91f3fabb6 --- /dev/null +++ b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui @@ -0,0 +1,122 @@ +//--- OBJECT WRITE BEGIN --- +$guiContent = new GuiControl(classPrototyping) { + extent = "1024 768"; + profile = "GuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; + isContainer = "1"; + canSaveDynamicFields = "1"; + originalAssetName = "classPrototyping"; + + new GuiWindowCtrl() { + text = "Class Prototyping"; + position = "216 124"; + extent = "592 519"; + horizSizing = "center"; + vertSizing = "center"; + profile = "ToolsGuiWindowProfile"; + tooltipProfile = "GuiToolTipProfile"; + + new GuiScrollCtrl() { + lockVertScroll = "1"; + position = "14 30"; + extent = "564 33"; + profile = "ToolsGuiScrollProfile"; + tooltipProfile = "GuiToolTipProfile"; + + new GuiDynamicCtrlArrayControl(ClassInheritanceListCtrl) { + colCount = "1"; + colSize = "80"; + rowCount = "1"; + rowSize = "18"; + autoCellSize = "1"; + fillRowFirst = "0"; + dynamicSize = "1"; + position = "1 1"; + extent = "400 18"; + profile = "GuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + }; + new GuiTextCtrl() { + text = "Callbacks"; + position = "24 66"; + extent = "54 14"; + profile = "ToolsGuiTextProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiScrollCtrl() { + position = "19 80"; + extent = "552 326"; + profile = "ToolsGuiScrollProfile"; + tooltipProfile = "GuiToolTipProfile"; + + new GuiDynamicCtrlArrayControl(ClassMethodListCtrl) { + colCount = "1"; + colSize = "8000"; + rowCount = "1"; + rowSize = "18"; + dynamicSize = "1"; + extent = "552 326"; + profile = "GuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + }; + new GuiBitmapButtonCtrl() { + BitmapAsset = "ToolsModule:iconOpen_image"; + bitmapMode = "Centered"; + position = "348 467"; + extent = "22 22"; + horizSizing = "left"; + profile = "ToolsGuiButtonProfile"; + command = "SelectAssetPath.showDialog(AssetBrowser.dirHandler.currentAddress, \"setAssetTargetUpdatePath\");\nSelectAssetPathWindow.selectWindow();"; + tooltipProfile = "GuiToolTipProfile"; + tooltip = "New Module"; + }; + new GuiTextEditCtrl() { + text = "data/ExampleModule"; + position = "143 470"; + extent = "201 20"; + horizSizing = "width"; + profile = "ToolsGuiTextEditProfile"; + active = "0"; + tooltipProfile = "GuiToolTipProfile"; + internalName = "targetPath"; + }; + new GuiTextCtrl() { + text = "Target Path:"; + position = "20 470"; + extent = "116 17"; + profile = "ToolsGuiTextProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiButtonCtrl() { + text = "Save"; + position = "431 465"; + profile = "ToolsGuiButtonProfile"; + command = "classPrototyping.writeResults();"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiCheckBoxCtrl(ReportCommands) { + text = "Report Commands"; + position = "16 420"; + extent = "125 30"; + profile = "ToolsGuiCheckBoxProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiCheckBoxCtrl(ReportVariables) { + text = "Report Stock Variables"; + position = "152 420"; + extent = "125 30"; + profile = "ToolsGuiCheckBoxProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiCheckBoxCtrl(ReportDynamicVariables) { + text = "Report Dynamic Variables"; + position = "250 420"; + extent = "125 30"; + profile = "ToolsGuiCheckBoxProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript new file mode 100644 index 000000000..eb9531ec4 --- /dev/null +++ b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript @@ -0,0 +1,142 @@ +function classPrototyping::onWake(%this) +{ + +} + +function classPrototyping::onSleep(%this) +{ + +} +//PrototypeClass(MainMenuGui) +//PrototypeClass(GuiChunkedBitmapCtrl) +function PrototypeClass(%classInstance) +{ + Canvas.pushDialog(classPrototyping); + classPrototyping.fillClasslist(%classInstance); + classPrototyping.SetNamespaceUsed(%classInstance); +} + +function classPrototyping::fillClasslist(%this, %classInstance) +{ + ClassInheritanceListCtrl.deleteAllObjects(); + %this.inst = %classInstance; + %this.instanceName = %classInstance.getName(); + + //get potentially scripted namespaces + %class = %classInstance.getClassName(); + %prepend = %classInstance.getName(); + if (%classInstance.class !$= "") + %prepend = %prepend SPC %classInstance.class; + if (%classInstance.superclass !$= "") + %prepend = %prepend SPC %classInstance.superclass; + + //append to hardcoded potential namespaces + %this.classlist = %prepend SPC getClassHierarchy(%class); + %this.classCount = getWordCount(%this.classlist); + for (%i=0; %i<%this.classCount; %i++) + { + %inheritanceOrder = %this.classCount-(%i+1); + %className = getWord(%this.classlist,%inheritanceOrder); + if (%i<%this.classCount-1) + %className = %className @"->"; + %elemClass = new GuiRadioCtrl("ProtoClassSelect"@ %i) { + text = %className; + entry = strreplace(%className,"->",""); + groupNum = "1"; + extent = "80 18"; + profile = "ToolsGuiRadioProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + eval("function ProtoClassSelect"@ %i @"::onClick(%this){classPrototyping.SetNamespaceUsed(%this.entry);}"); + ClassInheritanceListCtrl.addGuiControl(%elemClass); + } + %lastElem = "ProtoClassSelect"@ %this.classCount-1; + %lastElem.setStateOn(true); +} + +function classPrototyping::SetNamespaceUsed(%this, %nameSpaceUsed) +{ + ClassMethodListCtrl.deleteAllObjects(); + if (%nameSpaceUsed $= %this.instanceName) + { + %this.tempClass = %this.inst; + %this.fillMethodlist(%this.inst); + return; + } + eval("classPrototyping.tempClass = new "@ %nameSpaceUsed @"(){};"); + %this.fillMethodlist(%this.tempClass); +} + +function classPrototyping::fillMethodlist(%this, %classInstance) +{ + ClassMethodListCtrl.deleteAllObjects(); + + %this.methodArray = %classInstance.getMethodSigs(); + %this.methodCount = %this.methodArray.count(); + + for (%i=0; %i<%this.methodCount; %i++) + { + %methodDef = getRecord(%this.methodArray.getValue(%i),0); + %methodName = strreplace(%methodDef,"::"," "); + %methodName = getWord(strreplace(%methodName,"("," "),2); + + %elemMethod = new GuiCheckBoxCtrl("ProtoMethodSelect"@ %i) { + text = %methodName; + position = "1 1"; + profile = "ToolsGuiCheckBoxProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; + ClassMethodListCtrl.addGuiControl(%elemMethod); + } +} + +function classPrototyping::writeResults(%this) +{ + %namespaceUsed = ""; + for (%i=0; %i<%this.classCount; %i++) + { + %inheritanceOrder = %this.classCount-(%i+1); + %obj = "ProtoClassSelect"@ %i; + if (%obj.isStateOn()) + %namespaceUsed = getWord(%this.classlist,%inheritanceOrder); + } + echo(%namespaceUsed); + for (%i=0; %i<%this.methodCount; %i++) + { + %obj = "ProtoMethodSelect"@ %i; + if (%obj.isStateOn()) + echo(strreplace(%this.methodArray.getValue(%i),%this.instanceName,%namespaceUsed)); + } + + if (ReportCommands.isStateOn()) + { + %this.commandArray = %this.tempClass.getMethodSigs(true); + %this.commandCount = %this.commandArray.count(); + echo("/* Available Commands:"); + for (%i=0; %i< %this.commandCount; %i++) + { + echo(getRecord(%this.commandArray.getValue(%i),0)); + } + echo("*/"); + } + + if (ReportVariables.isStateOn()) + { + echo("/* HardCoded Variables"); + for (%i=0; %i< %this.tempClass.getFieldCount(); %i++) + { + echo(%this.tempClass.getField(%i)); + } + echo("*/"); + } + + if (ReportDynamicVariables.isStateOn()) + { + echo("/* Dynamic Variables"); + for (%i=0; %i< %this.tempClass.getDynamicFieldCount(); %i++) + { + echo(getword(%this.tempClass.getDynamicField(%i),0)); + } + echo("*/"); + } +} \ No newline at end of file From c10808873d2b038c0af2e17ab3d1f3c08c7f450f Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Fri, 24 Nov 2023 15:44:54 -0600 Subject: [PATCH 2/8] hook PrototypeClass(%objectName) on up to inspector fix dialog close, fix dynamic variable gui element alignment --- Engine/source/console/simObject.cpp | 15 +++++++++++++-- Engine/source/console/simObject.h | 4 ++-- .../game/data/Prototyping/UI/classPrototyping.gui | 6 +++--- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 6c01e4f00..0b887cb08 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -40,6 +40,7 @@ #include "core/fileObject.h" #include "persistence/taml/tamlCustom.h" #include "gui/editor/guiInspector.h" +#include "console/script.h" #include "sim/netObject.h" @@ -90,7 +91,7 @@ SimObject::SimObject() mNameSpace = NULL; mNotifyList = NULL; mFlags.set( ModStaticFields | ModDynamicFields ); - + mPrototype = true; mProgenitorFile = StringTable->EmptyString(); mFieldDictionary = NULL; @@ -159,7 +160,8 @@ void SimObject::initPersistFields() addProtectedField("inheritFrom", TypeString, Offset(mInheritFrom, SimObject), &setInheritFrom, &defaultProtectedGetFn, "Optional Name of object to inherit from as a parent."); - + + addProtectedField("Prototype", TypeBool, Offset(mPrototype, SimObject), &_doPrototype, &defaultProtectedGetFn, "Prototype Methods", AbstractClassRep::FieldFlags::FIELD_ComponentInspectors); endGroup( "Ungrouped" ); addGroup( "Object" ); @@ -212,6 +214,15 @@ void SimObject::initPersistFields() } //----------------------------------------------------------------------------- +bool SimObject::_doPrototype(void* object, const char* index, const char* data) +{ + if (!Con::isFunction("PrototypeClass")) return false; + if (dAtoi(data) != 1) return false; + SimObject* obj = reinterpret_cast(object); + String command = String("PrototypeClass(") + (obj->getName()? String(obj->getName()) : String::ToString(obj->getId())) + ");"; + Con::evaluate(command.c_str()); + return false; +} String SimObject::describeSelf() const { diff --git a/Engine/source/console/simObject.h b/Engine/source/console/simObject.h index 912f1b086..947302f0e 100644 --- a/Engine/source/console/simObject.h +++ b/Engine/source/console/simObject.h @@ -300,7 +300,7 @@ class SimObject: public ConsoleObject, public TamlCallbacks SimObject* nextIdObject; StringTableEntry mInheritFrom; - + bool mPrototype; /// SimGroup we're contained in, if any. SimGroup* mGroup; @@ -388,7 +388,7 @@ class SimObject: public ConsoleObject, public TamlCallbacks public: inline void setProgenitorFile(const char* pFile) { mProgenitorFile = StringTable->insert(pFile); } inline StringTableEntry getProgenitorFile(void) const { return mProgenitorFile; } - + static bool _doPrototype(void* object, const char* index, const char* data); protected: /// Taml callbacks. virtual void onTamlPreWrite(void) {} diff --git a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui index 91f3fabb6..e0aa673aa 100644 --- a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui +++ b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui @@ -15,7 +15,7 @@ $guiContent = new GuiControl(classPrototyping) { vertSizing = "center"; profile = "ToolsGuiWindowProfile"; tooltipProfile = "GuiToolTipProfile"; - + closeCommand = "Canvas.popDialog(classPrototyping);"; new GuiScrollCtrl() { lockVertScroll = "1"; position = "14 30"; @@ -112,8 +112,8 @@ $guiContent = new GuiControl(classPrototyping) { }; new GuiCheckBoxCtrl(ReportDynamicVariables) { text = "Report Dynamic Variables"; - position = "250 420"; - extent = "125 30"; + position = "300 420"; + extent = "150 30"; profile = "ToolsGuiCheckBoxProfile"; tooltipProfile = "GuiToolTipProfile"; }; From 4b86e112c8d8a1c15a4fe45600f914c320597a65 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Fri, 24 Nov 2023 15:58:35 -0600 Subject: [PATCH 3/8] add safeties --- .../game/data/Prototyping/UI/classPrototyping.tscript | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript index eb9531ec4..341670ae2 100644 --- a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript +++ b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript @@ -11,6 +11,7 @@ function classPrototyping::onSleep(%this) //PrototypeClass(GuiChunkedBitmapCtrl) function PrototypeClass(%classInstance) { + if (!isObject(%classInstance)) return; Canvas.pushDialog(classPrototyping); classPrototyping.fillClasslist(%classInstance); classPrototyping.SetNamespaceUsed(%classInstance); @@ -24,7 +25,9 @@ function classPrototyping::fillClasslist(%this, %classInstance) //get potentially scripted namespaces %class = %classInstance.getClassName(); - %prepend = %classInstance.getName(); + %prepend = ""; + if (%classInstance.getName() !$= "") + %prepend = %classInstance.getName(); if (%classInstance.class !$= "") %prepend = %prepend SPC %classInstance.class; if (%classInstance.superclass !$= "") From b03cb4c49b63585c811285a7049637c936f38aaf Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 24 Dec 2023 02:46:26 -0600 Subject: [PATCH 4/8] add a getMethodSigsNS takes a namespace as an explici value fed to it as oposed to inferring from an passed object --- Engine/source/console/simObject.cpp | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 38780df02..92080dff1 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -2718,6 +2718,59 @@ DefineEngineMethod(SimObject, getMethodSigs, ArrayObject*, (bool commands), (fal return dictionary; } + +DefineEngineFunction(getMethodSigsNS, ArrayObject*, (StringTableEntry className, bool commands), (false), + "List the methods defined on this object.\n\n" + "Each description is a newline-separated vector with the following elements:\n" + "- method prototype string.\n" + "- Documentation string (not including prototype). This takes up the remainder of the vector.\n" + "@return An ArrayObject populated with (name,description) pairs of all methods defined on the object.") +{ + + Namespace* ns = Con::lookupNamespace(className); + if (!ns) + return 0; + + ArrayObject* dictionary = new ArrayObject(); + dictionary->registerObject(); + + VectorPtr vec(__FILE__, __LINE__); + ns->getEntryList(&vec); + for (Vector< Namespace::Entry* >::iterator j = vec.begin(); j != vec.end(); j++) + { + Namespace::Entry* e = *j; + + if (commands) + { + if ((e->mType < Namespace::Entry::ConsoleFunctionType)) + continue; + } + else + { + if ((e->mType > Namespace::Entry::ScriptCallbackType)) + continue; + } + StringBuilder str; + str.append("function "); + str.append(ns->getName()); + str.append("::"); + str.append(e->getPrototypeSig()); + str.append('\n'); + str.append("{"); + String docs = e->getDocString(); + if (!docs.isEmpty()) + { + str.append("\n/*"); + str.append(docs); + str.append("\n*/"); + } + str.append('\n'); + str.append("}"); + dictionary->push_back(e->mFunctionName, str.end()); + } + + return dictionary; +} //----------------------------------------------------------------------------- namespace { From 5791ee68a7dd6946d30b3ab55b63987942a7b289 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 24 Dec 2023 03:15:56 -0600 Subject: [PATCH 5/8] adds a getFieldCountNS and getFieldNS method to allow field lookup by namespace --- Engine/source/console/simObject.cpp | 63 +++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 92080dff1..c3a45c3be 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -3326,6 +3326,33 @@ DefineEngineMethod( SimObject, getFieldCount, S32, (),, return list.size() - numDummyEntries; } +DefineEngineFunction(getFieldCountNS, S32, (StringTableEntry className), , + "Get the number of static fields on the name space.\n" + "@return The number of static fields defined on the object.") +{ + Namespace* ns = Con::lookupNamespace(className); + if (!ns) + return 0; + AbstractClassRep* rep = ns->mClassRep; + if (!rep) + return 0; + + const AbstractClassRep::FieldList& list = rep->mFieldList; + const AbstractClassRep::Field* f; + U32 numDummyEntries = 0; + + for (S32 i = 0; i < list.size(); i++) + { + f = &list[i]; + + // The special field types do not need to be counted. + if (f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) + numDummyEntries++; + } + + return list.size() - numDummyEntries; +} + //----------------------------------------------------------------------------- DefineEngineMethod( SimObject, getField, const char*, ( S32 index ),, @@ -3357,6 +3384,42 @@ DefineEngineMethod( SimObject, getField, const char*, ( S32 index ),, return ""; } +DefineEngineFunction(getFieldNS, const char*, (StringTableEntry className,S32 index), , + "Retrieve the value of a static field by index.\n" + "@param index The index of the static field.\n" + "@return The value of the static field with the given index or \"\".") +{ + Namespace* ns = Con::lookupNamespace(className); + if (!ns) + return 0; + AbstractClassRep* rep = ns->mClassRep; + if (!rep) + return 0; + + const AbstractClassRep::FieldList& list = rep->mFieldList; + if ((index < 0) || (index >= list.size())) + return ""; + + const AbstractClassRep::Field* f; + S32 currentField = 0; + for (U32 i = 0; i < list.size() && currentField <= index; i++) + { + f = &list[i]; + + // The special field types can be skipped. + if (f->type >= AbstractClassRep::ARCFirstCustomField || f->flag.test(AbstractClassRep::FieldFlags::FIELD_ComponentInspectors)) + continue; + + if (currentField == index) + return f->pFieldname; + + currentField++; + } + + // if we found nada, return nada. + return ""; +} + DefineEngineFunction(getClassHierarchy, const char*, (const char* name), , "Returns the inheritance hierarchy for a given class.") { From ca31e4c2c9b98981f107d52c326aa25d4e08e174 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 24 Dec 2023 03:27:18 -0600 Subject: [PATCH 6/8] leverage the new getMethodSigsNS, getFieldCountNS, and getFieldNS functions to look up methods and (hardcoded) variables from the classrep rather than creating an instance this did cost us dynamic variable listing, but that's runtime assignment as-is and can likely be referenced another route in the end --- .../data/Prototyping/UI/classPrototyping.gui | 7 ----- .../Prototyping/UI/classPrototyping.tscript | 31 +++++-------------- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui index e0aa673aa..bc30ae062 100644 --- a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui +++ b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui @@ -110,13 +110,6 @@ $guiContent = new GuiControl(classPrototyping) { profile = "ToolsGuiCheckBoxProfile"; tooltipProfile = "GuiToolTipProfile"; }; - new GuiCheckBoxCtrl(ReportDynamicVariables) { - text = "Report Dynamic Variables"; - position = "300 420"; - extent = "150 30"; - profile = "ToolsGuiCheckBoxProfile"; - tooltipProfile = "GuiToolTipProfile"; - }; }; }; //--- OBJECT WRITE END --- diff --git a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript index 341670ae2..c50c47360 100644 --- a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript +++ b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript @@ -60,21 +60,14 @@ function classPrototyping::fillClasslist(%this, %classInstance) function classPrototyping::SetNamespaceUsed(%this, %nameSpaceUsed) { ClassMethodListCtrl.deleteAllObjects(); - if (%nameSpaceUsed $= %this.instanceName) - { - %this.tempClass = %this.inst; - %this.fillMethodlist(%this.inst); - return; - } - eval("classPrototyping.tempClass = new "@ %nameSpaceUsed @"(){};"); - %this.fillMethodlist(%this.tempClass); + %this.fillMethodlist(%nameSpaceUsed); } -function classPrototyping::fillMethodlist(%this, %classInstance) +function classPrototyping::fillMethodlist(%this, %nameSpaceUsed) { ClassMethodListCtrl.deleteAllObjects(); - - %this.methodArray = %classInstance.getMethodSigs(); + %this.nameSpaceUsed = %nameSpaceUsed; + %this.methodArray = getMethodSigsNS(%nameSpaceUsed); %this.methodCount = %this.methodArray.count(); for (%i=0; %i<%this.methodCount; %i++) @@ -113,7 +106,7 @@ function classPrototyping::writeResults(%this) if (ReportCommands.isStateOn()) { - %this.commandArray = %this.tempClass.getMethodSigs(true); + %this.commandArray = getMethodSigsNS(%this.nameSpaceUsed,true); %this.commandCount = %this.commandArray.count(); echo("/* Available Commands:"); for (%i=0; %i< %this.commandCount; %i++) @@ -126,19 +119,9 @@ function classPrototyping::writeResults(%this) if (ReportVariables.isStateOn()) { echo("/* HardCoded Variables"); - for (%i=0; %i< %this.tempClass.getFieldCount(); %i++) + for (%i=0; %i< getFieldCountNS(%this.nameSpaceUsed); %i++) { - echo(%this.tempClass.getField(%i)); - } - echo("*/"); - } - - if (ReportDynamicVariables.isStateOn()) - { - echo("/* Dynamic Variables"); - for (%i=0; %i< %this.tempClass.getDynamicFieldCount(); %i++) - { - echo(getword(%this.tempClass.getDynamicField(%i),0)); + echo(getFieldNS(%this.nameSpaceUsed,%i)); } echo("*/"); } From ace243171edb1e11722cca8631cc3d9e625008ee Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 24 Dec 2023 12:03:48 -0600 Subject: [PATCH 7/8] file saving --- .../data/Prototyping/UI/classPrototyping.gui | 2 +- .../Prototyping/UI/classPrototyping.tscript | 59 +++++++++++-------- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui index bc30ae062..e01b92046 100644 --- a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui +++ b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.gui @@ -68,7 +68,7 @@ $guiContent = new GuiControl(classPrototyping) { extent = "22 22"; horizSizing = "left"; profile = "ToolsGuiButtonProfile"; - command = "SelectAssetPath.showDialog(AssetBrowser.dirHandler.currentAddress, \"setAssetTargetUpdatePath\");\nSelectAssetPathWindow.selectWindow();"; + command = "SelectAssetPath.showDialog(AssetBrowser.dirHandler.currentAddress, \"setProtoTypeFilePath\");\nSelectAssetPathWindow.selectWindow();"; tooltipProfile = "GuiToolTipProfile"; tooltip = "New Module"; }; diff --git a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript index c50c47360..aa0cb25db 100644 --- a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript +++ b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript @@ -20,7 +20,6 @@ function PrototypeClass(%classInstance) function classPrototyping::fillClasslist(%this, %classInstance) { ClassInheritanceListCtrl.deleteAllObjects(); - %this.inst = %classInstance; %this.instanceName = %classInstance.getName(); //get potentially scripted namespaces @@ -86,6 +85,11 @@ function classPrototyping::fillMethodlist(%this, %nameSpaceUsed) } } +function setProtoTypeFilePath(%targetPath) +{ + classPrototyping-->targetPath.text = %targetPath; +} + function classPrototyping::writeResults(%this) { %namespaceUsed = ""; @@ -96,33 +100,42 @@ function classPrototyping::writeResults(%this) if (%obj.isStateOn()) %namespaceUsed = getWord(%this.classlist,%inheritanceOrder); } - echo(%namespaceUsed); - for (%i=0; %i<%this.methodCount; %i++) + %file = new FileObject(); + %filename = classPrototyping-->targetPath.text @"/"@ %namespaceUsed @"."@ $TorqueScriptFileExtension; + if(%file.openForWrite(%filename)) { - %obj = "ProtoMethodSelect"@ %i; - if (%obj.isStateOn()) - echo(strreplace(%this.methodArray.getValue(%i),%this.instanceName,%namespaceUsed)); - } - - if (ReportCommands.isStateOn()) - { - %this.commandArray = getMethodSigsNS(%this.nameSpaceUsed,true); - %this.commandCount = %this.commandArray.count(); - echo("/* Available Commands:"); - for (%i=0; %i< %this.commandCount; %i++) + for (%i=0; %i<%this.methodCount; %i++) { - echo(getRecord(%this.commandArray.getValue(%i),0)); + %obj = "ProtoMethodSelect"@ %i; + if (%obj.isStateOn()) + %file.writeLine(strreplace(%this.methodArray.getValue(%i),%this.instanceName,%namespaceUsed)); } - echo("*/"); - } - if (ReportVariables.isStateOn()) - { - echo("/* HardCoded Variables"); - for (%i=0; %i< getFieldCountNS(%this.nameSpaceUsed); %i++) + if (ReportCommands.isStateOn()) { - echo(getFieldNS(%this.nameSpaceUsed,%i)); + %this.commandArray = getMethodSigsNS(%this.nameSpaceUsed,true); + %this.commandCount = %this.commandArray.count(); + %file.writeLine("/* Available Commands:"); + for (%i=0; %i< %this.commandCount; %i++) + { + %file.writeLine(getRecord(%this.commandArray.getValue(%i),0)); + } + %file.writeLine("*/"); + } + + if (ReportVariables.isStateOn()) + { + %file.writeLine("/* HardCoded Variables"); + for (%i=0; %i< getFieldCountNS(%this.nameSpaceUsed); %i++) + { + %file.writeLine(getFieldNS(%this.nameSpaceUsed,%i)); + } + %file.writeLine("*/"); } - echo("*/"); } + else + { + error( "Failed to open " @ %filename @ " for writing" ); + } + %file.delete(); } \ No newline at end of file From caa93e2179506e9b07c9478b87e89a5d4c1a0e14 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 24 Dec 2023 15:18:18 -0600 Subject: [PATCH 8/8] leverage writeapppend to add any new info requested. filter out pre-existing callback defines --- .../Prototyping/UI/classPrototyping.tscript | 83 ++++++++++++++++--- 1 file changed, 73 insertions(+), 10 deletions(-) diff --git a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript index aa0cb25db..1a2ca8fac 100644 --- a/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript +++ b/Templates/BaseGame/game/data/Prototyping/UI/classPrototyping.tscript @@ -90,6 +90,56 @@ function setProtoTypeFilePath(%targetPath) classPrototyping-->targetPath.text = %targetPath; } +function classPrototyping::readExistingLayout(%this) +{ + for (%i=0; %i<%this.classCount; %i++) + { + %inheritanceOrder = %this.classCount-(%i+1); + %obj = "ProtoClassSelect"@ %i; + if (%obj.isStateOn()) + %namespaceUsed = getWord(%this.classlist,%inheritanceOrder); + } + + %file = new FileObject(); + %filename = classPrototyping-->targetPath.text @"/"@ %namespaceUsed @"."@ $TorqueScriptFileExtension; + + if (!isObject(%this.callbacksDefined)) + %this.callbacksDefined = new arrayobject(); + %this.callbacksDefined.empty(); + %this.reportedCommands = false; + %this.reportedVariables = false; + %this.callbackBlockDefined = false; + + %key=0; + if(%file.openForRead(%filename)) + { + while (!%file.isEof()) + { + %line = %file.readLine(); + + //have we already reported commands? + if (startsWith(%line,"/* Available Commands:") ) + %this.reportedCommands = true; + + //have we already reported variables? + if (startsWith(%line,"/* HardCoded Variables") ) + %this.reportedVariables = true; + + if (startsWith(%line,"/*--- Callbacks ---*/") ) + %this.callbackBlockDefined = true; + + //get list of methods already existing + if (startswith(%line,"function "@ %namespaceUsed) ) + { + %methodName = strreplace(%line,"::"," "); + %methodName = getWord(strreplace(%methodName,"("," "),2); + %this.callbacksDefined.add(%key++,%methodName); + } + } + } + %file.delete(); +} + function classPrototyping::writeResults(%this) { %namespaceUsed = ""; @@ -100,18 +150,12 @@ function classPrototyping::writeResults(%this) if (%obj.isStateOn()) %namespaceUsed = getWord(%this.classlist,%inheritanceOrder); } + %this.readExistingLayout(); %file = new FileObject(); %filename = classPrototyping-->targetPath.text @"/"@ %namespaceUsed @"."@ $TorqueScriptFileExtension; - if(%file.openForWrite(%filename)) + if(%file.openForAppend(%filename)) { - for (%i=0; %i<%this.methodCount; %i++) - { - %obj = "ProtoMethodSelect"@ %i; - if (%obj.isStateOn()) - %file.writeLine(strreplace(%this.methodArray.getValue(%i),%this.instanceName,%namespaceUsed)); - } - - if (ReportCommands.isStateOn()) + if (ReportCommands.isStateOn() && %this.reportedCommands == false) { %this.commandArray = getMethodSigsNS(%this.nameSpaceUsed,true); %this.commandCount = %this.commandArray.count(); @@ -123,7 +167,7 @@ function classPrototyping::writeResults(%this) %file.writeLine("*/"); } - if (ReportVariables.isStateOn()) + if (ReportVariables.isStateOn() && %this.reportedVariables == false) { %file.writeLine("/* HardCoded Variables"); for (%i=0; %i< getFieldCountNS(%this.nameSpaceUsed); %i++) @@ -132,6 +176,25 @@ function classPrototyping::writeResults(%this) } %file.writeLine("*/"); } + + if (%this.callbackBlockDefined == false) + %file.writeLine("\n/*--- Callbacks ---*/\n"); + + for (%i=0; %i<%this.methodCount; %i++) + { + %obj = "ProtoMethodSelect"@ %i; + if (%obj.isStateOn()) + { + %methodDef = getRecord(%this.methodArray.getValue(%i),0); + %methodName = strreplace(%methodDef,"::"," "); + %methodName = getWord(strreplace(%methodName,"("," "),2); + if (%this.callbacksDefined.countValue(%methodName)==0) + { + echo(%methodName @ "not found. defining..."); + %file.writeLine("\n" @ strreplace(%this.methodArray.getValue(%i),%this.instanceName,%namespaceUsed)); + } + } + } } else {