Exemple #1
0
		private void OnGUI() { DrawWindow(); if (repaint) DrawWindow(); repaint = false; } //drawing window, or doing it twice if repaint is needed
		private void DrawWindow()
		{
			if (gens == null) return;

			//un-selecting field on drag
			#if !UNITY_EDITOR_LINUX
			if (Event.current.button != 0  &&  UnityEngine.GUI.GetNameOfFocusedControl() != "Temp") RemoveFocusOnControl();
			#endif

			//startingscript.layout
			
			if (gens.layout==null) 
				{ gens.layout = new Layout(); gens.layout.scroll = gens.guiScroll; gens.layout.zoom = gens.guiZoom; gens.layout.maxZoom = 1f; }
			gens.layout.Zoom(); gens.layout.Scroll(); //scrolling and zooming
			if (gens.layout.zoom < 0.0001f) gens.layout.zoom = 1;
			gens.layout.field = this.position;

			//zoomning with keyboard
			if (Event.current.type == EventType.KeyDown)
			{
				if (Event.current.keyCode==KeyCode.Equals && Event.current.alt) { gens.layout.zoom += gens.layout.zoomStep; if (gens.layout.zoom>1) gens.layout.zoom=1; Event.current.Use(); }
				if (Event.current.keyCode==KeyCode.Minus && Event.current.alt) { gens.layout.zoom -= gens.layout.zoomStep; Event.current.Use(); }
			}
			
			//unity 5.4 beta
			if (Event.current.type == EventType.Layout) return; 

			if (Event.current.type == EventType.MouseDrag) //skip all mouse drags (except when dragging text selection cursor in field)
			{
				if (!UnityEditor.EditorGUIUtility.editingTextField) return;
				if (UnityEngine.GUI.GetNameOfFocusedControl() == "Temp") return; 
			}

			//using middle mouse click events
			if (Event.current.button == 2) Event.current.Use();

			//undo
			Undo.undoRedoPerformed -= PerformUndo;
			Undo.undoRedoPerformed += PerformUndo;

			//setting title content
			titleContent = new GUIContent("Map Magic");
			titleContent.image =gens.layout.GetIcon("MapMagic_WindowIcon");

			//drawing background
			Vector2 windowZeroPos =gens.layout.ToInternal(Vector2.zero);
			windowZeroPos.x = ((int)(windowZeroPos.x/64f)) * 64; 
			windowZeroPos.y = ((int)(windowZeroPos.y/64f)) * 64; 

			Texture2D backTex = gens.layout.GetIcon("MapMagic_Background");
			Rect backRect = new Rect(windowZeroPos - new Vector2(64,64), position.size + new Vector2(127,127));
			UnityEditor.EditorGUI.DrawPreviewTexture(new Rect(0,0,position.width,position.height), backTex, null, ScaleMode.ScaleAndCrop);
			gens.layout.Icon(backTex, backRect, tile:true);

			//drawing test center
			//script.layout.Button("Zero", new Rect(-10,-10,20,20));

			//calculating visible area
			Rect visibleArea = gens.layout.ToInternal( new Rect(0,0,position.size.x,position.size.y) );
			if (forceAll) { visibleArea = new Rect(-200000,-200000,400000,400000); forceAll = false; }
			//visibleArea = new Rect(visibleArea.x+100, visibleArea.y+100, visibleArea.width-200, visibleArea.height-200);
			//layout.Label("Area", helpBox:true, rect:visibleArea);

			//checking if all generators are loaded, and none of them is null
			for (int i=gens.list.Length-1; i>=0; i--)
			{
				if (gens.list[i] == null) { ArrayTools.RemoveAt(ref gens.list, i); continue; }
				foreach (Generator.Input input in gens.list[i].Inputs()) 
				{
					if (input == null) continue;
					if (input.linkGen == null) input.Link(null, null);
				}
			}

			#region Drawing groups
				for(int i=0; i<gens.list.Length; i++)
				{
					if (!(gens.list[i] is Group)) continue;
					Group group = gens.list[i] as Group;

					//checking if this is withinscript.layout field
					if (group.guiRect.x > visibleArea.x+visibleArea.width || group.guiRect.y > visibleArea.y+visibleArea.height ||
						group.guiRect.x+group.guiRect.width < visibleArea.x || group.guiRect.y+group.guiRect.height < visibleArea.y) 
							if (group.guiRect.width > 0.001f && gens.layout.dragState != Layout.DragState.Drag) continue; //if guiRect initialized and not dragging

					//settingscript.layout data
					group.layout.field = group.guiRect;
					group.layout.scroll = gens.layout.scroll;
					group.layout.zoom = gens.layout.zoom;

					group.OnGUI(gens);

					group.guiRect = group.layout.field;
				}
			#endregion

			#region Drawing connections (before generators to make them display under nodes)

				foreach(Generator gen in gens.list)
				{
					foreach (Generator.Input input in gen.Inputs())
					{
						if (input==null || input.link == null) continue; //input could be null in layered generators
						if (gen is Portal)
						{ 
							Portal portal = (Portal)gen;
							if (!portal.drawInputConnection) continue;
						}
						gens.layout.Spline(input.link.guiConnectionPos, input.guiConnectionPos, color:GeneratorsAsset.CanConnect(input.link,input)? input.guiColor : Color.red);
					}
				}
			#endregion

			#region creating connections (after generators to make clicking in inout work)

			int dragIdCounter = gens.list.Length+1;
				foreach (Generator gen in gens.list)
					foreach (Generator.IGuiInout inout in gen.Inouts())
				{
					if (inout == null) continue;
					if (gens.layout.DragDrop(inout.guiRect, dragIdCounter))
					{
						//finding target
						Generator.IGuiInout target = null;
						foreach (Generator gen2 in gens.list)
							foreach (Generator.IGuiInout inout2 in gen2.Inouts())
								if (inout2.guiRect.Contains(gens.layout.dragPos)) target = inout2;

						//converting inout to Input (or Output) and target to Output (or Input)
						Generator.Input input = inout as Generator.Input;		if (input==null) input = target as Generator.Input;
						Generator.Output output = inout as Generator.Output;	if (output==null) output = target as Generator.Output;

						//connection validity test
						bool canConnect = input!=null && output!=null && GeneratorsAsset.CanConnect(output,input);

						//infinite loop test
						if (canConnect)
						{ 
							Generator outputGen = output.GetGenerator(gens.list);
							Generator inputGen = input.GetGenerator(gens.list);
							if (inputGen == outputGen || gens.CheckDependence(inputGen,outputGen)) canConnect = false;
						}

						//drag
						//if (script.layout.dragState==Layout.DragState.Drag) //commented out because will not be displayed on repaint otherwise
						//{
							if (input == null)gens.layout.Spline(output.guiConnectionPos,gens.layout.dragPos, color:Color.red);
							else if (output == null)gens.layout.Spline(gens.layout.dragPos, input.guiConnectionPos, color:Color.red);
							else gens.layout.Spline(output.guiConnectionPos, input.guiConnectionPos, color:canConnect? input.guiColor : Color.red);
						//}

						//release
						if (gens.layout.dragState==Layout.DragState.Released && input!=null) //on release. Do nothing if input not defined
						{
							Undo.RecordObject (gens, "MapMagic Connection"); 
							gens.setDirty = !gens.setDirty;

							input.Unlink();
							if (canConnect) input.Link(output, output.GetGenerator(gens.list));
							if (mapMagic!=null) 
							{
								mapMagic.ClearResults(gen);
								mapMagic.Generate();
							}

							EditorUtility.SetDirty(gens);
						}
					}
					dragIdCounter++;
				}
			#endregion

			#region Drawing generators

				for(int i=0; i<gens.list.Length; i++)
				{
					Generator gen = gens.list[i];
					if (gen is Group) continue; //skipping groups

					//checking if this generator is withinscript.layout field
					if (gen.guiRect.x > visibleArea.x+visibleArea.width || gen.guiRect.y > visibleArea.y+visibleArea.height ||
						gen.guiRect.x+gen.guiRect.width < visibleArea.x || gen.guiRect.y+gen.guiRect.height < visibleArea.y) 
							if (gen.guiRect.width > 0.001f && gens.layout.dragState != Layout.DragState.Drag) continue; //if guiRect initialized and not dragging

					if (gen.layout == null) gen.layout = new Layout();
					gen.layout.field = gen.guiRect;
					gen.layout.field.width = 160; //MapMagic.instance.guiGeneratorWidth;
				
					//gen.layout.OnBeforeChange -= RecordGeneratorUndo;
					//gen.layout.OnBeforeChange += RecordGeneratorUndo;
					gen.layout.undoObject = gens;
					gen.layout.undoName = "MapMagic Generators Change"; 
					gen.layout.dragChange = true;
					gen.layout.disabled = changeLock;

					//copyscript.layout params
					gen.layout.scroll = gens.layout.scroll;
					gen.layout.zoom = gens.layout.zoom;

					//drawing background
					gen.layout.Element("MapMagic_Window", gen.layout.field, new RectOffset(34,34,34,34), new RectOffset(33,33,33,33));

					//resetting layout
					gen.layout.field.height = 0;
					gen.layout.field.width =160;
					gen.layout.cursor = new Rect();
					gen.layout.change = false;
					gen.layout.margin = 1; gen.layout.rightMargin = 1;
					gen.layout.fieldSize = 0.4f;   
					
					//drawing header
					gen.DrawHeader (mapMagic, gens);
					if (gen is OutputGenerator && gen.layout.change && gen.enabled == false) //if just disabled output
						gensBiomeHierarchy[0].OnDisableGenerator(gen);

					//drawing parameters
					#if WDEBUG
					gen.OnGUI(gens);
					#else
					try { gen.OnGUI(gens); }
					catch (UnityException e) { Debug.LogError("Error drawing generator " + GetType() + "\n" + e);} 
					//should be system.exception but it causes ExitGUIException on opening curve/color/texture fields
					//it's so unity...
					//if something goes wrong but no error is displayed - you know where to find it
					#endif
					gen.layout.Par(3);

					//drawing debug generate time
					#if WDEBUG
					if (mapMagic!=null)
					{
						Rect timerRect = new Rect(gen.layout.field.x, gen.layout.field.y+gen.layout.field.height, 200, 20);
						string timeLabel = "g:" + gen.guiGenerateTime + "ms ";
						if (gen is OutputGenerator)
						{
							if (Generator.guiProcessTime.ContainsKey(gen.GetType())) timeLabel += " p:" + Generator.guiProcessTime[gen.GetType()] + "ms ";
							if (Generator.guiApplyTime.ContainsKey(gen.GetType())) timeLabel += " a:" + Generator.guiApplyTime[gen.GetType()] + "ms ";
						}
						gen.layout.Label(timeLabel, timerRect);
					}
					#endif

					//instant generate on params change
					if (gen.layout.change) 
					{
						if (mapMagic!=null) 
						{
							mapMagic.ClearResults(gen);
							mapMagic.Generate();
						}
						repaint=true; Repaint();

						EditorUtility.SetDirty(gens);
					}

					//drawing biome "edit" button. Rather hacky, but we have to call editor method when pressing "Edit"
					if (gen is Biome)
					{
						Biome biome = (Biome)gen;
						if (gen.layout.Button("Edit", disabled:biome.data==null)) 
						{
							MapMagicWindow.Show(biome.data, mapMagic, forceOpen:true,asBiome: true);
							Repaint();
							return; //cancel drawing this graph if biome was opened
						}
						gen.layout.Par(10);
					}

					//changing all of the output generators of the same type (in case this one was disabled to make refresh)
					if (gen.layout.change && !gen.enabled && gen is OutputGenerator)
					{
						foreach (GeneratorsAsset ga in gensBiomeHierarchy)
						foreach (OutputGenerator sameOut in ga.GeneratorsOfType<OutputGenerator>(onlyEnabled:true, checkBiomes:true))
							if (sameOut.GetType() == gen.GetType()) 
							{
								mapMagic.ClearResults(sameOut);
								mapMagic.Generate();
							}
					}

			
					if (gen.guiRect.width<1 && gen.guiRect.height<1) { repaint=true;  Repaint(); } //repainting if some of the generators rect is 0
					gen.guiRect = gen.layout.field;
				}
			#endregion

			#region Toolbar

				if (toolbarLayout==null) toolbarLayout = new Layout();
				toolbarLayout.margin = 0; toolbarLayout.rightMargin = 0;
				toolbarLayout.field.width = this.position.width;
				toolbarLayout.field.height = 18;
				toolbarLayout.cursor = new Rect();
				//toolbarLayout.window = this;
				toolbarLayout.Par(18, padding:0);

				EditorGUI.LabelField(toolbarLayout.field, "", EditorStyles.toolbarButton);

				if (mapMagic!=null  &&  mapMagic.ToString()!="null"  &&  !ReferenceEquals(mapMagic.gameObject,null)) //check game object in case it was deleted
				//mapMagic.ToString()!="null" - the only efficient delete check. Nor Equals neither ReferenceEquals are reliable. I <3 Unity!
				{
					//drawing state icon
					toolbarLayout.Inset(25);
					if (ThreadWorker.IsWorking("MapMagic")) { toolbarLayout.Icon("MapMagic_Loading", new Rect(5,0,16,16), animationFrames:12); Repaint(); }
					else toolbarLayout.Icon("MapMagic_Success", new Rect(5,0,16,16));
					//TODO: changed sign

					//mapmagic name
					Rect nameLabelRect = toolbarLayout.Inset(100); nameLabelRect.y+=1; //nameLabelRect.height-=4;
					EditorGUI.LabelField(nameLabelRect, mapMagic.gameObject.name, EditorStyles.miniLabel);

					//generate buttons
					if (GUI.Button(toolbarLayout.Inset(110,padding:0), "Generate Changed", EditorStyles.toolbarButton)) mapMagic.Generate(force:true);
					if (GUI.Button(toolbarLayout.Inset(110,padding:0), "Force Generate All", EditorStyles.toolbarButton)) 
					{ 
						mapMagic.ClearResults();  

						if (MapMagic.instance != null)
							foreach (Chunk chunk in MapMagic.instance.chunks.All())
								if (chunk.terrain != null) chunk.terrain.transform.RemoveChildren();
							
						mapMagic.Generate(force:true); 
					}

					//seed field
					toolbarLayout.Inset(10);
					Rect seedLabelRect = toolbarLayout.Inset(34); seedLabelRect.y+=1; seedLabelRect.height-=4;
					Rect seedFieldRect = toolbarLayout.Inset(64); seedFieldRect.y+=2; seedFieldRect.height-=4;
				}
				else
				{
					Rect nameLabelRect = toolbarLayout.Inset(300); nameLabelRect.y+=1; //nameLabelRect.height-=4;
					EditorGUI.LabelField(nameLabelRect, "External data '" + AssetDatabase.GetAssetPath(gens) + "'", EditorStyles.miniLabel); 
				}

				//right part
				toolbarLayout.Inset(toolbarLayout.field.width - toolbarLayout.cursor.x - 150 - 22,padding:0);

				//drawing exit biome button
				Rect biomeRect = toolbarLayout.Inset(80, padding:0);
				if (gensBiomeHierarchy.Count>1) 
				{
					if (toolbarLayout.Button("", biomeRect, icon:"MapMagic_ExitBiome", style:EditorStyles.toolbarButton)) 
					{
						gensBiomeHierarchy.RemoveAt(gensBiomeHierarchy.Count-1);
						Repaint();
						return;
					}

					toolbarLayout.Label("Exit Biome", new Rect(toolbarLayout.cursor.x-60, toolbarLayout.cursor.y+3, 60, toolbarLayout.cursor.height), fontSize:9);
				}

				//focus button 
				
			//	if (GUI.Button(script.toolbarLayout.Inset(100,padding:0), "Focus", EditorStyles.toolbarButton)) FocusOnGenerators();
				if (toolbarLayout.Button("", toolbarLayout.Inset(23,padding:0), icon:"MapMagic_Focus", style:EditorStyles.toolbarButton)) FocusOnGenerators();
				
				if (toolbarLayout.Button("", toolbarLayout.Inset(47,padding:0), icon:"MapMagic_Zoom", style:EditorStyles.toolbarButton)) gens.layout.zoom=1;
				toolbarLayout.Label((int)(gens.layout.zoom*100)+"%", new Rect(toolbarLayout.cursor.x-28, toolbarLayout.cursor.y+3, 28, toolbarLayout.cursor.height), fontSize:8);  
				
				toolbarLayout.Inset(3, margin:0);
				toolbarLayout.Label("",  toolbarLayout.Inset(22, margin:0), url:"https://gitlab.com/denispahunov/mapmagic/wikis/Editor%20Window", icon:"MapMagic_Help"); 

			#endregion

			#region Draging

				//dragging generators
				for(int i=gens.list.Length-1; i>=0; i--)
				{
					Generator gen = gens.list[i];
					if (gen is Group) continue;
					gen.layout.field = gen.guiRect;

					//dragging
					if (gens.layout.DragDrop(gen.layout.field, i)) 
					{
						if (gens.layout.dragState == Layout.DragState.Pressed) 
						{
							Undo.RecordObject (gens, "MapMagic Generators Drag");
							gens.setDirty = !gens.setDirty;
						}
						if (gens.layout.dragState == Layout.DragState.Drag || gens.layout.dragState == Layout.DragState.Released) 
						{ 
							//gen.Move(gens.layout.dragDelta,true);
							
							gen.layout.field.position += gens.layout.dragDelta;
							gen.guiRect = gens.layout.field;

							//moving inouts to remove lag
							foreach (Generator.IGuiInout inout in gen.Inouts()) 
								inout.guiRect = new Rect(inout.guiRect.position+gens.layout.dragDelta, inout.guiRect.size);

							//moving group
							if (gen is Group)
							{
								Group group = gen as Group;
								for (int g=0; g<group.generators.Count; g++) //group.generators[g].Move(delta,false);
								{
									group.generators[g].layout.field.position += gens.layout.dragDelta;
									group.generators[g].guiRect = gens.layout.field;

									foreach (Generator.IGuiInout inout in group.generators[g].Inouts())  //moving inouts to remove lag
										inout.guiRect = new Rect(inout.guiRect.position+gens.layout.dragDelta, inout.guiRect.size);
								}
							}

							repaint=true; Repaint(); 

							EditorUtility.SetDirty(gens);
						}
					}

					//saving all generator rects
					gen.guiRect = gen.layout.field;
				}

				//dragging groups
				for (int i=gens.list.Length-1; i>=0; i--)
				{
					//Generator gen = gens.list[i];
					Group group = gens.list[i] as Group;
					if (group == null) continue;
					group.layout.field = group.guiRect;

					//resizing
					group.layout.field =gens.layout.ResizeRect(group.layout.field, i+20000);

					//dragging
					if (gens.layout.DragDrop(group.layout.field, i)) 
					{
						if (gens.layout.dragState == Layout.DragState.Pressed) 
						{
							Undo.RecordObject (gens, "MapMagic Group Drag");
							gens.setDirty = !gens.setDirty;
							group.Populate(gens);
						}
						if (gens.layout.dragState == Layout.DragState.Drag || gens.layout.dragState == Layout.DragState.Released) 
						{ 
							//group.Move(gens.layout.dragDelta,true);
							
							group.layout.field.position += gens.layout.dragDelta;
							group.guiRect = gens.layout.field;

							for (int g=0; g<group.generators.Count; g++) //group.generators[g].Move(delta,false);
							{
								group.generators[g].layout.field.position += gens.layout.dragDelta;
								group.generators[g].guiRect.position += gens.layout.dragDelta; // = gens.layout.field;

					//			foreach (Generator.IGuiInout inout in group.generators[g].Inouts())  //moving inouts to remove lag
					//				inout.guiRect = new Rect(inout.guiRect.position+gens.layout.dragDelta, inout.guiRect.size);
							}

							repaint=true; Repaint(); 

							EditorUtility.SetDirty(gens);
						}
						if (gens.layout.dragState == Layout.DragState.Released && group != null) gens.SortGroups();
					}

					//saving all group rects
					group.guiRect = group.layout.field;
				}

			#endregion

			//right-click menus
			if (Event.current.type == EventType.ContextClick || (Event.current.type == EventType.MouseDown && Event.current.control)) DrawPopup();

			//debug center
			//EditorGUI.HelpBox(script.layout.ToLocal(new Rect(-25,-10,50,20)), "Zero", MessageType.None);

			//assigning portal popup action
			Portal.OnChooseEnter -= DrawPortalSelector; Portal.OnChooseEnter += DrawPortalSelector;

			//saving scroll and zoom
			gens.guiScroll = gens.layout.scroll; gens.guiZoom = gens.layout.zoom;  

			DrawDemoLock();

		}
