static void Main() { Application.AddMessageFilter(new MouseWheelMessageFilter()); try { SemanticTypeSystem = new STS(); Skin = new Membrane(SemanticTypeSystem); Skin.Name = "Skin"; // Receptors = new ReceptorsContainer(); // Receptors.SemanticTypeSystem = SemanticTypeSystem; DropReceptor = new DropReceptor(Skin.ReceptorSystem); // Program.Skin.RegisterReceptor("DropReceptor", dr); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); AppState = new StatePersistence(); AppState.ReadState("appState.xml"); // Load the last application state. MainForm = MycroParser.InstantiateFromFile <Form>("mainform.xml", null); Application.Run(MainForm); AppState.WriteState("appState.xml"); // Save the application state. } catch (Exception ex) { System.Diagnostics.Debugger.Break(); } }
public void ConnectTo(Membrane newNext) { Assert.IsNull(newNext.prev); Assert.IsNull(nextJoint); nextJoint = JointWrapper.MakeJoint(this, newNext); Assert.IsNotNull(nextJoint); }
public void DoDraw() { if (current == null) { return; } if (current.nextJoint != null) { if (Mouse.RightMouseDown()) { Membrane nextNext = (Membrane)current.nextJoint.GetConnected(); current.Disconnect(); Membrane next = CreateMembrane((nextNext.transform.position + current.transform.position) / 2); current.ConnectTo(next); next.ConnectTo(nextNext); } } else { var difference = Mouse.WorldPosition() - (Vector2)current.transform.position; float springDist = current.GetNearbyRadius() + .25f; // if mouse is more than immediateSpringDist from current, make a new node if (difference.magnitude > springDist) { Membrane next = CreateMembrane((Vector2)current.transform.position + difference.normalized * springDist); current.ConnectTo(next); current = next; } } }
void FindNext() { Assert.IsNull(nextJoint); Membrane closest = null; foreach (SimplePart sibling in nearby.nearby) { if (sibling != this && sibling is Membrane m) { if (closest == null || Distance(m) < Distance(closest)) { if (m.prev == null && !m.GetNexts(minLoopSize).Contains(this)) { closest = m; } } } } if (closest != null) { ConnectTo(closest); } }
public virtual void Update(float elapsed) { // TODO: it would be nicer if this were notified when the // membrane changes to not recheck this constantly Vector3 middle = Hex.AxialToCartesian(new Hex(0, 0)); var relativeOrganellePosition = middle - organellePos; if (relativeOrganellePosition == Vector3.Zero) { relativeOrganellePosition = DefaultVisualPos; } Vector3 exit = middle - relativeOrganellePosition; var membraneCoords = organelle !.ParentMicrobe !.Membrane.GetVectorTowardsNearestPointOfMembrane(exit.x, exit.z); if (!membraneCoords.Equals(lastCalculatedPosition) || NeedsUpdateAnyway()) { float angle = GetAngle(relativeOrganellePosition); var rotation = MathUtils.CreateRotationForExternal(angle); OnPositionChanged(rotation, angle, membraneCoords); lastCalculatedPosition = membraneCoords; } }
public Tuple<ActionEnum, DirectionEnum> MyTurn(FoodMatrix eatMatrix, Membrane[,] creatures, Point position, Random random, bool hasOneBite, int energyPoints) { var action = GetAction(random, hasOneBite, energyPoints); var direction = (action == ActionEnum.Eat || action == ActionEnum.MakeChild) ? DirectionEnum.Stay : GetDirection(eatMatrix, creatures, position, random); return Tuple.Create(action, direction); }
public Speaker(double x, double c = 1e-3) : base(x) { Membrane = new Membrane(x, c) { Color = Color.Aquamarine , Mass = Mass }; }
public void InboundPermeableTo <M, T>() where M : IMembrane, new() where T : ISemanticType { Membrane m = (Membrane)RegisterMembrane <M>(); m.InboundPermeableTo <T>(); }
public override void OnUnownedJointBroke(JointWrapper joint) { if (joint.GetSource() is Membrane m) { Assert.AreEqual(m, prev, "Unexpected joint connection broke"); prev = null; } }
public override void OnConnectedTo(JointWrapper joint) { if (joint.GetSource() is Membrane m) { Assert.IsNull(prev, "Unexpected joint connection"); prev = m; } }
private Membrane CreateMembrane(Vector2 position) { Membrane next = MonoBehaviour.Instantiate(Refs.inst.membrane, current.transform.parent).GetComponent <Membrane>(); next.transform.position = position; return(next); }
/// <summary> /// Add the child (second generic type) to the outer (first generic type) membrane. /// </summary> /// <typeparam name="Outer"></typeparam> /// <typeparam name="Inner"></typeparam> /// <returns></returns> public void AddChild <Outer, Inner>() where Outer : IMembrane, new() where Inner : IMembrane, new() { Membrane mOuter = (Membrane)RegisterMembrane <Outer>(); Membrane mInner = (Membrane)RegisterMembrane <Inner>(); mOuter.AddChild(mInner); }
List <Membrane> GetNexts(int numNext) { if (nextJoint == null || numNext == 0) { return(new List <Membrane>()); } else { Membrane n = nextJoint.GetConnected() as Membrane; List <Membrane> l = n.GetNexts(numNext - 1); l.Add(n); return(l); } }
protected override DirectionEnum GetDirection(FoodMatrix eatMatrix, Membrane[,] creatures, Point position, Random random) { var points = CommonMethods.GetPoints(position); var directions = new List<DirectionEnum>(); var directionsWithFood = new List<DirectionEnum>(); foreach (var item in points) { if (!CommonMethods.IsValidAndFree(item, creatures)) continue; directions.Add(DirectionEx.DirectionByPoints(position, item)); if(eatMatrix.HasOneBite(item)) directionsWithFood.Add(DirectionEx.DirectionByPoints(position, item)); } if (directions.Count == 0) return DirectionEnum.Stay; return directionsWithFood.Count == 0 ? directions.ElementAt(random.Next(directions.Count)) : directionsWithFood.ElementAt(random.Next(directionsWithFood.Count)); }
public void SetMembrane(string membraneName) { var membrane = SimulationParameters.Instance.GetMembrane(membraneName); if (Membrane.Equals(membrane)) return; var action = new EditorAction(this, membrane.EditorCost, DoMembraneChangeAction, UndoMembraneChangeAction, new MembraneActionData(Membrane, membrane)); EnqueueAction(action); // In case the action failed, we need to make sure the membrane buttons are updated properly gui.UpdateMembraneButtons(Membrane.InternalName); }
public void SetMembrane(Membrane membrane) { if (Membrane.Equals(membrane)) { return; } throw new NotImplementedException(); // int cost = SimulationParameters::membraneRegistry().getTypeData( // string(vars.GetSingleValueByName("membrane"))).editorCost; // EditorAction@ action = EditorAction(cost, // // redo // function(EditorAction@ action, MicrobeEditor@ editor){ // editor.membrane = MembraneTypeId(action.data["membrane"]); // GenericEvent@ event = GenericEvent("MicrobeEditorMembraneUpdated"); // NamedVars@ vars = event.GetNamedVars(); // vars.AddValue(ScriptSafeVariableBlock("membrane", // SimulationParameters::membraneRegistry().getInternalName(editor.membrane))); // GetEngine().GetEventHandler().CallEvent(event); // // Calculate and send energy balance to the GUI // calculateEnergyBalanceWithOrganellesAndMembraneType( // editor.editedMicrobeOrganelles, editor.membrane, editor.targetPatch); // // not using _onEditedCellChange due to visuals not needing update // }, // // undo // function(EditorAction@ action, MicrobeEditor@ editor){ // editor.membrane = MembraneTypeId(action.data["prevMembrane"]); // GenericEvent@ event = GenericEvent("MicrobeEditorMembraneUpdated"); // NamedVars@ vars = event.GetNamedVars(); // vars.AddValue(ScriptSafeVariableBlock("membrane", // SimulationParameters::membraneRegistry().getInternalName(editor.membrane))); // GetEngine().GetEventHandler().CallEvent(event); // // Calculate and send energy balance to the GUI // calculateEnergyBalanceWithOrganellesAndMembraneType( // editor.editedMicrobeOrganelles, editor.membrane, editor.targetPatch); // } // ); // action.data["membrane"] = SimulationParameters::membraneRegistry().getTypeId( // string(vars.GetSingleValueByName("membrane"))); // action.data["prevMembrane"] = membrane; // enqueueAction(action); }
/// <summary> /// Calculates a world pos for emitting compounds /// </summary> private Vector3 CalculateNearbyWorldPosition() { // The back of the microbe var exit = Hex.AxialToCartesian(new Hex(0, 1)); var membraneCoords = Membrane.GetVectorTowardsNearestPointOfMembrane(exit.x, exit.z); // Get the distance to eject the compounds var ejectionDistance = Membrane.EncompassingCircleRadius; // The membrane radius doesn't take being bacteria into account if (Species.IsBacteria) { ejectionDistance *= 0.5f; } float angle = 180; // Find the direction the microbe is facing var yAxis = Transform.basis.y; var microbeAngle = Mathf.Atan2(yAxis.x, yAxis.y); if (microbeAngle < 0) { microbeAngle += 2 * Mathf.Pi; } microbeAngle = microbeAngle * 180 / Mathf.Pi; // Take the microbe angle into account so we get world relative degrees var finalAngle = (angle + microbeAngle) % 360; var s = Mathf.Sin(finalAngle / 180 * Mathf.Pi); var c = Mathf.Cos(finalAngle / 180 * Mathf.Pi); var ejectionDirection = new Vector3(-membraneCoords.x * c + membraneCoords.z * s, 0, membraneCoords.x * s + membraneCoords.z * c); return(Translation + (ejectionDirection * ejectionDistance)); }
/// <summary> /// This method calculates the relative rotation and translation this microbe should have to its microbe parent. /// <a href="https://randomthrivefiles.b-cdn.net/documentation/fixed_colony_rotation_explanation_image.png"> /// Visual explanation /// </a> /// </summary> /// <remarks> /// <para> /// Storing the old global translation and rotation, re-parenting and then reapplying the stored values is /// worse than this code because this code utilizes GetVectorTowardsNearestPointOfMembrane. This reduces the /// visual gap between the microbes in a colony. /// </para> /// </remarks> /// <returns>Returns relative translation and rotation</returns> private (Vector3 Translation, Vector3 Rotation) GetNewRelativeTransform() { // Gets the global rotation of the parent var globalParentRotation = ColonyParent.GlobalTransform.basis.GetEuler(); // A vector from the parent to me var vectorFromParent = GlobalTransform.origin - ColonyParent.GlobalTransform.origin; // A vector from me to the parent var vectorToParent = -vectorFromParent; // TODO: using quaternions here instead of assuming that rotating about the up/down axis is right would be nice // This vector represents the vectorToParent as if I had no rotation. // This works by rotating vectorToParent by the negative value (therefore Down) of my current rotation // This is important, because GetVectorTowardsNearestPointOfMembrane only works with non-rotated microbes var vectorToParentWithoutRotation = vectorToParent.Rotated(Vector3.Down, Rotation.y); // This vector represents the vectorFromParent as if the parent had no rotation. var vectorFromParentWithoutRotation = vectorFromParent.Rotated(Vector3.Down, globalParentRotation.y); // Calculates the vector from the center of the parent's membrane towards me with canceled out rotation. // This gets added to the vector calculated one call before. var correctedVectorFromParent = ColonyParent.Membrane .GetVectorTowardsNearestPointOfMembrane(vectorFromParentWithoutRotation.x, vectorFromParentWithoutRotation.z).Rotated(Vector3.Up, globalParentRotation.y); // Calculates the vector from my center to my membrane towards the parent. // This vector gets rotated back to cancel out the rotation applied two calls above. // -= to negate the vector, so that the two membrane vectors amplify correctedVectorFromParent -= Membrane .GetVectorTowardsNearestPointOfMembrane(vectorToParentWithoutRotation.x, vectorToParentWithoutRotation.z) .Rotated(Vector3.Up, Rotation.y); // Rotated because the rotational scope is different. var newTranslation = correctedVectorFromParent.Rotated(Vector3.Down, globalParentRotation.y); return(newTranslation, Rotation - globalParentRotation); }
protected override DirectionEnum GetDirection(FoodMatrix eatMatrix, Membrane[,] creatures, Point position, Random random) { var points = CommonMethods.GetPoints(position); var state = new Dictionary<int, int>(); foreach (var point in points) { var direction = DirectionEx.DirectionByPointsWithNumber(position, point); if (CommonMethods.IsValidAndFree(point, creatures)) state.Add(direction, eatMatrix.HasOneBite(point) ? 4 : 3); if (!CommonMethods.IsValid(point, eatMatrix.Length, eatMatrix.Height)) state.Add(direction, 1); else if (!CommonMethods.IsFree(point, creatures)) state.Add(direction, 2); } var result = _executor.Execute(CommandsForGetDirection, new MyExecutorToolset(random, state)); return DirectionEx.DirectionByNumber(int.Parse(result)); }
public static bool IsFree(Point currentPoint, Membrane[,] creatures) { return creatures[currentPoint.X, currentPoint.Y] == null; }
protected void DeserializeMembranes(MembraneDef membraneDef, Membrane membrane, List <Membrane> membraneList) { Dictionary <IReceptor, Point> receptorLocationMap = new Dictionary <IReceptor, Point>(); Dictionary <IReceptor, List <UserConfig> > configs = new Dictionary <IReceptor, List <UserConfig> >(); Point noLocation = new Point(-1, -1); membrane.Name = membraneDef.Name; membraneDef.Receptors.ForEach(n => { IReceptor r = membrane.RegisterReceptor(n.Name, n.AssemblyName); receptorLocationMap[r] = n.Location; r.Enabled = n.Enabled; configs[r] = n.UserConfigs; }); // After registration, but before the NewReceptor fire event, set the drop point. // Load all the receptors defined in this membrane first. membrane.LoadReceptors((rec) => { // Restore any user configuration values. List <UserConfig> configList; if (configs.TryGetValue(rec, out configList)) { configList.ForEach(uc => { Type rt = rec.Instance.GetType(); PropertyInfo pi = rt.GetProperty(uc.Name); string strVal = uc.Value; object val = Converter.Convert(strVal, pi.PropertyType); pi.SetValue(rec.Instance, val); }); } Point p; // Internal receptors, like ourselves, will not be in this deserialized collection. if (receptorLocationMap.TryGetValue(rec, out p)) { if (p == noLocation) { VisualizerController.View.ClientDropPoint = VisualizerController.View.GetRandomLocation(); } else { VisualizerController.View.ClientDropPoint = p; } } }); // Load the permeability configuration. We do this after loading the receptors, because // this way the permeability has been initialized via the NewReceptor event hook. membraneDef.Permeabilities.ForEach(p => { membrane.ProtocolPermeability[new PermeabilityKey() { Protocol = p.Protocol, Direction = p.Direction }] = new PermeabilityConfiguration() { Permeable = p.Permeable }; }); // Next, load the inner membrane and receptors. membraneDef.Membranes.ForEach(innerMembraneDef => { Membrane innerMembrane = membrane.CreateInnerMembrane(); membraneList.Add(innerMembrane); // Handled now by the NewMembrane event handler. // Each membrane needs a system receptor to handle, among other things, the carrier animation. // innerMembrane.RegisterReceptor("System", this); DeserializeMembranes(innerMembraneDef, innerMembrane, membraneList); }); }
public void LoadApplet(string filename) { Reset(null, EventArgs.Empty); CurrentFilename = filename; SetCaption(filename); applet = MycroParser.InstantiateFromFile <Applet>(filename, null); // Create the membranes and their containing receptors: List <Membrane> membraneList = new List <Membrane>(); membraneList.Add(Program.Skin); VisualizerController.View.StartDrop = true; VisualizerController.View.ShowMembranes = false; // don't show membranes while we're loading the applet. Causes problems because the model isn't fully loaded! // Skin is the the root membrane. It has no siblings. DeserializeMembranes(applet.MembranesDef.Membranes[0], Program.Skin, membraneList); VisualizerController.View.StartDrop = false; VisualizerController.View.ShowMembranes = true; // Create the carriers if they exist. if (applet.CarriersDef != null) { applet.CarriersDef.Carriers.ForEach(c => { ISemanticTypeStruct protocol = Program.Skin.SemanticTypeSystem.GetSemanticTypeStruct(c.Protocol); dynamic signal = Program.Skin.SemanticTypeSystem.Create(c.Protocol); Type t = signal.GetType(); c.Attributes.ForEach(attr => { PropertyInfo pi = t.GetProperty(attr.Name); TypeConverter tcFrom = TypeDescriptor.GetConverter(pi.PropertyType); if (tcFrom.CanConvertFrom(typeof(string))) { object val = tcFrom.ConvertFromInvariantString(attr.Value); pi.SetValue(signal, val); } else { throw new ApplicationException("Cannot convert string to type " + t.Name); } }); // TODO: Carriers need to specify into which membrane they are placed. Membrane inMembrane = membraneList.SingleOrDefault(m => m.Name == c.Membrane); if (inMembrane != null) { inMembrane.CreateCarrier(Program.Skin["DropReceptor"].Instance, protocol, signal); } else { // TODO: Inform user that carrier is not associated with a defined membrane. } }); } // When we're all done, recreate the connections because the membrane permeability might have changed. // TODO: Should this be an event the visualizer picks up on? VisualizerController.View.UpdateConnections(); // Inform all receptors that the system is fully initialized. Program.Skin.EndSystemInit(); }
public MembraneDrawer(Membrane startPoint) { current = startPoint; }
public static bool IsValidAndFree(Point position, Membrane[,] creatures) { return IsValid(position, creatures.GetLength(0), creatures.GetLength(1)) && IsFree(position, creatures); }
protected abstract DirectionEnum GetDirection(FoodMatrix eatMatrix, Membrane[,] creatures, Point position, Random random);