From ed9ba1a7a3899888e4819771e2aa13f9c785f033 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sat, 5 Oct 2019 07:53:43 -0500 Subject: [PATCH 1/3] adds a moduleDependencySort qsort callback, and uses it in the findModule method to massage the return vector by depends order --- Engine/source/module/moduleManager.cpp | 29 +++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/Engine/source/module/moduleManager.cpp b/Engine/source/module/moduleManager.cpp index d8620c1f0..22c877594 100644 --- a/Engine/source/module/moduleManager.cpp +++ b/Engine/source/module/moduleManager.cpp @@ -38,9 +38,16 @@ #include "console/consoleTypes.h" #endif +#ifndef _MODULE_DEFINITION_H +#include "module/moduleDefinition.h" +#endif + +#ifndef _STRINGFUNCTIONS_H_ +#include "core/strings/stringFunctions.h" +#endif + // Script bindings. #include "moduleManager_ScriptBinding.h" - //----------------------------------------------------------------------------- IMPLEMENT_CONOBJECT( ModuleManager ); @@ -65,6 +72,25 @@ S32 QSORT_CALLBACK moduleDefinitionVersionIdSort( const void* a, const void* b ) return versionId1 > versionId2 ? -1 : versionId1 < versionId2 ? 1 : 0; } +S32 QSORT_CALLBACK moduleDependencySort(const void* a, const void* b) +{ + // Fetch module definitions. + ModuleDefinition* pDefinition1 = *(ModuleDefinition * *)a; + ModuleDefinition* pDefinition2 = *(ModuleDefinition * *)b; + + // Fetch version Ids. + ModuleDefinition::typeModuleDependencyVector moduleDependencies = pDefinition1->getDependencies(); + bool foundDependant = false; + for (ModuleDefinition::typeModuleDependencyVector::const_iterator dependencyItr = moduleDependencies.begin(); dependencyItr != moduleDependencies.end(); ++dependencyItr) + { + if (dStrcmp(dependencyItr->mModuleId, pDefinition2->getModuleId()) + && (dependencyItr->mVersionId == pDefinition2->getVersionId())) + foundDependant = true; + } + + return foundDependant ? 1 : -1; +} + //----------------------------------------------------------------------------- ModuleManager::ModuleManager() : @@ -1087,6 +1113,7 @@ void ModuleManager::findModules( const bool loadedOnly, typeConstModuleDefinitio moduleDefinitions.push_back( pModuleDefinition ); } } + dQsort(moduleDefinitions.address(), moduleDefinitions.size(), sizeof(ModuleDefinition*), moduleDependencySort); } //----------------------------------------------------------------------------- From 13e84eee5153b1231bfad562398bc48755fd9554 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sat, 5 Oct 2019 08:03:13 -0500 Subject: [PATCH 2/3] adds an optional entry to registerDatablock that sets a flag in the datablock files to-be-executed DatablockFilesList ArrayObject that erases relative-path duplicates and surpresses overwrites. setting it again in a sucessively executed module will take ownership of the exclusivity. otherwise, all script files follwing the same general path will be executed. adds an unRegisterDatablock to remove a given "relativePath / file" from the list sets up an automatically-cleaned ExecFilesList ArrayObject following a similar pattern, and executed for each callOnModules call, so that for instance all module::initServer(%this) entries are parsed, %this.queueExec feeds the vector, and opon completion of gathering the list, all are then executed in module-dependency order --- .../game/core/utility/scripts/module.cs | 194 +++++++++++++++++- 1 file changed, 190 insertions(+), 4 deletions(-) diff --git a/Templates/BaseGame/game/core/utility/scripts/module.cs b/Templates/BaseGame/game/core/utility/scripts/module.cs index 2ff14c1e1..a81be2bf2 100644 --- a/Templates/BaseGame/game/core/utility/scripts/module.cs +++ b/Templates/BaseGame/game/core/utility/scripts/module.cs @@ -1,5 +1,12 @@ +$traceModuleCalls=false; +$reportModuleFileConflicts=true; +if (!isObject(ExecFilesList)) + new ArrayObject(ExecFilesList); + function callOnModules(%functionName, %moduleGroup) { + //clear per module group file execution chain + ExecFilesList.empty(); //Get our modules so we can exec any specific client-side loading/handling %modulesList = ModuleDatabase.findModules(false); for(%i=0; %i < getWordCount(%modulesList); %i++) @@ -16,7 +23,14 @@ function callOnModules(%functionName, %moduleGroup) { eval(%module.scopeSet @ "." @ %functionName @ "();"); } - } + } + + %execFilecount = ExecFilesList.count(); + for (%i=0;%i<=%execFilecount;%i++) + { + %filename = ExecFilesList.getKey(%i); + exec(%filename); + } } function loadModuleMaterials(%moduleGroup) @@ -69,10 +83,12 @@ function SimSet::getModulePath(%scopeSet) return ""; } -function SimSet::registerDatablock(%scopeSet, %datablockFilePath) +function SimSet::registerDatablock(%scopeSet, %datablockFilePath, %isExclusive) { + if ($traceModuleCalls) + warn("SimSet::registerDatablock"); %name = %scopeSet.getName(); - %moduleDef = ModuleDatabase.findModule(%name); + %moduleDef = ModuleDatabase.findModule(%name, 1); if(!isObject(%moduleDef)) { @@ -89,6 +105,176 @@ function SimSet::registerDatablock(%scopeSet, %datablockFilePath) %relativePath = makeRelativePath(%datablockFilePath); %fullPath = pathConcat(%moduleDef.ModulePath, %relativePath); + ///go through all entries + %locked = false; + %dbFilecount = DatablockFilesList.count(); + for (%i=0;%i<=%dbFilecount;%i++) + { + %check = DatablockFilesList.getKey(%i); + //look for a substring match + %isMatch = strIsMatchExpr("*"@ %datablockFilePath,%check ); + if (%isMatch) + { + //check if we're already locked in + //and kill off any duplicates + //do note that doing it in this order means setting exclusive twice + //allows one to override exclusive with exclusive + %locked = DatablockFilesList.getValue(%i); + + if ((!%locked && !%isExclusive)&&($reportModuleFileConflicts)) + error("found" SPC %datablockFilePath SPC "duplicate file!"); + if (!%locked || (%locked && %isExclusive)) + { + DatablockFilesList.erase(%i); + } + } + } + //if we're not locked, or we are exclusive, go ahead and add it to the pile + //(ensures exclusives get re-added after that erasure) + if (!%locked || %isExclusive) + DatablockFilesList.add(%fullPath,%isExclusive); + if ($traceModuleCalls) + DatablockFilesList.echo(); +} + +function SimSet::unRegisterDatablock(%scopeSet, %datablockFilePath) +{ + if ($traceModuleCalls) + warn("SimSet::unRegisterDatablock"); + %name = %scopeSet.getName(); + %moduleDef = ModuleDatabase.findModule(%name, 1); + + if(!isObject(%moduleDef)) + { + error("Module::unRegisterDatablock() - unable to find a module with the moduleID of " @ %name); + return; + } - DatablockFilesList.add(%fullPath); + if(!isObject(DatablockFilesList)) + { + error("Module::unRegisterDatablock() - DatablockFilesList array object doesn't exist!"); + return; + } + + %relativePath = makeRelativePath(%datablockFilePath); + + %fullPath = pathConcat(%moduleDef.ModulePath, %relativePath); + ///go through all entries + %locked = false; + %dbFilecount = DatablockFilesList.count(); + for (%i=0;%i<=%dbFilecount;%i++) + { + %check = DatablockFilesList.getKey(%i); + //look for a substring match + %isMatch = strIsMatchExpr("*"@ %datablockFilePath,%check ); + if (%isMatch) + { + //check if we're already locked in. if not, kill it. + %locked = DatablockFilesList.getValue(%i); + if (!%locked) + { + DatablockFilesList.erase(%i); + } + } + } + if ($traceModuleCalls) + DatablockFilesList.echo(); +} + +function SimSet::queueExec(%scopeSet, %execFilePath, %isExclusive) +{ + if ($traceModuleCalls) + warn("SimSet::queueExec"); + %name = %scopeSet.getName(); + %moduleDef = ModuleDatabase.findModule(%name, 1); + + if(!isObject(%moduleDef)) + { + error("Module::queueExec() - unable to find a module with the moduleID of " @ %name); + return; + } + + if(!isObject(ExecFilesList)) + { + error("Module::queueExec() - ExecFilesList array object doesn't exist!"); + return; + } + + if ($traceModuleCalls) + warn("module root path="@ makeRelativePath(%moduleDef.ModulePath)); + + %fullPath = makeRelativePath(%moduleDef.ModulePath) @ %execFilePath; + ///go through all entries + %locked = false; + %execFilecount = ExecFilesList.count(); + for (%i=0;%i<=%execFilecount;%i++) + { + %check = ExecFilesList.getKey(%i); + //look for a substring match + %isMatch = strIsMatchExpr("*"@ %execFilePath,%check ); + if (%isMatch) + { + //check if we're already locked in + //and kill off any duplicates + //do note that doing it in this order means setting exclusive twice + //allows one to override exclusive with exclusive + %locked = ExecFilesList.getValue(%i); + if ((!%locked && !%isExclusive)&&($reportModuleFileConflicts)) + error("found" SPC %execFilePath SPC "duplicate file!"); + if (!%locked || (%locked && %isExclusive)) + { + ExecFilesList.erase(%i); + } + } + } + //if we're not locked, or we are exclusive, go ahead and add it to the pile + //(ensures exclusives get re-added after that erasure) + if (!%locked || %isExclusive) + ExecFilesList.add(%fullPath,%isExclusive); + if ($traceModuleCalls) + ExecFilesList.echo(); +} + +function SimSet::unQueueExec(%scopeSet, %execFilePath) +{ + if ($traceModuleCalls) + warn("SimSet::unRegisterDatablock"); + %name = %scopeSet.getName(); + %moduleDef = ModuleDatabase.findModule(%name, 1); + + if(!isObject(%moduleDef)) + { + error("Module::unRegisterDatablock() - unable to find a module with the moduleID of " @ %name); + return; + } + + if(!isObject(ExecFilesList)) + { + error("Module::unRegisterDatablock() - ExecFilesList array object doesn't exist!"); + return; + } + + %relativePath = makeRelativePath(%execFilePath); + + %fullPath = pathConcat(%moduleDef.ModulePath, %relativePath); + ///go through all entries + %locked = false; + %execFilecount = ExecFilesList.count(); + for (%i=0;%i<=%execFilecount;%i++) + { + %check = ExecFilesList.getKey(%i); + //look for a substring match + %isMatch = strIsMatchExpr("*"@ %execFilePath,%check ); + if (%isMatch) + { + //check if we're already locked in. if not, kill it. + %locked = ExecFilesList.getValue(%i); + if (!%locked) + { + ExecFilesList.erase(%i); + } + } + } + if ($traceModuleCalls) + ExecFilesList.echo(); } \ No newline at end of file From e7ccc362e2cee7fa836d5d9b6a3b75b057024736 Mon Sep 17 00:00:00 2001 From: AzaezelX Date: Sun, 6 Oct 2019 11:08:49 -0500 Subject: [PATCH 3/3] looks like arrayObjects return count() as size+1; one of these days should really do a consistency pass on those... --- Templates/BaseGame/game/core/utility/scripts/module.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Templates/BaseGame/game/core/utility/scripts/module.cs b/Templates/BaseGame/game/core/utility/scripts/module.cs index a81be2bf2..7d6cc5eed 100644 --- a/Templates/BaseGame/game/core/utility/scripts/module.cs +++ b/Templates/BaseGame/game/core/utility/scripts/module.cs @@ -26,7 +26,7 @@ function callOnModules(%functionName, %moduleGroup) } %execFilecount = ExecFilesList.count(); - for (%i=0;%i<=%execFilecount;%i++) + for (%i=0;%i<%execFilecount;%i++) { %filename = ExecFilesList.getKey(%i); exec(%filename); @@ -108,7 +108,7 @@ function SimSet::registerDatablock(%scopeSet, %datablockFilePath, %isExclusive) ///go through all entries %locked = false; %dbFilecount = DatablockFilesList.count(); - for (%i=0;%i<=%dbFilecount;%i++) + for (%i=0;%i<%dbFilecount;%i++) { %check = DatablockFilesList.getKey(%i); //look for a substring match @@ -162,7 +162,7 @@ function SimSet::unRegisterDatablock(%scopeSet, %datablockFilePath) ///go through all entries %locked = false; %dbFilecount = DatablockFilesList.count(); - for (%i=0;%i<=%dbFilecount;%i++) + for (%i=0;%i<%dbFilecount;%i++) { %check = DatablockFilesList.getKey(%i); //look for a substring match @@ -207,7 +207,7 @@ function SimSet::queueExec(%scopeSet, %execFilePath, %isExclusive) ///go through all entries %locked = false; %execFilecount = ExecFilesList.count(); - for (%i=0;%i<=%execFilecount;%i++) + for (%i=0;%i<%execFilecount;%i++) { %check = ExecFilesList.getKey(%i); //look for a substring match @@ -260,7 +260,7 @@ function SimSet::unQueueExec(%scopeSet, %execFilePath) ///go through all entries %locked = false; %execFilecount = ExecFilesList.count(); - for (%i=0;%i<=%execFilecount;%i++) + for (%i=0;%i<%execFilecount;%i++) { %check = ExecFilesList.getKey(%i); //look for a substring match