You get a bonus - 1 coin for daily activity. Now you have 1 coin

Component-Oriented Programming and the Entity Component System

Lecture



Component-based software engineering ( CBSE ), also called component-based development ( CBD ), is a software development style whose goal is to build software out of loosely coupled, modular components. It emphasizes the separation of concerns between the different parts of a software system.

Since the first programmable computer was built in 1946, programming has never slowed down. Requirements placed on programs kept growing, and along with them came ever more powerful languages and ever more revolutionary programming approaches. In the same way, component-oriented programming is now smoothly but steadily displacing object-oriented programming. It is worth identifying the objective reasons why component-oriented programming is gaining ever greater popularity in our time.
Today there is an acute need for the fast, well-coordinated development of large and complex products. Any program must have a flexible structure and the ability to have its functionality fixed and extended with
minimal expenditure of resources. Even the slightest mistake in choosing a structure or a programming approach can lead to fatal consequences when you try to fix, change or add functionality. Object-oriented programming is familiar to practically every programmer. According to this approach, a program is a collection of objects that carry the basic characteristics of their classes and interact with one another. Along with this, the approach offers four basic concepts: encapsulation, inheritance, polymorphism and abstraction. These are, without a doubt,
excellent principles with thousands of possible implementations

Definition and characteristics of components

Component-oriented programming (COP) treats a program as a set of encapsulated components that interact with other components through a container. Each component is a separate subprogram that describes only one piece of functionality and exposes an interface for accessing it. Component containers implement the interaction of components and their functionality. At the same time, component-oriented programming practically rules out the use of inheritance and introduces new concepts: introspection (the ability to describe oneself),
modularity, persistence (the ability to save and restore a given state) and the ability to reuse the same component many times.
When developing large software products with a complex architecture, object-oriented programming runs into a number of problems. Component-oriented programming makes it possible to correct these shortcomings and brings greater functionality.
Interdependence of objects and the fragile base class problem. Since COP operates only with components that are independent of one
another, and with containers holding their instances, there is no longer any need to use inheritance.
Insufficient control over information. The risk of memory leaks. Components are part of their containers, so when a container is destroyed the memory of all its components is released. Dependence on the programming language and platform. According to the philosophy of COP, every component is a separate, independent piece of functionality, which means it can easily be extracted into a separate program module with a well-defined access interface,
yet it can be compiled in any language and on any platform. Difficulty of organizing the architecture. The whole structure is reduced to a set of containers into which the required components can easily
be plugged from an available list, creating the required functionality. Difficulty of controlling an object's life cycle. Each component is able to save and restore its own state and to unload it.
Under component-oriented programming, a program is broken down into a large collection of modules, which makes it possible to fix, modify or extend functionality quickly and easily. So component-oriented programming corrects most of the shortcomings of its predecessor and brings
many advantages, such as easy structuring, ease of correction and extension, which is especially important in the development of
large-scale software products.

An individual software component is a software package, web service, web resource or module that encapsulates a set of related functions or data.

Components interact with one another through interfaces . Each component provides an interface (called the provided interface ) through which other components can use it. When a component uses another component's interface, that interface is called the required interface.

In the UML illustrations in this article, provided interfaces are represented by lollipop symbols and required interfaces are represented by open socket symbols.

Component-Oriented Programming and the Entity Component System

A simple example of several software components, depicted in a hypothetical holiday booking system rendered in UML 2.0.

Components must be interchangeable , that is, a component must be replaceable by another one with the same interfaces without breaking the rest of the system.

Components must be reusable.

Component usability testing should be considered when software components interact directly with users.

Components must be:

  • fully documented
  • thoroughly tested
    • robust - with comprehensive input validity checking
    • able to pass back appropriate error messages or return codes

History

The idea that software should be componentized, that is, built from ready-made components , first became prominent in Douglas McIlroy's address at the NATO conference on software engineering in Garmisch , Germany , in 1968, titled « Mass Produced Software Components» . The aim of the conference was to counter the so-called software crisis. McIlroy's subsequent introduction of pipes and filters into the Unix operating system was the first implementation of an infrastructure for this idea.

Brad Cox of Stepstone largely defined the modern concept of a software component. He called them Software ICs and set out to create an infrastructure and a market for these components by inventing the Objective-C programming language. (He summarizes this view in his book « Object-Oriented Programming – An Evolutionary Approach», 1986.)

