{"id":291886,"date":"2019-07-10T09:01:26","date_gmt":"2019-07-10T09:01:26","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=291886"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=291886","title":{"rendered":"\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 ECS"},"content":{"rendered":"\n<div class=\"post__text post__text-html js-mediator-article\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/4c9\/fc6\/23e\/4c9fc623e0787518bde7823317b0e6af.png\" alt=\"image\"><\/div>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u0439 \u043d\u0435\u0434\u0435\u043b\u0435 \u044f \u043d\u0430\u0447\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0434 \u0441\u0432\u043e\u0438\u043c \u0434\u0432\u0438\u0436\u043a\u043e\u043c \u0434\u043b\u044f \u0438\u0433\u0440\u044b Vagabond \u0438 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043b \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Entity_component_system\">entity-component-system<\/a>.<\/p>\n<p>  \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u0430 <a href=\"https:\/\/github.com\/pvigier\/ecs\">GitHub<\/a>. \u041d\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u044f \u0445\u043e\u0447\u0443 \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0435\u0433\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043d\u0430\u0447\u043d\u0443 \u0441 \u043f\u0435\u0440\u0432\u043e\u0439 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u043c\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e \u0435\u0451 \u0441\u0438\u043b\u044c\u043d\u044b\u0435 \u0438 \u0441\u043b\u0430\u0431\u044b\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0443\u043b\u0443\u0447\u0448\u0438\u043b \u0435\u0451. \u0412 \u043a\u043e\u043d\u0446\u0435 \u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044e \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0441\u043f\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c.<\/p>\n<h1>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h1>\n<p>  <\/p>\n<h2>\u041c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u044f<\/h2>\n<p>  \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u0445 ECS \u043f\u0435\u0440\u0435\u0434 \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441 \u044d\u0442\u0438\u043c \u0445\u043e\u0440\u043e\u0448\u043e \u0441\u043f\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u043c\u043d\u043e\u0433\u0438\u0435 \u043b\u044e\u0434\u0438 \u0434\u043e \u043c\u0435\u043d\u044f. \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043f\u0435\u0440\u0432\u044b\u0445 \u043f\u0440\u043e ECS \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b \u043d\u0430 <a href=\"https:\/\/web.archive.org\/web\/20101011021902\/http:\/\/scottbilas.com\/files\/2002\/gdc_san_jose\/game_objects_slides.pdf\">GDC 2002<\/a> \u0421\u043a\u043e\u0442\u0442 \u0411\u0438\u043b\u0430\u0441. \u0421\u0440\u0435\u0434\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0437\u043d\u0430\u043c\u0435\u043d\u0438\u0442\u044b\u0445 \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0439 \u0432 \u0442\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u0442\u044c <a href=\"http:\/\/cowboyprogramming.com\/2007\/01\/05\/evolve-your-heirachy\/\">Evolve Your Hierarchy<\/a> \u041c\u0430\u0439\u043a\u0430 \u0423\u044d\u0441\u0442\u0430 \u0438 \u0433\u043b\u0430\u0432\u0443 <a href=\"http:\/\/gameprogrammingpatterns.com\/component.html\">Components<\/a> \u0438\u0437 \u043f\u043e\u0442\u0440\u044f\u0441\u0430\u044e\u0449\u0435\u0439 \u043a\u043d\u0438\u0433\u0438 <a href=\"http:\/\/gameprogrammingpatterns.com\/\">Game Programming Patterns<\/a> \u0420\u043e\u0431\u0435\u0440\u0442\u0430 \u041d\u0438\u0441\u0442\u0440\u043e\u043c\u0430.<\/p>\n<p>  \u0412\u043a\u0440\u0430\u0442\u0446\u0435 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0430 ECS \u2014 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043a \u0438\u0433\u0440\u043e\u0432\u044b\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c \u0438 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043b\u043e\u0433\u0438\u043a\u0438. \u0421\u0443\u0449\u043d\u043e\u0441\u0442\u0438 (Entities) \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u0437 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0435. \u0410 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u0443, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442 \u044d\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0435\u0442\u0430\u043b\u0438, \u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e <a href=\"https:\/\/en.wikipedia.org\/wiki\/Inheritance_(object-oriented_programming)\">\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f<\/a> \u0432 ECS \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/en.wikipedia.org\/wiki\/Object_composition\">\u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f<\/a>. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434, \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043a\u044d\u0448, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h2>\u041f\u0440\u0438\u043c\u0435\u0440\u044b<\/h2>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0443\u0433\u043b\u0443\u0431\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u043a\u043e\u0434, \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0430\u043c, \u0447\u0442\u043e \u043c\u044b \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c\u0441\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>  \u0417\u0430\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<pre><code class=\"cpp\">struct Position : public Component&lt;Position&gt; {     float x;     float y; };  struct Velocity : public Component&lt;Velocity&gt; {     float x;     float y; };<\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d <a href=\"https:\/\/en.wikipedia.org\/wiki\/Curiously_recurring_template_pattern\">CRTP<\/a>.<\/p>\n<p>  \u0417\u0430\u0442\u0435\u043c, \u043f\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u043e\u0431\u044a\u044f\u0441\u043d\u044e \u043f\u043e\u0437\u0436\u0435, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0438\u0441\u0442\u0435\u043c:<\/p>\n<pre><code class=\"cpp\">constexpr auto ComponentCount = 32; constexpr auto SystemCount = 8;<\/code><\/pre>\n<p>  \u0414\u0430\u043b\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438, \u0438\u043c\u0435\u044e\u0449\u0438\u0435 \u043e\u0431\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0438\u0445 \u043f\u043e\u0437\u0438\u0446\u0438\u0438:<\/p>\n<pre><code class=\"cpp\">class PhysicsSystem : public System&lt;ComponentCount, SystemCount&gt; { public:     PhysicsSystem(EntityManager&lt;ComponentCount, SystemCount&gt;&amp; entityManager) : mEntityManager(entityManager)     {         setRequirements&lt;Position, Velocity&gt;();     }      void update(float dt)     {         for (const auto&amp; entity : getManagedEntities())         {             auto [position, velocity] = mEntityManager.getComponents&lt;Position, Velocity&gt;(entity);             position.x += velocity.x * dt;             position.y += velocity.y * dt;         }     }  private:     EntityManager&lt;ComponentCount, SystemCount&gt;&amp; mEntityManager; };<\/code><\/pre>\n<p>  \u0414\u043b\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u0445 \u0435\u0451 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <code>setRequirements<\/code>. \u0417\u0430\u0442\u0435\u043c \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <code>update<\/code> \u043e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>getManagedEntities<\/code> \u0434\u043b\u044f \u0438\u0442\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043e\u0431\u0445\u043e\u0434\u0430 \u0432\u0441\u0435\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0445 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c.<\/p>\n<p>  \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0430 \u0437\u0430\u0442\u0435\u043c \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0438\u0445 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b:<\/p>\n<pre><code class=\"cpp\">auto manager = EntityManager&lt;ComponentCount, SystemCount&gt;(); manager.registerComponent&lt;Position&gt;(); manager.registerComponent&lt;Velocity&gt;(); auto system = manager.createSystem&lt;PhysicsSystem&gt;(manager); for (auto i = 0; i &lt; 10; ++i) {     auto entity = manager.createEntity();     manager.addComponent&lt;Position&gt;(entity);     manager.addComponent&lt;Velocity&gt;(entity); } auto dt = 1.0f \/ 60.0f; while (true)     system-&gt;update(dt);<\/code><\/pre>\n<p>  <\/p>\n<h3>\u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438<\/h3>\n<p>  \u041d\u0435 \u0431\u0443\u0434\u0443 \u043f\u0440\u0438\u0442\u0432\u043e\u0440\u044f\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043b \u0441\u0430\u043c\u0443\u044e \u043b\u0443\u0447\u0448\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 ECS. \u041c\u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0451 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u043d\u0430\u0434 \u043d\u0435\u0439 \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u043d\u0435\u0434\u0435\u043b\u044e.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u0430, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435\u0447\u0442\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438:<\/p>\n<ul>\n<li>\u041f\u0435\u0440\u0432\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438;<\/li>\n<li>\u0412\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043b\u044f \u0438\u0442\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043e\u0431\u0445\u043e\u0434\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439;<\/li>\n<li>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0430\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438;<\/li>\n<\/ul>\n<p>  \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0432\u0441\u0435\u0445 \u044d\u0442\u0438\u0445 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u043e\u0432 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0443 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438, \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0438\u0441\u0442\u0435\u043c. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430\u0448\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0434\u043b\u044f \u0442\u0440\u0451\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439:<\/p>\n<ul>\n<li>\u041f\u0440\u043e\u0444\u0438\u043b\u044c A: 32 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438 16 \u0441\u0438\u0441\u0442\u0435\u043c;<\/li>\n<li>\u041f\u0440\u043e\u0444\u0438\u043b\u044c AA: 128 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 32 \u0441\u0438\u0441\u0442\u0435\u043c\u044b;<\/li>\n<li>\u041f\u0440\u043e\u0444\u0438\u043b\u044c AAA: 512 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438 64 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/li>\n<\/ul>\n<p>  \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u044d\u0442\u0438 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438 \u0434\u0430\u0434\u0443\u0442 \u043d\u0430\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043e\u043d\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u044d\u0442\u0438\u0445 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430\u0445 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e\u0440\u043e\u0434\u043d\u044b\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438, \u0430 \u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043c\u0430\u043b\u044b.<\/p>\n<h1>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h1>\n<p>  <\/p>\n<h2>\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u044c<\/h2>\n<p>  \u0412 \u043c\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u2014 \u044d\u0442\u043e \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c id:<\/p>\n<pre><code class=\"cpp\">using Entity = uint32_t;<\/code><\/pre>\n<p>  \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0432 <a href=\"https:\/\/pvigier.github.io\/2019\/07\/07\/entity-component-system-part1.html\">Entity.h<\/a> \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c <code>Index<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u0437\u0436\u0435:<\/p>\n<pre><code class=\"cpp\">using Index = uint32_t; static constexpr auto InvalidIndex = std::numeric_limits&lt;Index&gt;::max();<\/code><\/pre>\n<p>  \u042f \u0440\u0435\u0448\u0438\u043b \u0432\u043c\u0435\u0441\u0442\u043e 64-\u0431\u0438\u0442\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0438\u043b\u0438 <code>std::size_t<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>uint32_t<\/code>, \u0447\u0442\u043e\u0431\u044b \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438 \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e \u043a\u044d\u0448\u0430. \u041f\u043e\u0442\u0435\u0440\u044f\u0435\u043c \u043c\u044b \u043d\u0435 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e: \u043c\u0430\u043b\u043e\u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0443 \u043a\u043e\u0433\u043e-\u0442\u043e \u0431\u0443\u0434\u0443\u0442 \u043c\u0438\u043b\u043b\u0438\u0430\u0440\u0434\u044b \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<h2>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442<\/h2>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T, auto Type&gt; class Component { public:     static constexpr auto type = static_cast&lt;std::size_t&gt;(Type); };<\/code><\/pre>\n<p>  \u041a\u043b\u0430\u0441\u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442, \u043e\u043d \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0445\u0440\u0430\u043d\u0438\u0442 id \u0442\u0438\u043f\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u043e\u0437\u0436\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u0442\u0438\u043f\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>  \u041f\u0435\u0440\u0432\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u2014 \u044d\u0442\u043e \u0442\u0438\u043f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u0412\u0442\u043e\u0440\u043e\u0439 \u2014 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c\u043e\u0435 \u0432 <code>std::size_t<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442\u044c id \u0442\u0438\u043f\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.<\/p>\n<p>  \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>Position<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">struct Positon : Component&lt;Position, 0&gt; {     float x;     float y; };<\/code><\/pre>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"cpp\">enum class ComponentType {     Position };  struct Positon : Component&lt;Position, ComponentType::Position&gt; {     float x;     float y; };<\/code><\/pre>\n<p>  \u0412\u043e \u0432\u0432\u043e\u0434\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0435\u0441\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0448\u0430\u0431\u043b\u043e\u043d\u0430: \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c id \u0442\u0438\u043f\u0430 \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u041f\u043e\u0437\u0436\u0435 \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c, \u043a\u0430\u043a \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0442\u0438\u043f\u043e\u0432 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<h2>EntityContainer<\/h2>\n<p>  \u041a\u043b\u0430\u0441\u0441 <code>EntityContainer<\/code> \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043d\u0438\u0445 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/utility\/bitset\"><code>std::bitset<\/code><\/a>. \u042d\u0442\u043e\u0442 \u043d\u0430\u0431\u043e\u0440 \u0431\u0438\u0442\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0432\u043b\u0430\u0434\u0435\u0435\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>  \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 <code>std::vector<\/code>, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b id \u0431\u044b\u043b\u0438 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0438 \u043c\u0435\u043d\u044c\u0448\u0435 \u043f\u0430\u043c\u044f\u0442\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043d\u043e\u0432\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c id \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0435 id \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>mFreeEntities<\/code>.<\/p>\n<p>  \u0412\u043e\u0442 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 <code>EntityContainer<\/code>:<\/p>\n<pre><code class=\"cpp\">template&lt;std::size_t ComponentCount, std::size_t SystemCount&gt; class EntityContainer { public:     void reserve(std::size_t size);     std::vector&lt;std::bitset&lt;ComponentCount&gt;&gt;&amp; getEntityToBitset();     const std::bitset&lt;ComponentCount&gt;&amp; getBitset(Entity entity) const;     Entity create();     void remove(Entity entity);  private:     std::vector&lt;std::bitset&lt;ComponentCount&gt;&gt; mEntityToBitset;     std::vector&lt;Entity&gt; mFreeEntities; };<\/code><\/pre>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u043c\u0435\u0442\u043e\u0434\u044b.<\/p>\n<p>  <code>getEntityToBitset<\/code> \u0438 <code>getBitset<\/code> \u2014 \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0433\u0435\u0442\u0442\u0435\u0440\u044b:<\/p>\n<pre><code class=\"cpp\">std::vector&lt;std::bitset&lt;ComponentCount&gt;&gt;&amp; getEntityToBitset() {     return mEntityToBitset; }  const std::bitset&lt;ComponentCount&gt;&amp; getBitset(Entity entity) const {     return mEntityToBitset[entity]; }<\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>create<\/code> \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0435\u043d:<\/p>\n<pre><code class=\"cpp\">Entity create() {     auto entity = Entity();     if (mFreeEntities.empty())     {         entity = static_cast&lt;Entity&gt;(mEntityToBitset.size());         mEntityToBitset.emplace_back();     }     else     {         entity = mFreeEntities.back();         mFreeEntities.pop_back();         mEntityToBitset[entity].reset();     }     return entity; }<\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u0430\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c, \u043e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0435\u0451 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u0435\u0442\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043d\u043e\u0432\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>remove<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0434\u043b\u044f \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0432 <code>mFreeEntities<\/code>:<\/p>\n<pre><code class=\"cpp\">void remove(Entity entity) {     mFreeEntities.push_back(entity); }<\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u2014 \u044d\u0442\u043e <code>reserve<\/code>. \u0415\u0433\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u043f\u043e\u0434 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b. \u041a\u0430\u043a \u043c\u044b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u043d\u0430\u0435\u0442\u0435, \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u2014 \u044d\u0442\u043e \u0437\u0430\u0442\u0440\u0430\u0442\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u043d\u0430\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0432 \u0438\u0433\u0440\u0435, \u0442\u043e \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443:<\/p>\n<pre><code class=\"cpp\">void reserve(std::size_t size) {     mFreeEntities.resize(size);     std::iota(std::begin(mFreeEntities), std::end(mFreeEntities), 0);     mEntityToBitset.resize(size); }<\/code><\/pre>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 \u043e\u043d \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442 <code>mFreeEntities<\/code>.<\/p>\n<h2>ComponentContainer<\/h2>\n<p>  \u041a\u043b\u0430\u0441\u0441 <code>ComponentContainer<\/code> \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430.<\/p>\n<p>  \u0412 \u043c\u043e\u0435\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u0432\u0441\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435. \u0422\u043e \u0435\u0441\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0434\u0438\u043d \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 <code>mComponents<\/code>.<\/p>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438\u0437 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0437\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043e\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043a \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u0438 \u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043a \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0435\u0449\u0451 \u0434\u0432\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>mComponentToEntity<\/code> \u0438 <code>mEntityToComponent<\/code>.<\/p>\n<p>  \u0412\u043e\u0442 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 <code>ComponentContainer<\/code>:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T, std::size_t ComponentCount, std::size_t SystemCount&gt; class ComponentContainer : public BaseComponentContainer { public:     ComponentContainer(std::vector&lt;std::bitset&lt;ComponentCount&gt;&gt;&amp; entityToBitset);      virtual void reserve(std::size_t size) override;      T&amp; get(Entity entity);     const T&amp; get(Entity entity) const;     template&lt;typename... Args&gt;     void add(Entity entity, Args&amp;&amp;... args);     void remove(Entity entity);     virtual bool tryRemove(Entity entity) override;     Entity getOwner(const T&amp; component) const;  private:     std::vector&lt;T&gt; mComponents;     std::vector&lt;Entity&gt; mComponentToEntity;     std::unordered_map&lt;Entity, Index&gt; mEntityToComponent;     std::vector&lt;std::bitset&lt;ComponentCount&gt;&gt;&amp; mEntityToBitset; };<\/code><\/pre>\n<p>  \u041c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043e\u043d \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 <code>BaseComponentContainer<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cpp\">class BaseComponentContainer { public:     virtual ~BaseComponentContainer() = default;      virtual void reserve(std::size_t size) = 0;     virtual bool tryRemove(Entity entity) = 0; };<\/code><\/pre>\n<p>  \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b <code>ComponentContainer<\/code> \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u0432.<\/p>\n<p>  \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440: \u043e\u043d \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043d\u0430\u0431\u043e\u0440\u044b \u0431\u0438\u0442\u043e\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0451 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0431\u043e\u0440\u0430 \u0431\u0438\u0442\u043e\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430:<\/p>\n<pre><code class=\"cpp\">ComponentContainer(std::vector&lt;std::bitset&lt;ComponentCount&gt;&gt;&amp; entityToBitset) :     mEntityToBitset(entityToBitset) {  }<\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>get<\/code> \u043f\u0440\u043e\u0441\u0442, \u043c\u044b \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>mEntityToComponent<\/code> \u0434\u043b\u044f \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 <code>entity<\/code> \u0432 <code>mComponents<\/code>:<\/p>\n<pre><code class=\"cpp\">T&amp; get(Entity entity) {     return mComponents[mEntityToComponent[entity]]; }<\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>add<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0432\u043e\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432 \u043a\u043e\u043d\u0435\u0446 <code>mComponents<\/code>, \u0430 \u0437\u0430\u0442\u0435\u043c \u043e\u043d \u043f\u043e\u0434\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043e\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043a \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u0438 \u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043a \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. \u0412 \u043a\u043e\u043d\u0446\u0435 \u043e\u043d \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442 \u0431\u0438\u0442\u0443 \u043d\u0430\u0431\u043e\u0440\u0430 \u0431\u0438\u0442\u043e\u0432 <code>entity<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>true<\/code>:<\/p>\n<pre><code class=\"cpp\">template&lt;typename... Args&gt; void add(Entity entity, Args&amp;&amp;... args) {     auto index = static_cast&lt;Index&gt;(mComponents.size());     mComponents.emplace_back(std::forward&lt;Args&gt;(args)...);     mComponentToEntity.emplace_back(entity);     mEntityToComponent[entity] = index;     mEntityToBitset[entity][T::type] = true; }<\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>remove<\/code> \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u0431\u0438\u0442\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>false<\/code>, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>mComponents<\/code> \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443 \u0442\u043e\u0433\u043e, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0443\u0434\u0430\u043b\u0438\u0442\u044c. \u041e\u043d \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u043b\u0438, \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u043e\u0434\u0438\u043d \u0438\u0437 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c:<\/p>\n<pre><code class=\"cpp\">void remove(Entity entity) {     mEntityToBitset[entity][T::type] = false;     auto index = mEntityToComponent[entity];     \/\/ Update mComponents     mComponents[index] = std::move(mComponents.back());     mComponents.pop_back();     \/\/ Update mEntityToComponent     mEntityToComponent[mComponentToEntity.back()] = index;     mEntityToComponent.erase(entity);     \/\/ Update mComponentToEntity     mComponentToEntity[index] = mComponentToEntity.back();     mComponentToEntity.pop_back(); }<\/code><\/pre>\n<p>  \u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0437\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c. \u0418 \u0432 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u0442\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0432 <code>std::vector<\/code> \u0437\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>tryRemove<\/code> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0435\u0441\u0442\u044c \u043b\u0438 \u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0435\u0433\u043e:<\/p>\n<pre><code class=\"cpp\">virtual bool tryRemove(Entity entity) override {     if (mEntityToBitset[entity][T::type])     {         remove(entity);         return true;     }     return false; }<\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>getOwner<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043b\u0430\u0434\u0435\u0435\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u043a\u043e\u0439 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 <code>mComponentToEntity<\/code>:<\/p>\n<pre><code class=\"cpp\">Entity getOwner(const T&amp; component) const {     auto begin = mComponents.data();     auto index = static_cast&lt;std::size_t&gt;(&amp;component - begin);     return mComponentToEntity[index]; }<\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u2014 \u044d\u0442\u043e <code>reserve<\/code>, \u043e\u043d \u0438\u043c\u0435\u0435\u0442 \u0442\u0430\u043a\u043e\u0435 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432 <code>EntityContainer<\/code>:<\/p>\n<pre><code class=\"cpp\">virtual void reserve(std::size_t size) override {     mComponents.reserve(size);     mComponentToEntity.reserve(size);     mEntityToComponent.reserve(size); }<\/code><\/pre>\n<p>  <\/p>\n<h2>\u0421\u0438\u0441\u0442\u0435\u043c\u0430<\/h2>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043b\u0430\u0441\u0441 <code>System<\/code>.<\/p>\n<p>  \u041a\u0430\u0436\u0434\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0438\u043c\u0435\u0435\u0442 \u043d\u0430\u0431\u043e\u0440 \u0431\u0438\u0442\u043e\u0432 <code>mRequirements<\/code>, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0435\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043e\u043d\u0430 \u0445\u0440\u0430\u043d\u0438\u0442 \u043d\u0430\u0431\u043e\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 <code>mManagedEntities<\/code>, \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0445 \u044d\u0442\u0438\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c. \u041f\u043e\u0432\u0442\u043e\u0440\u044e\u0441\u044c, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0437\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043e\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043a \u0435\u0451 \u0438\u043d\u0434\u0435\u043a\u0441\u0443 \u0432 <code>mManagedEntities<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f <code>std::unordered_map<\/code> \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>mEntityToManagedEntity<\/code>.<\/p>\n<p>  \u0412\u043e\u0442 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 <code>System<\/code>:<\/p>\n<pre><code class=\"cpp\">template&lt;std::size_t ComponentCount, std::size_t SystemCount&gt; class System { public:     virtual ~System() = default;  protected:     template&lt;typename ...Ts&gt;     void setRequirements();     const std::vector&lt;Entity&gt;&amp; getManagedEntities() const;     virtual void onManagedEntityAdded([[maybe_unused]] Entity entity);     virtual void onManagedEntityRemoved([[maybe_unused]] Entity entity);  private:     friend EntityManager&lt;ComponentCount, SystemCount&gt;;      std::bitset&lt;ComponentCount&gt; mRequirements;     std::size_t mType;     std::vector&lt;Entity&gt; mManagedEntities;     std::unordered_map&lt;Entity, Index&gt; mEntityToManagedEntity;      void setUp(std::size_t type);     void onEntityUpdated(Entity entity, const std::bitset&lt;ComponentCount&gt;&amp; components);     void onEntityRemoved(Entity entity);     void addEntity(Entity entity);     void removeEntity(Entity entity); };<\/code><\/pre>\n<p>  \u0414\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0431\u0438\u0442\u043e\u0432 <code>setRequirements<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/fold\">\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u0432\u0451\u0440\u0442\u043a\u0438<\/a>:<\/p>\n<pre><code class=\"cpp\">template&lt;typename ...Ts&gt; void setRequirements() {     (mRequirements.set(Ts::type), ...); }<\/code><\/pre>\n<p>  <code>getManagedEntities<\/code> \u2014 \u044d\u0442\u043e \u0433\u0435\u0442\u0442\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0440\u043e\u0436\u0434\u0451\u043d\u043d\u044b\u043c\u0438 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c:<\/p>\n<pre><code class=\"cpp\">const std::vector&lt;Entity&gt;&amp; getManagedEntities() const {     return mManagedEntities; }<\/code><\/pre>\n<p>  \u041e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0440\u043e\u0436\u0434\u0451\u043d\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u043d\u0435 \u043f\u044b\u0442\u0430\u043b\u0438\u0441\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c <code>mManagedEntities<\/code>.<\/p>\n<p>  <code>onManagedEntityAdded<\/code> \u0438 <code>onManagedEntityRemoved<\/code> \u043f\u0443\u0441\u0442\u044b. \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b. \u042d\u0442\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432 <code>mManagedEntities<\/code> \u0438\u043b\u0438 \u0435\u0451 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438.<\/p>\n<p>  \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u043c\u0438 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 <code>EntityManager<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0434\u0440\u0443\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441.<\/p>\n<p>  <code>setUp<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0434\u043b\u044f \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f id \u0441\u0438\u0441\u0442\u0435\u043c\u0435. \u0417\u0430\u0442\u0435\u043c \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0434\u043b\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">void setUp(std::size_t type) {     mType = type; }<\/code><\/pre>\n<p>  <code>onEntityUpdated<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438, \u0442.\u0435. \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430. \u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0435\u043d\u044b \u043b\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0431\u044b\u043b\u0430 \u043b\u0438 \u0443\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c. \u0415\u0441\u043b\u0438 \u043e\u043d\u0430 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u0438 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0431\u044b\u043b\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430, \u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0435\u0451 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442. \u041e\u0434\u043d\u0430\u043a\u043e \u0435\u0441\u043b\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u0438 \u0443\u0436\u0435 \u0431\u044b\u043b\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430, \u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0435\u0451 \u0443\u0434\u0430\u043b\u044f\u0435\u0442. \u0412\u043e \u0432\u0441\u0435\u0445 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442:<\/p>\n<pre><code class=\"cpp\">void onEntityUpdated(Entity entity, const std::bitset&lt;ComponentCount&gt;&amp; components) {     auto satisfied = (mRequirements &amp; components) == mRequirements;     auto managed = mEntityToManagedEntity.find(entity) != std::end(mEntityToManagedEntity);     if (satisfied &amp;&amp; !managed)         addEntity(entity);     else if (!satisfied &amp;&amp; managed)         removeEntity(entity); }<\/code><\/pre>\n<p>  <code>onEntityRemoved<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. \u0415\u0441\u043b\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439, \u043e\u043d \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0435\u0451:<\/p>\n<pre><code class=\"cpp\">void onEntityRemoved(Entity entity) {     if (mEntityToManagedEntity.find(entity) != std::end(mEntityToManagedEntity))         removeEntity(entity); }<\/code><\/pre>\n<p>  <code>addEntity<\/code> \u0438 <code>removeEntity<\/code> \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b.<\/p>\n<p>  <code>addEntity<\/code> \u0437\u0430\u0434\u0430\u0451\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043e\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043f\u043e \u0435\u0451 \u0438\u043d\u0434\u0435\u043a\u0441\u0443 \u0432 <code>mManagedEntities<\/code>, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>onManagedEntityAdded<\/code>:<\/p>\n<pre><code class=\"cpp\">void addEntity(Entity entity) {     mEntityToManagedEntity[entity] = static_cast&lt;Index&gt;(mManagedEntities.size());     mManagedEntities.emplace_back(entity);     onManagedEntityAdded(entity); }<\/code><\/pre>\n<p>  <code>removeEntity<\/code> \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>onManagedEntityRemoved<\/code>. \u0417\u0430\u0442\u0435\u043c \u043e\u043d \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443 \u0442\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f. \u041e\u043d \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0451\u043d\u043d\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c. \u0412 \u043a\u043e\u043d\u0446\u0435 \u043e\u043d \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c, \u0438\u0437 <code>mManagedEntities<\/code> \u0438 <code>mEntityToManagedEntity<\/code>:<\/p>\n<pre><code class=\"cpp\">void removeEntity(Entity entity) {     onManagedEntityRemoved(entity);     auto index = mEntityToManagedEntity[entity];     mEntityToManagedEntity[mManagedEntities.back()] = index;     mEntityToManagedEntity.erase(entity);     mManagedEntities[index] = mManagedEntities.back();     mManagedEntities.pop_back(); }<\/code><\/pre>\n<p>  <\/p>\n<h2>EntityManager<\/h2>\n<p>  \u0412\u0441\u044f \u0432\u0430\u0436\u043d\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u0430\u0445. \u041c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0451 \u0432\u043c\u0435\u0441\u0442\u0435.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u043d\u0430 \u0435\u0433\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"cpp\">template&lt;std::size_t ComponentCount, std::size_t SystemCount&gt; class EntityManager { public:     template&lt;typename T&gt;     void registerComponent();     template&lt;typename T, typename ...Args&gt;     T* createSystem(Args&amp;&amp; ...args);     void reserve(std::size_t size);     Entity createEntity();     void removeEntity(Entity entity);     template&lt;typename T&gt;     bool hasComponent(Entity entity) const;     template&lt;typename ...Ts&gt;     bool hasComponents(Entity entity) const;     template&lt;typename T&gt;     T&amp; getComponent(Entity entity);     template&lt;typename T&gt;     const T&amp; getComponent(Entity entity) const;     template&lt;typename ...Ts&gt;     std::tuple&lt;Ts&amp;...&gt; getComponents(Entity entity);     template&lt;typename ...Ts&gt;     std::tuple&lt;const Ts&amp;...&gt; getComponents(Entity entity) const;     template&lt;typename T, typename... Args&gt;     void addComponent(Entity entity, Args&amp;&amp;... args);     template&lt;typename T&gt;     void removeComponent(Entity entity);     template&lt;typename T&gt;     Entity getOwner(const T&amp; component) const;  private:     std::array&lt;std::unique_ptr&lt;BaseComponentContainer&gt;, ComponentCount&gt; mComponentContainers;     EntityContainer&lt;ComponentCount, SystemCount&gt; mEntities;     std::vector&lt;std::unique_ptr&lt;System&lt;ComponentCount, SystemCount&gt;&gt;&gt; mSystems;      template&lt;typename T&gt;     void checkComponentType() const;     template&lt;typename ...Ts&gt;     void checkComponentTypes() const;      template&lt;typename T&gt;     auto getComponentContainer();     template&lt;typename T&gt;     auto getComponentContainer() const; };<\/code><\/pre>\n<p>  \u041a\u043b\u0430\u0441\u0441 <code>EntityManager<\/code> \u0438\u043c\u0435\u0435\u0442 \u0442\u0440\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0447\u043b\u0435\u043d\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u0430: <code>mComponentContainers<\/code>, \u0445\u0440\u0430\u043d\u044f\u0449\u0443\u044e \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 <code>std::unique_ptr<\/code> \u043d\u0430 <code>BaseComponentContainer<\/code>, <code>mEntities<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u043c <code>EntityContainer<\/code> \u0438 <code>mSystems<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0445\u0440\u0430\u043d\u0438\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 <code>unique_ptr<\/code> \u043d\u0430 <code>System<\/code>.<\/p>\n<p>  \u041a\u043b\u0430\u0441\u0441 \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u043d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432\u0441\u0435 \u043e\u043d\u0438 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u044b.<\/p>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u043d\u0430 <code>getComponentContainer<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0442\u0438\u043f\u0430 <code>T<\/code>:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T&gt; auto getComponentContainer() {     return static_cast&lt;ComponentContainer&lt;T, ComponentCount, SystemCount&gt;*&gt;(mComponentContainers[T::type].get()); }<\/code><\/pre>\n<p>  \u0415\u0449\u0451 \u043e\u0434\u043d\u0430 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u2014 \u044d\u0442\u043e <code>checkComponentType<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0447\u0442\u043e id \u0442\u0438\u043f\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043d\u0438\u0436\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T&gt; void checkComponentType() const {     static_assert(T::type &lt; ComponentCount); }<\/code><\/pre>\n<p>  <code>checkComponentTypes<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u0432\u0451\u0440\u0442\u043a\u0438 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0442\u0438\u043f\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">template&lt;typename ...Ts&gt; void checkComponentTypes() const {     (checkComponentType&lt;Ts&gt;(), ...); }<\/code><\/pre>\n<p>  <code>registerComponent<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T&gt; void registerComponent() {     checkComponentType&lt;T&gt;();     mComponentContainers[T::type] = std::make_unique&lt;ComponentContainer&lt;T, ComponentCount, SystemCount&gt;&gt;(         mEntities.getEntityToBitset()); }<\/code><\/pre>\n<p>  <code>createSystem<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043d\u043e\u0432\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0438 \u0437\u0430\u0434\u0430\u0451\u0442 \u0435\u0451 \u0442\u0438\u043f:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T, typename ...Args&gt; T* createSystem(Args&amp;&amp; ...args) {     auto type = mSystems.size();     auto&amp; system = mSystems.emplace_back(std::make_unique&lt;T&gt;(std::forward&lt;Args&gt;(args)...));     system-&gt;setUp(type);     return static_cast&lt;T*&gt;(system.get()); }<\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>reserve<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u044b <code>reserve<\/code> \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 <code>ComponentContainer<\/code> \u0438 <code>EntityContainer<\/code>:<\/p>\n<pre><code class=\"cpp\">void reserve(std::size_t size) {     for (auto i = std::size_t(0); i &lt; ComponentCount; ++i)     {         if (mComponentContainers[i])             mComponentContainers[i]-&gt;reserve(size);     }     mEntities.reserve(size); }<\/code><\/pre>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>createEntity<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u0435\u0442\u043e\u0434\u0430 <code>create<\/code> \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 <code>EntityManager<\/code>:<\/p>\n<pre><code class=\"cpp\">Entity createEntity() {     return mEntities.create(); }<\/code><\/pre>\n<p>  <code>hasComponent<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043d\u0430\u0431\u043e\u0440 \u0431\u0438\u0442\u043e\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0443 \u044d\u0442\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T&gt; bool hasComponent(Entity entity) const {     checkComponentType&lt;T&gt;();     return mEntities.getBitset(entity)[T::type]; }<\/code><\/pre>\n<p>  <code>hasComponents<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u0432\u0451\u0440\u0442\u043a\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0430\u0431\u043e\u0440\u0430 \u0431\u0438\u0442\u043e\u0432, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0435\u0433\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0430 \u0437\u0430\u0442\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0435\u0433\u043e \u0441 \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0431\u0438\u0442\u043e\u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0442\u043e\u0433\u043e, \u0435\u0441\u0442\u044c \u043b\u0438 \u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0432\u0441\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b:<\/p>\n<pre><code class=\"cpp\">template&lt;typename ...Ts&gt; bool hasComponents(Entity entity) const {     checkComponentTypes&lt;Ts...&gt;();     auto requirements = std::bitset&lt;ComponentCount&gt;();     (requirements.set(Ts::type), ...);     return (requirements &amp; mEntities.getBitset(entity)) == requirements; }<\/code><\/pre>\n<p>  <code>getComponent<\/code> \u043f\u0435\u0440\u0435\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0443\u0436\u043d\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T&gt; T&amp; getComponent(Entity entity) {     checkComponentType&lt;T&gt;();     return getComponentContainer&lt;T&gt;()-&gt;get(entity); }<\/code><\/pre>\n<p>  <code>getComponents<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u0440\u0442\u0435\u0436 \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/utility\/tuple\/tie\"><code>std::tie<\/code><\/a> \u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u0432\u0451\u0440\u0442\u043a\u0438:<\/p>\n<pre><code class=\"cpp\">template&lt;typename ...Ts&gt; std::tuple&lt;Ts&amp;...&gt; getComponents(Entity entity) {     checkComponentTypes&lt;Ts...&gt;();     return std::tie(getComponentContainer&lt;Ts&gt;()-&gt;get(entity)...); }<\/code><\/pre>\n<p>  <code>addComponent<\/code> \u0438 <code>removeComponent<\/code> \u043f\u0435\u0440\u0435\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u043d\u0443\u0436\u043d\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0430 \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0441\u0438\u0441\u0442\u0435\u043c\u044b <code>onEntityUpdated<\/code>:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T, typename... Args&gt; void addComponent(Entity entity, Args&amp;&amp;... args) {     checkComponentType&lt;T&gt;();     getComponentContainer&lt;T&gt;()-&gt;add(entity, std::forward&lt;Args&gt;(args)...);     \/\/ Send message to systems     const auto&amp; bitset = mEntities.getBitset(entity);     for (auto&amp; system : mSystems)         system-&gt;onEntityUpdated(entity, bitset); }  template&lt;typename T&gt; void removeComponent(Entity entity) {     checkComponentType&lt;T&gt;();     getComponentContainer&lt;T&gt;()-&gt;remove(entity);     \/\/ Send message to systems     const auto&amp; bitset = mEntities.getBitset(entity);     for (auto&amp; system : mSystems)         system-&gt;onEntityUpdated(entity, bitset); }<\/code><\/pre>\n<p>  \u041d\u0430\u043a\u043e\u043d\u0435\u0446, <code>getOwner<\/code> \u043f\u0435\u0440\u0435\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0443\u0436\u043d\u043e\u043c\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T&gt; Entity getOwner(const T&amp; component) const {     checkComponentType&lt;T&gt;();     return getComponentContainer&lt;T&gt;()-&gt;getOwner(component); }<\/code><\/pre>\n<p>  \u0422\u0430\u043a\u043e\u0439 \u0431\u044b\u043b\u0430 \u043c\u043e\u044f \u043f\u0435\u0440\u0432\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f. \u041e\u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432\u0441\u0435\u0433\u043e \u0438\u0437 357 \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430. \u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u044d\u0442\u043e\u0439 <a href=\"https:\/\/github.com\/pvigier\/ecs\/tree\/unordered_map\">\u0432\u0435\u0442\u043a\u0435<\/a>.<\/p>\n<h1>\u041f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438<\/h1>\n<p>  <\/p>\n<h2>\u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438<\/h2>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0441\u0442\u0430\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438 \u043c\u043e\u0435\u0439 \u043f\u0435\u0440\u0432\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 ECS!<\/p>\n<p>  \u0412\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/4c9\/fc6\/23e\/4c9fc623e0787518bde7823317b0e6af.png\"><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/bb0\/323\/9a9\/bb03239a90cccf5f95ab47ecf94e3a4d.png\"><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/679\/e54\/f0e\/679e54f0e32260a9f62621838b51a15e.png\"><\/div>\n<p>  \u0428\u0430\u0431\u043b\u043e\u043d \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f! \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0445 \u0437\u0430 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e \u043f\u0440\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0438 \u0441\u043c\u0435\u043d\u0435 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439 (A, AA \u0438 AAA).<\/p>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043e\u043d \u0445\u043e\u0440\u043e\u0448\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0432 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u0445. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c \u0441 \u0442\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438, \u043e\u043d\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0442 \u0432 \u0442\u0440\u0438 \u0440\u0430\u0437\u0430 \u043c\u0435\u0434\u043b\u0435\u043d\u0435\u0435, \u0447\u0435\u043c \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c \u0441 \u043e\u0434\u043d\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c. \u042d\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0440\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430.<\/p>\n<h2>\u041f\u0440\u043e\u043c\u0430\u0445\u0438 \u043a\u044d\u0448\u0430<\/h2>\n<p>  \u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043f\u0440\u043e\u043c\u0430\u0445\u043e\u0432 \u043a\u044d\u0448\u0430 \u044f \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b \u0432\u0437\u044f\u0442\u044b\u0439 <a href=\"https:\/\/github.com\/pvigier\/ecs\/blob\/master\/examples\/physics.cpp\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a> \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 <a href=\"http:\/\/valgrind.org\/docs\/manual\/cg-manual.html\">cachegrind<\/a>.<\/p>\n<p>  \u0412\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0434\u043b\u044f 10 000 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439:<\/p>\n<p>  <code>==1652== D refs: 277,577,353 (254,775,159 rd + 22,802,194 wr)<br \/>  ==1652== D1 misses: 20,814,368 ( 20,759,914 rd + 54,454 wr)<br \/>  ==1652== LLd misses: 43,483 ( 7,847 rd + 35,636 wr)<br \/>  ==1652== D1 miss rate: 7.5% ( 8.1% + 0.2% )<br \/>  ==1652== LLd miss rate: 0.0% ( 0.0% + 0.2% )<\/code><\/p>\n<p>  \u0412\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0434\u043b\u044f 100 000 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439:<\/p>\n<p>  <code>==1738== D refs: 2,762,879,670 (2,539,368,564 rd + 223,511,106 wr)<br \/>  ==1738== D1 misses: 207,415,181 ( 206,902,072 rd + 513,109 wr)<br \/>  ==1738== LLd misses: 207,274,328 ( 206,789,289 rd + 485,039 wr)<br \/>  ==1738== D1 miss rate: 7.5% ( 8.1% + 0.2% )<br \/>  ==1738== LLd miss rate: 7.5% ( 8.1% + 0.2% )<\/code><\/p>\n<p>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0435\u043f\u043b\u043e\u0445\u0438. \u0422\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u043f\u043e\u0447\u0435\u043c\u0443 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u043c\u0430\u0445\u043e\u0432 LLd \u043f\u0440\u0438 100 000 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<h2>\u041f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h2>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u044f \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043b \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <a href=\"https:\/\/sourceware.org\/binutils\/docs\/gprof\/\">gprof<\/a>.<\/p>\n<p>  \u0412\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p>  <code>Flat profile:<\/p>\n<p>  Each sample counts as 0.01 seconds.<br \/>   % cumulative self self total<br \/>   time seconds seconds calls ms\/call ms\/call name<br \/>   57.45 1.16 1.16 200300000 0.00 0.00 std::__detail::_Map_base&lt;unsigned int, std::pair&lt;unsigned int const, unsigned int&gt;, std::allocator&lt;std::pair&lt;unsigned int const, unsigned int&gt; &gt;, std::__detail::_Select1st, std::equal_to&lt;unsigned int&gt;, std::hash&lt;unsigned int&gt;, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits&lt;false, false, true&gt;, true&gt;::operator[](unsigned int const&amp;)<br \/>   19.31 1.55 0.39 main<br \/>   16.34 1.88 0.33 200500000 0.00 0.00 std::_Hashtable&lt;unsigned int, std::pair&lt;unsigned int const, unsigned int&gt;, std::allocator&lt;std::pair&lt;unsigned int const, unsigned int&gt; &gt;, std::__detail::_Select1st, std::equal_to&lt;unsigned int&gt;, std::hash&lt;unsigned int&gt;, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits&lt;false, false, true&gt; &gt;::_M_find_before_node(unsigned long, unsigned int const&amp;, unsigned long) const<br \/>   3.96 1.96 0.08 300000 0.00 0.00 std::_Hashtable&lt;unsigned int, std::pair&lt;unsigned int const, unsigned int&gt;, std::allocator&lt;std::pair&lt;unsigned int const, unsigned int&gt; &gt;, std::__detail::_Select1st, std::equal_to&lt;unsigned int&gt;, std::hash&lt;unsigned int&gt;, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits&lt;false, false, true&gt; &gt;::_M_insert_unique_node(unsigned long, unsigned long, std::__detail::_Hash_node&lt;std::pair&lt;unsigned int const, unsigned int&gt;, false&gt;*)<br \/>   2.48 2.01 0.05 300000 0.00 0.00 unsigned int&amp; std::vector&lt;unsigned int, std::allocator&lt;unsigned int&gt; &gt;::emplace_back&lt;unsigned int&amp;&gt;(unsigned int&amp;)<br \/>   0.50 2.02 0.01 3 3.33 3.33 std::_Hashtable&lt;unsigned int, std::pair&lt;unsigned int const, unsigned int&gt;, std::allocator&lt;std::pair&lt;unsigned int const, unsigned int&gt; &gt;, std::__detail::_Select1st, std::equal_to&lt;unsigned int&gt;, std::hash&lt;unsigned int&gt;, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits&lt;false, false, true&gt; &gt;::~_Hashtable()<br \/>   0.00 2.02 0.00 200000 0.00 0.00 std::_Hashtable&lt;unsigned int, std::pair&lt;unsigned int const, unsigned int&gt;, std::allocator&lt;std::pair&lt;unsigned int const, unsigned int&gt; &gt;, std::__detail::_Select1st, std::equal_to&lt;unsigned int&gt;, std::hash&lt;unsigned int&gt;, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits&lt;false, false, true&gt; &gt;::find(unsigned int const&amp;)<\/code><\/p>\n<p>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0441\u043a\u0430\u0436\u0435\u043d\u044b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044f \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043b \u0441 \u0444\u043b\u0430\u0433\u043e\u043c <code>-O1<\/code>, \u0447\u0442\u043e\u0431\u044b gprof \u0432\u044b\u0432\u043e\u0434\u0438\u043b \u043d\u0435\u0447\u0442\u043e \u043e\u0441\u043c\u044b\u0441\u043b\u0435\u043d\u043d\u043e\u0435. \u041f\u043e\u0445\u043e\u0436\u0435, \u0447\u0442\u043e \u043f\u0440\u0438 \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u0438 \u0443\u0440\u043e\u0432\u043d\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0430\u0433\u0440\u0435\u0441\u0441\u0438\u0432\u043d\u043e \u0432\u0441\u0451 \u0432\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0438 gprof \u043f\u043e\u0447\u0442\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u0442.<\/p>\n<p>  \u041f\u043e \u0434\u0430\u043d\u043d\u044b\u043c gprof, \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c \u0443\u0437\u043a\u0438\u043c \u043c\u0435\u0441\u0442\u043e\u043c \u0432 \u044d\u0442\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f <code>std::unordered_map<\/code>. \u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0451, \u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043e\u0442 \u043d\u0438\u0445 \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f.<\/p>\n<h2>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 <code>std::map<\/code><\/h2>\n<p>  \u041c\u043d\u0435 \u0441\u0442\u0430\u043b\u0430 \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u0430 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 <code>std::unordered_map<\/code> \u0438 <code>std::map<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0437\u0430\u043c\u0435\u043d\u0438\u043b \u0432 \u043a\u043e\u0434\u0435 \u0432\u0441\u0435 <code>std::unordered_map<\/code> \u043d\u0430 <code>std::map<\/code>. \u042d\u0442\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u044b\u043b\u043e\u0436\u0435\u043d\u0430 <a href=\"https:\/\/github.com\/pvigier\/ecs\/tree\/map\">\u0437\u0434\u0435\u0441\u044c<\/a><\/p>\n<p>  \u0412\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u043e\u0432:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/611\/50b\/3da\/61150b3da1ec1cf850a0ed5b761f03a1.png\"><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/136\/3be\/951\/1363be95163a3dfb2ab968c1591c7c60.png\"><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/d08\/b4b\/7f1\/d08b4b7f1b5b35531bdc32a614ccbb81.png\"><\/div>\n<p>  \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043b\u043e\u0445\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u0418 \u0434\u0430\u0436\u0435 \u043f\u0440\u0438 1000 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u043e\u043d\u0430 \u0432 \u0434\u0432\u0430 \u0440\u0430\u0437\u0430 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u0432 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f\u0445, \u0447\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044f \u0441 <code>std::unordered_map<\/code>.<\/p>\n<h1>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h1>\n<p>  \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u0443\u044e, \u043d\u043e \u0443\u0436\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u043d\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 entity-component-system. \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0439 \u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0439.<\/p>\n<p>  \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043f\u043e\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0437\u0430\u043c\u0435\u043d\u0438\u0432 <code>std::unordered_map<\/code> \u043d\u0430 <code>std::vector<\/code>. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043c\u044b \u043f\u043e\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c id \u0442\u0438\u043f\u0430.<\/p>\n<h1>\u0417\u0430\u043c\u0435\u043d\u0430 std::unordered_map \u043d\u0430 std::vector<\/h1>\n<p>  \u041a\u0430\u043a \u043c\u044b \u0443\u0432\u0438\u0434\u0435\u043b\u0438, <code>std::unordered_map<\/code> \u0431\u044b\u043b\u0438 \u0443\u0437\u043a\u0438\u043c \u043c\u0435\u0441\u0442\u043e\u043c \u043d\u0430\u0448\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u043c\u0435\u0441\u0442\u043e <code>std::unordered_map<\/code> \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432 <code>mEntityToComponent<\/code> \u0434\u043b\u044f <code>ComponentContainer<\/code> \u0438 \u0432 <code>mEntityToManagedEntity<\/code> \u0434\u043b\u044f <code>System<\/code> \u0432\u0435\u043a\u0442\u043e\u0440\u044b <code>std::vector<\/code>.<\/p>\n<h2>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f<\/h2>\n<p>  \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0443\u0442 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043d\u0438\u0445 \u043c\u043e\u0436\u043d\u043e <a href=\"https:\/\/github.com\/pvigier\/ecs\/commit\/290099e821036225b9d7fe75ca7ffcbb2c0ae7a4\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0442\u043e\u043d\u043a\u043e\u0441\u0442\u044c \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b <code>vector<\/code> \u0432 <code>mEntityToComponent<\/code> \u0438 <code>mEntityToManagedEntity<\/code> \u0431\u044b\u043b\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u0438\u043d\u043d\u044b\u043c\u0438 \u0434\u043b\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438 \u043b\u044e\u0431\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c\u044e. \u0427\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c, \u044f \u0440\u0435\u0448\u0438\u043b \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u044d\u0442\u0438 <code>vector<\/code> \u0432 <code>EntityContainer<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0437\u043d\u0430\u0435\u043c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 id \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. \u0422\u043e\u0433\u0434\u0430 \u044f \u043f\u0435\u0440\u0435\u0434\u0430\u044e \u0432\u0435\u043a\u0442\u043e\u0440\u044b <code>vector<\/code> \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 \u0438\u043b\u0438 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044e \u0432 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439.<\/p>\n<p>  \u0418\u0437\u043c\u0435\u043d\u0451\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u044d\u0442\u043e\u0439 <a href=\"https:\/\/github.com\/pvigier\/ecs\/tree\/vector\">\u0432\u0435\u0442\u043a\u0435<\/a>.<\/p>\n<h2>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b<\/h2>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043b\u0443\u0447\u0448\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u044d\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f, \u0447\u0435\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/38a\/1df\/4bd\/38a1df4bd3c8110d3873588854ffc314.png\"><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/0f5\/897\/2ae\/0f58972ae408b9726899597fbd774be1.png\"><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/22b\/3f5\/fcd\/22b3f5fcd21c8285cc779f46ca3896a4.png\"><\/div>\n<p>  \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u0441\u0438\u0441\u0442\u0435\u043c \u0441\u0442\u0430\u043b\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e <br \/>  \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u0442\u0430\u043b\u0430 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u043f\u043e\u0447\u0442\u0438 \u0432 \u0434\u0435\u0441\u044f\u0442\u044c \u0440\u0430\u0437! \u0418 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u043d\u0430 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e. \u042d\u0442\u043e \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u0441 \u0441\u0438\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0448\u0438\u0432\u0430\u0435\u0442 \u0437\u0430\u043c\u0435\u0434\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f. \u0418 \u044d\u0442\u043e \u043b\u043e\u0433\u0438\u0447\u043d\u043e: \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0440\u0430\u0437, \u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0441\u043d\u0438\u0437\u0438\u043b\u043e \u043b\u0438 \u044d\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u043c\u0430\u0445\u043e\u0432 \u043a\u044d\u0448\u0430.<\/p>\n<p>  \u0412\u043e\u0442 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 cachegrind \u043f\u0440\u0438 10 000 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u0445:<\/p>\n<p>  <code>==1374== D refs: 94,563,949 (72,082,880 rd + 22,481,069 wr)<br \/>  ==1374== D1 misses: 4,813,780 ( 4,417,702 rd + 396,078 wr)<br \/>  ==1374== LLd misses: 378,905 ( 9,626 rd + 369,279 wr)<br \/>  ==1374== D1 miss rate: 5.1% ( 6.1% + 1.8% )<br \/>  ==1374== LLd miss rate: 0.4% ( 0.0% + 1.6% )<\/code><\/p>\n<p>  \u0410 \u0432\u043e\u0442 \u0432\u044b\u0432\u043e\u0434 \u0434\u043b\u044f 100 000 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439:<\/p>\n<p>  <code>==1307== D refs: 938,405,796 (715,424,940 rd + 222,980,856 wr)<br \/>  ==1307== D1 misses: 51,034,738 ( 44,045,090 rd + 6,989,648 wr)<br \/>  ==1307== LLd misses: 5,866,508 ( 1,997,948 rd + 3,868,560 wr)<br \/>  ==1307== D1 miss rate: 5.4% ( 6.2% + 3.1% )<br \/>  ==1307== LLd miss rate: 0.6% ( 0.3% + 1.7% )<\/code><\/p>\n<p>  \u041c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 \u0442\u0440\u0438 \u0440\u0430\u0437\u0430 \u043c\u0435\u043d\u044c\u0448\u0435 \u0441\u0441\u044b\u043b\u043e\u043a \u0438 \u0432 \u0447\u0435\u0442\u044b\u0440\u0435 \u0440\u0430\u0437\u0430 \u043c\u0435\u043d\u044c\u0448\u0435 \u043f\u0440\u043e\u043c\u0430\u0445\u043e\u0432 \u043a\u044d\u0448\u0430.<\/p>\n<h1>\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u0438\u043f\u044b<\/h1>\n<p>  \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0435\u043c, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u0441\u0442\u0430\u043d\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u0442\u0438\u043f\u043e\u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432.<\/p>\n<h2>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f<\/h2>\n<p>  \u041d\u0430 \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 id \u0442\u0438\u043f\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/pvigier\/ecs\/commit\/09b2b8b6aa4abe65255ac716a85dcf8d25a7e586\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  \u0414\u043b\u044f, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 id \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043d\u0443\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f CRTP \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0441\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u043e\u043c:<\/p>\n<pre><code class=\"cpp\">template&lt;typename T&gt; class Component { public:     static const std::size_t type; };  std::size_t generateComponentType() {     static auto counter = std::size_t(0);     return counter++; }  template&lt;typename T&gt; const std::size_t Component&lt;T&gt;::type = generateComponentType();<\/code><\/pre>\n<p>  \u041c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e id \u0442\u0438\u043f\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f, \u0430 \u0440\u0430\u043d\u0435\u0435 \u043e\u043d \u0431\u044b\u043b \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<p>  \u041a\u043e\u0434 \u043f\u043e\u0441\u043b\u0435 \u0432\u043d\u0435\u0441\u0451\u043d\u043d\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u044d\u0442\u043e\u0439 <a href=\"https:\/\/github.com\/pvigier\/ecs\/tree\/automatic_component_type\">\u0432\u0435\u0442\u043a\u0435<\/a>.<\/p>\n<h2>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b<\/h2>\n<p>  \u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u044d\u0442\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u044f \u043f\u0440\u043e\u0432\u0451\u043b \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/7bd\/112\/0da\/7bd1120da37daac5e3ef48446776b6e7.png\"><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/234\/f2f\/937\/234f2f9377a0f3ad8ea231f91e335ddf.png\"><\/div>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/101\/4f2\/ade\/1014f2adebd6156bc48c9b6fe5670b43.png\"><\/div>\n<p>  \u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0435\u043c\u0438 \u0436\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u0442\u0430\u043b\u0430 \u0447\u0443\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043d\u0430 10%.<\/p>\n<p>  \u042d\u0442\u043e \u0437\u0430\u043c\u0435\u0434\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u0442\u0435\u043c, \u0447\u0442\u043e \u0440\u0430\u043d\u044c\u0448\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0437\u043d\u0430\u043b \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0442\u0438\u043f\u043e\u0432 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0433 \u043b\u0443\u0447\u0448\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434.<\/p>\n<p>  \u0420\u0443\u0447\u043d\u043e\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 id \u0442\u0438\u043f\u043e\u0432 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u043e \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043a \u043e\u0448\u0438\u0431\u043a\u0430\u043c. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u0443\u0441\u0442\u044c \u043c\u044b \u0434\u0430\u0436\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043d\u0438\u0437\u0438\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u044d\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0435\u043c \u044e\u0437\u0430\u0431\u0438\u043b\u0438\u0442\u0438 \u043d\u0430\u0448\u0435\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 ECS.<\/p>\n<h1>\u0418\u0434\u0435\u0438 \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0438\u0445 \u0443\u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0439<\/h1>\n<p>  \u041f\u0435\u0440\u0435\u0434 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435\u043c \u0441\u0442\u0430\u0442\u044c\u0438 \u044f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u0438\u0434\u0435\u044f\u043c\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0439. \u041f\u043e\u043a\u0430 \u044f \u0438\u0445 \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b, \u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0441\u0434\u0435\u043b\u0430\u044e \u044d\u0442\u043e \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c.<\/p>\n<h2>\u0414\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u0441\u0438\u0441\u0442\u0435\u043c<\/h2>\n<p>  \u041d\u0435\u0443\u0434\u043e\u0431\u043d\u043e \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u0438 \u0441\u0438\u0441\u0442\u0435\u043c \u0432 \u0432\u0438\u0434\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0430. \u0414\u0443\u043c\u0430\u044e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c <code>std::array<\/code> \u0432 <code>EntityManager<\/code> \u043d\u0430 <code>std::vector<\/code> \u0431\u0435\u0437 \u0441\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043d\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e <code>std::bitset<\/code> \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0437\u043d\u0430\u0442\u044c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0431\u0438\u0442\u043e\u0432. \u041f\u043e\u043a\u0430 \u044f \u0434\u0443\u043c\u0430\u044e \u0443\u0441\u0442\u0440\u0430\u043d\u0438\u0442\u044c \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0437\u0430\u043c\u0435\u043d\u043e\u0439 <code>std::vector&lt;bitset&lt;ComponentCount&gt;&gt;<\/code> \u0432 <code>EntityContainer<\/code> \u043d\u0430 <code>std::vector&lt;char&gt;<\/code> \u0438 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0431\u0430\u0439\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0431\u043e\u0440\u043e\u0432 \u0431\u0438\u0442\u043e\u0432 \u0432\u0441\u0435\u0445 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043e\u0431\u043b\u0435\u0433\u0447\u0451\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>BitsetView<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434\u0435 \u043f\u0430\u0440\u0443 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430 \u043d\u0430\u0447\u0430\u043b\u043e \u0438 \u043a\u043e\u043d\u0435\u0446 \u043d\u0430\u0431\u043e\u0440\u0430 \u0431\u0438\u0442\u043e\u0432, \u0430 \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0432\u0441\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0441 <code>std::bitset<\/code> \u0432 \u044d\u0442\u043e\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>  \u0415\u0449\u0451 \u043e\u0434\u043d\u0430 \u0438\u0434\u0435\u044f: \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0431\u043e\u0440\u044b \u0431\u0438\u0442\u043e\u0432 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0432 <code>mEntityToComponent<\/code>, \u0435\u0441\u0442\u044c \u043b\u0438 \u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442.<\/p>\n<h2>\u0423\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u0430\u044f \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f \u043f\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c<\/h2>\n<p>  \u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u0435\u0441\u043b\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0445\u043e\u0447\u0435\u0442 \u0438\u0442\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e \u043e\u0431\u043e\u0439\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u0435\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cpp\">for (const auto&amp; entity : getManagedEntities()) {     auto [position, velocity] = mEntityManager.getComponents&lt;Position, Velocity&gt;(entity);     ... }<\/code><\/pre>\n<p>  \u0411\u044b\u043b\u043e \u0431\u044b \u043a\u0440\u0430\u0441\u0438\u0432\u0435\u0435 \u0438 \u043f\u0440\u043e\u0449\u0435, \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u043e\u0433\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435\u0447\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435:<\/p>\n<pre><code class=\"cpp\">for (auto&amp; [position, velocity] : mEntityManager.getComponents&lt;Position, Velocity&gt;(mManagedEntities)) {     ... }<\/code><\/pre>\n<p>  \u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0449\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>std::view::transform<\/code> \u0432 C++20 <br \/>  \u0438\u0437 <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/ranges\">\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 ranges<\/a>.<\/p>\n<p>  \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0435\u0451 \u043f\u043e\u043a\u0430 \u043d\u0435\u0442. \u042f \u043c\u043e\u0433 \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/ericniebler\/range-v3\">\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 range<\/a> \u042d\u0440\u0438\u043a\u0430 \u041d\u0438\u0431\u043b\u0435\u0440\u0430, \u043d\u043e \u043d\u0435 \u0445\u043e\u0447\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u0420\u0435\u0448\u0435\u043d\u0438\u0435 \u043c\u043e\u0433\u043b\u043e \u0431\u044b \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 <code>EntityRangeView<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u043b \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u0442\u0438\u043f\u044b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 <code>std::vector<\/code> \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u0422\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u0431\u044b \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c <code>begin<\/code>, <code>end<\/code> \u0438 \u0442\u0438\u043f \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f. \u042d\u0442\u043e \u043d\u0435 \u043e\u0441\u043e\u0431\u043e \u0441\u043b\u043e\u0436\u043d\u043e, \u043d\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0440\u0443\u0434\u043e\u0451\u043c\u043a\u043e \u0432 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438.<\/p>\n<h2>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u043c\u0438<\/h2>\n<p>  \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438\u0437 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c <code>onEntityUpdated<\/code> \u0432\u0441\u0435\u0445 \u0441\u0438\u0441\u0442\u0435\u043c. \u042d\u0442\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0435\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u043d\u043e\u0433\u0438\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u0438\u043f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0431\u044b\u043b \u0438\u0437\u043c\u0435\u043d\u0451\u043d.<\/p>\n<p>  \u0427\u0442\u043e\u0431\u044b \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0440\u043e\u043d, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c \u0442\u0438\u043f\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>std::array&lt;std::vector&lt;System&lt;ComponentCount, SystemCount&gt;&gt;, ComponentCount&gt;<\/code>. \u0422\u043e\u0433\u0434\u0430 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0438 \u0431\u044b \u043c\u0435\u0442\u043e\u0434 <code>onEntityUpdated<\/code> \u0441\u0438\u0441\u0442\u0435\u043c, \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432 \u044d\u0442\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435.<\/p>\n<h2>\u041f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0435 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0432\u043c\u0435\u0441\u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c<\/h2>\n<p>  \u041c\u043e\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0438\u0434\u0435\u044f \u043f\u0440\u0438\u0432\u0435\u043b\u0430 \u0431\u044b \u043a \u0431\u043e\u043b\u0435\u0435 \u043e\u0431\u0448\u0438\u0440\u043d\u044b\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<\/p>\n<p>  \u0412\u043c\u0435\u0441\u0442\u043e \u0441\u0438\u0441\u0442\u0435\u043c, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u0441\u0432\u043e\u0438\u043c\u0438 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430\u043c\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u044d\u0442\u0438\u043c \u0431\u044b \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0441\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u0442\u0430\u043a\u043e\u0439 \u0441\u0445\u0435\u043c\u044b \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0434\u0432\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043c\u044b \u043d\u0435 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439, \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0449\u0438\u0445 \u044d\u0442\u0438\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c.<\/p>\n<p>  \u0421\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0437\u0430\u044f\u0432\u043b\u044f\u0442\u044c \u043e \u0441\u0432\u043e\u0438\u0445 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u0445 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0443 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u0422\u043e\u0433\u0434\u0430 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u0445\u0440\u0430\u043d\u0438\u043b \u0431\u044b \u0432\u0441\u0435 \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0431\u044b \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u043b\u0438 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430:<\/p>\n<pre><code class=\"cpp\">for (const auto&amp; entity : mEntityManager.getEntitiesWith&lt;Position, Velocity&gt;()) {     ... }<\/code><\/pre>\n<p>  <\/p>\n<h1>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h1>\n<p>  \u041f\u043e\u043a\u0430 \u044d\u0442\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u043e \u043c\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 entity-component-system. \u0415\u0441\u043b\u0438 \u044f \u0432\u043d\u0435\u0441\u0443 \u0434\u0440\u0443\u0433\u0438\u0435 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f, \u0442\u043e, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043d\u0430\u043f\u0438\u0448\u0443 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043d\u043e\u0432\u044b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<p>  \u041e\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430: \u043e\u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043c\u0435\u043d\u0435\u0435 \u0447\u0435\u043c 500 \u0441\u0442\u0440\u043e\u043a \u043a\u043e\u0434\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0445\u043e\u0440\u043e\u0448\u0435\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e. \u0412\u0441\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u044b \u0437\u0430 (\u0430\u043c\u043e\u0440\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435) \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043e\u043d\u0430 \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043a\u044d\u0448 \u0438 \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0438 \u0438\u0442\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u044b\u043b\u0430 \u0434\u043b\u044f \u0432\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439.<\/p>\n<h1>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435<\/h1>\n<p>  \u0412\u043e\u0442 \u043f\u0430\u0440\u0430 \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0433\u043e \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0448\u0430\u0431\u043b\u043e\u043d\u0430 entity-component-system:<\/p>\n<ul>\n<li>\u041c\u0438\u0448\u0435\u043b\u044c \u041a\u0430\u0439\u043d\u0438, \u0430\u0432\u0442\u043e\u0440 <a href=\"https:\/\/github.com\/skypjack\/entt\">entt<\/a>, \u043f\u0438\u0448\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0443\u044e \u0441\u0435\u0440\u0438\u044e \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u043e\u0431 entity-component-system \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/skypjack.github.io\/2019-02-14-ecs-baf-part-1\/\">ECS back and forth<\/a>.<\/li>\n<li><a href=\"http:\/\/entity-systems.wikidot.com\/\">Entity Systems Wiki<\/a> \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0438 \u0441\u0441\u044b\u043b\u043a\u0438.<\/li>\n<\/ul>\n<\/div>\n<p>               <script class=\"js-mediator-script\">!function(e){function t(t,n){if(!(n in e)){for(var r,a=e.document,i=a.scripts,o=i.length;o--;)if(-1!==i[o].src.indexOf(t)){r=i[o];break}if(!r){r=a.createElement(\"script\"),r.type=\"text\/javascript\",r.async=!0,r.defer=!0,r.src=t,r.charset=\"UTF-8\";var d=function(){var e=a.getElementsByTagName(\"script\")[0];e.parentNode.insertBefore(r,e)};\"[object Opera]\"==e.opera?a.addEventListener?a.addEventListener(\"DOMContentLoaded\",d,!1):e.attachEvent(\"onload\",d):d()}}}t(\"\/\/mediator.mail.ru\/script\/2820404\/\",\"_mediator\")}(window);<\/script>     <br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/459288\/\"> https:\/\/habr.com\/ru\/post\/459288\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html js-mediator-article\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/4c9\/fc6\/23e\/4c9fc623e0787518bde7823317b0e6af.png\" alt=\"image\"><\/div>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u0439 \u043d\u0435\u0434\u0435\u043b\u0435 \u044f \u043d\u0430\u0447\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0434 \u0441\u0432\u043e\u0438\u043c \u0434\u0432\u0438\u0436\u043a\u043e\u043c \u0434\u043b\u044f \u0438\u0433\u0440\u044b Vagabond \u0438 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043b \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Entity_component_system\">entity-component-system<\/a>.<\/p>\n<p>  \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u0430 <a href=\"https:\/\/github.com\/pvigier\/ecs\">GitHub<\/a>. \u041d\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u044f \u0445\u043e\u0447\u0443 \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0435\u0433\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043d\u0430\u0447\u043d\u0443 \u0441 \u043f\u0435\u0440\u0432\u043e\u0439 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u043c\u043d\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e \u0435\u0451 \u0441\u0438\u043b\u044c\u043d\u044b\u0435 \u0438 \u0441\u043b\u0430\u0431\u044b\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0443\u043b\u0443\u0447\u0448\u0438\u043b \u0435\u0451. \u0412 \u043a\u043e\u043d\u0446\u0435 \u044f \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044e \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0441\u043f\u0435\u043a\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c.<\/p>\n<h1>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h1>\n<p>  <\/p>\n<h2>\u041c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u044f<\/h2>\n<p>  \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043e \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u0430\u0445 ECS \u043f\u0435\u0440\u0435\u0434 \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e-\u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441 \u044d\u0442\u0438\u043c \u0445\u043e\u0440\u043e\u0448\u043e \u0441\u043f\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u043c\u043d\u043e\u0433\u0438\u0435 \u043b\u044e\u0434\u0438 \u0434\u043e \u043c\u0435\u043d\u044f. \u041e\u0434\u043d\u0438\u043c \u0438\u0437 \u043f\u0435\u0440\u0432\u044b\u0445 \u043f\u0440\u043e ECS \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b \u043d\u0430 <a href=\"https:\/\/web.archive.org\/web\/20101011021902\/http:\/\/scottbilas.com\/files\/2002\/gdc_san_jose\/game_objects_slides.pdf\">GDC 2002<\/a> \u0421\u043a\u043e\u0442\u0442 \u0411\u0438\u043b\u0430\u0441. \u0421\u0440\u0435\u0434\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0437\u043d\u0430\u043c\u0435\u043d\u0438\u0442\u044b\u0445 \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0439 \u0432 \u0442\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0437\u0432\u0430\u0442\u044c <a href=\"http:\/\/cowboyprogramming.com\/2007\/01\/05\/evolve-your-heirachy\/\">Evolve Your Hierarchy<\/a> \u041c\u0430\u0439\u043a\u0430 \u0423\u044d\u0441\u0442\u0430 \u0438 \u0433\u043b\u0430\u0432\u0443 <a href=\"http:\/\/gameprogrammingpatterns.com\/component.html\">Components<\/a> \u0438\u0437 \u043f\u043e\u0442\u0440\u044f\u0441\u0430\u044e\u0449\u0435\u0439 \u043a\u043d\u0438\u0433\u0438 <a href=\"http:\/\/gameprogrammingpatterns.com\/\">Game Programming Patterns<\/a> \u0420\u043e\u0431\u0435\u0440\u0442\u0430 \u041d\u0438\u0441\u0442\u0440\u043e\u043c\u0430.<\/p>\n<p>  \u0412\u043a\u0440\u0430\u0442\u0446\u0435 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u0437\u0430\u0434\u0430\u0447\u0430 ECS \u2014 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043a \u0438\u0433\u0440\u043e\u0432\u044b\u043c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044f\u043c \u0438 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043b\u043e\u0433\u0438\u043a\u0438. \u0421\u0443\u0449\u043d\u043e\u0441\u0442\u0438 (Entities) \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u0437 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0435. \u0410 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u0443, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442 \u044d\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0435\u0442\u0430\u043b\u0438, \u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e <a href=\"https:\/\/en.wikipedia.org\/wiki\/Inheritance_(object-oriented_programming)\">\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f<\/a> \u0432 ECS \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/en.wikipedia.org\/wiki\/Object_composition\">\u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f<\/a>. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u044d\u0442\u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434, \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445, \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043a\u044d\u0448, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-291886","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/291886","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=291886"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/291886\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=291886"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=291886"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=291886"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}