概要
ノードシステムとは別のスタックとして、ECS(Entity Component System)をプラグインで提供する構想。既存のノードシステムには手を加えず、ImGuiプラグインと同じ立ち位置でオプション機能として導入する。
設計方針
全体構成
PrometeApp
├── Scene (既存のノードシステム - 変更なし)
│ └── Node階層 → Collect() → RenderCommandQueue
│
└── EcsPlugin (新規プラグイン)
└── World + Systems → RenderSystem → RenderCommandQueue
↑
同じキューに合流
コマンドキューより下(CommandRunner、バッチング、GL呼び出し)は完全に共有
ユーザーはノードとECSを好きに選べるし、混在も可能
EcsPlugin
IInitializable / IUpdatable / IDisposable を実装し、既存のプラグインライフサイクルにそのまま乗せる
Worldのライフサイクルはシーン遷移イベント(SceneWillChangeイベントに遷移種類情報を追加 #92 の SceneTransitionType)に連動して自動管理
Load → World破棄&再生成
Push → World一時停止(System実行を停止)、新World生成
Pop → 現World破棄、スタックからWorld復帰&再開
Entity / Component / World
Entity : 軽量ID + 世代番号(use-after-free防止)
Component : IComponent を実装する構造体(純粋なデータ)
World : sparse setベースのストレージ(2Dゲームの規模感ならArchetypeは過剰)
WorldはDIコンテナにシングルトンで登録
System
GameSystem 基底クラスとして定義し、DIで登録
既存のRenderCommandQueueをインジェクションして描画コマンドを生成
利用イメージ
// アプリ構築
var app = PrometeApp . Create ( )
. Use < Keyboard > ( )
. UseEcs ( ecs =>
{
ecs . AddSystem < TransformSystem > ( ) ;
ecs . AddSystem < SpriteRenderSystem > ( ) ;
} )
. BuildWithOpenGLDesktop ( ) ;
// シーンでの利用
public class BattleScene ( EcsPlugin ecs , Keyboard keyboard ) : Scene
{
private Entity _player ;
public override void OnStart ( )
{
_player = ecs . World . Create ( ) ;
ecs . World . Add ( _player , new Transform { Location = ( 100 , 200 ) } ) ;
ecs . World . Add ( _player , new SpriteRenderer { Texture = playerTex } ) ;
}
public override void OnUpdate ( )
{
ref var t = ref ecs . World . Get < Transform > ( _player ) ;
if ( keyboard [ Key . Right ] ) t . Location += ( 3 , 0 ) ;
}
}
検討事項
ZIndex / 描画順序 : ZIndexコンポーネントでRenderSystem側がソートするか、レイヤー方式にするか
階層的な変換 : Parent/Childrenコンポーネントで階層を表現し、TransformSystemが絶対座標を計算
Container系の描画制御 : IsTrimmableやMaskedContainerのPushTrim/PopTrimをECS側でどう表現するか
Textのテクスチャキャッシュ : TextRenderSystemがContent変更検知→テクスチャ再生成を担当
ノードとECSの描画合流時の順序制御 : 最初はシンプルに固定順で、必要に応じて拡張
概要
ノードシステムとは別のスタックとして、ECS(Entity Component System)をプラグインで提供する構想。既存のノードシステムには手を加えず、ImGuiプラグインと同じ立ち位置でオプション機能として導入する。
設計方針
全体構成
EcsPlugin
IInitializable/IUpdatable/IDisposableを実装し、既存のプラグインライフサイクルにそのまま乗せるSceneTransitionType)に連動して自動管理Entity / Component / World
IComponentを実装する構造体(純粋なデータ)System
GameSystem基底クラスとして定義し、DIで登録利用イメージ
検討事項