amazon web services – EC2 Instance cannot connect to ECS Cluster

Helo,
I have empty AWS ECS Cluster but I am unable to put instances into it.
I wanted to use Launch templates and Autoscaling Group, but I am unable to assign created EC2 Instance.

The issue is in shown in ecs-agent.log

level=error time=2020-10-17T23:23:37Z msg="Unable to register as a container instance with ECS: RequestError: send request failedncaused by: Post "https://ecs.eu-central-1.amazonaws.com/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)" module=client.go
level=error time=2020-10-17T23:23:37Z msg="Error registering: RequestError: send request failedncaused by: Post "https://ecs.eu-central-1.amazonaws.com/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)" module=agent.go

Notes:

  • Using AMI ami-0eff571a24849e852
  • Cluster name: debug
  • Region is eu-central-1
  • Instance has no public IP
  • Instance is in 10.10.100.0/24 subnet (10.10.100.14) and VPN subnet is 10.10.0.0/16
  • Instance can reach the internet through NAT Instance:
(ec2-user@ip-10-10-100-14 ecs)$ ping google.com
PING google.com (216.58.212.142) 56(84) bytes of data.
64 bytes from ams15s21-in-f14.1e100.net (216.58.212.142): icmp_seq=1 ttl=109 time=50.1 ms
64 bytes from ams15s21-in-f142.1e100.net (216.58.212.142): icmp_seq=2 ttl=109 time=40.1 ms
  • DNS to outside is resolving fine
(ec2-user@ip-10-10-100-14 ecs)$ nslookup google.com
Server:     10.10.0.2
Address:    10.10.0.2#53

Non-authoritative answer:
Name:   google.com
Address: 216.58.212.142
  • Just to be sure, I have created Endpoints from VPC and Subnet where Instance is to ECS
  • I have attached the security group with no restrictions for test
  • ecs.config:
ECS_CLUSTER=debug
ECS_BACKEND_HOST=
(ec2-user@ip-10-10-100-14 ecs)$ nslookup ecs.eu-central-1.amazonaws.com
Server:     10.10.0.2
Address:    10.10.0.2#53

Non-authoritative answer:
Name:   ecs.eu-central-1.amazonaws.com
Address: 10.10.100.219

Does anyone have any suggestions?

amazon ecs – How to expose AWS Fargate ECS containers to internet with Route53 DNS?

I have an ECS Task running on fargate and my service get an public ip address automatically. How do I simply expose fargate task to internet with Route53 dns? I was looking around the internet for a whole day today an I couldn’t find an example about this simplest possible scenario where I just want to expose a port from said task to the internet and map a Route53 record to point to its ip address.

If I understood correctly from the minimal information I found is that I would have to create an vpc endpoint but I couldn’t find information about how to route the traffic to a task/container.

amazon web services – AWS multiple scaling groups in single ECS cluster

I want to place some ECS services on two separate security groups.

Say services S1, S2 on security group SG1, and services S3, S4 on security group SG2.

One approach would be to place them on two separate ECS clusters.

However, I prefer to place them on the same ECS cluster.

So I thought of defining two austoscaling groups (ASG1, ASG2) on the cluster, in order to achieve that. This means that machines on ASG1 would be associated with SG1, and machines on ASG2 would beassociated with SG2.

My question is, how do I associate S1, S2 with the machines on ASG1, and S3, S4 with the machines on ASG2?

c++ – Efficient communication between entities using ECS via entt

To avoid confusion about the ECS terms I’ll use, I explain them here quickly. I use entt terminology and set-up my architecture like this:

  • Entity: is only an id (entt::entity)
  • Component: is a struct holding plain data (int, floats, etc.)
  • System: is a function looping over a family of components (using entt::registry.view)

In my game, I model a space ship that can have multiple engines. The engines apply a force on the ship each frame so the ship accelerates. I implemented it like the following:

Ship is an entity, Engine is an entity. Ship has the components AppliedForces, Mass and Velocity. Engine has the components Parent and Thrust. Parent is a component containing the parent’s id of the engine (in this case a ship entity).

I have two systems: ThrustSystem goes through all entities that have the components Thrust and Parent. It looks up the AppliedForces component of the parent and adds the thrust vector to it. Then the AccelerationSystem runs through all entities with the components AppliedForces, Mass and Velocity. It adds the applied forces to entity’s velocity. In code, it looks like this:


void ThrustSystem::update(entt::registry& entities)
{
  auto view = entities.view<Thrust, Parent>();
  for (auto (thrust, parent): view)
  {
    auto& applied_forces = entities.get<AppliedForces>(parent.id);
    applied_forces.vector += thrust.vector;
  }
}

void AccelerationSystem::update(entt::registry& entities, dt)
{
  auto view = entities.view<AppliedForces, Mass, Velocity>();
  for (auto (applied_forces, mass, velocity): view)
  {
    velocity.vector += applied_forces.vector * mass * dt;
  }
}

