public async Task InsertRaceConditionTestAsync() { var h = new Hero(0, 0, 0, null, null); var algorithm = new BehaviourAlgorithm(h); const int count = 100; var tasks = new Task[count]; for (var i = 0; i < tasks.Length; i++) { tasks[i] = Task.Run(() => algorithm.Insert(new ShootElement())); } await Task.WhenAll(tasks); Assert.AreEqual(count, algorithm.CodeElements.Count); }
public async Task RemoveRaceConditionTestAsync() { var h = new Hero(0, 0, 0, null, null); const int count = 100; var algorithm = new BehaviourAlgorithm(h); for (var i = 0; i < count; i++) { algorithm.Insert(new ShootElement()); } var tasks = new Task[count]; for (var i = 0; i < tasks.Length; i++) { var element = new ShootElement(); tasks[i] = Task.Run(() => algorithm.RemoveAt(0)); } await Task.WhenAll(tasks); CollectionAssert.IsEmpty(algorithm.CodeElements); }
/// <summary> /// Deserializes JSON string to BehaviourAlgorithm. /// </summary> /// <param name="json"></param> /// <returns>Deserialized BehaviourAlgorithm object.</returns> public static BehaviourAlgorithm ToBehaviourAlgorithm(string json, Hero hero) { var jsonVal = JArray.Parse(json) as JArray; dynamic elements = jsonVal; var algorithm = new BehaviourAlgorithm(hero); foreach (var element in elements) { algorithm.Insert(DeserializeCodeElementInternal(element)); } return(algorithm); BaseCodeElement DeserializeCodeElementInternal(dynamic element) { BaseCodeElement ret; switch ((string)element["type"]) { case "ShootElement": ret = new ShootElement(new RateLimiter(Design.ShootElementCooldown)); break; case "IdleElement": ret = new IdleElement(); break; case "CodeBlockElement": var children = new List <BaseCodeElement>(); foreach (var child in element.elements) { children.Add(DeserializeCodeElementInternal(child)); } ret = new CodeBlockElement(children); break; case "BranchingElement": var thenBlock = new List <BaseCodeElement>(); var elseBlock = new List <BaseCodeElement>(); try { foreach (var child in [email protected]) { thenBlock.Add(DeserializeCodeElementInternal(child)); } } catch (RuntimeBinderException) { } try { foreach (var child in [email protected]) { elseBlock.Add(DeserializeCodeElementInternal(child)); } } catch (RuntimeBinderException) { } ret = new BranchingElement( DeserializeConditionElementInternal(element["cond"]), new CodeBlockElement(thenBlock), new CodeBlockElement(elseBlock) ); break; case "TargetElement": ret = new TargetElement(); break; case "MoveAwayFromElement": ret = new MoveAwayFromElement(); break; default: ret = null; break; } if (element["isActive"] is JValue jv) { bool.TryParse(jv.Value.ToString(), out bool b); ret.IsActive = b; } return(ret); } BaseConditionElement DeserializeConditionElementInternal(dynamic element) { if (element is null) { return(null); } switch ((string)element["type"]) { case "IsEnemyNearCondition": return(new IsEnemyNearCondition()); default: return(null); } } }