From a8a82e0b21230e876d428a8ed9b8404cfd5d30a5 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sun, 27 Nov 2011 11:44:05 +0200 Subject: Sort mods by dependencies defined by modpath/depends.txt in each mod (not mandatory) --- src/server.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/src/server.cpp b/src/server.cpp index 1d0b747bf..7229bec36 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "server.h" #include "utility.h" #include +#include #include "clientserver.h" #include "map.h" #include "jmutexautolock.h" @@ -927,20 +928,32 @@ u32 PIChecksum(core::list &l) return checksum; } +/* + Mods +*/ + struct ModSpec { std::string name; std::string path; + std::set depends; + std::set unsatisfied_depends; - ModSpec(const std::string &name_="", const std::string path_=""): + ModSpec(const std::string &name_="", const std::string path_="", + const std::set &depends_=std::set()): name(name_), - path(path_) + path(path_), + depends(depends_), + unsatisfied_depends(depends_) {} }; +// Get a dependency-sorted list of ModSpecs static core::list getMods(core::list &modspaths) { - core::list mods; + std::queue mods_satisfied; + core::list mods_unsorted; + core::list mods_sorted; for(core::list::Iterator i = modspaths.begin(); i != modspaths.end(); i++){ std::string modspath = *i; @@ -950,10 +963,38 @@ static core::list getMods(core::list &modspaths) continue; std::string modname = dirlist[j].name; std::string modpath = modspath + DIR_DELIM + modname; - mods.push_back(ModSpec(modname, modpath)); + std::set depends; + std::ifstream is((modpath+DIR_DELIM+"depends.txt").c_str(), + std::ios_base::binary); + while(is.good()){ + std::string dep; + std::getline(is, dep); + dep = trim(dep); + if(dep != "") + depends.insert(dep); + } + ModSpec spec(modname, modpath, depends); + mods_unsorted.push_back(spec); + if(depends.empty()) + mods_satisfied.push(spec); + } + } + while(!mods_satisfied.empty()){ + ModSpec mod = mods_satisfied.front(); + mods_satisfied.pop(); + mods_sorted.push_back(mod); + for(core::list::Iterator i = mods_unsorted.begin(); + i != mods_unsorted.end(); i++){ + ModSpec mod2 = *i; + if(mod2.unsatisfied_depends.empty()) + continue; + mod2.unsatisfied_depends.erase(mod.name); + if(!mod2.unsatisfied_depends.empty()) + continue; + mods_satisfied.push(mod2); } } - return mods; + return mods_sorted; } /* -- cgit v1.2.3