Software components are used in two different contexts and in two kinds: i) using components as parts to build a single executable, or ii) each executable is treated as a component in a distributed environment, where components interact with one another over the Internet or an intranet using communication protocols for IPC (inter-process communication). The former belongs to the first kind, and the latter to the second.

In the early 1990s IBM took this route by developing its System Object Model (SOM). In response, Microsoft paved the way for the actual deployment of component software with Object Linking and Embedding (OLE) and the Component Object Model (COM). As of 2010 there are many successful software component models.

Architecture

A computer running several software components is often called an application server. Such a combination of application servers and software components is usually called distributed computing. A typical real-world use of this is, for example, in financial applications or business software.

Component models

A component model is a specification of the properties of a component.

Examples of component models are: the Enterprise JavaBeans (EJB) model, the Component Object Model (COM), the .NET model, the X-MAN component model, and the Common Object Request Broker Architecture (CORBA) component model.

Technologies

  • Business object technologies
    • Newi
  • Domain-specific component software frameworks
    • Advanced Component Framework
    • Earth System Modeling Framework (ESMF)
    • MASH IoT Platform for Asset Management
    • The KOALA component model, developed for software in consumer electronics
    • Web: React , [10] : 4–6 Vue.js
    • Software Communications Architecture (JTRS SCA)
  • Component-oriented programming
    • Bundles as defined by the OSGi Service Platform specification.
    • Component Object Model (OCX/ActiveX/COM) and DCOM from Microsoft
    • TASCS - SciDAC Center for Technology for Advanced Scientific Component Software
    • The Eiffel programming language
    • Enterprise JavaBeans from Sun Microsystems (now Oracle )
    • Flow-based programming
    • Fractal component model from ObjectWeb
    • MidCOM component framework for Midgard and PHP
    • Oberon , Component Pascal and the BlackBox Component Builder
    • rCOS method of component-based model-driven design from UNU-IIST
    • SOFA component system from ObjectWeb
    • The System.ComponentModelnamespace in Microsoft .NET
    • Unity, developed by Unity Technologies
    • Unreal Engine, developed by Epic Games.
    • UNO from the OpenOffice.org office suite
    • VCL and CLX from Borland and the similar free LCL library.
    • XPCOM from the Mozilla Foundation
  • Compound document technologies
    • Active documents in the Oberon system and the BlackBox Component Builder
    • KParts , the compound document technology of KDE .
    • Object Linking and Embedding (OLE)
    • OpenDoc
  • Software components for distributed computing
    • .NET Remoting from Microsoft
    • The distributed 9P protocol, developed for Plan 9 and used by Inferno and other systems.
    • CORBA and the CORBA Component Model from the Object Management Group
    • D-Bus from the freedesktop.org organization
    • DCOM and later versions of COM (and COM+) from Microsoft
    • DSOM and SOM from IBM (now withdrawn from sale)
    • Ice from ZeroC
    • Java EE from Sun
    • Kompics [11] from SICS
    • Universal Network Objects (UNO) from OpenOffice.org
    • Web services
      • REST
    • Zope from Zope Corporation
    • AXCIOMA (a component framework for distributed, real-time and embedded systems) from Remedy IT.
    • COHORTE — a cross-platform runtime for executing and managing resilient and reliable distributed service-oriented component applications, from isandlaTech .
    • The DX-MAN service model
  • Generic programming emphasizes the separation of algorithms from data representation.
  • Interface description languages (IDL)
    • Open Service Interface Definitions (OSID)
    • Part of COM and CORBA
    • Platform-Independent Component Modeling Language
    • SIDL — Scientific Interface Definition Language
      • Part of the Babel Scientific Programming Language Interoperability System (SIDL and Babel are core technologies of CCA and of the SciDAC TASCS Center — see above).
    • SOAP IDL from the World Wide Web Consortium (W3C)
    • WDDX
    • XML-RPC , the predecessor of SOAP.
  • Inversion of control (IoC) and Plain Old C++/Java Object (POCO/POJO) component frameworks
  • Pipes and filters
    • The Unix operating system

Entity Component System ( ECS )

Entity Component System ( ECS ) is a software architectural pattern most commonly used in video game development to represent objects of the game world. ECS involves entities made up of data components , and systems that operate on the components of entities.

ECS follows the principle of composition over inheritance , which means that each entity is defined not by a type hierarchy but by the components associated with it. Systems act globally on all entities that have the required components.