Exemple #2
0
		public void Update () 
		{ 
			//shifting world
			if (!isEditor && shift) WorldShifter.Update(shiftThreshold, shiftExcludeLayers);

			//checking if instance already exists and disabling if it is another mm
			if (instance != null && instance != this) { Debug.LogError("MapMagic object already present in scene. Disabling duplicate"); this.enabled = false; return; }
		
			//do nothing if chink size is zero
			if (terrainSize < 0.1f) return;

			//finding camera positions
			camPoses = Extensions.GetCamPoses(genAroundMainCam:genAroundMainCam, genAroundTag:genAroundObjsTag? genAroundTag : null, camPoses:camPoses);
			if (camPoses.Length == 0) return; //no cameras to deploy Voxeland
			transform.InverseTransformPoint(camPoses); 
				
			//deploy
			if (!isEditor && generateInfinite) 
			{
				//finding deploy rects
				if (deployRects == null || deployRects.Length!=camPoses.Length)
				{
					deployRects = new CoordRect[camPoses.Length]; 
					removeRects = new CoordRect[camPoses.Length];
				}
				
				for (int r=0; r<camPoses.Length; r++) //TODO: add cam pos change check
				{
					deployRects[r] = CoordRect.PickIntersectingCellsByPos(camPoses[r], generateRange, cellSize:terrainSize);
					removeRects[r] = CoordRect.PickIntersectingCellsByPos(camPoses[r], removeRange, cellSize:terrainSize);
				}

				//checking and deploying
				bool chunksChange = chunks.CheckDeploy(deployRects);
				if (chunksChange) chunks.Deploy(deployRects, removeRects, parent:this, allowMove:true);
			}

			//updating chunks
			foreach (Chunk chunk in chunks.All()) 
			{
				//removing (unpinning) chunk if it's terrain was removed somehow
				if (chunk.terrain==null || chunk.terrain.transform==null || chunk.terrain.terrainData==null) { chunk.pinned = false; return; } //TODO: causes out of sync error

				//distance, priority and visibility
				float distance = camPoses.DistToRectAxisAligned(chunk.coord.x*terrainSize, chunk.coord.z*terrainSize, terrainSize);
				chunk.worker.priority = 1f / distance;

				//starting generate
				if ((distance<MapMagic.instance.generateRange || MapMagic.instance.isEditor) && chunk.worker.blank && !chunk.locked && instantGenerate) chunk.worker.Start(); 

				//enabling/disabling (after starting generate to avoid blink)
				if (!MapMagic.instance.isEditor && //if non-editor
					(
					(!chunk.worker.ready && !chunk.locked) || //if non-ready
					(MapMagic.instance.hideFarTerrains && distance>MapMagic.instance.enableRange) //or if out of range in playmode
					)	) 
					//TODO: it works but I don't like the way it formatted
						{ if (chunk.terrain.gameObject.activeSelf) chunk.terrain.gameObject.SetActive(false); } //disabling
				else 
					{ if (!chunk.terrain.gameObject.activeSelf) chunk.terrain.gameObject.SetActive(true); } //enabling
					

				//setting terrain neighbors (they reset after each serialize)
				chunk.SetNeighbors(); //TODO: try doing in ondeserialize
			}


			//updating threads
			ThreadWorker.multithreading = multithreading;
			ThreadWorker.maxThreads = maxThreads; 
			ThreadWorker.autoMaxThreads = autoMaxThreads;
			ThreadWorker.maxApplyTime = maxApplyTime;
			ThreadWorker.Refresh();

		}
