Originally Posted by
Queuete
No sorry that wont happen.
That would be a lot more code to maintain and a lot more clutter in the codebase. Mostly for future reasons, but even currently Coroutines Multithreading is not working flaweless.
I would be interested in more details on "Makes code flexible and easy to expand". Beside replacing the "yield..." statements with appropriate Thread.Sleep statements most of the code can stay as it is.
Read
#1
Sure. I have big finite state machine describing logic (40+ states)
Code:
private IEnumerator MainCoroutine()
{
while (true)
{
var fsm = _dpContainer.GetInstance<IFsm>();
yield return fsm?.Tick();
}
}
Code:
private void InitializeHandlers()
{
_stateHandlers = new Dictionary<State, StateHandler>
{
{State.BlightPrepare, DoBlightPrepare},
{State.BlightDefend, DoBlightDefend},
{State.BlightExterminateStart, DoBlightExterminateStart},
{State.BlightExterminateRoam, DoBlightExterminateRoam},
{State.BlightExterminateEngage, DoBlightExterminateEngage},
{State.BlightExterminateFight, DoBlightExterminateFight},
Code:
public IEnumerator Tick()
{
// some extra code here
yield return _stateHandlers?[_currentState]();
}
Code:
var blightDefendTimer = new Stopwatch();
_machine.Configure(State.BlightDefend)
.OnEntry(() => blightDefendTimer.Start())
.OnExit(() => blightDefendTimer.Reset())
.OnEntry(() =>
{
BlightDefendTimer?.Start();
_buildCoroutine = null;
_logger.LogMessage("Opening map overlay", 1);
_complexInput.KeyPressRelease(Keys.Tab, 100);
})
.OnExit(() =>
{
_buildCoroutine?.Done(true);
_buildCoroutine = null;
})
.PermitIf(Trigger.BlightTimerExpired, State.BlightExterminateStart,
() => BlightDefendTimer?.Elapsed.TotalSeconds >=
_pluginSettings.BlightDefendTimeoutSecondsWithEnemies1 ||
BlightDefendTimer?.Elapsed.TotalSeconds >=
_pluginSettings.BlightDefendTimeoutSecondsNoEnemies1 &&
_blightInterface.BlightTimeLeft <= 0 &&
_entityManager?.ClosestToPumpMonster == null ||
blightDefendTimer.Elapsed.TotalMinutes > 25)
.PermitIf(Trigger.IsBlightLootPhase, State.BlightLootingStart,
() => _blightInterface.Stage == BlightStages.BlightLooting)
.PermitIf(Trigger.Died, State.Dead, BotDiedGuard);
and main part where I start another coroutine inside
Code:
private IEnumerator DoBlightDefend()
{
if (ActivateTrigger(Trigger.IsBlightFailedPhase)) yield break;
if (ActivateTrigger(Trigger.BlightTimerExpired)) yield break;
if (ActivateTrigger(Trigger.IsBlightLootPhase)) yield break;
if (_helperMethods.IsInventoryOpened()) yield return _helperMethods.CloseAllUi();
if (_blightEntityManager.IsPumpInDanger(null))
{
_logger.LogMessage("Defending pump", 1);
_buildCoroutine?.Done(true);
yield return _blightEntityManager.WalkToPump();
}
else
{
if (_buildCoroutine == null || _buildCoroutine?.IsDone == true)
{
_logger.LogMessage("Creating new builder", 1);
_buildCoroutine = new Coroutine(
_builder.Build(),
_pluginOwner,
"TD_Build");
ExileCore.Core.ParallelRunner.Run(_buildCoroutine);
}
else if (_buildCoroutine?.Running == false)
{
_logger.LogMessage("Resume builder", 1);
_buildCoroutine.Resume();
}
yield return _currentCombatRoutine?.Do();
}
if (_blightEntityManager.IsPumpInDanger(null)) yield return _currentCombatRoutine?.Fight();
}
How would u change that ? I also hope that this sample helps to create more complex plugins