However, because of the ambiguity of English, the commonly accepted interpretation of the name is that ECS is a system made up of entities and components. For example, in a GDC 2013 talk Scott Bilas compares a C++ object system with his new custom component system. This is consistent with the traditional use of the term system in general systems engineering, with the Common Lisp Object System and the type system as examples.

ECS combines orthogonal, well-established ideas from general computer science and programming language theory . For example, components can be regarded as the mixin idiom in various programming languages. Components are a special case within the general approach of delegation (object-oriented programming) and the metaobject protocol . That is, any complete component object system can be expressed using the templates and empathy model within the Treaty of Orlando's vision of object-oriented programming .

Entity : An entity is a general-purpose object. For example, in the context of a game engine every coarse game object is represented as an entity. It usually consists only of a unique identifier. Implementations typically use a simple integer for this.

Component : A component labels an entity as possessing a particular aspect and holds the data needed to model that aspect. For example, every game object that can take damage might have a "Health" component associated with its entity. Implementations typically use structs , classes or associative arrays .

System : A system is a process that acts on all entities with the desired components. For example, a physics system may query for entities that have mass, velocity and position components, and iterate over the results, performing physics calculations on the sets of components for each entity.

An entity's behavior can be changed at run time by systems that add, remove or modify components. This eliminates the ambiguity problems of the deep and wide inheritance hierarchies often found in object-oriented programming techniques, which are hard to understand, maintain and extend. Common ECS approaches are highly compatible with, and are often combined with, data-oriented design techniques. The data for all instances of a component is usually stored together in physical memory, which provides efficient memory access for systems that operate on many entities.

Component-Oriented Programming and the Entity Component System

A simple layout of an Entity Component System.

an example of a simple Entity-Component-System (ECS) implementation in JavaScript:

// Component classes
class PositionComponent {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
}

class RenderComponent {
    render() {
        console.log("Rendering entity...");
    }
}

// Entity class
class Entity {
    constructor(id) {
        this.id = id;
        this.components = {};
    }

    addComponent(component) {
        this.components[component.constructor.name] = component;
    }

    removeComponent(componentName) {
        delete this.components[componentName];
    }
}

// System class
class RenderingSystem {
    renderEntity(entity) {
        if (entity.components['RenderComponent']) {
            const renderComponent = entity.components['RenderComponent'];
            renderComponent.render();
        }
    }
}

// Usage example
const entity = new Entity(1);
entity.addComponent(new PositionComponent(10, 20));
entity.addComponent(new RenderComponent());

const system = new RenderingSystem();
system.renderEntity(entity);

This example demonstrates the core concepts of ECS:

  1. Components - classes that hold data and/or logic for specific aspects of an entity's behavior (for example, position, rendering).
  2. Entity - an object that represents an entity in the game world. An entity can have one or more components.
  3. System - a class that processes entities, performing certain actions on the components of those entities (for example, rendering).

In this example the RenderingSystem system checks whether the entity has a rendering component (RenderComponent), and if it does, it calls that component's render() method.

In Unity, the Inspector is an interface window that lets you view and edit the properties and components of objects in your scene or project. It is an essential part of the Unity editor and provides a convenient way to configure objects and components without having to change code.

From the standpoint of Component-Oriented Programming and the Entity Component System (ECS) in Unity, the Inspector plays the role of visualizing and editing the components that make up the entities in your game.

In the ECS paradigm in Unity:

  1. Components are small modules that hold data and/or logic for specific aspects of an entity's behavior.
  2. Entities are simply containers that hold components. They usually contain no logic of their own and merely serve to group components together.
  3. Systems are classes that perform operations on entities by processing their components.

The Inspector in Unity lets you view and change the components attached to entities, which allows you to dynamically configure the behavior and parameters of your objects in the Unity editor without changing code. This is convenient when creating and editing game objects and can significantly speed up the development process.

Component-Oriented Programming and the Entity Component System

Component-Oriented Programming and the Entity Component System

History

In 1998, Thief: The Dark Project was the first game to introduce ECS. The engine was later used in its sequel, as well as in System Shock 2 .

In 2007, the team working on Operation Flashpoint: Dragon Rising experimented with ECS designs, including ones inspired by Bilas/ Dungeon Siege , and Adam Martin later wrote a detailed account of ECS design, including definitions of the core terminology and concepts. ] In particular, Martin's work popularized the ideas of systems as first-class elements, entities as identifiers, components as raw data, and code stored in systems rather than in components or entities.