Exemple #3
0
        public static void GetProgresByTag(string tag, out float contained, out float calculated, out float ready)
        {
            if (profile)
            {
                UnityEngine.Profiling.Profiler.BeginSample("Get Progress Tag");
            }

            DictTuple <string, bool, bool> dict = new DictTuple <string, bool, bool>();

            int queueCount = queue.Count;

            contained = 0; calculated = 0; ready = 0;

            for (int i = 0; i < queueCount; i++)
            {
                ThreadWorker worker = queue[i];
                if (worker.stage == Stage.stop || worker.stage == Stage.blank)
                {
                    continue;
                }
                if (!worker.tag.Contains(tag))
                {
                    continue;
                }

                //contains
                if (!dict.ContainsKey(worker.tag))
                {
                    dict.Add(worker.tag, true, true);
                }

                //calculated
                TupleSet <bool, bool> tuple = dict[worker.tag];
                if (worker.stage != Stage.applyEnqueued && worker.stage != Stage.coroutineEnqueued && worker.stage != Stage.coroutineRunning && worker.stage != Stage.ready)
                {
                    tuple.item1 = false; tuple.item2 = false; dict[worker.tag] = tuple;
                }

                //ready
                if (worker.stage != Stage.ready)
                {
                    tuple.item2 = false; dict[worker.tag] = tuple;
                }
            }

            //calculating total statistics
            contained = dict.Count;
            foreach (TupleSet <bool, bool> tuple in dict.Values())
            {
                if (tuple.item1)
                {
                    calculated++;
                }
                if (tuple.item2)
                {
                    ready++;
                }
            }

            if (profile)
            {
                UnityEngine.Profiling.Profiler.EndSample();
            }
        }
