From dab2f8ede6513c12092b3238b1e13a92f9463ac9 Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Fri, 26 Apr 2024 04:58:41 -0400 Subject: [PATCH] Decouple the generator and the starmap defs. I changed it to use string lookups. This permits hardcoded strings in the table, which defeats a bit of static checking -- but the goal is to permit those strings also at runtime so folks can define their own generators as plugins. Further, the decoupling means that there's less tight coupling between how the generator works and how the map is defined -- fewer forward decls and constants for each race, etc. --- sc2/src/uqm/gendef.c | 19 +---- sc2/src/uqm/gendef.h | 2 +- sc2/src/uqm/plandata.c | 10 +-- sc2/src/uqm/planets/generate-base.cpp | 72 +++++++++++++++++-- sc2/src/uqm/planets/generate.h | 7 ++ .../uqm/planets/generate/gencol-modern.cpp | 16 +++-- .../uqm/planets/generate/genshof-modern.cpp | 11 +-- .../uqm/planets/generate/gensly-modern.cpp | 11 +-- sc2/src/uqm/planets/planets.h | 4 +- sc2/src/uqm/planets/solarsys.c | 3 +- sc2/src/uqm/uqmdebug.c | 3 +- 11 files changed, 105 insertions(+), 53 deletions(-) diff --git a/sc2/src/uqm/gendef.c b/sc2/src/uqm/gendef.c index fac9ce2f8..634717a04 100644 --- a/sc2/src/uqm/gendef.c +++ b/sc2/src/uqm/gendef.c @@ -50,24 +50,18 @@ extern GenerateFunctions generateYehatFunctions; extern GenerateFunctions generateZoqFotPikFunctions; extern GenerateFunctions generateZoqFotPikScoutFunctions; -extern GenerateFunctions *getGenerateCxxFunctions( void ); - - -extern struct GeneratorBase cxxDefaultPlanetGen; - const GenerateFunctions * -getGenerateFunctions (STAR_DESC *const star, void **sup, const char **supArg ) +getGenerateFunctions (STAR_DESC *const star) { - *sup= star->supplement; - *supArg= 0; - switch (star->Index) { // Legacy ones are disabled... case SHOFIXTI_DEFINED: case SLYLANDRO_DEFINED: case START_COLONY_DEFINED: + case CXX_DEFINED: + default: abort(); case SOL_DEFINED: @@ -137,13 +131,6 @@ getGenerateFunctions (STAR_DESC *const star, void **sup, const char **supArg ) return &generateRainbowWorldFunctions; case ILWRATH_DEFINED: return &generateIlwrathFunctions; - default: - *sup= &cxxDefaultPlanetGen; - // FALLTHROUGH - - // Eventually everything should go thru this. - case CXX_DEFINED: - return getGenerateCxxFunctions(); } } diff --git a/sc2/src/uqm/gendef.h b/sc2/src/uqm/gendef.h index 3d1d099c7..c2b6b4e90 100644 --- a/sc2/src/uqm/gendef.h +++ b/sc2/src/uqm/gendef.h @@ -8,7 +8,7 @@ extern "C" { #endif -const GenerateFunctions *getGenerateFunctions (STAR_DESC *star, void **sup, const char **arg ); +const GenerateFunctions *getGenerateFunctions (STAR_DESC *star); enum { diff --git a/sc2/src/uqm/plandata.c b/sc2/src/uqm/plandata.c index 0ab6829a6..75d73a2ed 100644 --- a/sc2/src/uqm/plandata.c +++ b/sc2/src/uqm/plandata.c @@ -21,10 +21,6 @@ #include "planets/planets.h" #include "planets/elemdata.h" -extern struct GeneratorBase slyDef; -extern struct GeneratorBase shofDef; -extern struct GeneratorBase colonyDef; - // This array has to be sorted in Y coordinate order then X coordinate order. // Items out of order can cause crashes (better, actually) or "ghost" // stars in the map that cannot be entered. @@ -542,8 +538,8 @@ STAR_DESC starmap_array[] = #endif //{{2908, 269}, MAKE_STAR (DWARF_STAR, BLUE_BODY, -1), SHOFIXTI_DEFINED, 4, 82}, - {{1004, 1083}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), CXX_DEFINED, 2, 27, &slyDef}, - {{1776, 1395}, MAKE_STAR (DWARF_STAR, YELLOW_BODY, -1), CXX_DEFINED, 0, 98, &colonyDef}, + {{1004, 1083}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 2, 27, "Slylandro"}, + {{1776, 1395}, MAKE_STAR (DWARF_STAR, YELLOW_BODY, -1), 0, 0, 98, "Colony"}, {{1777, 1405}, MAKE_STAR (DWARF_STAR, YELLOW_BODY, -1), 0, 0, 99}, @@ -552,7 +548,7 @@ STAR_DESC starmap_array[] = {{1752, 1450}, MAKE_STAR (DWARF_STAR, YELLOW_BODY, -1), SOL_DEFINED, 0, 129}, - {{1848, 1469}, MAKE_STAR (DWARF_STAR, BLUE_BODY, -1), CXX_DEFINED, 4, 82, &shofDef}, + {{1848, 1469}, MAKE_STAR (DWARF_STAR, BLUE_BODY, -1), 0, 4, 82, "Shofixti"}, {{1751, 1479}, MAKE_STAR (GIANT_STAR, GREEN_BODY, -1), URQUAN_WRECK_DEFINED, 1, 59}, {{1707, 1501}, MAKE_STAR (DWARF_STAR, GREEN_BODY, -1), 0, 0, 52}, diff --git a/sc2/src/uqm/planets/generate-base.cpp b/sc2/src/uqm/planets/generate-base.cpp index 1696d35c7..ab5e73455 100644 --- a/sc2/src/uqm/planets/generate-base.cpp +++ b/sc2/src/uqm/planets/generate-base.cpp @@ -16,9 +16,16 @@ #include "uqm/planets/generate.h" +#include #include +#include +#include + +#include +#include #include "uqm/planets/generate/gendefault.h" +#include "uqm/gendef.h" /* * XXX: Note that the way that defaults get called via C++ is a bit @@ -171,18 +178,69 @@ namespace Planets ::detail:: Generate_m namespace { - class RealDefaultGenerator - : public DefaultGenerator + auto & + registry() { - public: - ~RealDefaultGenerator() override= default; - }; + static std::map< std::string, std::unique_ptr< Generator > > r; + return r; + } + + auto init= [] + { + class RealDefaultGenerator + : public DefaultGenerator + { + public: + ~RealDefaultGenerator() override= default; + }; + Generator::add( ".default", std::make_unique< RealDefaultGenerator >() ); + return 0xDEADBEEF; + }(); + } + + void + Generator::add( const std::string &name, std::unique_ptr< Generator > gen ) + { + registry()[ name ]= std::move( gen ); } - } extern "C" { - Planets::detail::Generate_m::RealDefaultGenerator cxxDefaultPlanetGen; + using Planets::SolarSystem; + using Planets::detail::Generate_m::registry; + + extern GenerateFunctions *getGenerateCxxFunctions( void ); + + void + SetupGeneratorForSolarSystem( STAR_DESC *const desc, SolarSystem *const solarSys ) + { + // Must either have a legacy constructor or a named lookup, + // but not both. + + // If there's a legacy builder, we must have no supplement. + // We just go to the old way of doing things... + if( desc->Index ) + { + assert( desc->supplement == nullptr ); + solarSys->genFuncs= getGenerateFunctions( desc ); + return; + } + + // If we've a supplement, there should be no legacy. + + solarSys->genFuncs= getGenerateCxxFunctions(); // By default we pull up into C++ + + const std::string name= desc->supplement == nullptr ? ".default" : desc->supplement; + + if( not registry().count( name ) ) + { + throw std::runtime_error{ "Solar System generator " + name + " is missing" }; + } + + solarSys->genSupplement= registry().at( name ).get(); + + solarSys->supArgument= desc->supArg; + } } diff --git a/sc2/src/uqm/planets/generate.h b/sc2/src/uqm/planets/generate.h index 2f76dbddc..2eb7e089f 100644 --- a/sc2/src/uqm/planets/generate.h +++ b/sc2/src/uqm/planets/generate.h @@ -116,9 +116,14 @@ struct GenerateFunctions { PickupLifeFunction pickupLife; }; +void SetupGeneratorForSolarSystem( STAR_DESC *desc, SOLARSYS_STATE *state ); + #if defined(__cplusplus) } // extern "C" +#include +#include + namespace Planets ::detail:: Generate_m { inline namespace exports @@ -133,6 +138,8 @@ namespace Planets ::detail:: Generate_m : public GeneratorBase { public: + static void add( const std::string &name, std::unique_ptr< Generator > ); + virtual ~Generator()= 0; virtual void initNpcs( SolarSystem *solarSys )= 0; diff --git a/sc2/src/uqm/planets/generate/gencol-modern.cpp b/sc2/src/uqm/planets/generate/gencol-modern.cpp index b074af422..a28ed5305 100644 --- a/sc2/src/uqm/planets/generate/gencol-modern.cpp +++ b/sc2/src/uqm/planets/generate/gencol-modern.cpp @@ -33,16 +33,18 @@ namespace : public DefaultGenerator { public: - void initNpcs( SolarSystem *solarSys) override; - bool generatePlanets( SolarSystem *solarSys) override; + void initNpcs( SolarSystem *solarSys ) override; + bool generatePlanets( SolarSystem *solarSys ) override; bool generateOrbital( SolarSystem *solarSys, - PLANET_DESC *world) override; + PLANET_DESC *world ) override; }; -} -extern "C" -{ - GenerateColony colonyDef; + auto init= [] + { + Generator::add( "Colony", std::make_unique< GenerateColony >() ); + + return 0xDEADBEEF; + }(); } diff --git a/sc2/src/uqm/planets/generate/genshof-modern.cpp b/sc2/src/uqm/planets/generate/genshof-modern.cpp index 30e6e3f9f..2dd7da5a4 100644 --- a/sc2/src/uqm/planets/generate/genshof-modern.cpp +++ b/sc2/src/uqm/planets/generate/genshof-modern.cpp @@ -39,13 +39,14 @@ namespace static void check_old_shofixti (); }; -} -extern "C" -{ - GenerateShofixti shofDef; -} + auto init= [] + { + Generator::add( "Shofixti", std::make_unique< GenerateShofixti >() ); + return 0xDEADBEEF; + }(); +} void GenerateShofixti::initNpcs( SolarSystem *const solarSys ) diff --git a/sc2/src/uqm/planets/generate/gensly-modern.cpp b/sc2/src/uqm/planets/generate/gensly-modern.cpp index 6406a82c6..1f6541eb4 100644 --- a/sc2/src/uqm/planets/generate/gensly-modern.cpp +++ b/sc2/src/uqm/planets/generate/gensly-modern.cpp @@ -58,9 +58,12 @@ namespace return DefaultGenerator::generateOrbital( solarSys, world ); } }; + + auto init= [] + { + Generator::add( "Slylandro", std::make_unique< GenerateSlylandro >() ); + + return 0xDEADBEEF; + }(); } -extern "C" -{ - GenerateSlylandro slyDef; -} diff --git a/sc2/src/uqm/planets/planets.h b/sc2/src/uqm/planets/planets.h index 45ad9b926..bc53c7103 100644 --- a/sc2/src/uqm/planets/planets.h +++ b/sc2/src/uqm/planets/planets.h @@ -142,8 +142,8 @@ struct star_desc BYTE Prefix; BYTE Postfix; - void *supplement; // The CXX builder's pointer gets put here. - void *supArg; // Extra info for the CXX builder goes here. + const char *supplement; // The CXX builder's name gets put here. + const char *supArg; // Extra info for the CXX builder goes here. }; struct node_info diff --git a/sc2/src/uqm/planets/solarsys.c b/sc2/src/uqm/planets/solarsys.c index c02accd2f..f805f004d 100644 --- a/sc2/src/uqm/planets/solarsys.c +++ b/sc2/src/uqm/planets/solarsys.c @@ -1735,8 +1735,7 @@ ExploreSolarSys (void) memset (pSolarSysState, 0, sizeof (*pSolarSysState)); - SolarSysState.genFuncs = getGenerateFunctions (CurStarDescPtr, &SolarSysState.genSupplement, - &SolarSysState.supArgument); + SetupGeneratorForSolarSystem( CurStarDescPtr, &SolarSysState ); InitSolarSys (); SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE); diff --git a/sc2/src/uqm/uqmdebug.c b/sc2/src/uqm/uqmdebug.c index 7dc8fba84..231982411 100644 --- a/sc2/src/uqm/uqmdebug.c +++ b/sc2/src/uqm/uqmdebug.c @@ -645,8 +645,7 @@ starRecurse (STAR_DESC *star, void *arg) SolarSysState.SunDesc[0].location.x = 0; SolarSysState.SunDesc[0].location.y = 0; //SolarSysState.SunDesc[0].radius = MIN_ZOOM_RADIUS; - SolarSysState.genFuncs = getGenerateFunctions (star, &SolarSysState.genSupplement, - &SolarSysState.supArgument); + SetupGeneratorForSolarSystem( star, &SolarSysState ); pSolarSysState = &SolarSysState; (*SolarSysState.genFuncs->generatePlanets) (&SolarSysState);