diff --git a/README.md b/README.md
index 9ddc146..0b0d482 100644
--- a/README.md
+++ b/README.md
@@ -10,67 +10,160 @@ Svelto.ECS is easy to start with, but full of tricks for expert users. The harde
simplest setup:
```csharp
+ using System;
+using Svelto.ECS;
+using Svelto.ECS.Schedulers;
+using Svelto.ECS.Vanilla.Example.SimpleEntityEngine;
+
+///
+/// This is the common pattern to declare Svelto Exclusive Groups (usually split by composition root)
+///
+public static class ExclusiveGroups
+{
+ public static ExclusiveGroup group0 = new ExclusiveGroup();
+ public static ExclusiveGroup group1 = new ExclusiveGroup();
+}
+
+namespace Svelto.ECS.Vanilla.Example
+{
+ ///
+ /// The Context is the application starting point.
+ /// As a Composition root, it gives to the coder the responsibility to create, initialize and
+ /// inject dependencies.
+ /// Every application can have more than one context and every context can have one
+ /// or more composition roots (a facade, but even a factory, can be a composition root)
+ ///
public class SimpleContext
{
- //the group where the entity will be built in
- public static ExclusiveGroup group0 = new ExclusiveGroup();
-
public SimpleContext()
{
- var simpleSubmissionEntityViewScheduler = new SimpleEntitiesSubmissionScheduler();
- //Build Svelto Entities and Engines container, called EnginesRoot
- _enginesRoot = new EnginesRoot(simpleSubmissionEntityViewScheduler);
-
- var entityFactory = _enginesRoot.GenerateEntityFactory();
-
- //Add an Engine to the enginesRoot to manage the SimpleEntities
- var behaviourForEntityClassEngine = new BehaviourForEntityClassEngine();
+ //an entity submission scheduler is needed to submit entities to the Svelto database, Svelto is not
+ //responsible to decide when to submit entities, it's the user's responsibility to do so.
+ var entitySubmissionScheduler = new SimpleEntitiesSubmissionScheduler();
+ //An EnginesRoot holds all the engines and entities created. it needs a EntitySubmissionScheduler to know when to
+ //add previously built entities to the Svelto database. Using the SimpleEntitiesSubmissionScheduler
+ //is expected as it gives complete control to the user about when the submission happens
+ _enginesRoot = new EnginesRoot(entitySubmissionScheduler);
+
+ //an entity factory allows to build entities inside engines
+ var entityFactory = _enginesRoot.GenerateEntityFactory();
+ //the entity functions allows other operations on entities, like remove and swap
+ var entityFunctions = _enginesRoot.GenerateEntityFunctions();
+
+ //Add the Engine to manage the SimpleEntities
+ var behaviourForEntityClassEngine = new BehaviourForEntityClassEngine(entityFunctions);
_enginesRoot.AddEngine(behaviourForEntityClassEngine);
- //build a new Entity with ID 0 in group0
+ //build Entity with ID 0 in group0
entityFactory.BuildEntity(new EGID(0, ExclusiveGroups.group0));
//submit the previously built entities to the Svelto database
- simpleSubmissionEntityViewScheduler.SubmitEntities();
+ entitySubmissionScheduler.SubmitEntities();
- //as Svelto doesn't provide an engine ticking system, it's the user's responsibility to
- //update engines
+ //as Svelto doesn't provide an engine/system ticking system, it's the user's responsibility to
+ //update engines
behaviourForEntityClassEngine.Update();
+
+ Console.Log("Done - click any button to quit");
+
+ System.Console.ReadKey();
+
+ Environment.Exit(0);
}
-
- readonly EnginesRoot _enginesRoot;
- }
-```
-your first entity descriptor:
+ readonly EnginesRoot _enginesRoot;
+ }
-```csharp
+ //An EntityComponent must always implement the IEntityComponent interface
+ //don't worry, boxing/unboxing will never happen.
public struct EntityComponent : IEntityComponent
{
- public int counter;
+ public int counter;
}
- class SimpleEntityDescriptor : GenericEntityDescriptor
- {}
-```
-
-your first engine executing entities behaviours:
+ ///
+ /// The EntityDescriptor identifies your Entity. It's essential to identify
+ /// your entities with a name that comes from the Game Design domain.
+ ///
+ class SimpleEntityDescriptor : GenericEntityDescriptor { }
-```csharp
- public class BehaviourForEntityClassEngine : IQueryingEntitiesEngine
+ namespace SimpleEntityEngine
{
- public EntitiesDB entitiesDB { get; set; }
-
- public void Ready() { }
-
- public void Update()
+ public class BehaviourForEntityClassEngine :
+ //this interface makes the engine reactive, it's absolutely optional, you need to read my articles
+ //and wiki about it.
+ IReactOnAddEx, IReactOnSwapEx, IReactOnRemoveEx,
+ //while this interface is optional too, it's almost always used as it gives access to the entitiesDB
+ IQueryingEntitiesEngine
{
- var (components, count) = entitiesDB.QueryEntities(ExclusiveGroups.group0);
-
- for (var i = 0; i < count; i++)
- components[i].counter++;
+ //extra entity functions
+ readonly IEntityFunctions _entityFunctions;
+
+ public BehaviourForEntityClassEngine(IEntityFunctions entityFunctions)
+ {
+ _entityFunctions = entityFunctions;
+ }
+
+ public EntitiesDB entitiesDB { get; set; }
+
+ public void Ready() { }
+
+ public void Update()
+ {
+ //Simple query to get all the entities with EntityComponent in group1
+ var (components, entityIDs, count) = entitiesDB.QueryEntities(ExclusiveGroups.group1);
+
+ uint entityID;
+ for (var i = 0; i < count; i++)
+ {
+ components[i].counter++;
+ entityID = entityIDs[i];
+ }
+
+ Console.Log("Entity Struct engine executed");
+ }
+
+ //the following methods are called by Svelto.ECS when an entity is added to a group
+ public void Add((uint start, uint end) rangeOfEntities, in EntityCollection entities
+ , ExclusiveGroupStruct groupID)
+ {
+ var (_, entityIDs, _) = entities;
+
+ for (uint index = rangeOfEntities.start; index < rangeOfEntities.end; index++)
+ //Swap entities between groups is a very common operation and it's necessary to
+ //move entities between groups/sets. A Group represent a state/adjective of an entity, so changing
+ //group means change state/behaviour as different engines will process different groups.
+ //it's the Svelto equivalent of adding/remove components to an entity at run time
+ _entityFunctions.SwapEntityGroup(new EGID(entityIDs[index], groupID), ExclusiveGroups.group1);
+ }
+
+ //the following methods are called by Svelto.ECS when an entity is swapped from a group to another
+ public void MovedTo((uint start, uint end) rangeOfEntities, in EntityCollection entities
+ , ExclusiveGroupStruct fromGroup, ExclusiveGroupStruct toGroup)
+ {
+ var (_, entityIDs, _) = entities;
+
+ for (var index = rangeOfEntities.start; index < rangeOfEntities.end; index++)
+ {
+ Console.Log($"entity {entityIDs[index]} moved from {fromGroup} to {toGroup}");
+ //like for the swap operation, removing entities from the Svelto database is a very common operation.
+ //For both operations is necessary to specify the EntityDescriptor to use. This has also a philosophical
+ //reason to happen, it's to always remind which entity type we are operating with.
+ _entityFunctions.RemoveEntity(new EGID(entityIDs[index], toGroup));
+ }
+ }
+
+ //the following methods are called by Svelto.ECS when an entity is removed from a group
+ public void Remove((uint start, uint end) rangeOfEntities, in EntityCollection entities, ExclusiveGroupStruct groupID)
+ {
+ var (_, entityIDs, _) = entities;
+
+ for (uint index = rangeOfEntities.start; index < rangeOfEntities.end; index++)
+ Console.Log($"entity {entityIDs[index]} removed from {groupID.ToString()}");
+ }
}
}
+}
```
learn more about svelto on the Wiki page: https://github.com/sebas77/Svelto.ECS/wiki