Scorpio, спроектируй всё нормально и нить происходящего не будет теряться, будут интервалы перед действиями и т.д. вариантов как реализовывать море. из того старого проекта, что уже упоминал немного покопипастил и подправил для наглядности
- Код: Выделить всё • Развернуть
public class JumpSensor : ISensor
{
private readonly IEventDispatcher eventDispatcher;
private FieldObjectMode modeChangedFrom;
private FieldObjectMode modeChangedTo;
public JumpSensor(IEventDispatcher eventDispatcher)
{
this.eventDispatcher = eventDispatcher;
}
public void Update()
{
var currentMode = Unit.Mode;
if (this.modeChangedTo != currentMode)
{
this.modeChangedFrom = this.modeChangedTo;
this.modeChangedTo = currentMode;
if (this.modeChangedTo == FieldObjectMode.Jump)
{
this.eventDispatcher.Dispatch(new JumpStartedEvent());
}
else if (this.modeChangedFrom == FieldObjectMode.Jump)
{
this.eventDispatcher.Dispatch(new JumpEndedEvent());
}
}
}
}
public class JumpToFieldObjectAction : IAction<JumpToFieldObjectContext>
{
private readonly ICommandDispatcher commandDispatcher;
public JumpToFieldObjectAction(ICommandDispatcher commandDispatcher)
{
this.commandDispatcher = commandDispatcher;
}
public RunStatus Execute(JumpToFieldObjectContext context)
{
this.commandDispatcher.Dispatch(new JumpToFieldObjectCommand(context.FieldObject, context.Distance));
return RunStatus.Success;
}
}
public class JumpToFieldObjectCommandHandler : ICommandHandler<JumpToFieldObjectCommand>
{
private readonly IEventDispatcher eventDispatcher;
public JumpToFieldObjectCommandHandler(IEventDispatcher eventDispatcher)
{
this.eventDispatcher = eventDispatcher;
}
public void Execute(JumpToFieldObjectCommand command)
{
command.FieldObject.JumpTo(command.Distance);
this.eventDispatcher.Dispatch(new StartJumpingToFieldObjectEvent(command.FieldObject, command.Distance));
}
}
public class CanJumpToFieldObjectCondition : ICondition<JumpToFieldObjectContext>
{
private readonly IJumpManager JumpManager;
public CanJumpToFieldObjectCondition(IJumpManager JumpManager)
{
this.JumpManager = JumpManager;
}
public bool IsSatisfies(JumpToFieldObjectContext context)
{
return this.JumpManager.CanJumpTo(context.FieldObject);
}
}
public class StartJumpingToFieldObjectEvent : IEvent
{
public StartJumpingToFieldObjectEvent(FieldObject FieldObject, double distance)
{
this.FieldObject = FieldObject;
this.Distance = distance;
}
public FieldObject FieldObject { get; }
public double Distance { get; }
}
public class JumpEndedEvent : IEvent { }
public class JumpStartedEvent : IEvent { }
public class JumpManager : IJumpManager, IEventHandler<StartJumpingToFieldObjectEvent>, IEventHandler<JumpEndedEvent>
{
private readonly ITimeoutProvider timeoutProvider;
private DateTime nextJumpAfter;
public JumpManager(ITimeoutProvider timeoutProvider)
{
this.timeoutProvider = timeoutProvider;
}
public bool CanJump()
{
if (this.nextJumpAfter > DateTime.UtcNow) return false;
if (Unit.Mode == FieldObjectMode.Jump) return false;
if (Unit.Item.Attributes.TryGetValue("JumpEnergyNeed", out attributeValue) && Unit.Energy - attributeValue.ToDouble() < 0) return false;
return true;
}
public bool CanJumpTo(IJumpable obj)
{
return this.CanJump() && obj.IsInJumpRange;
}
public void Handle(StartJumpingToFieldObjectEvent @event)
{
this.nextJumpAfter = DateTime.UtcNow + this.timeoutProvider.GetRandomTimeout(2000, 4000);
}
public void Handle(JumpEndedEvent @event)
{
this.nextJumpAfter = DateTime.UtcNow + this.timeoutProvider.GetRandomTimeout(2000, 3500);
}
}
там свои особенности и ограничения были, а работая в своём коде можно сделать намного лучше и удобней. или тот тестовый пример с зарядкой акума смутил? так он тестовый, на пощупать - как компилировать, как заливать, сколько бинарик будет занимать, как быстро что-то выполняться будет (чужие тесты с чудными данными это хорошо, но недостаточно), как стыкуется mf с конкретным мк (работа с переферией, таймерами и т.д.) и прочее. а так будет более адекватный (как там дерево это ни разу не для реального применения - старые корявые костыли, только в профиль) небольшой фреймворк с событими, планировщиками действий и использовании разных подходов (машина состояний, деревья,...) на различных уровнях, подсистемами, сервисами, псевдомногопоточностью,...
доступ к различным примерам реализации у тебя же есть, возьми и посмотри повнимательней хотя бы как на дотнете из коробки реализованы различные типы приложений, покопай роботикс студию, рос, юнити3д, поковырять игры, ботов для соревнований, как реализовано управление во всяких машинках, обучающих конструкторах и т.д.