Vi "Diseño orientado a datos y C ++" de Mike Acton y me pareció bastante interesante. Sin embargo, no entiendo cómo se resuelven las dependencias de datos.

Imagina que tengo un motor 2d simple con: * datos físicos - para manejar la física * datos gráficos - para renderizar sprites * datos de sonido - para reproducir sonidos

Los datos gráficos y los datos de sonido dependen de la posición almacenada en los datos físicos. Se puede hacer referencia a la posición a partir de los datos físicos, pero eso, en mi opinión, mata todo el punto del DOD: tener datos requeridos en la misma ubicación de memoria.

¿Cómo se maneja esta situación en el diseño orientado a datos?

1
Stan Prokop 13 nov. 2017 a las 00:16

2 respuestas

La mejor respuesta

DOD es más una forma general de diseñar su arquitectura que se enfoca en cómo representar los datos de manera eficiente primero. No hay una forma única de hacerlo. Linus Torvalds exhibió esa mentalidad hacia el Kernel de Linux y Git y demás, pero es un dominio muy diferente de los juegos. Lo principal es que se centró en cómo representar datos de manera eficiente ante todo.

Como ejemplo básico, si está diseñando una aplicación de procesamiento de imágenes, entonces si no estaba pensando en una forma orientada a los datos y, en cambio, se centró en cómo admitir más fácilmente la gama más amplia de formatos de píxeles y crear las interfaces más fáciles para utilizar, podría llegar a un resumen Pixel y tal vez incluso una asignación de montón por píxel. En ese punto, está pagando el costo de un puntero virtual (a menudo más grande que los píxeles en sí), envío dinámico por píxel , posiblemente otra capa de direccionamiento indirecto y potencialmente una pérdida completa de localidad espacial. Si, en cambio, pensara en cómo representar de manera eficiente los datos primero, probablemente abstraería en un nivel Image más grueso (una colección abstracta de píxeles, posiblemente millones de píxeles para una imagen dada) si abstrae en absoluto donde no paga por tales gastos generales en un nivel por píxel.

Dicho esto, para los juegos, a menudo la forma más común de abordar lo que estás hablando es hacer que los datos sean accesibles de forma centralizada . Y esto puede parecer una violación de los principios de SE, pero por lo general, si usa algo como un sistema de componente de entidad, a menudo solo un pequeño número de sistemas accederá a cualquier tipo de componente. Como resultado, el alcance de esos datos tiende a ser lo suficientemente pequeño como para mantener invariantes de manera efectiva.

enter image description here

En cuanto a los eventos que pueden ocurrir en el juego, como dos entidades que chocan entre sí en el sistema de física para las cuales el sistema de sonido podría querer reproducir un sonido, existen muchos enfoques para mantener la física y el sistema de sonido desacoplados de cada uno. otro. Uno es usar una cola de eventos.

En cuanto a que los datos requeridos de un sistema también se compartan con otro, eso generalmente es bastante práctico. Si desea ejecutar estos sistemas en paralelo entre sí, aún tendrán que copiar los datos compartidos, actualizarlos y coordinar de alguna manera sus resultados. Dicho esto, en mi opinión, es mucho más productivo evitar jugar con eso y simplemente paralelizar lo que está haciendo un sistema (por ejemplo: usar un ciclo for paralelo), porque normalmente solo hay un puñado de sistemas en un ECS que son hotspots. y hacer un trabajo realmente pesado, y puede distribuir fácilmente el trabajo de esos sistemas específicos en subprocesos sin intentar ejecutar muchos sistemas al mismo tiempo y abrir esa lata de gusanos.

1
Dragon Energy 21 dic. 2017 a las 04:17

No estoy seguro si es perfectamente DOD, pero si sus identificaciones o identificadores se comparten en todos sus subsistemas de física y gráficos, puede hacer que su subsistema de física produzca una serie de posiciones e identificaciones / identificadores de todos los objetos actualizados y usarlos como entrada para el subsistema de gráficos .

1
thbusch 13 nov. 2017 a las 09:19