This works perfectly for me, the systems are decoupled and work independently from each other and I don’t experience any performance issues (I model max. 1000 ships with an average number of 4 engines each). So I will stick to this implementation in my current game.

But I am actually curious and I would like to learn more about the “correct” usage of ECS in game code: is this a recommended approach to gain high performances and avoid cache misses? This is my first project with ECS and I am not an expert in CPU stuff at all but naively-thinking I would say there are two “bottlenecks” in my code:

  • Look-up time for the AppliedForces component of the parent entity in ThrustSystem
  • The AppliedForces is probably further away from Thrust and Parent in memory. So I introduced a cache miss.

At first, are my assumptions correct? And if yes, how would one avoid these bottlenecks?

amazon s3 – How to use input transformer for ECS Fargate launch type with Terraform CloudWatch event trigger

I’m using terraform to create a CloudWatch Event Trigger with a ECS Fargate launch type which the event source is S3. When I use the input_transformer field to pass in the bucket and key into the ECS task, my event rule results in a failed invocation.

This is the aws_cloudwatch_event_rule:

resource "aws_cloudwatch_event_rule" "event_rule" {
  name          = "dev-gnss-source-put-rule-tf"
  description   = "Capture S3 events on uploads bucket"
  event_pattern = <<PATTERN
{
  "source": [
    "aws.s3"
  ],
  "detail-type": [
    "AWS API Call via CloudTrail"
  ],
  "detail": {
    "eventSource": [
      "s3.amazonaws.com"
    ],
    "eventName": [
      "PutObject"
    ],
    "requestParameters": {
      "bucketName": [
        "example-bucket-name"
      ]
    }
  }
}
PATTERN
}

This is the aws_cloudwatch_event_target:

resource "aws_cloudwatch_event_target" "event_target" {
  target_id = "dev-gnss-upload-event-target-tf"
  arn       = "example-cluster-arn"
  rule      = aws_cloudwatch_event_rule.event_rule.name
  role_arn  = aws_iam_role.uploads_events.arn
  ecs_target {
    launch_type = "FARGATE"
    task_count  = 1 # Launch one container / event
    task_definition_arn = "example-task-definition-arn"
    network_configuration {
      subnets         = ["example-subnet"]
      security_groups = []
    }
  }

  input_transformer {
    input_paths = {
      s3_bucket = "$.detail.requestParameters.bucketName"
      s3_key    = "$.detail.requestParameters.key"
    }

    input_template = <<TEMPLATE
{
  "containerOverrides": [
    {
      "name": "myproject-task",
      "environment": [
        { "name": "S3_BUCKET", "value": <s3_bucket> },
        { "name": "S3_KEY", "value": <s3_key> }
      ]
    }
  ]
}
TEMPLATE
  }
}

If I remove the input_transformer section, it will work fine, but I need to pass in the s3 bucket and key to process the particular file.

My rationale for doing this is to remove the need for an intermediary Lambda and was guided by this Medium post: https://medium.com/@bowbaq/trigger-an-ecs-job-when-an-s3-upload-completes-3559c44c37d1

Any advice is appreciated.

architecture – How to model interaction between entities in ECS?

I am exploring the ECS pattern and my pet project is a simulation of an economy where the primary mode of interaction between economic agents is a transaction. Some of these agents are market makers (they passively advertise offers to trade – sometimes called making a market). Some agents are market takers (they browse offers and decide which they want to trade with).

So an offer is a component of a market maker. This is clear to me. I have a system that governs the process of market makers setting offers.

Now I need a system that governs the process of market takers browsing the offers and “notifying” the market maker of their intention to trade. I call this notification a proposed_trade. At every tick of the main loop, multiple marker takers may want to trade with the same market maker based on the same offer. The market maker will then accept the proposed_trades for as long as it has the resources to satisfy them, then reject them thereafter.

So how do I model this with an ECS? Some options:

  1. Each proposed_trade belongs to a distinct entity and references both the maker and the taker. There may be many relating to the same maker.
  2. Each maker has, as a component, a list of proposed_trades (like a buffer) and the takers just add to the list when they want to trade.

Are either of these considered more idiomatic or is the choice a matter of taste?

entity component system – Should the HUD be Entites in a ECS ? And how to handle Events if so?

I’m building a GameEngine using Ashley and some how I can’t figure out how.

I through I could use something like this. Or use the Signal/Listener from Ashley.
But how to Implement a interactive HUD? This is my current idea:

I have a System that only polls for inputs. If it detects an Input it would be a MouseClick so the PollySystem is sending out a MouseClickEvent witch the Coords. And a HUDClickedSystem will catch this event and checks if the click was inside a HUD Boundary and will Tag it with a clickedCompoment or not.
A Third system will look out for all entities with a clickedComponent and will react something like Respawn button clicked -> Respawn, Pause button clicked -> Pause etc.

