Repository URL to install this package:
|
Version:
2023.12.1 ▾
|
using System;
using System.Collections;
using System.Linq;
using Gs2.Core.Domain;
using Gs2.Core.Net;
using Gs2.Unity.Core;
using Gs2.Unity.Gs2StateMachine.Local.Model;
using Gs2.Unity.Util;
#if GS2_ENABLE_UNITASK
using Cysharp.Threading.Tasks;
#endif
namespace Gs2.Unity.Gs2StateMachine.Local
{
public class LocalStateMachineExecutor
{
private readonly ActiveStateMachine _activeStateMachine;
private readonly EventStream _eventStream;
private readonly SpeculativeExecuteStreamer _speculativeExecuteStreamer;
private LocalStateMachineExecutor(
ActiveStateMachine activeStateMachine,
EventStream eventStream,
SpeculativeExecuteStreamer speculativeExecuteStreamer
) {
this._eventStream = eventStream;
this._speculativeExecuteStreamer = speculativeExecuteStreamer;
this._activeStateMachine = activeStateMachine;
}
public static IFuture<LocalStateMachineExecutor> StartFuture(
Gs2Domain gs2,
GameSession gameSession,
string stateMachineNamespaceName,
string statusName
) {
IEnumerator Impl(IFuture<LocalStateMachineExecutor> self)
{
var future = gs2.StateMachine.Namespace(
stateMachineNamespaceName
).Me(
gameSession
).Status(
statusName
).ModelFuture();
yield return future;
if (future.Error != null) {
self.OnError(future.Error);
yield break;
}
var status = future.Result;
var activeStateMachine = ActiveStateMachine.Setup(
gameSession,
status
);
var eventStream = new EventStream();
eventStream.Attach(
activeStateMachine,
stateMachineNamespaceName,
statusName
);
var speculativeExecuteStreamer = new SpeculativeExecuteStreamer();
speculativeExecuteStreamer.Attach(activeStateMachine);
activeStateMachine.Start(new MapVariableValue());
self.OnComplete(new LocalStateMachineExecutor(
activeStateMachine,
eventStream,
speculativeExecuteStreamer
));
}
return new Gs2InlineFuture<LocalStateMachineExecutor>(Impl);
}
#if GS2_ENABLE_UNITASK
public static async UniTask<LocalStateMachineExecutor> StartAsync(
Gs2Domain gs2,
GameSession gameSession,
string stateMachineNamespaceName,
string statusName
) {
var status = await gs2.StateMachine.Namespace(
stateMachineNamespaceName
).Me(
gameSession
).Status(
statusName
).ModelAsync();
var activeStateMachine = ActiveStateMachine.Setup(
gameSession,
status
);
var eventStream = new EventStream();
eventStream.Attach(
activeStateMachine,
stateMachineNamespaceName,
statusName
);
var speculativeExecuteStreamer = new SpeculativeExecuteStreamer();
speculativeExecuteStreamer.Attach(activeStateMachine);
activeStateMachine.Start(new MapVariableValue());
return new LocalStateMachineExecutor(
activeStateMachine,
eventStream,
speculativeExecuteStreamer
);
}
#endif
public MapVariableValue CurrentVariables => this._activeStateMachine.CurrentVariables;
public MapVariableValue Variables(string stateMachineName) {
return this._activeStateMachine.Variables(stateMachineName);
}
public ActiveStateMachineStatus Status => this._activeStateMachine.Status;
public string LastError => this._activeStateMachine.LastError;
public void Emit(string eventName, MapVariableValue parameters) {
this._activeStateMachine.Emit(eventName, parameters);
}
public event ActiveStateMachine.ChangeStateHandler OnChangeState
{
add => this._activeStateMachine.OnChangeState += value;
remove => this._activeStateMachine.OnChangeState -= value;
}
public event EventStream.DetectStateMismatchHandler OnDetectStateMismatch
{
add => this._eventStream.OnDetectStateMismatch += value;
remove => this._eventStream.OnDetectStateMismatch -= value;
}
public Gs2Future DispatchFuture(
Gs2Domain gs2,
GameSession gameSession
) {
IEnumerator Impl(Gs2Future self)
{
{
var future = this._eventStream.DispatchFuture(
gs2,
gameSession
);
yield return future;
if (future.Error != null) {
self.OnError(future.Error);
yield break;
}
}
{
var future = this._speculativeExecuteStreamer.DispatchFuture(
gs2,
gameSession
);
yield return future;
if (future.Error != null) {
self.OnError(future.Error);
yield break;
}
}
self.OnComplete(null);
}
return new Gs2InlineFuture(Impl);
}
#if GS2_ENABLE_UNITASK
public async UniTask DispatchAsync(
Gs2Domain gs2,
GameSession gameSession
) {
await this._eventStream.DispatchAsync(
gs2,
gameSession
);
await this._speculativeExecuteStreamer.DispatchAsync(
gs2,
gameSession
);
}
#endif
}
}