//#define WRITE_LOG
using System;
using UnityEngine;
namespace Unity.Entities
{
public delegate void ConfigInit(World world);
public static class DefaultTinyWorldInitialization
{
///
/// Initialize the Tiny World with all the boilerplate that needs to be done.
/// ComponentSystems will be created and sorted into the high level ComponentSystemGroups.
///
///
/// The simple use case is:
///
/// world = DefaultTinyWorldInitialization.InitializeWorld("main");
///
/// However, it's common to need to set initialization data. That can be
/// done with the following code:
///
///
/// world = DefaultTinyWorldInitialization.InitializeWorld("main");
/// TinyEnvironment env = world.TinyEnvironment();
/// // set configuration variables...
/// DefaultTinyWorldInitialization.InitializeSystems(world);
///
///
///
///
public static World Initialize(string worldName)
{
World world = InitializeWorld(worldName);
InitializeSystems(world);
// Note that System sorting is done by the individual ComponentSystemGroups, as needed.
return world;
}
///
/// Initialize the World object. See for use.
///
public static World InitializeWorld(string worldName)
{
var world = new World(worldName);
World.Active = world;
return world;
}
///
/// Initialize the ComponentSystems. See for use.
///
public static void InitializeSystems(World world)
{
var allSystemTypes = TypeManager.GetSystems();
var allSystemNames = TypeManager.SystemNames;
if (allSystemTypes.Length == 0)
{
throw new InvalidOperationException("DefaultTinyWorldInitialization: No Systems found.");
}
// Create top level presentation system and simulation systems.
InitializationSystemGroup initializationSystemGroup = new InitializationSystemGroup();
world.AddSystem(initializationSystemGroup);
SimulationSystemGroup simulationSystemGroup = new SimulationSystemGroup();
world.AddSystem(simulationSystemGroup);
PresentationSystemGroup presentationSystemGroup = new PresentationSystemGroup();
world.AddSystem(presentationSystemGroup);
// Create the working set of systems.
#if WRITE_LOG
Console.WriteLine("--- Adding systems:");
#endif
for (int i = 0; i < allSystemTypes.Length; i++)
{
if (TypeManager.GetSystemAttributes(allSystemTypes[i], typeof(DisableAutoCreationAttribute)).Length > 0)
continue;
if (allSystemTypes[i] == initializationSystemGroup.GetType() ||
allSystemTypes[i] == simulationSystemGroup.GetType() ||
allSystemTypes[i] == presentationSystemGroup.GetType())
{
continue;
}
// Subtle issue. If the System was created by GetOrCreateSystem at the "right" time
// before its own initialization, then it will exist. GetExistingSystem will return a valid
// object. BUT, that object will not have been put into a SystemGroup.
var sys = world.GetExistingSystem(allSystemTypes[i]);
if (sys != null)
{
AddSystemToGroup(world, sys);
continue;
}
#if WRITE_LOG
Console.WriteLine(allSystemNames[i]);
#endif
AddSystem(world, TypeManager.ConstructSystem(allSystemTypes[i]));
}
}
///
/// Call this to add a System that was manually constructed; normally these
/// Systems are marked with [DisableAutoCreation].
///
public static void AddSystem(World world, ComponentSystemBase system)
{
if (world.GetExistingSystem(system.GetType()) != null)
throw new ArgumentException("AddSystem: Error to add a duplicate system.");
world.AddSystem(system);
AddSystemToGroup(world, system);
}
private static void AddSystemToGroup(World world, ComponentSystemBase system)
{
var groups = TypeManager.GetSystemAttributes(system.GetType(), typeof(UpdateInGroupAttribute));
if (groups.Length == 0)
{
var simulationSystemGroup = world.GetExistingSystem();
simulationSystemGroup.AddSystemToUpdateList(system);
}
for (int g = 0; g < groups.Length; ++g)
{
var groupType = groups[g] as UpdateInGroupAttribute;
var groupSystem = world.GetExistingSystem(groupType.GroupType) as ComponentSystemGroup;
if (groupSystem == null)
throw new Exception("AddSystem failed to find existing SystemGroup.");
groupSystem.AddSystemToUpdateList(system);
}
}
}
}