まだちゃんと分かってない。例のゲームシステム。

『花火』でゲームシステムを考える - 書き物
ここで試したゲームシステムですが、まだちゃんと理解していませんでした。


分からないところというのが、マネージャーを多段に噛ました場合のメッセージ転送方法です。
例えば次のような構成で作る場合、

GameManager implements IStageManagerCtx
┗ StageManager implements IPlayerCtx, IEnemyCtx・・・
  ┣ Player
  ┣ Enemy
  ・
  ・
  ・

PlayerがGameManagerのデータを参照したい場合、どうすれば良いか。
この場合、StageManagerがGameManagerの情報をPlayerへ橋渡しする必要があると思うのですが、
それをしようとすると路頭に迷ってしまいました。


まずはStageManagerがGameManagerからデータを取得する場合、
IStageManagerCtxにGameManagerからデータを取得する処理を定義、GameManagerで実装します。
これは前回書いた通り。


で、IPlayerCtxにStageManagerがGameManagerからデータを取得する処理を定義、StageManagerで実装・・・
とやってみたら、GameManagerからデータを取得できませんでした。
GameManagerはStageManager::execメソッドを呼ぶ際、自身を引数に指定します。
StageManager::execメソッドの引数は、context:IStageManagerCtxなわけで、
IStageManagerCtxで定義された処理を呼び出し、GameManagerからデータを取得できると。
このcontextからデータを取得する処理をIPlayerCtxに定義して、
IPlayerCtx::execメソッドを実行すれば、GameManagerのデータを取得できるはず・・・と思っていたのですが。
contextはexecの引数なので、exec以外のメソッドからはアクセスできません・・・。
なので、GameManagerのデータの取得ができないです。


対策としてほんとにパッと思いつく方法としては、
StageManagerにcontext:IStageManagerCtxをメンバとして持たせます。
これならIPlayerCtxでcontextからデータを取得する処理を定義すれば良いだけです。
確かに「メッセージを転送する」という意味では転送になるんだろうと思いますが、
StageManagerがメンバにcontextを持つという設計は、あまり美しくないんじゃないかと。


もうひとつは、

class StageManager
{
	private var _player:Player;
	
	public function exec(context:IStageManagerCtx):void
	{
		_player.exec(this, context);
	}
}

というように、Player::execメソッドをStageManagerのthisと、context:IStageManagerCtxを2つとも指定する方法です。
これも転送・・・ですかね?
ただし、PlayerがGameManagerから取得するデータをStageManagerが制限できません。
いわばPlayerのGameManagerに対するアクセス権がStageManagerと同等になってしまい、
システムの意義がなくなるんじゃないかと思います。


このゲームシステムの各クラスがどういう役割で、何をすべきなのかをちゃんと分かっていないのかもしれません。
ここを決着をつけてから先に進みたいところです。