¿Por qué usar archivos de manifiesto de activos?

12

A veces verá que la gente lo recomienda en lugar de usar gráficos / archivos de sonido / etc. Me gusta esto...

// Game code
Image myImage = new Image("path/to/image.png");

... deberías usar un archivo de manifiesto como un nivel de indirección en su lugar:

// Manifest file
MY_IMAGE: path/to/image.png

// Game code
Manifest myManifest = new Manifest("path/to/manifest");
Image myImage = myManifest.getImage("MY_IMAGE");

¿Qué razones tendría para adoptar este tipo de enfoque? Si no estoy usando un lenguaje compilado, ¿habría alguna razón para hacerlo?

Tung Nguyen
fuente

Respuestas:

8

La mayoría de las veces los archivos de manifiesto están asociados con algún tipo de formato de archivo comprimido. Por ejemplo, un archivo JAR en Java es simplemente un archivo zip con un archivo de manifiesto que enumera los activos dentro del archivo zip y dónde encontrarlos. En ese caso, la "ruta / a / image.png" no es una ruta real del sistema de archivos, sino que es información sobre cómo encontrar el objeto dentro de un archivo comprimido. Además de la ventaja del espacio en disco de la compresión, el uso de un archivo comprimido puede mejorar el rendimiento porque Windows tiene dificultades para manejar decenas de miles de archivos individuales en un pequeño número de directorios.

Al usar un archivo de manifiesto de este tipo, puede abstraer por completo de dónde proviene un fragmento de datos. Tal vez su archivo está en un DVD, o se transmite por Internet, o dentro de un archivo zip. Tendrás que escribir un código adicional para tratar estos casos, pero al usar un archivo de manifiesto, la lógica del juego no tiene que preocuparse en absoluto de dónde se carga algo.

Ahora, si está utilizando un lenguaje no compilado, este archivo de manifiesto ciertamente podría ser un archivo fuente C #, pero es bueno si puede modificar fácilmente qué archivo de manifiesto está utilizando en el momento de la ejecución del cliente en función de una configuración de registro o algo similar. Por ejemplo, puede verificar durante la ejecución para ver si existe un caché en el disco duro, o si solo el DVD está disponible. A continuación, puede cambiar qué manifiesto usar según la configuración disponible.

Ben Zeigler
fuente
Puedo ver la necesidad de abstraer ubicaciones de archivos en escenarios complejos, pero solo recuperar archivos de un archivo zip no debería requerir un manifiesto ya que los nombres de archivo y las rutas se conservan en el archivo.
Alex Jasmin
4

Una razón: programación basada en datos.

Es posible que su código solo quiera saber que necesita una textura "LightWood" y dejar que el administrador de recursos use esta clave para encontrar la ruta correcta al archivo. Aún más, en los scripts, las personas no quieren recordar las rutas de los archivos. Son desordenados, pueden ser incorrectos. Deje que el manifiesto descubra dónde está el archivo, y deje que el humano resuelva qué material necesita por su nombre, no por el nombre del archivo.

<material name="wood">
  <diffuse color="1,1,1,1">environment.zip/wood_diffuse.jpg</diffuse>
  <normals>environment.zip/wood_normals.jpg</normals>
  <shader>environment.zip/wood.fx</shader>
  <specular color="1,1,1,1" power="0.5" flat="yes" />
</material>
Nick Bedford
fuente
2

Como patrón de diseño general, los manifiestos son útiles cuando desea recopilar toda la información sobre un conjunto de objetos dispares en un solo lugar. No tiene que ser sobre archivos archivados / empaquetados, o sobre indirección para permitir que las cosas se muevan sin recompilar / actualizar referencias originales. De hecho, este último puede introducir más problemas de los que resuelve, por lo que solo lo haría si resolviera una necesidad particular que tenía.

La gran ventaja de los manifiestos es que actúan como un índice de una gran cantidad de datos en un solo lugar compacto. Como tal, mejoran el rendimiento (porque simplemente puede cargar todo el manifiesto del disco y mantenerlo en la memoria), especialmente en el caso de que necesite iterar sobre varios objetos, pero no sabe de antemano cuáles serán esos objetos . Si los objetos están en el disco, especialmente si están en varios lugares, debe tocar el sistema de archivos cada vez que desee iterar sobre los archivos. Para los sistemas de archivos basados ​​en disco, el tiempo necesario para tocar el sistema de archivos es prohibitivo, por lo que iterar sobre los archivos en un directorio es un costo enorme. Al precompilar un manifiesto de archivos en el momento de la compilación (NB: no en tiempo de compilación), intercambia ese costo por el uso de memoria.

Los archivos de archivo requieren el uso de manifiestos, simplemente porque la tabla de contenido del archivo es esencialmente un manifiesto en sí mismo, por lo que obtienes el comportamiento de forma gratuita. Y si tiene que usar manifiestos para activos en una ubicación, puede ser más claro insistir en que todos los activos sean referenciados a través de manifiestos; lo que le permite abstraer la ubicación / mecanismo de almacenamiento real de los activos a partir de las referencias a esos activos en el código. De esa manera, puede tener un solo tipo de referencia de activo en su código, y no tener que hacer la distinción entre rutas de archivo, ruta de archivo de archivo + desplazamiento o sub-activos.

MrCranky
fuente
1

Además de las otras respuestas, también hace que su código esté un poco más separado de sus activos. Podría, por ejemplo, permitir que un artista trabaje directamente con los archivos de manifiesto sin tener que hacer que un programador realice el cambio y realice una nueva compilación. Todo lo que se necesitaría sería cambiar el archivo de manifiesto para que apunte a una nueva imagen y simplemente volver a ejecutar el juego.

Dennis Munsie
fuente
0

Los archivos de manifiesto proporcionan una capa de indirección entre el nombre del recurso y su ubicación. Ofrecer capas adicionales de indirección es solo una señal de sobre diseño. Sin embargo, a veces esa capa adicional es lo que se necesita para construir una solución elegante y eficiente.

Aquí hay un ejemplo concreto simple donde la separación de nombre / ubicación del recurso me ayudó. Mientras estoy en desarrollo, mis activos artísticos están en control de revisiones con código fuente. Es muy conveniente y me permite iterar rápidamente. Por lo general, el nombre del recurso refleja su ubicación. El manifiesto de desarrollo es muy sencillo.

No quiero distribuir un juego con los activos dispersos. Entonces, cuando estoy listo para distribuirlo, puedo comprimir fácilmente mis activos en un archivo de recursos y crear un nuevo manifiesto.

También los atlas de texturas son una excelente manera de extraer un poco más de rendimiento del sistema gráfico. Los atlas son rápidos, pero es difícil trabajar con ellos mientras el arte aún está en desarrollo. Mi solución es construir solo el atlas al final cuando estoy optimizando el juego. Como estoy usando manifiestos, todo lo que necesito hacer es actualizar el manifiesto para que apunte a una ubicación de atlas y listo, el juego ahora está usando atlas en lugar de archivos directos.

código_deft
fuente