- 処理の流れを管理するクラスと、イベントを発火するクラスを疎結合にする
- 処理の流れを分かりやすく簡潔に表現する手段の提供
- Scene遷移やAPI呼び出しなど、並列で行われると怖い処理に繋がるイベントのハンドリング
- 待機するイベントを処理の流れに応じて変えたい時
RequestPusherを使用して、各クラスでイベント発火時にRequestを投げるRequestConsumerを使用して、RequestのPushをawaitConcurrentProcessを使用して、複数のRequestConsumerの並列待機し、各Requestが来た時の処理を個別に記述
// ----- In some installer
// Request毎に独自の型を定義する必要があります
var effectRequestHandler = new RequestHandler<EffectRequest>();
Container.BindInstance<IRequestPusher<EffectRequest>>(effectRequestHandler);
var closeRequestHandler = new RequestHandler<CloseRequest>();
Container.BindInstance<IRequestPusher<CloseRequest>>(closeRequestHandler);
var nextSceneRequestHandler = new RequestHandler<NextSceneRequest>();
Container.BindInstance<IRequestPusher<NextSceneRequest>>(nextSceneRequestHandler);
var waitRequestClass = new WaitRequestClass(
effectRequestConsumer: effectRequestHandler,
closeRequestConsumer: closeRequestHandler,
nextSceneRequestConsumer: nextSceneRequestHandler
);// ----- In some object
[SerializeField] private Button _closeButton;
[Inject] private IRequestPusher<CloseRequest> _closeRequestPusher;
private void Start()
{
_closeButton.OnClickAsObservable()
.Subscribe(_ => _closeRequestPusher.PushRequest(new CloseRequest()))
.AddTo(this);
}await ConcurrentProcess.Create(
// waitTaskを抜けた時にonPassedTaskのawaitが行われます。その際、他ProcessのwaitTaskはキャンセルされます
// この仕様によって、同時にハンドリングするRequestが常に一つであることを保証します
Process.Create(
waitTask: async ct => await EffectRequestConsumer.WaitRequestAndConsumeAsync(ct),
onPassedTask: async ct =>
{
await PlayEffectAsync(ct);
// onPassedTaskでContinueを返すと、Requestの並列待機を継続する
return ProcessContinueType.Continue;
}),
Process.Create(
waitTask: async ct => await CloseRequestConsumer.WaitRequestAndConsumeAsync(ct),
onPassedTask: async ct =>
{
await CloseAsync(ct);
// onPassedTaskでBreakを返すと、LoopProcessAsyncのawaitを抜ける
return ProcessContinueType.Break;
}),
Process.Create(
waitTask: async ct => await NextSceneRequestConsumer.WaitRequestAndConsumeAsync(ct),
onPassedTask: async ct =>
{
await LoadNextSceneAsync(ct);
return ProcessContinueType.Break;
}),
)
.LoopProcessAsync(cancellationToken: ct);LiteRequestBrokerは、RequestHandlerクラスを使用せずにリクエストを送信するために使用できるクラスです。
下記のような場合に使用することをおすすめします。
- リクエストがパラメータを持たない時
- 同じリクエストが同時に待機されない時
// ----- In some installer
var liteRequestBroker = new LiteRequestBroker();
Container.BindInstance<ILiteRequestPusher>(liteRequestBroker);
Container.BindInstance<ILiteRequestConsumer>(liteRequestBroker);// ----- In some object
[SerializeField] private Button _closeButton;
[Inject] private ILiteRequestPusher _liteRequestPusher;
private void Start()
{
_closeButton.OnClickAsObservable()
// I reccommend defining a const string for each request
.Subscribe(_ => _liteRequestPusher.PushRequest("CloseRequest"))
.AddTo(this);
}await ConcurrentProcess.Create(
Process.Create(
waitTask: async ct => await LiteRequestConcumer.WaitRequestAndConsumeAsync("CloseRequest", ct),
onPassedTask: async ct =>
{
await CloseAsync(ct);
return ProcessContinueType.Break;
}),
// ...
)
.LoopProcessAsync(cancellationToken: ct);下記のdefine symbolを定義することでログ関連の実装を有効にできます。
UNITY_PROCESS_MANAGER_LOGGER
await ConcurrentProcess.CreateWithLog(
Logger, // Microsoft.Extensions.Loggingを継承したクラス(ログ出しにはZLoggerがおすすめです)
MoveToLicensesProcessProvider // IProcessProviderを継承した自作クラス
)
.LoopProcessAsync(cancellationToken: cancellationToken);var liteRequestBroker = new LiteRequestBroker(Logger);- Open the Package Manager
- Press [+▼] button and click Add package from git URL...
- Enter the following:
openupm add com.tanitaka-tech.unity-process-managerIssueやPR作成など、大歓迎です!
また、このプロジェクトに興味を持っていただけた方は、ぜひスターを付けてください!