private void AssignEventLog(Scene scene, EventOrderLog eventLog)
 {
     foreach (TestComponent component in scene.FindComponents <TestComponent>())
     {
         component.EventLog = eventLog;
     }
 }
        [Test] public void EnforceOrderPrefabSaved()
        {
            EventOrderLog eventLog = new EventOrderLog();

            eventLog.EventFilter = EventType.Saved;

            GameObject root = this.GenerateSampleTree(10, false,
                                                      typeof(TestComponentA1),
                                                      typeof(TestComponentA2),
                                                      typeof(TestComponentA3),
                                                      typeof(TestComponentA4),
                                                      typeof(TestComponentA5));

            // Assign the event log so it gets serialized and it already
            // there when the scene is initialized after loading
            this.AssignEventLog(root, eventLog, false);

            // Injecting an object into a prefab will invoke its Saving and Saved events
            Prefab prefab = new Prefab();

            prefab.Inject(root);

            // Evaluate results
            this.AssertEventOrder(eventLog, 5 * 10, Component.ExecOrder, false);
        }
        [Test] public void EnforceOrderGameObjectActivate([Values(true, false)] bool deepObjectTree)
        {
            EventOrderLog eventLog = new EventOrderLog();

            eventLog.EventFilter = EventType.Activate;

            int        objectCount = deepObjectTree ? 10 : 1;
            GameObject root        = this.GenerateSampleTree(objectCount, true,
                                                             typeof(TestComponentA1),
                                                             typeof(TestComponentA2),
                                                             typeof(TestComponentA3),
                                                             typeof(TestComponentA4),
                                                             typeof(TestComponentA5));

            root.Active = false;

            Scene.SwitchTo(new Scene(), true);
            Scene.Current.AddObject(root);

            this.AssignEventLog(root, eventLog, true);
            root.Active = true;
            this.AssertEventOrder(eventLog, 5 * objectCount, Component.ExecOrder, false);

            Scene.SwitchTo(null, true);
        }
        [Test] public void EnforceOrderSceneLoad()
        {
            EventOrderLog eventLog = new EventOrderLog();

            eventLog.EventFilter = EventType.Loaded;

            Scene scene = this.GenerateSampleScene(10,
                                                   typeof(TestComponentA1),
                                                   typeof(TestComponentA2),
                                                   typeof(TestComponentA3),
                                                   typeof(TestComponentA4),
                                                   typeof(TestComponentA5));

            // Assign the event log so it gets serialized and it already
            // there when the scene is initialized after loading
            this.AssignEventLog(scene, eventLog);

            // Save the scene and reload it so the OnLoaded code is triggered
            using (MemoryStream data = new MemoryStream())
            {
                scene.Save(data);
                data.Position = 0;
                scene         = Resource.Load <Scene>(data);
            }

            // Retrieve the deserialized event log again and evaluate results
            eventLog = scene.FindComponent <TestComponent>().EventLog;
            this.AssertEventOrder(eventLog, 5 * 10, Component.ExecOrder, false);
        }
        [Test] public void EnforceOrderPrefabLoad()
        {
            EventOrderLog eventLog = new EventOrderLog();

            eventLog.EventFilter = EventType.Loaded;

            GameObject root = this.GenerateSampleTree(10, false,
                                                      typeof(TestComponentA1),
                                                      typeof(TestComponentA2),
                                                      typeof(TestComponentA3),
                                                      typeof(TestComponentA4),
                                                      typeof(TestComponentA5));

            // Assign the event log so it gets serialized and it already
            // there when the scene is initialized after loading
            this.AssignEventLog(root, eventLog, false);

            // Save the scene and reload it so the OnLoaded code is triggered
            using (MemoryStream data = new MemoryStream())
            {
                Prefab prefab = new Prefab(root);
                prefab.Save(data);
                data.Position = 0;
                prefab        = Resource.Load <Prefab>(data);

                // Note that due to lack of API to directly access the prefab object tree,
                // we're creating a clone by instantiation here - however, since all the
                // event logs are cloned as well, this won't invalidate the test results.
                root = prefab.Instantiate();
            }

            // Retrieve the deserialized event log again and evaluate results
            eventLog = root.GetComponentsInChildren <TestComponent>().FirstOrDefault().EventLog;
            this.AssertEventOrder(eventLog, 5 * 10, Component.ExecOrder, false);
        }
		private void AssertEventOrder(EventOrderLog eventLog, int eventCount, ComponentExecutionOrder order, bool reverseOrder)
		{
			int actualEventCount = eventLog.EventOrder.Count();
			Assert.AreEqual(
				eventCount, 
				actualEventCount, 
				string.Format("Expected {0} events of type/s {2}, but got {1}", eventCount, actualEventCount, eventLog.EventFilter));

			this.AssertComponentOrder(eventLog.EventOrder, eventCount, order, reverseOrder);
		}
		private void AssignEventLog(GameObject root, EventOrderLog eventLog, bool includeRoot)
		{
			IEnumerable<TestComponent> components;
			if (includeRoot)
				components = root.GetComponentsDeep<TestComponent>();
			else
				components = root.GetComponentsInChildren<TestComponent>();

			foreach (TestComponent component in components)
				component.EventLog = eventLog;
		}
		[Test] public void EnforceOrderSceneFind()
		{
			EventOrderLog eventLog = new EventOrderLog();
			eventLog.EventFilter = EventType.Update;

			Scene scene = this.GenerateSampleScene(10,
				typeof(TestComponentA1), 
				typeof(TestComponentA2), 
				typeof(TestComponentA3), 
				typeof(TestComponentA4), 
				typeof(TestComponentA5));

			// Since scene iteration is the basis for delivering broadcasted messages, we'll
			// expect all related API to behave consistenly with regard to component execution order.
			this.AssertComponentOrder(scene.FindComponents<TestComponent>().ToArray(), 5 * 10, Component.ExecOrder, false);
		}
		[Test] public void EnforceOrderSceneDeactivate()
		{
			EventOrderLog eventLog = new EventOrderLog();
			eventLog.EventFilter = EventType.Deactivate;

			Scene scene = this.GenerateSampleScene(10,
				typeof(TestComponentA1), 
				typeof(TestComponentA2), 
				typeof(TestComponentA3), 
				typeof(TestComponentA4), 
				typeof(TestComponentA5));

			Scene.SwitchTo(scene, true);

			this.AssignEventLog(scene, eventLog);
			Scene.SwitchTo(null, true);
			this.AssertEventOrder(eventLog, 5 * 10, Component.ExecOrder, true);
		}
		[Test] public void EnforceOrderSceneSaving()
		{
			EventOrderLog eventLog = new EventOrderLog();
			eventLog.EventFilter = EventType.Saving;

			Scene scene = this.GenerateSampleScene(10,
				typeof(TestComponentA1), 
				typeof(TestComponentA2), 
				typeof(TestComponentA3), 
				typeof(TestComponentA4), 
				typeof(TestComponentA5));

			this.AssignEventLog(scene, eventLog);
			using (MemoryStream data = new MemoryStream())
			{
				scene.Save(data);
			}
			this.AssertEventOrder(eventLog, 5 * 10, Component.ExecOrder, true);
		}