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);