protected override Action <TMessage> FindReceiver(IInlet <TMessage> inletSendingMessage) { var leftReceiver = LeftOutlet.FindReceiver(); var rightReceiver = RightOutlet.FindReceiver(); if (leftReceiver == null) { return(rightReceiver); } if (rightReceiver == null) { return(leftReceiver); } switch (TieBreaker.ResolveTie()) { case TieResult.Left: return(leftReceiver); case TieResult.Right: return(rightReceiver); default: throw new ArgumentOutOfRangeException(); } }
protected override Action <TMessage> FindReceiverFor <TMessage>(IInlet <TMessage> inletSendingMessage) { var outlet = inletOutletBiLookup[inletSendingMessage].Single(); var typedOutlet = (IOutlet <TMessage>)outlet; return(typedOutlet.FindReceiver()); }
//renamed to ReadInlet public object this[IInlet <object> inlet] { get { if (inlet == null) { return(null); } if (inletProducts.TryGetValue(inlet, out object obj)) { return(obj); } return(null); } set { if (inletProducts.ContainsKey(inlet)) { inletProducts[inlet] = value; } else { inletProducts.Add(inlet, value); } } }
public void UnlinkGenerator(Generator gen) /// Removes all links from and to this generator { List <IInlet <object> > genLinks = new List <IInlet <object> >(); //both that connected to this gen inlets and outlets foreach (var kvp in links) { IInlet <object> inlet = kvp.Key; IOutlet <object> outlet = kvp.Value; //unlinking this from others (not needed on remove, but Unlink could be called not only on remove) if (inlet.Gen == gen) { genLinks.Add(inlet); } //unlinking others from this if (outlet.Gen == gen) { genLinks.Add(inlet); } } foreach (IInlet <object> inlet in genLinks) { links.Remove(inlet); } //cachedBackwardLinks = null; }
public static ITestInput CreateTestInput(GameObject go, IInlet <TransitionsList> inlet, TransitionsList trsList) { Mesh mesh = new Mesh(); mesh.vertices = new Vector3[] { new Vector3(-.5f, -.5f, -.5f), new Vector3(.5f, -.5f, -.5f), new Vector3(.5f, .5f, -.5f), new Vector3(-.5f, .5f, -.5f), new Vector3(-.5f, .5f, .5f), new Vector3(.5f, .5f, .5f), new Vector3(.5f, -.5f, .5f), new Vector3(-.5f, -.5f, .5f) }; mesh.triangles = new int[] { 0, 2, 1, 0, 3, 2, 2, 3, 4, 2, 4, 5, 1, 2, 5, 1, 5, 6, 0, 7, 4, 0, 4, 3, 5, 4, 7, 5, 7, 6, 0, 6, 7, 0, 1, 6 }; for (int t = 0; t < trsList.count; t++) { GameObject trsGo = new GameObject(); MeshRenderer renderer = trsGo.AddComponent <MeshRenderer>(); MeshFilter filter = trsGo.AddComponent <MeshFilter>(); filter.mesh = mesh; trsGo.transform.localScale = new Vector3(5, 5, 5); trsGo.name = "Object" + t; trsGo.transform.position = trsList.arr[t].pos; trsGo.transform.parent = go.transform; } ObjectsIn objsIn = new ObjectsIn() { parent = go.transform }; return(objsIn); }
private void CacheBackwardLinks() { Dictionary <IOutlet <object>, HashSet <IInlet <object> > > bck = new Dictionary <IOutlet <object>, HashSet <IInlet <object> > >(); foreach (var kvp in links) { IInlet <object> inlet = kvp.Key; IOutlet <object> outlet = kvp.Value; HashSet <IInlet <object> > linkedInlets; if (!bck.TryGetValue(outlet, out linkedInlets)) { linkedInlets = new HashSet <IInlet <object> >(); bck.Add(outlet, linkedInlets); } if (!linkedInlets.Contains(inlet)) { linkedInlets.Add(inlet); } //TODO: check if we really need to check if it's added (maybe use list) } Dictionary <IOutlet <object>, IInlet <object>[]> newBck = new Dictionary <IOutlet <object>, IInlet <object>[]>(); foreach (var kvp in bck) { newBck.Add(kvp.Key, kvp.Value.ToArray()); } //cachedBackwardLinks = newBck; }
public Action <TMessage> FindReceiver <TMessage>(IInlet <TMessage> inletSendingMessage) { if (!PipeInlets.Contains(inletSendingMessage)) { throw new InvalidOperationException("The inlet sending the message is not associated to this pipe."); } return(FindReceiverFor(inletSendingMessage)); }
public StateGroup(IInlet firstState, List <IOutlet> lastStates, TimeSpan?stateTimeoutDuration = null, StateExit exit = null) : base(stateTimeoutDuration: stateTimeoutDuration, exit: exit) { this.Entrance.Transition(firstState); foreach (IOutlet lastState in lastStates) { lastState.Transition(this.Exit); } }
/// <summary> /// Sets the outlet. This should be called before state is left! /// </summary> /// <param name="outlet">The callback to use.</param> public void SetOutlet(IInlet outlet, List <User> specificUsers = null) { if (outlet == null) { throw new ArgumentNullException("Outlet cannot be null"); } SetOutlet(() => outlet, specificUsers); }
/// Simply gets inlet's link public void UnlinkInlet(IInlet <object> inlet) { if (links.ContainsKey(inlet)) { links.Remove(inlet); } //cachedBackwardLinks = null; }
protected override Action <TSourceMessage> FindReceiver(IInlet <TSourceMessage> inletSendingMessage) { var receiver = Outlet.FindReceiver(); if (receiver == null) { return(null); } return(m => receiver(Map(m))); }
public static PopupMenu.Item InsertItems(Vector2 mousePos, Graph graph, IInlet <object> inlet, int priority = 4) { IOutlet <object> outlet = graph.GetLink(inlet); PopupMenu.Item insertItems; if (inlet != null && outlet != null) { Type genericLinkType = Generator.GetGenericType(inlet); PopupMenu.Item createItems = CreateItems(mousePos, graph); PopupMenu.Item catItems = createItems.Find(GetCategoryByType(genericLinkType)); insertItems = catItems.Find("Modifiers"); //adding link to all create actions foreach (PopupMenu.Item item in insertItems.All(true)) { if (item.onClick != null) { Action baseOnClick = item.onClick; item.onClick = () => { baseOnClick(); Generator createdGen = graph.generators[graph.generators.Length - 1]; //the last on is the one that's just created. Hacky if (createdGen != null && Generator.GetGenericType((Generator)createdGen) == genericLinkType) { //inlet graph.AutoLink(createdGen, outlet); //outlet if (createdGen is IOutlet <object> createdOutlet) { graph.Link(createdOutlet, inlet); } } GraphWindow.RefreshMapMagic(createdGen); }; } } } else { insertItems = new PopupMenu.Item("Add"); insertItems.onDraw = RightClick.DrawItem; insertItems.disabled = true; } insertItems.name = "Add (Insert)"; insertItems.icon = RightClick.texturesCache.GetTexture("MapMagic/Popup/Create"); insertItems.color = Color.gray; insertItems.priority = priority; return(insertItems); }
protected override Action <T> FindReceiverFor <T>(IInlet <T> inletSendingMessage) { var inlet = (IInlet <TSourceMessage>)inletSendingMessage; var receiver = FindReceiver(inlet); if (receiver == null) { return(null); } return(m => receiver((TSourceMessage)(object)m)); }
public override T ReadInlet <T> (IInlet <T> inlet) { if (inlet == null) { return(null); } if (inletProducts.TryGetValue(inlet, out object obj)) { return((T)obj); } return(null); }
public static ITestInput CreateTestInput(GameObject go, IInlet <SplineSys> inlet, SplineSys splineSys) { SplineObject splineObj = go.AddComponent <SplineObject>(); splineObj.splineSys = splineSys; SplineInout splineIn = new SplineInout() { splineObj = splineObj }; return(splineIn); }
protected override Action <TMessage> FindReceiver(IInlet <TMessage> inletSendingMessage) { var receivers = Outlets.Select((outlet, index) => new Tuple <int, Action <TMessage> >(index, outlet.FindReceiver())).Where(t => t.Item2 != null).ToList(); if (!receivers.Any()) { return(null); } var result = TieBreaker.ResolveTie(receivers.Select(s => s.Item1)); return(receivers.Single(s => s.Item1 == result).Item2); }
/// <summary> /// Sets the outlet generator. This should be called before state is entered! /// </summary> /// <param name="outletGenerator">This will be called at the last moment to determine the inlet to transition to.</param> public void SetOutlet(Func <IInlet> outletGenerator, List <User> specificUsers = null) { //Debug.WriteLine(Invariant($"|||STATE SETUP|||{this.StateId}|{this.GetType()}|{(specificUsers == null ? "all users" : string.Join(", ", specificUsers.Select(user => user.DisplayName)))}")); IInlet nextState = null; void InternalOutlet(User user, UserStateResult result, UserFormSubmission input) { // An outlet should only ever be called once per user. Ignore extra calls (most likely a timeout thread). if (this.HaveAlreadyCalledOutlet.TryUpdate(user, newValue: true, comparisonValue: true)) { return; } // Throw if not able to set called outlet bit. if (!this.HaveAlreadyCalledOutlet.TryAdd(user, true)) { throw new Exception($"Issue updating the called outlet bit for user '{user.Id}'"); } if (outletGenerator == null) { var prompt = user.UserState.UserRequestingCurrentPrompt(user); string thisStateSummary = string.Empty; if (this is State badCodingPractice) { thisStateSummary = badCodingPractice.GetSummary(user); } throw new Exception(Invariant($"Outlet not defined for User '{user.DisplayName}'\n Executing state: '{this.GetType()}:[{thisStateSummary}]\n User state: '{user.UserState.GetType()}:[{user.UserState.GetSummary(user)}]'.\n\n State Stack: '{string.Join(",\n",user.StateStack.ToArray().Select(state => $"{state.GetType()}:[{state.GetSummary(user)}]"))}'")); } if (nextState == null) { nextState = outletGenerator(); } nextState.Inlet(user, result, input); } if (specificUsers == null) { this.InternalOutlet = InternalOutlet; } else { foreach (User user in specificUsers) { this.UserOutletOverrides[user] = InternalOutlet; } } }
public bool CheckLinkValidity(IOutlet <object> outlet, IInlet <object> inlet) { if (Generator.GetGenericType(outlet) != Generator.GetGenericType(inlet)) { return(false); } if (AreDependent(inlet.Gen, outlet.Gen)) //in this order { return(false); } return(true); }
protected void Disconnect <TMessage>(IInlet <TMessage> inlet, IOutlet <TMessage> outlet) { Try(() => { if (inlet == null || outlet == null || inlet.ConnectedOutlet != outlet || outlet.ConnectedInlet != inlet) { throw new InvalidOperationException("The inlet and outlet were not connected"); } inlet.ConnectedOutlet = null; outlet.ConnectedInlet = null; activeResourceGroup.DisconnectSharedResources(inlet.SharedResource, outlet.SharedResource); }); }
public virtual T ReadInlet <T> (IInlet <T> inlet) where T : class //virtual to override in tester mockup { if (!linksLut.TryGetValue(inlet, out IOutlet <object> outlet)) { return(null); } if (outlet == null) { return(null); } if (products.TryGetValue(outlet, out object obj)) { return((T)obj); } return(null); }
protected override Action <TMessage> FindReceiver(IInlet <TMessage> inletSendingMessage) { var receivers = Outlets.Select(o => o.FindReceiver()).Where(r => r != null).ToList(); if (receivers.Count != Outlets.Count) { return(null); } return(message => { foreach (var receiver in receivers) { receiver(message); } }); }
protected void Connect <TMessage>(IInlet <TMessage> inlet, IOutlet <TMessage> outlet, bool checkPipeSystemFormsTree) { Try(() => { if (!inlet.CanConnect()) { throw new InvalidOperationException("The inlet was not ready to connect."); } if (!outlet.CanConnect()) { throw new InvalidOperationException("The outlet was not ready to connect."); } inlet.ConnectedOutlet = outlet; outlet.ConnectedInlet = inlet; if (checkPipeSystemFormsTree && !inlet.Pipe.CreateGraphOfPipeSystem().IsTree()) { inlet.ConnectedOutlet = null; outlet.ConnectedInlet = null; throw new InvalidOperationException("Connecting these pipes results in a pipe system that does not form a tree."); } activeResourceGroup.ConnectSharedResources(inlet.SharedResource, outlet.SharedResource); while (true) { var sender = outlet.Pipe.FindSender(outlet); if (sender == null) { return; } var receiver = inlet.Pipe.FindReceiver(inlet); if (receiver != null) { receiver(sender()); } else { return; } } }); }
/// <summary> /// A convenience method for creating an adapter for an inlet pair. /// This will automatically connect the adapter to the internal inlet and pass events between the adapter and external inlet. /// /// The external inlet should be the inlet the world can interact with, while the internal inlet is the corresponding inlet of /// our internal pipe system - the implementation of this pipe. /// </summary> protected IAdapterOutlet <TMessage> CreateAndConnectAdapter <TMessage>(IInlet <TMessage> internalInlet, IInlet <TMessage> externalInlet) { var promisedPipe = new Promised <IPipe>(); promisedPipe.Fulfill(this); var adapterOutlet = new AdapterOutlet <TMessage>(promisedPipe); SharedResource.ConnectTo(adapterOutlet.SharedResource); adapterOutlets.Add(adapterOutlet); inletOutletBiLookup.Add(externalInlet, adapterOutlet); // Do not check if the graph forms a tree - it probably doesn't as all adapters are connected // to this pipe. However, messages should never be passed in a cycle or violate the "tree-ness" nevertheless. adapterOutlet.ConnectTo(internalInlet, false); return(adapterOutlet); }
public static Type GetGenericType(IInlet <object> inlet) { if (inlet is IInlet <MatrixWorld> ) { return(typeof(MatrixWorld)); } else if (inlet is IInlet <TransitionsList> ) { return(typeof(TransitionsList)); } else if (inlet is IInlet <SplineSys> ) { return(typeof(SplineSys)); } else { return(GetGenericType(inlet.GetType())); } }
protected override Action <TMessage> FindReceiver(IInlet <TMessage> inletSendingMessage) { var leftReceiver = LeftOutlet.FindReceiver(); var rightReceiver = RightOutlet.FindReceiver(); if (leftReceiver == null) { return(null); } if (rightReceiver == null) { return(null); } return(message => { leftReceiver(message); rightReceiver(message); }); }
public static ITestInput CreateTestInput(GameObject go, IInlet <object> inlet, object product) { if (inlet is IInlet <MatrixWorld> mInlet) //checking inlet class, not product: product could be null { return(CreateTestInput(go, mInlet, (MatrixWorld)product)); } if (inlet is IInlet <TransitionsList> tInlet) { return(CreateTestInput(go, tInlet, (TransitionsList)product)); } if (inlet is IInlet <SplineSys> sInlet) { return(CreateTestInput(go, sInlet, (SplineSys)product)); } Debug.Log("Create Test: Skipping inlet of unknown type"); return(null); }
public static ITestInput CreateTestInput(GameObject go, IInlet <MatrixWorld> inlet, MatrixWorld matrix) { Terrain terrain = CreateTerrain(go); int terrainRes = Mathf.NextPowerOfTwo(matrix.rect.size.x - 1) + 1; float resFactor = 1f * terrainRes / matrix.rect.size.x; terrain.terrainData.heightmapResolution = terrainRes; float[,] arr2D = new float[terrainRes, terrainRes]; matrix.ExportHeights(arr2D); terrain.terrainData.SetHeights(0, 0, arr2D); terrain.transform.position = matrix.worldPos; terrain.terrainData.size = new Vector3(matrix.worldSize.x * resFactor, matrix.worldSize.y, matrix.worldSize.z * resFactor); //since terrainRes is usually about 2 times bigger TerrainInout terrIn = new TerrainInout() { terrain = terrain }; return(terrIn); }
public void Link(IOutlet <object> outlet, IInlet <object> inlet) { //unlinking if (outlet == null && links.ContainsKey(inlet)) { links.Remove(inlet); } //linking else //if (CheckLinkValidity(outlet, inlet)) { if (links.ContainsKey(inlet)) { links[inlet] = outlet; } else { links.Add(inlet, outlet); } } //cachedBackwardLinks = null; }
protected override Action <TMessage> FindReceiver(IInlet <TMessage> inletSendingMessage) { if (storedMessages.Any()) { if (HasSpareCapacity()) { return(message => storedMessages.Enqueue(message)); } } else { var receiver = Outlet.FindReceiver(); if (receiver != null) { return(receiver); } if (HasSpareCapacity()) { return(message => storedMessages.Enqueue(message)); } } return(null); }
private void DrawGraph () // {using (Timer.Start("DrawGraph")) { //background #if MM_DOC float gridColor = 0.25f; float gridBackgroundColor = 0.25f; #else float gridColor = !StylesCache.isPro ? 0.45f : 0.14f; //0.135f; float gridBackgroundColor = !StylesCache.isPro ? 0.5f : 0.16f; //0.16f; #endif Draw.StaticGrid( displayRect: new Rect(0, 0, Screen.width, Screen.height-toolbarSize), cellSize:32, color:new Color(gridColor,gridColor,gridColor), background:new Color(gridBackgroundColor,gridBackgroundColor,gridBackgroundColor), fadeWithZoom:true); //drawing groups foreach (Group group in graph.groups) using (Cell.Custom(group.guiPos.x, group.guiPos.y, group.guiSize.x, group.guiSize.y)) { GroupDraw.DragGroup(group, graph.generators); GroupDraw.DrawGroup(group); } //dragging nodes foreach (Generator gen in graph.generators) GeneratorDraw.DragGenerator(gen, selected); //drawing links //using (Timer.Start("Links")) if (!UI.current.layout) { List<(IInlet<object> inlet, IOutlet<object> outlet)> linksToRemove = null; foreach (var kvp in graph.links) { IInlet<object> inlet = kvp.Key; IOutlet<object> outlet = kvp.Value; Cell outletCell = UI.current.cellObjs.GetCell(outlet, "Outlet"); Cell inletCell = UI.current.cellObjs.GetCell(inlet, "Inlet"); if (outletCell == null || inletCell == null) { Debug.LogError("Could not find a cell for inlet/outlet. Removing link"); if (linksToRemove == null) linksToRemove = new List<(IInlet<object> inlet, IOutlet<object> outlet)>(); linksToRemove.Add((inlet,outlet)); continue; } GeneratorDraw.DrawLink( GeneratorDraw.StartCellLinkpos(outletCell), GeneratorDraw.EndCellLinkpos(inletCell), GeneratorDraw.GetLinkColor(inlet) ); } if (linksToRemove != null) foreach ((IInlet<object> inlet, IOutlet<object> outlet) in linksToRemove) { graph.UnlinkInlet(inlet); graph.UnlinkOutlet(outlet); } } //removing null generators (for test purpose) for (int n=graph.generators.Length-1; n>=0; n--) { if (graph.generators[n] == null) ArrayTools.RemoveAt(ref graph.generators, n); } //drawing generators //using (Timer.Start("Generators")) foreach (Generator gen in graph.generators) using (Cell.Custom(gen.guiPosition.x, gen.guiPosition.y, GeneratorDraw.nodeWidth, 0)) { if (gen is IPortalEnter<object> || gen is IPortalExit<object> || gen is IFunctionInput<object> || gen is IFunctionOutput<object>) GeneratorDraw.DrawPortal(gen, graph, selected:selected.Contains(gen)); else { try { GeneratorDraw.DrawGenerator(gen, graph, selected:selected.Contains(gen)); } catch (ExitGUIException) { } //ignoring catch (Exception e) { Debug.LogError("Draw Graph Window failed: " + e); } } } //de-selecting nodes (after dragging and drawing since using drag obj) if (!UI.current.layout) { GeneratorDraw.SelectGenerators(selected); GeneratorDraw.DeselectGenerators(selected); } //add/remove button //using (Timer.Start("AddRemove")) using (Cell.Full) DragDrawAddRemove(); //right click menu (should have access to cellObjs) if (!UI.current.layout && Event.current.type == EventType.MouseDown && Event.current.button == 1) RightClick.DrawRightClickItems(graphUI, graphUI.mousePos, graph); //create menu on space if (!UI.current.layout && Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Space && !Event.current.shift) CreateRightClick.DrawCreateItems(graphUI.mousePos, graph); //delete selected generators if (selected!=null && selected.Count!=0 && Event.current.type==EventType.KeyDown && Event.current.keyCode==KeyCode.Delete) GraphEditorActions.RemoveGenerators(graph, selected); }