This is a mix from the ideas here and here

I would love to have something like the Command pattern / Intent System because I think it easy and straight forward but I can’t figure out how to handle more than a flag ( Key pressed / Mouse pressed ).
But for this I need to know where the Mouse is pressed.

c++ – Writing a data-oriented ECS update loop that handles multiple components

So I have an engine in progress that’s structured like this:

  • entities are simple ids (unsigned short)
  • components are stored in pools which are static members
  • systems are stored by the manager, and all inherit from a single base

What this looks like in code is like this:

struct transformComponent {
    const unsigned short id;
    vec2 pos, dim;

    transformComponent(vec2 pos, vec2 dim, unsigned short id): pos(pos), dim(dim), id(id) {}

    static componentPool<transformComponent> pool; // allows for scalability
};

struct physicsComponent {
    const unsigned short id;
    vec2 v, a, f;
    unsigned short mass;
    float invmass

    physicsComponent(vec2 v, vec2 a, vec2 f, unsigned short mass, unsigned short id): v(v), a(a), f(f), mass(mass), invmass(1.0/mass), id(id) {}

    static componentPool<physicsComponent> pool;
};

// same for other components

struct system {
    virtual void update() = 0; // don't care about virtual call, there will be only one per system
};

struct physicsSystem: public system {
    virtual void update() override; // the problem
};

struct room { // the manager
    std::vector<system*> systems;
    std::unordered_set<unsigned short> activeIds;

    void update() {for(auto* sys: systems) {sys->update();}}
};

Now I did everything I could, until now, to make this as cache-friendly as possible. The thing is: if the physics loop reads the physics components and writes to the transforms, doesn’t that completely eliminate the point? I’ll let some code explain what I mean:

/* either:
  physicsSystem has a hashmap of ids that it has to loop over to component pointers, which only gets updated when necessary (std::unordered_map<unsigned short, std::tuple<transformComponent*, physicsComponent*>> comps;), breaks purity (systems have no state)
or
  comps is created every frame (for every system), terribly inefficient
*/

// either:
void physicsSystem::update() {
    for(auto pair: comps) {
        physicsComponent* phy = std::get<physicsComponent*>(pair.second);
        transformComponent* tra = std::get<transformComponent*>(pair.second);

        phy->a = phy->f * phy->invmass;
        phy->v += phy->a;
        tra->pos += phy->v;

        // cache misses to load both transform and physics twice, for every entity, for every system, for every frame
    }
}

// or:
// comps is actually an std::unordered_map<unsigned short, std::tuple<transformComponent*, physicsComponent*, vec2>>
void physicsSystem::update() {
    for(auto pair: comps) {
        physicsComponent* phy = std::get<physicsComponent*>(pair.second);
        vec2& schedule = std::get<vec2>(pair.second);

        phy->a = phy->f * phy->invmass;
        phy->v += phy->a;
        schedule = phy->v;
    }
    for(auto pair: comps) {
        std::get<transformComponent*>(pair.second)->pos += std::get<vec2>(pair.second);
    }
    // smooth first loop, but still cache misses in the second (I think)
}

So, my question is: how would one go about making this loop cache-friendly? By that I mean, no cache misses for every entity, but only when the array size exceeds the cache and when switching between component types to update. I’d be happy to receive any different approaches, as well.
TIA.

architecture – How do you handle entity life-time and entities without all components in an ECS?

I’m just starting to implement my own ECS and am drawing everything down on paper to make sure I understand it all before tackling the implementation in code. However I’m getting stuck on entity-lifetime and nothing I’ve read really answers my question.

Just to be sure I’m not missing something, my understanding so far is:

  1. Components of the same type all sit next to each other in memory
  2. Entities are just an ID, which Components refer to (i.e. Components have an “owner”)
  3. Components all have a unique Id

Great! So for example, say I have a PositionComponent, VelocityComponent, and VisibleComponent.

struct PositionComponent {
    vector2f position;
};

struct VelocityComponent {
    vector2f velocity;
};

struct VisibleComponent {
    Image imageToRender;
};

Great. Now let’s say I have two types of Entity:

  1. EntityA has a position, velocity, and visible components
  2. EntityB has a position and velocity component, but is not visible

(let’s hypothetically say that the Image in the visible component is the actual image data because every entity is super unique or something)

Say I have an PhysicsSystem which wants to iterate over all the Position and Velocity components and update the Position. This works, because every entity I’ve created has both of these components.

And so we’re using EntityID as an index into the component arrays, we can easily know we’re accessing the correct ones.

But then if there was a RenderSystem that wants to iterate over all the Position and Visible Components, the problem is that the EntityId can no longer be an index into the arrays, because not every Entity has every component.

