How do you handle systems accessing multiple components (without dropping your cache load) in an entity component system? - entity

I'm currently writing my own Entity Component System, and I'm having a little bit of trouble optimizing my cache load when it comes to systems that look at multiple components.
I'm taking a very pure ECS approach: components of the same type are stored in a (sparse) vector, and entities are identified by their index in each component vector. I understand that this is good for performance, because a system working on a single component can fill the cache load fully with components that it needs.
But an issue arises when a system uses multiple components, and I don't know what I'm missing; for each entity, a system will need to drop its cache load of one component to look at the next one. Each component type a system looks at means a cache drop for each entity it looks at.
Is my problem clear? Does anyone have any solutions to this? What am I missing?

Related

Dealing with fast-changing data in React Native

Summary
I have an app which monitors a characteristic of a BLE device. It has to react to the changes (BLE device notifies of changes), save them, calculate some stuff and then display a plot, some values and a gps map. The data changes with a frequency of about 10Hz.
My current idea of the structure
main screen/component: Starts monitoring the device. On data change, saves raw data, calculates values (calls a function from a native component for performance reasons), sends some data to the plot page, gps page, another page. Returns/renders the following pages.
plot page: Uses expo-gl and threejs to display a plot, plot can be changed by changing values and calling some functions, does not need a state update. Also needs to display 15 values, from my experience fast props updates resulted in extremely poor performance, so I used textInputs with refs before to change them without props/state updates, but that was without gps and then characteristic monitoring was in this component.
gps page: Displays a map with a line which changes with BLE updates. Haven't implemented yet, I'm thinking about using rnmapbox. I'm worried that this requires data as props and therefore might have performance problems. Any ideas here are welcome.
another page: This has to display a table with 30 values. Again as they're fast changing I think refs have to be used. I used refs with 12 values, but I think it's slowly getting out of hand with that many refs.
Main questions I have
How does this structure seem? If anyone has any other ideas, all are welcome.
Is there any other, better way of updating fast-changing values, other that using refs and textInput?
How to structure refs? As there are so many refs, I'm wondering what's the best way of storing and sharing them between the components?
As right now it seems that everything is becoming so coupled, I'm wondering if it would be even better to just put everything in one file? Then the file would be long, but it might allow to omit some confusing parts of sharing data between components.
Thanks to everyone willing to help. It's my first question on here, so any tips on how to structure the question better are welcome.
EDIT:
I think I finally understood accessing child functions from parent component with refs. So I can use that to update most of the stuff without using props and keeping textInput refs in the components they belong to. However I'm still open to any ideas.

Reusing Components and Maintaining State with Vue

I have created a few linked Vue components that I reuse between multiple projects. Eventually I would like to do it with NPM or a tool like Bit, but right now I am doing it manually.
All of my components are just passing data between themselves using props and emits. This has gotten pretty inefficient as a lot of my components do not sit right next to one another all of the time, so I want to move them over to a more robust solution. Right now I am finding myself having to emit the same data multiple times just to get back up the chain.
Through reading I know that a global event bus can be used to maintain state between components, or Vuex could be used to maintain my overall application state, but how do I factor this into reusable components?
In my head it feels like if I base my components on either option, then I am committing to always using that component with a global event bus or Vuex. And obviously in some projects I may want to switch between using one or the other, depending on the application's complexity.
How do I best approach this? Do I need slightly different components depending on the overall application (this feels like I lose the reuse-ability) or is there something I am not taking into account here?
For one of my applications I have the following simplified component structure:
Root Component
Grid
Card
FilterDropdown
Graph
Currently I pass the data into my root component from the API, then pass it down to the Graph component through props at each stage.
On the other side, my FilterDropdown gets a distinct list of one of the data's columns, and provides a dropdown where the user can select a value. This values is then emitted 3 times back up the tree to the root component, where it is used to filter the data via a computed property, that is then passed down again using the same props.
Am I over-complicating things by thinking this needs changing? I can already imaging how I could achieve the same thing, with less overall confusion, by using an event bus or Vuex, but in my head I think I would lose some reuse-ability?
If an app is passing around props to unrelated components or it's becoming tedious to maintain a props/emit chain through multiple descendants, then it's probably a good time to use one of the options you mentioned. From the Vuex docs:
passing props can be tedious for deeply nested components, and simply doesn't work for sibling components.
If the architecture isn't that complicated, there's probably no need to switch. But if there is...
Vuex Modules
Since Vuex allows for modules, you can probably eliminate the question of whether it negatively impacts component reusability. You can think of the component(s) + their dedicated Vuex module(s) as a package. The Vuex module can encapsulate all of the necessary store functionality without affecting any part of the store of an app that utilizes it.
Plugins
You could even create plugins from these components and use dynamic module registration to register their associated Vuex module in the app's existing store.
You could do something similar with a plugin and event bus.
Instead of thinking of this as committing to a limitation, you can view it as the plugin providing an interface for apps to take advantage of its features. You could also go with an "all of the above" approach and create a solution for each option.

In ECS (Entity Component System) what is the difference between Component-Manager and a System?