Exemple #4
0
        public static void UpdateThreads()          //called each time any thread is complete
        {
            try{
                if (!on || queue.Count == 0)
                {
                    return;
                }

                        #if WDEBUG
                if (IsMainThread)
                {
                    Profiler.BeginSample("Update Threads");
                }
                        #endif

                int threadsRunning = 0;         //current number of threads then multithreading is on

                //calculating number of threads running
                int queueCount = queue.Count;
                for (int i = 0; i < queueCount; i++)
                {
                    if (queue[i].stage == Stage.threadRunning)
                    {
                        threadsRunning++;
                    }
                }

                //guard if all possible threads already started: exit with no queue locking
                if (threadsRunning >= maxThreads)
                {
                                #if WDEBUG
                    if (IsMainThread)
                    {
                        Profiler.EndSample();
                    }
                                #endif

                    return;
                }

                //staring new threads
                lock (queue)
                    while (threadsRunning < maxThreads)
                    {
                        //finding suitable worker with highest priority
                        float maxProirity = -2000000;
//				int maxProirityNum = -1;
                        ThreadWorker maxPriorityWorker = null;

                        queueCount = queue.Count;
                        for (int i = 0; i < queueCount; i++)
                        {
                            ThreadWorker worker = queue[i];
                            if (worker == null)
                            {
                                continue;
                            }
                            if (worker.priority < maxProirity)
                            {
                                continue;
                            }
                            if (worker.stage != Stage.threadEnqueued)
                            {
                                continue;                                                 //if object destroyed or other stage
                            }
                            if (worker.threadCondition != null && !worker.threadCondition())
                            {
                                continue;
                            }

                            maxPriorityWorker = worker;
                            maxProirity       = worker.priority;
//					maxProirityNum = i;
                        }

                        //no suitable threads
                        if (maxPriorityWorker == null)
                        {
                            break;
                        }

                        //starting thread
                        //lock (maxPriorityWorker.locker)
                        Monitor.Enter(maxPriorityWorker.locker); maxPriorityWorker.lockWasTaken = true;
                        try
                        {
                            if (maxPriorityWorker.stage != Stage.threadEnqueued)
                            {
                                return;                                                              //this could happen if two threads selecting one worker, or worker stopped while being selected
                            }
                            if (logging)
                            {
                                Log(maxPriorityWorker, "Refresh:ThreadSelected (max" + maxProirity + ") ");
                            }

                            threadsRunning++;

                            if (multithreading)
                            {
                                maxPriorityWorker.thread = new Thread(maxPriorityWorker.ThreadFn);

                                maxPriorityWorker.thread.IsBackground = true;
                                maxPriorityWorker.SwitchStage(Stage.threadRunning, "Refresh: start thread");                 //before actually starting

                                maxPriorityWorker.thread.Start();
                            }
                            else
                            {
                                maxPriorityWorker.ThreadFn(); if (IsMainThread)
                                {
                                    UnityEngine.Profiling.Profiler.EndSample();
                                }
                                if (oneThreadPerFrame)
                                {
                                    break;
                                }
                            }
                        }
                        finally { Monitor.Exit(maxPriorityWorker.locker); maxPriorityWorker.lockWasTaken = false; }
                    }

                        #if WDEBUG
                if (IsMainThread)
                {
                    Profiler.EndSample();
                }
                        #endif
            } catch (System.Exception e) { Debug.LogError("Spinner Error: " + e); }
        }