So; the way I’ve thought to address this is by having an “Entity to Index Map” for each component. Basically, this EntityID has a PositionComponent in index 232 of the array.

But because of this, now any system that needs two or more Components to act, will lose out on all the benefits of an ECS, right?

I dismissed giving all components arrays empty space to keep them all “in sync”, but that means I could have a lot of wasted data, which only gets worse the more different components I create.

There’s then the problem of lifetime. If EntityID 232 is killed, I ideally would shift all the components in these arrays down to fill the gap, which again means I can’t use EntityId as an index into the arrays.

A solution I thought of here was to re-use EntityIDs when they’re no longer needed, maybe by using a 16bits of a 32-bit ID as the actual array index, and the other 16-bits as some sort of random guid to keep it clear that it’s a new entity (and not the old one who’s EntityID is being reused). This means I don’t need to shift the data around, and wouldn’t need to keep a map from ID to Index; but it doesn’t solve the problem where not all entities have all components, so none of the arrays can ever be assumed to be “in sync”.

So in summary my questions are:
1. How does a System in an ECS handle iterating over two separate components, when it’s not guaranteed both component arrays will have the same entities components in the same indices?
2. Is it more beneficial to keep the data compact, or keep the arrays in sync?

game – data-oriented ECS C ++ implementation

I did an implementation of a data oriented ECS. It is divided into three classes: system, component and EcsInstance. EcsInstance is where everything is wrapped.

Component:


    typedef void* EntityHandle;
    typedef std::vector ComponentMem;
    typedef uint16_t ComponentId;
    struct IComponent;
    typedef u64(*ComponentCreateFn)(ComponentMem&, EntityHandle);
    typedef void(*ComponentFreeFn)(IComponent*);

    struct ComponentInfo {
        const ComponentCreateFn createFn;
        const ComponentFreeFn freeFn;
        const size_t size;
        const std::string name;
    };

    struct IComponent {
    public:
        EntityHandle entity = WZ_NULL_ENTITY_HANDLE;

    public:
        virtual ~IComponent() {}

        template 
        static ComponentId __REGISTER_COMPONENT_TYPE(ComponentCreateFn createFn,
                                                    ComponentFreeFn freeFn);
        static const ComponentInfo & IComponent::StaticInfo(ComponentId componentType) {
            return componentTypes()(componentType - 1);
        }

        inline static bool IsTypeValid(ComponentId type) {
            return type <= componentTypes().size() && type > 0;
        }

        inline static ComponentId GetNumRegisteredTypes() { return componentTypes().size(); }

        virtual void ShowGUI() {}
    private:
        inline static std::vector& componentTypes() {
            static std::vector s_componentTypes;
            return s_componentTypes;
        }
    };


    template 
    struct Component
        : public IComponent {
        virtual ~Component() {}
        const static ComponentCreateFn __CREATE_FN;
        const static ComponentFreeFn __FREE_FN;
        inline static ComponentId typeId()
        {
            static ComponentId id = IComponent::__REGISTER_COMPONENT_TYPE 
            (
                __COMPONENT_CREATE,
                __COMPONENT_FREE
            );
            return id;
        }
        const static size_t size;
    };

    template 
    inline u64 __COMPONENT_CREATE(ComponentMem& memory, EntityHandle entity) 
    {
        u64 index = static_cast(memory.size());
        memory.resize(index + TComponent::size);

        TComponent* component = new(&memory(index)) TComponent();

        component->entity = entity;
        return index;
    }

    template 
    inline void __COMPONENT_FREE(IComponent *component) {
        TComponent *_c = static_cast(component);
        _c->~TComponent();
    }

    template 
    inline ComponentId IComponent::__REGISTER_COMPONENT_TYPE(ComponentCreateFn createFn,
                                                    ComponentFreeFn freeFn) {
        componentTypes().push_back({
            createFn,
            freeFn,
            sizeof(TComponent),
            typestr(TComponent)
        });



        return static_cast(componentTypes().size());
    }

    template 
    const size_t Component::size(sizeof(TComponent));

    template 
    const ComponentCreateFn Component::__CREATE_FN(__COMPONENT_CREATE);

    template 
    const ComponentFreeFn Component::__FREE_FN(__COMPONENT_FREE);