In 2015, Apple Inc. introduced GameplayKit — an API framework for game development on iOS , macOS and tvOS that includes an ECS implementation.

In August 2018, Sander Mertens created the popular ECS framework flecs .

In October 2018, Unity released the Megacity demo, which used a technology stack built on ECS. It featured 100,000 audio sources — one for every car, neon sign and so on — creating a large and complex soundscape.

Variations

The data structure of different ECS implementations may differ, as may the definition of components, how they are associated with entities, and how systems access the components of entities.

Martin's ECS

Adam Martin's popular blog series defines what he considers to be the Entity Component System architecture:

An entity consists only of an identifier used to access components. It is common practice to use a unique identifier for each entity. This is not a strict requirement, but it has a number of advantages:

  • An entity can be referenced using an identifier instead of a pointer. This is more reliable, since it allows the entity to be destroyed without leaving dangling pointers.
  • It helps with persisting state externally. When the state is loaded again, there is no need to rebuild pointers.
  • Data can be shuffled around in memory when needed.
  • Entity identifiers can be used when communicating over a network to uniquely identify an entity.

Some of these advantages can also be achieved with smart pointers .

There is no game code (behavior) inside components. Components need not be physically located together with the entity, but they must be easy to find and access using the entity.

«Each system runs continuously (as if each system had its own private thread) and performs global actions on every entity that has a component or components matching that system's query».

The Unity game engine

Unity's layout uses tables, each containing columns of components. In this system, an entity's type is based on the components it holds. For each entity type there is a table (called an archetype ) containing component columns corresponding to the components used in the entity. To access a particular entity, you must find the correct archetype (table) and the index within each column in order to retrieve each corresponding component for that entity.

Apparatus ECS

Apparatus is a third-party ECS implementation for Unreal Engine that has brought some additional features to the general ECS paradigm. One such feature is support for component type hierarchies. Each component can have a base component type (or base class), as in OOP . A system can then run a query against the base class and match all of its descendants in the resulting selection of entities. This can be very useful for implementing some shared logic across a set of different components and adds an extra dimension to the paradigm.

FLECS

Flecs is a fast, lightweight ECS implementation for C and C++ that makes it possible to build games and simulations with millions of entities.

Common ECS usage patterns

The usual way to pass data between systems is to store the data in components and then give each system sequential access to the component. For example, an entity's position may be updated regularly. That position is then used by other systems. If there are many different infrequent events, a lot of flags will be needed in one or more components. In that case, systems would have to check these flags on every iteration, which can be inefficient. A solution may be to use the observer pattern . All systems that depend on an event subscribe to it. This way, the event's action is executed only once, when it occurs, and no polling is required.

In the ECS architecture there are none of the dependency problems commonly found in object-oriented programming , since components are simple segments of data and have no dependencies. Each system typically queries for the set of components an entity must have in order for the system to operate on it. For example, a rendering system might register the model, transform and drawable components. When it runs, the system will execute its logic on any entity that has all of these components. Other entities are simply skipped, and there is no need for complex dependency trees. However, this can be a place where bugs hide, since propagating values from one system to another through components can be hard to debug. ECS can be used wherever unrelated data needs to be bound to a given lifetime.

The ECS architecture uses composition rather than inheritance trees. An entity usually consists of an identifier and a list of components attached to it. Any game object can be created by adding the right components to an entity. This lets a developer easily add the features of one entity to another without any dependency problems. For example, a bullet component may be added to the player entity, and it will then meet the requirements of some BulletHandler system, which may result in the player damaging things by running into them.

The advantages of using ECS to store game state have been proclaimed by many game developers, such as Adam Martin. A good example is Richard Lord's blog posts, in which he discusses the advantages and why game data storage systems designed with ECS are so useful. [10]

Use outside games

Although the ECS architecture is used mainly in video game development, it can be useful in other fields as well.

See also

  • Business logic
  • Modular programming
  • Service Component Architecture (SCA)
  • Software Communications Architecture (JTRS SCA)
  • Third-party software component
  • Web service
  • Web Components

Comments

To leave a comment

If you have any suggestion, idea, thanks or comment, feel free to write. We really value feedback and are glad to hear your opinion.
To reply

Lectures and tutorial on "Software and information systems development"

Terms: Software and information systems development