diff --git a/documents/docs/networking/commands/README.md b/documents/docs/networking/commands/README.md new file mode 100644 index 0000000..a7401b0 --- /dev/null +++ b/documents/docs/networking/commands/README.md @@ -0,0 +1,29 @@ +# Commands +Commands are the primary extension point of the server. +Every client-facing operation e.g. checking a username, sending a chat message, joining a lobby is implemented as a command. +Each command consists of four classes: a **Parser**, a **Request**, a **Handler**, and a **Response**. + +The infrastructure for routing and dispatching commands lives in the `network/` layer and is intentionally kept generic. +The concrete implementations for each command live in `app/commands/` and are wired together at startup in `ServerApp`. + +![Overview of all components directly related to executing requests](/documents/images/docs/networking/commands/overview.svg) + +## Contents +### Guides +*Link to guides* + +### Reference +*Link to technical deep dives* + +## Key Concepts +**Each command is self-contained.** +A command's Parser, Request, Handler, and Response all live in the same package under `app/commands//`. +This keeps related code co-located and makes it easy to reason about a single command without navigating across multiple directories. + +**The `network/` layer knows nothing about specific commands.** +`CommandParser` and `CommandHandler` are generic interfaces. The `CommandParserDispatcher` and `CommandRouter` operate on those interfaces. +Adding a new command **never** requires modifying infrastructure code. + +**Registration happens at the composition root.** +All commands are wired in `ServerApp` by calling `parserDispatcher.register(...)` and `commandRouter.register(...)`. +This keeps the wiring explicit and compiler-checked. diff --git a/documents/images/docs/networking/commands/overview.puml b/documents/images/docs/networking/commands/overview.puml new file mode 100644 index 0000000..112f52e --- /dev/null +++ b/documents/images/docs/networking/commands/overview.puml @@ -0,0 +1,33 @@ +@startuml +skinparam backgroundColor transparent + +package "network/ (infrastructure)" { + class PrimitiveRequest <> + interface CommandParser + interface CommandHandler + class CommandParserDispatcher + class CommandRouter + abstract class Request + abstract class Response + + PrimitiveRequest --> CommandParserDispatcher : routes + PrimitiveRequest ..> CommandParser : parsed by + CommandParserDispatcher --> CommandParser : routes to + CommandParser --> Request : parses to + Request --> CommandRouter : routes + CommandRouter --> CommandHandler : routes to + Request ..> CommandHandler : executed by + CommandHandler --> Response : creates +} + +package "app/commands// (per command)" { + class ExampleParser implements CommandParser + class ExampleRequest extends Request + class ExampleHandler implements CommandHandler + class ExampleResponse extends Response + + ExampleParser --> ExampleRequest : parses to + ExampleRequest --> ExampleHandler : executed by + ExampleHandler --> ExampleResponse : produces +} +@enduml \ No newline at end of file diff --git a/documents/images/docs/networking/commands/overview.svg b/documents/images/docs/networking/commands/overview.svg new file mode 100644 index 0000000..8bc887d --- /dev/null +++ b/documents/images/docs/networking/commands/overview.svg @@ -0,0 +1 @@ +network/ (infrastructure)app/commands/<name>/ (per command)«record»PrimitiveRequestCommandParserT extends RequestCommandHandlerT extends RequestCommandParserDispatcherCommandRouterRequestResponseExampleParserCommandParserExampleRequestRequestExampleHandlerCommandHandlerExampleResponseResponseroutesparsed byroutes toparses toroutesroutes toexecuted bycreatesparses toexecuted byproduces \ No newline at end of file