private void AddPrivate(NeuralBucket bucket) { if (_itemsByToken.ContainsKey(bucket.Token)) { throw new ArgumentException("This bucket has already been added"); } // Find the wrapper with the least to do TaskWrapper wrapper = _tasks. Select(o => new { Count = o.Count, Wrapper = o }). OrderBy(o => o.Count). First().Wrapper; // Add to the wrapper wrapper.AddRemoves.Enqueue(Tuple.Create(bucket, true)); // Remember where it is _itemsByToken.Add(bucket.Token, Tuple.Create(bucket, wrapper)); }
private void RemovePrivate(NeuralBucket bucket) { if (!_itemsByToken.ContainsKey(bucket.Token)) { throw new ArgumentException("This bucket was never added"); } TaskWrapper wrapper = _itemsByToken[bucket.Token].Item2; // Remove from the wrapper wrapper.AddRemoves.Enqueue(Tuple.Create(bucket, false)); // Forget where it was _itemsByToken.Remove(bucket.Token); }
public void Add(NeuralBucket bucket) { lock (_lockInstance) { AddPrivate(bucket); } }
public void Remove(NeuralBucket bucket) { lock (_lockInstance) { RemovePrivate(bucket); } }
private void btnAdvanceBrainOne_Click(object sender, RoutedEventArgs e) { try { if (_links == null) { MessageBox.Show("There are no neural links", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } NeuralBucket worker = new NeuralBucket(_links.Outputs.SelectMany(o => UtilityCore.Iterate(o.InternalLinks, o.ExternalLinks)).ToArray()); worker.Tick(); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private static void OperateBrain(NeuralBucket worker, CancellationToken cancel) { //NOTE: This method is running on an arbitrary thread try { while (!cancel.IsCancellationRequested) { worker.Tick(); } } catch (Exception) { // Don't leak errors, just go away } }
private void StartBrainOperation() { // Make sure an existing operation isn't running CancelBrainOperation(); if (_links == null) { // There are no links, so there is nothing to do return; } // Hand all the links to the worker NeuralBucket worker = new NeuralBucket(_links.Outputs.SelectMany(o => UtilityCore.Iterate(o.InternalLinks, o.ExternalLinks)).ToArray()); _brainOperationCancel = new CancellationTokenSource(); // Run this on an arbitrary thread _brainOperationTask = Task.Factory.StartNew(() => { OperateBrain(worker, _brainOperationCancel.Token); }, _brainOperationCancel.Token); }
public Bot(BotConstruction_Result construction) { _options = construction.ArgsExtra.Options; _itemOptions = construction.ArgsExtra.ItemOptions; _radiation = construction.ArgsExtra.Radiation; _gravity = construction.ArgsExtra.Gravity; _cameraPool = construction.ArgsExtra.CameraPool; _parts = construction.PartConstruction; _thrusters = construction.PartConstruction.GetStandardParts<Thruster>(Thruster.PARTTYPE).ToArray(); _projectileGuns = construction.PartConstruction.GetStandardParts<ProjectileGun>(ProjectileGun.PARTTYPE).ToArray(); _updatableParts_MainThread = construction.UpdatableParts_MainThread; _updatableParts_AnyThread = construction.UpdatableParts_AnyThread; _dna = construction.DNA; _dnaParts = construction.DNAParts; this.Model = construction.Model; _visualEffects = construction.VisualEffects; _isPhysicsStatic = construction.ArgsExtra.IsPhysicsStatic; this.PhysicsBody = construction.PhysicsBody; this.Radius = construction.Radius; _partTransformToModel = _parts.AllPartsArray. Select(o => { Transform3DGroup transform = new Transform3DGroup(); transform.Children.Add(new TranslateTransform3D(-o.Position.ToVector())); transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(o.Orientation.ToReverse()))); return transform; }). ToArray(); // Hook up events if (!_isPhysicsStatic) { this.PhysicsBody.ApplyForceAndTorque += new EventHandler<BodyApplyForceAndTorqueArgs>(PhysicsBody_ApplyForceAndTorque); } foreach (var part in _parts.AllPartsArray) { part.RequestWorldLocation += new EventHandler<PartRequestWorldLocationArgs>(Part_RequestWorldLocation); part.RequestWorldSpeed += new EventHandler<PartRequestWorldSpeedArgs>(Part_RequestWorldSpeed); part.RequestParent += new EventHandler<PartRequestParentArgs>(Part_RequestParent); part.Resurrected += Part_Resurrected; part.Destroyed += Part_Destroyed; } // See if there are parts that can gradually change the ship's mass if ((_parts.Containers.Fuels.Count > 0 && _parts.StandardParts.ContainsKey(Thruster.PARTTYPE)) || (_parts.Containers.CargoBays.Count > 0 && (_parts.StandardParts.ContainsKey(ConverterMatterToEnergy.PARTTYPE) || _parts.StandardParts.ContainsKey(ConverterMatterToFuel.PARTTYPE))) || (_parts.Containers.Energies.Count > 0 && _parts.Containers.Fuels.Count > 0 && (_parts.StandardParts.ContainsKey(ConverterEnergyToFuel.PARTTYPE) || _parts.StandardParts.ContainsKey(ConverterFuelToEnergy.PARTTYPE))) ) { _hasMassChangingUpdatables_Small = true; } else { _hasMassChangingUpdatables_Small = false; } if (_parts.Containers.Ammos.Count > 0 && _parts.StandardParts.ContainsKey(ProjectileGun.PARTTYPE)) { _hasMassChangingUpdatables_Medium = true; } else { _hasMassChangingUpdatables_Medium = false; } // Set up a neural processor on its own thread/task _neuronLinks = construction.Links; if (_neuronLinks != null) { var bucketTask = AddToNeuralPool(_neuronLinks); _neuralPoolAddTask = bucketTask.Item1; _linkBucket = bucketTask.Item2; } _lifeEvents = construction.PartConstruction.LifeEventWatcher; this.ShouldRecalcMass_Large = false; this.ShouldRecalcMass_Small = false; this.CreationTime = DateTime.UtcNow; }
public static Tuple<Task<NeuralBucket>, NeuralBucket> AddToNeuralPool(NeuralUtility.ContainerOutput[] links) { // Create the bucket NeuralBucket bucket = new NeuralBucket(links.SelectMany(o => UtilityCore.Iterate(o.InternalLinks, o.ExternalLinks)).ToArray()); // Add to the pool from another thread. This way the lock while waiting to add won't tie up this thread Task<NeuralBucket> task = Task.Run(() => { NeuralPool.Instance.Add(bucket); return bucket; }); return Tuple.Create(task, bucket); }