System:

    template
    inline constexpr size_t indexOfVariadicType()
    {
        if constexpr (std::is_same::value)
            return 0;
        else
            return 1 + indexOfVariadicType();
    }

    typedef Bitset SystemSignature;



    template 
    class System 
    {
    public:
        enum ComponentFlags
        {
            flag_none = 0,
            flag_optional = BIT(1),
        };
        typedef System SystemImpl;


        static constexpr u32 NUM_COMPONENT_TYPES =  sizeof...(TComponents);
        static const ComponentId COMPONENT_TYPES(NUM_COMPONENT_TYPES);

    public:
        typedef std::array ComponentPass;

        inline bool ProcessComponentsPass(const Event& e, ComponentPass& components) const
        {
            return ProcessComponents(e, ((TComponents*)components.at(indexOfVariadicType()))...);
        }

        inline bool IsSubscribed(EventType eventType) const 
        { 
            return m_subscriptions.Get((s32)eventType);
        }

        inline bool HasType(ComponentId type) 
        {
            return fullSignature().Get(type);
        }

        inline const SystemSignature& GetFullSignature() const
        {
            return fullSignature();
        }

        inline const SystemSignature& GetMinimumSignature() const
        {
            return m_minimumSignature;
        }

        inline bool HasTypeFlag(ComponentId type, s32 flag) 
        {
            WZ_CORE_ASSERT(HasType(type), 
                "Cannot check type flag for component that is not in system signature");
            if (m_flags.find(type) == m_flags.end())
                m_flags(type) = flag_none;
            return m_flags.at(type) & flag;
        }

        template 
        inline void Flag(s32 flags)
        {
            assert(HasType(TComponent::typeId()) && "System must have type to flag it");
            if (m_flags.find(TComponent::typeId()) == m_flags.end()) 
                m_flags(TComponent::typeId()) = flag_none;
            m_flags(TComponent::typeId()) |= flags;
            if (flags |= flag_optional)
            {
                m_minimumSignature.Set(TComponent::typeId(), false);
            }
        }

    protected:
        inline void Subscribe(EventType eventType)
        {
            m_subscriptions.Set((s32)eventType, true);
        }

        virtual bool ProcessComponents(const Event& e, TComponents*...) const = 0;

    private:
        std::unordered_map m_flags;
        Bitset m_subscriptions;
        SystemSignature m_minimumSignature = fullSignature();

    public:
        inline static TSubclass* GetInstance() { return &s_instance; }
        inline static ComponentPass& GetComponentPass() { return s_componentPass; }
        inline static u32 GetComponentIndex(ComponentId type) {  return s_componentIndices.at(type);};

    protected:
        static TSubclass s_instance;
    private:
        template 
        inline static SystemSignature CreateFullSignature()
        {
            SystemSignature sig;


            (sig.Set(TComponents::typeId(), true), ...);

            return sig;
        }

        inline static const SystemSignature& fullSignature()
        {
            static SystemSignature s_fullSignature = CreateFullSignature();
            return s_fullSignature;
        }

        static ComponentPass s_componentPass;
        static const std::unordered_map s_componentIndices;
    };

    #define _SystemImpl System

    template 
    std::unordered_map BuildIndexMap()
    {
        u32 idx = 0;

        std::unordered_map map;
        (map.emplace(TComponent::typeId(), idx++), ...);

        return map;
    }

    template 
    TSubclass _SystemImpl::s_instance = TSubclass();

    template 
    const ComponentId _SystemImpl::COMPONENT_TYPES(_SystemImpl::NUM_COMPONENT_TYPES) =
    {
        TComponents::typeId()...
    };

    template 
    std::array _SystemImpl::s_componentPass;

    template 
    const std::unordered_map _SystemImpl::s_componentIndices = BuildIndexMap();