I'm trying to understand ECS. So a component is just plain data, and some manager holds these components in a container and loops through all of them to act on this data, to "update" them.
Is this manager what people call "component-manager" or is it a "system"? Or do they mean the same thing? If not, what does a component-manager and a system do?
ECS means different things to different people. There are a large number of approaches when it comes to implementation but I personally go by the following rules:
A Component is just plain data, typically a structure or some object with no logic associated with it what so ever.
An Entity is a collection of components. It is defined by an identifier, typically an integer, that can be used to look up components like an index.
A System is where all the game logic lives. Each System has an archetype, that is a specific set of components that it operates on. Systems have an update function, which when invoked accesses the specific set of components its interested in (its archetype), for all entities that have that specific collection of components. This update function is triggered externally (by what? see the next paragraph).
Now, here's the bit that addresses your question directly (or at least attempts to). Video games are simulations and they are typically driven by whats called an update loop (typically sync-ed to a monitor's refresh rate). In ECS architecture, there is typically dedicated code that strings your systems together in a queue and on each time-step of the update loop executes those systems in sequence (ie. calls their update functions). That bit of dedicated code not only manages the system update loop but is also responsible for managing components (stored as lists/arrays that can be indexed by an entity id) and a myriad of other tasks. In many implementations its referred to as the "Engine". This is what I take to be a "component-manager". But that could mean something else in another ECS approach. Just my two-cents. Hope it helped.

ECS / CES shared and dependent components and cache locality

I have been trying to wrap my head around how ECS works when there are components which are shared or dependent. I've read numerous articles on ECS and can't seem to find a definitive answer to this.
Assume the following scenario:
I have an entity which has a ModelComponent (or MeshComponent), a PositionComponent and a ParticlesComponent (or EmitterComponent).
The ModelRenderSystem needs both the ModelComponent and the PositionComponent.
The ParticleRenderSystem needs ParticlesComponent and the PositionComponent.
In the ModelRenderSystem, for cache efficiency / locality, I would like run through all the ModelComponents which are in a compact array and render them, however for each model I need to pull the PositionComponent. I haven't even started thinking about how to deal with the textures, shaders etc for each model (which will definitely blow the cache).
A similar issue with the ParticleRenderSystem.. I need both the ParticlesComponent as well as the PositionComponent, and I want to be able to run through all ParticlesComponents in a cache efficient / friendly manner.
I considered having ModelComponent and ParticlesComponent each having their own position, but they will need to be synched every time the models position changes (imagine a particle effect on a character). This adds another entity or component which needs to track and synch components or values (and potentially negates any cache efficiency).
How does everyone else handle these kinds of dependency issues?
One way to reduce the complexity could be to invert flow of data.
Consider that your ModelRenderSystem has a listener callback that allows the entity framework to inform it that an entity has been added to the simulation that contains both a position and model component. During this callback, the system could register a callback on the position component or the system that owns that component allowing the ModelRenderSystem to be informed when that position object changes.
As the change events from the position changes come in, the ModelRenderSystem can queue up a list of modifications it must replicate during its update phase and then during update, its really a simple lookup each modifications model and set the position to the value in the event.
The benefit is that per frame, you're only ever replicating position changes that actually changed during the frame and you minimize lookups needed to replicate the data. While the update of the position propagates to various systems of interest may not be as cache friendly, the gains you observe otherwise out weigh that.
Lastly, don't forget that systems do not necessarily need to iterate over the components proper. The components in your entity system exist to allow you to toggle plug-able behavior easily. The systems can always manage a more cache friendly data structure and using the above callback approach, allows you to do that and manage data replication super easily with minimal coupling.

Flex 3: should I provide prepared data to my component or make it to process data before display?

I'm starting to learn a little Flex just for fun and maybe to prove that I still can learn something new :) I have some idea for a project and one of its parts is a tree component which could display data in different ways depending on configuration.
The idea
There is list of objects having properties like id, date, time, name, description. And sometimes list should be displayed like this:
first level: date
second level: time
third level: name
and sometimes like this:
first level: year
second level: month
third level: day
fourth level: time and name
By level I mean level of nesting of course. So, we can have years, that have months, that have days, that have hours and so forth.
The problem
What could be the best way to do it? I mean, should I prepare data for different ways of nesting outside of component or even outside of flex? I can do it at web service level in C# where I plan to have database access layer and send to flex nice and ready to display XML or array of objects. But I wonder if that won't cause additional and maybe unneccessary network traffic.
I tried to hack some code in my component to convert my data objects into XML or ArrayCollection but I don't know enough of Flex and got stuck on elimination of duplicates or getting specific data by some key value. Usually to do such things I have STL with maps, sets and vectors and I find Flex arrays and even Dictionary a little bit confusing (I've read language reference and googled without any significant luck).
The question
So, to sum things up: should I give my tree component data prepared just for chosen type of display or should I try to do it internally inside component (or some helper class written in ActionScript)?
ADDITIONAL QUESTION
Would it be a good approach to prepare separate data models for each way of display and some converter to transfer data between them and resulting model would be binded to component as a dataProvider? Or maybe there is some other clever way to do it and my data will reorganize automagically by themselves? :)
I would favor receiving a raw stream of data from your web service and process it in various ways within the flex client (in a helper Actionscript class). Here are the advantages I see:
1) This gives a nice separation of responsibilities. E.g. the web service should know about the data but not what ways it will be displayed.
2) Faster processing and client responsiveness. Swapping views will not involve calling your web service and the Flex client will likely be faster processing the data itself than the extra web traffic
3) Increased availability. Without extra calls to your web service, there is less of a chance of a network failure.