mirror of
https://github.com/sebastiandine/Card-Collection-Manager-3.git
synced 2026-08-28 17:01:02 +00:00
55ace147bc
* initial development * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * pipeline * ci/cd * ci/cd * ci/cd * ci/cd * ci/cd * ci/cd * ci/cd * pokemon * pokemon * pokemon * pokemon * pokemon * pokemon * improvements * improvements * ci/cd * ci/cd * improvements * improvements * improvements * improvements * improvements * improvements * improvements * improvements * improvements --------- Co-authored-by: sdine <sdine@sdine.com>
4.3 KiB
4.3 KiB
app/AGENTS.md
The ccm executable — composition root only. The single place where concrete adapter types are mentioned. Read the root AGENTS.md first.
File pointers
main.cpp— the entire app. DefinesCcmApp : public wxApp, builds the dependency graph inOnInit(), then hands anAppContexttoMainFrame.CMakeLists.txt— declares theccmtarget. SetsWIN32_EXECUTABLE TRUEon Windows so no console window appears. Linksccm_core,ccm_ui_wx,ccm_warnings.
Conventions
- Composition root is the only place that names concrete adapters:
StdFileSystem,CprHttpClient,JsonCollectionRepository<MagicCard>,JsonCollectionRepository<PokemonCard>,JsonSetRepository,LocalImageStore,MagicGameModule,PokemonGameModule,MagicGameView,PokemonGameView, etc. If a concrete adapter type appears anywhere else in the codebase, move the wiring here. - Member declaration order in
CcmAppmatters — destruction is reverse, so a member that depends on another (e.g.magicCollSvc_depends onmagicRepo_andimgStore_;previewSvc_depends onhttp_and is consumed byctx_;magicView_depends on the typedmagicCollSvc_and the shared services) must be declared after its deps. Do not reorder casually. - Use
std::unique_ptrfor everything owned byCcmApp. TheAppContextthen holds plain references into those owned objects, plus a vector ofIGameView*raw pointers (theunique_ptr<>s for the views are the actual owners; the vector just describes the active set). - Game-to-directory mapping lives in
dirNameForGame(Game)(anonymous namespace). When adding a new game, extend this function — it is wired into all three repositories (JsonCollectionRepository,JsonSetRepository,LocalImageStore). config.jsonlocation is the executable's parent directory, resolved viawxStandardPaths::Get().GetExecutablePath(). Do not change this — existing installations rely on that location.- Image format handlers must be registered via
wxImage::AddHandler(new wxPNGHandler)andnew wxJPEGHandlerbefore any image is loaded. They are added inOnInit()first thing — keep it that way. - Card preview source ownership lives inside the
IGameModule. The composition root never constructs an<Name>CardPreviewSourcedirectly; it callspreviewSvc_->registerModule(*<name>Mod_)and the service pulls the module's preview source viaIGameModule::cardPreviewSource()(returningnullptris silently skipped).
Required follow-ups
- After adding a new game module you must: (1) add a
unique_ptr<<Name>GameModule>member in declaration-order-correct position, (2) construct it inOnInit(), (3) callsetSvc_->registerModule(<name>Mod_.get()), (4) callpreviewSvc_->registerModule(*<name>Mod_)(no-op when the module has no preview source), (5) extenddirNameForGame, (6) add a typedJsonCollectionRepository<<Name>Card>+CollectionService<<Name>Card>if the game has a custom card type, (7) construct a<Name>GameViewand append its raw pointer to theAppContext::gameViewsvector, (8) make sure the view'sunique_ptr<>member sits after all its deps (typed services +IGameModule). - After adding a new core service you must add a
unique_ptr<...>member, construct it inOnInit()after its deps, and add a reference field toAppContext. - After adding a new dependency edge you must verify destruction order is still correct: deps before dependents in the member list.
- After changing the IGameView contract or the AppContext shape, update
docs/adding-a-new-game.mdso the canonical procedure stays in sync.
Anti-patterns
- Don't add business logic here. If something is more than
std::make_uniqueand aregister/Bindcall, it belongs incore/. - Don't construct services on the stack inside
OnInit()— they must outlive theMainFrame, so they live asCcmAppmembers.
Commands
- Build the binary:
cmake --build build --target ccm - Run on Windows / MinGW-w64:
.\build\bin\ccm.exe. The cpr/curl/zlib DLLs are placed next to the exe automatically; the MSYS2 UCRT64 runtime (libgcc_s_seh-1.dll,libstdc++-6.dll) needs to be onPATH(e.g.P:\msys2\msys64\ucrt64\bin). On verified runs the exe loads under window title "Card Collection Manager 3".