I also made a SystemLayer class so you can create layouts and pass them directly for processing (see EcsInstance below):

    class SystemLayer
    {
    private:
        typedef std::function SystemProcessCallback;

    public:

        template 
        inline u32 Push(bool enabled = true)
        {
            void* handle = (void*)T::GetInstance();
            m_systemHandles.push_back(handle);
            m_processFunctions(handle) = (this)(const Event& e, EcsInstance* ecs)
            {
                return ecs->ProcessSystem(e);
            };

            m_enabledFlags(handle) = enabled;

            if (m_count.find(handle) == m_count.end())
            {
                m_count(handle) = 0;
            }

            m_count(handle)++;

            return m_systemHandles.size() - 1;
        }

        template 
        inline u32 Insert(u32 index, bool enabled = true)
        {
            void* handle = (void*)T::GetInstance();
            m_systemHandles.insert(m_systemHandles.begin() + index, handle);
            m_processFunctions(handle) = (this)(const Event& e, EcsInstance* ecs)
            {
                return ecs->ProcessSystem(e);
            };

            m_enabledFlags(handle) = enabled;

            if (m_count.find(handle) == m_count.end())
            {
                m_count(handle) = 0;
            }

            m_count(handle)++;

            return m_systemHandles.size() - 1;
        }

        inline void Pop()
        {
            WZ_CORE_ASSERT(m_systemHandles.size() > 0, "No systems to pop");
            auto handle = m_systemHandles(m_systemHandles.size() - 1);
            m_count(handle)--;
            if (m_count(handle) == 0) m_count.erase(handle);
            m_systemHandles.pop_back();
            m_enabledFlags.erase(handle);
            m_processFunctions.erase(handle);
        }

        template 
        inline void RemoveFirst()
        {
            WZ_CORE_ASSERT(m_count.find(T::GetInstance()) != m_count.end(),
                "System not in layout");

            for (int i = 0; i < m_systemHandles.size(); i++)
            {
                if ((void*)T::GetInstance() == m_systemHandles(i))
                {
                    m_systemHandles.erase(m_systemHandles.begin() + i);
                    return;
                }
            }

            WZ_BREAK;
        }

        template 
        inline void RemoveLast()
        {
            WZ_CORE_ASSERT(m_count.find(T::GetInstance()) != m_count.end(),
                "System not in layout");

            for (int i = m_systemHandles.size() - 1; i >= 0; i--)
            {
                if ((void)T::GetInstance() == m_systemHandles(i))
                {
                    m_systemHandles.erase(m_systemHandles.begin() + i);
                    return;
                }
            }

            WZ_BREAK;
        }

        inline void Remove(u32 index)
        {
            WZ_CORE_ASSERT(index < m_systemHandles.size(), "System not in layout");
            m_systemHandles.erase(m_systemHandles.begin() + index);
        }

        template 
        inline void SetEnabled(bool enabled)
        {
            WZ_CORE_ASSERT(m_count.find(T::GetInstance()) != m_count.end(),
                "Cannot SetEnabled on system that's not in layout");
            m_enabledFlags(T::GetInstance()) = enabled;
        }

        inline void SetEnabled(u32 index, bool enabled)
        {
            WZ_CORE_ASSERT(index < m_systemHandles.size(),
                "Layout system index out of range");

            m_enabledFlags(m_systemHandles(index)) = enabled;
        }

        template 
        inline bool IsEnabled()
        {
            WZ_CORE_ASSERT(m_count.find(T::GetInstance()) != m_count.end(),
                "Cannot check IsEnabled for system that's not in layout");
            return m_enabledFlags(T::GetInstance());
        }

        inline bool IsEnabled(u32 index)
        {
            WZ_CORE_ASSERT(index < m_systemHandles.size(),
                "Cannot check IsEnabled for system that's not in layout");
            return m_enabledFlags(m_systemHandles(index));
        }

        template 
        inline bool Has()
        {
            return m_count.find(T::GetInstance()) != m_count.end();
        }

        template 
        inline bool Is(u32 index)
        {
            return m_systemHandles(index) == (void*)T::GetInstance();
        }

        template 
        inline u32 Count()
        {
            WZ_CORE_ASSERT(m_count.find(T::GetInstance()) != m_count.end(),
                "Cannot check IsEnabled for system that's not in layout");
            return m_count(T::GetInstance());
        }

        inline u32 Count() const
        {
            return m_systemHandles.size();
        }

        template 
        inline u32 IndexOfFirst()
        {
            WZ_CORE_ASSERT(m_count.find(T::GetInstance()) != m_count.end(),
                "System not in layout");

            for (int i = 0; i < m_systemHandles.size(); i++)
            {
                if ((void*)T::GetInstance() == m_systemHandles(i)) return i;
            }

            WZ_BREAK;
            return 0;
        }

        template 
        inline u32 IndexOfLast()
        {
            WZ_CORE_ASSERT(m_count.find(T::GetInstance()) != m_count.end(),
                "System not in layout");

            for (int i = m_systemHandles.size() - 1; i >= 0; i--)
            {
                if ((void*)T::GetInstance() == m_systemHandles(i)) return i;
            }

            WZ_BREAK;
            return 0;
        }

        inline bool _Process(u32 index, const Event& e, EcsInstance* ecs)
        {
            return m_processFunctions(m_systemHandles(index))(e, ecs);
        }

        inline void SetEnabledAll(bool enabled)
        {
            for (auto handle : m_systemHandles)
            {
                m_enabledFlags(handle) = enabled;
            }
        }

    private:
        // TODO: Think of a less spaghetti solution (#RETHINK)
        std::vector m_systemHandles;

        std::unordered_map m_enabledFlags;
        std::unordered_map m_processFunctions;
        std::unordered_map m_count;
    };

And here is the EcsInstance where the components are stored and the systems can process them:

