Changyu Lee

GPP - Part 1. GoF’s Design Patterns - 1) Commander Pattern (C#, Unity)

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

Part 1. 1) Commander Pattern (C#, Unity)

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
Class InputHandler() { public void handleInput(){ if (isPressed(ButtonX) jump(); else if (isPressed(ButtonY) fireGun(); } void jump() {...} void fireGun() {...} //implicitly call the actors public void isPressed(UserInput ButtonX) //UserInput is peusdo class
C#
복사
After
class Command() { public virtual Command() {} public virtual void execute {} } class JumpCommand() : Command { public virtual void execute() { jump(); } } class FireCommand() : Command { public virtual void execute() { fireGun(); } } class InputHandler { private Command buttonX; private Command buttonY; ... public void handleInput(){ if(isPressed(ButtonX)) buttonX.execute(); ... } }
C#
복사
Constraints : the code has coupling; each function (jump & fire_gun()) finds character objects implicitly.
Solve: Pass the character object as a parameter
class JumpCommand: Command { public virtual void execute(GameActor actor) { actor.jump(); } }
C#
복사
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() {}; public virtual execute() {}; public virtual undo() {}; }
Python
복사
store previous status into variables
public class MoveUnitCommand : Command { private Unit unit; private int x, y; private int xBefore, yBefore; public MoveUnitCommand(Unit unit, int x, int y) { this.unit = unit; this.x = x; this.y = y; this.xBefore = 0; // Assuming default initialization this.yBefore = 0; } public override void Execute() { // Store previous status into variables xBefore = unit.X; // Assuming X and Y are properties of Unit yBefore = unit.Y; unit.MoveTo(x, y); // Assuming MoveTo is a method of Unit } public override void Undo() { unit.MoveTo(xBefore, yBefore); } }
C#
복사

Summary

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.
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)
This contents are originated from “Game Programming Patterns”, Robert, Hanbit Media Inc. (Korean Version)