Changyu Lee

GPP - Part 1. GoF’s Design Patterns - 1) Commander Pattern

Published at
2024/01/08
Last edited time
2024/03/02 00:09
Created
2024/01/07 13:56
Section
Unity
Status
Done
Series
Tags
Theory
AI summary
Keywords
SW ENG Theory
Game Programming Pattern
Design Pattern
Language

Part 1. 1) Commander Pattern

Commander Pattern

Capsulate the command itself. Through this, make different users who have different inputs parameter, wait or logging the users’ requests and supporting the restore operation.
= Command Patterns reify calling functions.
“reifing” means changing the concept into object.
“reifing calling functions” means that wrapping calling functions with objects
it is equal to express callbacks (or function pointer) with OOP (Object-Oriented Programming)

Example

Changing the Input keys
X → JUMP() Y → FURE_GUN() Z → LURCH() X → SWAP_WEAPON()
Before
void InputHandler::handleInput(){ if (isPressed(BUTTON_X) jump(); else if (isPressed(BUTTON_Y) fireGun(); }
Python
복사
After
class Command() { public: virtual ~Command() {} virtual void execute {} } class JumpCommand() : public Command { public: virtual void execute() { jump(); } } class FireCommand() : public Command { public: virtual void execute() { fireGun(); } } class InputHandler { public: void handelInput(); private: Command* buttonX_; Command* buttonY_; ... } void InputHandler::handelInput() { if(isPressed(BUTTON_X)) buttonX_->execute(); ... }
Python
복사
Constraints : the code has coupling; each function (jump & fire_gun()) finds character objects implicitly.
Solve: Pass the character object as a parameter
class JumpCommand: public Command { public: virtual void execute(GameActor& actor) { actor.jump(); } }
Python
복사
Key idea: one abstract class between actor and command
From now on, we can handle all the actors cause we used Command Pattern by passing the actors as a parameter !

Other Use Case

Command Stream
AI (Input Handler, Producer) → Command Stream → Actor (Dispatcher, Subscriber)
Undo Command
define virtual method undo()
class Command() { public: virtual ~Command() {} virtual void execute() = 0; virtual void undo() = 0; }
Python
복사
store previous status into variables
class MoveUnitCommand : public Command() { public: MoveUnitCommand(Unit* unit, int x, int y) { : unit_(unit), x_(x), y_(y), xBefore_(0), yBefore(0), x_(x), y_(y) { } virtual void execute() { //store previous satus into variables xBefore = unit_->x(); yBefore = unit_->y(); unit_->moveTo(x_, y_); virtual void undo() { unit_-> moveTo(xBefore_, yBefore_); } private: Unit* unit_; int x_, y_; int xBefore, yBefore; };
Python
복사
Chain of Responsibility
if objects can react to the command and can assign processing command to sub-objects, it could be the Chain of Responsiblity Pattern.

Summary

1.
I would say Commander Pattern is making abstract class for the command to do decoupling user’s input and actors
2.
Commander Pattern can be utilized to implement the undo function

Reference

There are some commands only have actions without status. If so, making many instances of the command classes are memory-wasting job. It can be solved by the Lightweight Patterns
This contents are originated from “Game Programming Patterns”, Robert, Hanbit Media Inc. (Korean Version)