class SystemLayer;

    class EcsInstance
    {
    private:
        struct Entity;

        typedef std::vector                           DataPool;
        typedef u64                                         DataIndex;
        typedef u32                                         EntityId;
        typedef std::map                  EntityMap;
        typedef std::unordered_map   DataPoolMap;

        struct Entity
        {
            std::unordered_map componentRefs;
            EntityId id;
            SystemSignature signature;
        };

    public:
        template 
        EntityHandle CreateEntity();
        EntityHandle CreateEntity();

        void DestroyEntity(EntityHandle hEntity);

        template 
        void CreateComponent(EntityHandle hEntity);
        void CreateComponent(EntityHandle hEntity, ComponentId type);

        template 
        void DestroyComponent(EntityHandle hEntity);
        void DestroyComponent(EntityHandle hEntity, ComponentId type);

        template 
        T* GetComponent(EntityHandle hEntity);
        IComponent* GetComponent(EntityHandle hEntity, ComponentId type);

        template 
        bool HasComponent(EntityHandle hEntity);
        bool HasComponent(EntityHandle hEntity, ComponentId type);

        template 
        bool ProcessSystem(const Event& e);

        bool ProcessLayout(SystemLayer& layout, const Event& e);

        void ForEachEntity(std::function);

    private:
        Entity& FromHandle(EntityHandle hEntity);
        EntityHandle ToHandle(Entity& entity);

        inline u32 GetComponentCount(ComponentId type)
        {
            auto& typeInfo = IComponent::StaticInfo(type);

            return m_dataPools(type).size() / typeInfo.size;
        }

        inline EntityId GetNextEntityId()
        {
            static EntityId current = 0;
            return ++current;
        }

    private:
        DataPoolMap m_dataPools;
        EntityMap   m_entities;
    };

    template 
    inline EntityHandle EcsInstance::CreateEntity()
    {
        auto newId = GetNextEntityId();
        auto& entity = m_entities(newId);
        entity.id = newId;

        EntityHandle hEntity = ToHandle(entity);
        (CreateComponent(hEntity), ...);

        return hEntity;
    }

    inline EntityHandle EcsInstance::CreateEntity()
    {
        auto newId = GetNextEntityId();
        auto& entity = m_entities(newId);
        entity.id = newId;
        return ToHandle(entity);
    }

    inline void EcsInstance::DestroyEntity(EntityHandle hEntity)
    {
        auto& entity = FromHandle(hEntity);

        // Copy refs, as its modified in DestroyComponent
        auto componentRefs = entity.componentRefs;
        for (auto (type, dataIndex) : componentRefs)
        {
            DestroyComponent(hEntity, type);
        }

        m_entities.erase(entity.id);
    }

    template 
    inline void EcsInstance::CreateComponent(EntityHandle hEntity)
    {
        CreateComponent(hEntity, T::typeId());
    }
    inline void EcsInstance::CreateComponent(EntityHandle hEntity, ComponentId type)
    {
        WZ_CORE_ASSERT(IComponent::IsTypeValid(type), 
            "Tried creating a component on entity with invalid ID");
        auto& entity = FromHandle(hEntity);
        WZ_CORE_ASSERT(entity.signature.Get(type) == false, 
            "Tried creating duplicate of Component type on entity. Only one component per type allowed");

        const auto& typeInfo = IComponent::StaticInfo(type);
        const auto& createFn = typeInfo.createFn;
        auto& dataPool = m_dataPools(type);

        auto oldSize = dataPool.size();

        entity.componentRefs(type) = createFn(dataPool, hEntity);
        entity.signature.Set(type, true);

        GetComponent(hEntity, type)->entity = hEntity;
    }

    template 
    inline void EcsInstance::DestroyComponent(EntityHandle hEntity)
    {
        DestroyComponent(hEntity, T::typeId());
    }
    inline void EcsInstance::DestroyComponent(EntityHandle hEntity, ComponentId type)
    {
        auto& entity = FromHandle(hEntity);
        WZ_CORE_ASSERT(entity.signature.Get(type) == true, 
            "Tried destroying a component the entity doesn't have");

        const auto& typeInfo = IComponent::StaticInfo(type);
        const auto& freeFn = typeInfo.freeFn;
        auto& dataPool = m_dataPools(type);

        IComponent* component = GetComponent(hEntity, type);

        DataIndex deadCompIndex = entity.componentRefs(type);
        DataIndex lastCompIndex = dataPool.size() - typeInfo.size;

        freeFn(component);
        entity.componentRefs.erase(type);
        entity.signature.Set(type, false);

        if (deadCompIndex != lastCompIndex)
        {
            // Move last component to replace dead component
            memcpy(&dataPool(deadCompIndex), &dataPool(lastCompIndex), typeInfo.size);

            IComponent* movedComponent = (IComponent*)&dataPool(deadCompIndex);

            Entity& affectedEntity = FromHandle(movedComponent->entity);
            affectedEntity.componentRefs(type) = deadCompIndex;
        }

        dataPool.resize(dataPool.size() - typeInfo.size);
        // TODO: Maybe shrink_to_fit here to actually deallocate the memory? 
        // Not doing so will avoid dynamic allocations for future components... 
    }

    template 
    inline T* EcsInstance::GetComponent(EntityHandle hEntity)
    {
        return (T*)GetComponent(hEntity, T::typeId());
    }
    inline IComponent* EcsInstance::GetComponent(EntityHandle hEntity, ComponentId type)
    {
        WZ_CORE_ASSERT(IComponent::IsTypeValid(type), "Invalid component type");
        auto& entity = FromHandle(hEntity);
        WZ_CORE_ASSERT(entity.signature.Get(type) == true, 
            "Tried getting non-existent component from entity");
        auto& dataPool = m_dataPools(type);
        return (IComponent*)&dataPool(entity.componentRefs(type));
    }

    template 
    inline bool EcsInstance::HasComponent(EntityHandle hEntity)
    {
        return HasComponent(hEntity, T::typeId());
    }
    inline bool EcsInstance::HasComponent(EntityHandle hEntity, ComponentId type)
    {
        auto& entity = FromHandle(hEntity);

        return entity.signature.Get(type);
    }

    template 
    inline bool EcsInstance::ProcessSystem(const Event& e)
    {
        bool handled = false;
        auto system = TSystem::GetInstance();
        if (!system->IsSubscribed(e.GetEventType())) return false;
        auto& pass = system->GetComponentPass();

        u32 smallestPoolType = 0;

        // TODO: Maybe there's a way to cache this? (#OPTIMIZE)
        for (int i = 0; i < TSystem::NUM_COMPONENT_TYPES; i++)
        {
            ComponentId type = TSystem::COMPONENT_TYPES(i);

            if (smallestPoolType == 0
                || (GetComponentCount(type) < GetComponentCount(smallestPoolType)
                    && !system->HasTypeFlag(type, TSystem::flag_optional)))
            {
                smallestPoolType = type;
            }
        }

        if (m_dataPools(smallestPoolType).size() == 0) return false;

        auto& smallestTypeInfo = IComponent::StaticInfo(smallestPoolType);
        auto& smallestPool = m_dataPools(smallestPoolType);

        for (DataIndex dataIndex = 0; dataIndex < smallestPool.size(); dataIndex += smallestTypeInfo.size)
        {
            IComponent* smallestPoolComponent = (IComponent*)&smallestPool(dataIndex);
            Entity& entity = FromHandle(smallestPoolComponent->entity);
            auto& systemSig = system->GetMinimumSignature();
            if ((entity.signature & systemSig) != systemSig) continue;

            // TODO: Generate this code with templates voodoo to avoid for loop? (#OPTIMIZE)
            for (u32 i = 0; i < TSystem::NUM_COMPONENT_TYPES; i++)
            {
                ComponentId type = TSystem::COMPONENT_TYPES(i);

                if (entity.signature.Get(type))
                {
                    auto& dataPool = m_dataPools(type);
                    auto& dataIndex = entity.componentRefs(type);
                    pass(system->GetComponentIndex(type)) = (IComponent*)&dataPool(dataIndex);
                }
                else
                {
                    pass(system->GetComponentIndex(type)) = NULL;
                }

            }

            if (system->ProcessComponentsPass(e, pass))
            {
                handled = true;
                break;
            }
        }

        return handled;
    }

    inline EcsInstance::Entity& EcsInstance::FromHandle(EntityHandle hEntity)
    {

        WZ_CORE_ASSERT(m_entities.find(reinterpret_cast(hEntity)) 
                        != m_entities.end(), "Invalid Entity Handle");
        return m_entities(reinterpret_cast(hEntity));
    }
    inline EntityHandle EcsInstance::ToHandle(Entity& entity)
    {
        return (void*)entity.id;
    }

    inline void EcsInstance::ForEachEntity(std::function fn)
    {
        for (auto& (entityId, entity) : m_entities)
        {
            auto hEntity = ToHandle(entity);

            if (!fn(hEntity)) break;
        }
    }

It is not multithreaded, but it would not be a problem to implement it. Here is an example case for a SpriteRenderer video game system representing a sprite in one position with an optional rotation:

struct Position : public Component
{
   float x, y;
};

struct Rotation : public Component
{
    float rads;
};

struct Sprite : public Component
{
    Texture* texture;
    Color color;
};

class SpriteRenderer : public System
{
public:
    SpriteRenderer()
    {
        Subscribe(EventType::app_init);
        Subscribe(EventType::app_update);
    }

    bool ProcessComponents(const Event& e, Position* position, Rotation* rotation, Sprite* sprite) const override
    {
        switch(e.GetEventType())
        {
            case EventType::app_init:
            {
                // Do some initialization...
            }

            case EventType::app_update:
            {
                if (rotation)
                {
                    // Has rotation - do some rotation stuff
                }
                //Do some rendering...
            }
        }
        return false;
    }
};

For a more "real world" implementation check out my demo game: https://github.com/N00TN00T/Wizzy/blob/master/Sandbox/src/DemoGame2D.cpp.

I'm pretty unhappy with the SystemLayer implementation, but that's simply because I can't think of a better solution right now …

I guess I want to know if I am missing any of the ECS principles and what could I do better.