Exemple #5
0
        public static void UpdateApply()
        {
            if (!on || queue.Count == 0)
            {
                return;
            }

                        #if WDEBUG
            Profiler.BeginSample("Update Apply");
                        #endif

            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            timer.Start();

            while (timer.ElapsedMilliseconds < maxApplyTime)
            {
                //if couroutine has started - moving coroutine
                if (CurrentCoroutine != null)
                {
                    currentCoroutineWorker.CoroutineFn(); continue;
                }

                //finding suitable worker with highest priority
                float maxProirity = -2000000;
//				int maxProirityNum = -1;
                ThreadWorker maxPriorityWorker = null;

                int queueCount = queue.Count;
                for (int i = 0; i < queueCount; i++)
                {
                    ThreadWorker worker = queue[i];

                    if (worker == null)
                    {
                        continue;                                   //if object destroyed
                    }
                    if (worker.priority < maxProirity)
                    {
                        continue;
                    }
                    if (worker.stage != Stage.applyEnqueued && worker.stage != Stage.prepareEnqueued && worker.stage != Stage.coroutineEnqueued && worker.stage != Stage.coroutineRunning)
                    {
                        continue;                                                                                                                                                                                //other stage
                    }
                    if (worker.stage == Stage.prepareEnqueued && worker.prepareCondition != null && !worker.prepareCondition())
                    {
                        continue;
                    }
                    if (worker.stage == Stage.applyEnqueued && worker.applyCondition != null && !worker.applyCondition())
                    {
                        continue;                                                                                                                   //if apply condition has not met
                    }
                    if (worker.stage == Stage.coroutineEnqueued && worker.coroutineCondition != null && !worker.coroutineCondition())
                    {
                        continue;                                                                                                                               //if coroutine condition has not met (note that conditions is checked only before starting coroutine)
                    }
                    maxPriorityWorker = worker;
                    maxProirity       = worker.priority;
//					maxProirityNum = i;
                }

                //no suitable applies
                if (maxPriorityWorker == null)
                {
                    break;
                }

                //apply
                //lock (maxPriorityWorker.locker)
                Monitor.Enter(maxPriorityWorker.locker); maxPriorityWorker.lockWasTaken = true;
                try
                {
                    if (logging)
                    {
                        Log(maxPriorityWorker, "Refresh:ApplyPrepSelected");
                    }

                    if (maxPriorityWorker.stage == Stage.prepareEnqueued)
                    {
                        //maxPriorityWorker.SwitchStage(Stage.applyRunning);
                        maxPriorityWorker.PrepareFn();
                    }

                    if (maxPriorityWorker.stage == Stage.applyEnqueued)
                    {
                        //maxPriorityWorker.SwitchStage(Stage.applyRunning);
                        maxPriorityWorker.ApplyFn();
                    }

                    if (maxPriorityWorker.stage == Stage.coroutineEnqueued || maxPriorityWorker.stage == Stage.coroutineRunning)
                    {
                        maxPriorityWorker.CoroutineFn();
                    }
                }
                finally { Monitor.Exit(maxPriorityWorker.locker); maxPriorityWorker.lockWasTaken = false; }
            }

                        #if WDEBUG
            Profiler.EndSample();
                        #endif
        }
Exemple #6
0
 public static string PrintLog(ThreadWorker worker)
 {
     List <ThreadWorker> workers = new List <ThreadWorker>(); workers.Add(worker); return(PrintLog(workers));
 }