Open ArnauPrat opened 10 years ago
Que os parece hacer que el gestor de recursos vaya a una nueva rama develop hasta que esté completo? Creo que aún tiene bastante que madurar y cambiar porque va a ser parte importante del engine.
Estoy de acuerdo con @adrigm dado que es algo que va para largo y creo que es clave para el proyecto. Respecto a lo que comenta @rickyah , siempre tengo 1000 problemas para dar nombre a la funcion deinit/release o como sea. En este caso usé deinit por una simple cuesitión de simetria y coherencia con alguna otra clase ya existente en el proyecto ( que usa init para inicializar ). Yo normalmente uso StartUp/ShutDown...
Al respecto, creo que estaría bien definir una convención concreta para nombrar a los métodos init / release, y aplicarlo siempre Yo indicaba la de dispose, por que es la que usa C#. Ya voy avisando que soy bastante fan del lenguaje, me parece muy bien pensado (que no perfecto) pero este es uno de los casos en los que no importa tanto qué nombre elijamos mientras lo apliquemos de forma consistente
yo utilizo init y cleanup, es como está implementado en App y en el SceneManager. En señal de inicialización y tareas de limpieza.
Pues propongo usar como convencion el formato init/cleanUp que usa @adrigm . Estaria bien actualizar la wiki.
Acabo de actualizar la wiki con esa convención
@ArnauPrat, A mi lo que no me acaba de convencer es tener un objeto para cada tipo de recurso, es decir un textureManager, soundManager, ...
No sería mejor algo integrado?
Más que un ResourceManager en realidad es un Resource.
Es decir, en mi opinión, habría que tener un ResourceManager
que gestiona todos los recursos, y luego una clase base virtual Resource, que los únicos métodos que tendría serían para cargar eliminar el recurso.
Luego, para cada recurso que queramos añadir, simplemente hay que hacer una clase derivada de Resource para gestionar cómo debe gestionarse dicho recurso (cargar los datos, o hacer un release)
El ResourceManager entonces sólo se encarga de gestionar, comprueba que un recurso no se carga dos veces, etc, pero no sabe nada de cómo cargarlo, ni siquiera sabe el tipo de dato que carga.
Esta es la idea:
Esto ya está casi así de hecho.
Buenas, antes de nada, buen trabajo! Esta es la primera vez que comento y me gustaría hacer algunos apuntos en cuanto al API de esta clase.
Creo que añadir el nombre Resource a cada método es algo redundante, puesto que la clase ya se llama ResourceManager podría omitirse y así acortar los nombres, en mi opinión ya se sobre entienden.
Propongo esta interfaz:
ResourceManager
public:
- init()
- cleanUp()
- get(string fileName);
- delete(string fileName);
protected:
- T* load(string fileName)
- void release(T* resource)
Un ejemplo:
ResourceManager resourceManager = new ResourceManager();
resourceManager.init();
Resource *resource = resourceManager.get('Data/textures/bird.jpg')
...
resourceManager.delete('Data/textures/bird.jpg')
...
resourceManager.cleanUp();
@rickyah, tú método es lo que había pensado, pero como hacemos que se nos devuelva un recurso? Me explico:
Tu tienes tu clase Abstracta Resource que heredan todos los tipos de recursos y que tendrá sus métodos virtuales puros Load, Cleanup, ... que cada recurso implementará convenientemente, hasta ahí bien.
Ahora como gestionas el recurso pedido para que devuelva un recurso adecuado, no puedes tener un método Get genérico ya que cada recurso devolverá un tipo de dato distinto.
Yo hago mi propuesta que era algo así:
https://gist.github.com/adrigm/7405117
Es algo rudimentario, pero creo que es simple. Su utilización sería:
AssetManager* am = AssetManager::instance();
sf::Texture *t = am->getTexture("data/player.png");
El AssetManager se encargaría internamente de comprobar si ya está cargada y devolver el puntero adecuado, o si no, cargarla y devolver el puntero. En caso de no poder cargarla podría devover una textura vacía por defecto impidiendo que falle el engine.
Yo así lo veo perfecto @adrigm y pondría el path en el init.
Por cierto los parámetros con el "the" delante entran en la guía de estilo? Es que he visto que por el ejemplo la clase Log no utiliza esta "convención"
@titoneo, es de un antiguo proyecto mío en lo que lo usaba. Como veáis si lo metemos en la guía o lo descartamos para todas las clases.
Podríamos include tener algo como
addPath("...")
para que el usuario añada varias carpetas donde quiere buscar recursos
Con templates y castings se puede hacer bien, y es más extensible que la solución que propones. Estoy haciendo un POC
@rickyah, en que sentido sería más extensible?
Generas tu clase Resource que sepa como cargarlo, y ya puedes usarlo en el resource manager. Con tu idea hay que añadir un nuevo método por cada recurso, y que el ResourceManager se encargue de gestionar los recursos y además de cargarlos borrarlos según el tipo de recurso podría ser visto como tener dos responsabilidades.
Yo de todas maneras acabo mi idea y os la pongo por un gist, guste o no, se meta o no al final, algo aprenderé y así lo debatimos, que al final es de lo que va todo esto :)
@rickyah Sí, esa es la pega de mi método que si se quieren añadir nuevos recursos hay que tocar el AssetManager. Veamos la que nos planteas tú!
Puede que tarde un poco, que tengo c++, y sobre todo las templates oxidadas :(
Aquí está el gist con mi prueba de concepto. Está hecho mal y pronto, pero es para mostraos qué os parece antes de irme a la cama
Buenos dias, La arquitectura que proponeis, está bien. Pero cuando pensé en como hacer el gestor de recursos, la descarté principalmente por los siguientes motivos:
Aun así, he de reconocer que no son diferencias cruciales/determinantes, así que si lo creeis conveniente, adelante.
Mi opinión a tus consideraciones:
Gracias @rickyah , estoy de acuerdo con tus observaciones.
Personalmente a mi, de las 3 propuestas que se han hecho, @adrigm @ArnauPrat y @rickyah la que más me convence es la de @rickyah puesto que creo que es la más sencilla y mas potente a la hora de extender su funcionalidad.
La de @adrigm le veía fallos a la hora de tener que añadir un nuevo recurso, que habría que modificar la clase y añadir métodos y la propuesta de @ArnauPrat le veo el fallo de tener un manager por cada tipo de recurso
@RdlP votas por la de @ArnauPrat o por la de @rickyah ?
A mi de las 3 (incluida la mía) la que más me convence por ahora es la de @rickyah, claro está con los consecuentes ampliaciones para manejo de rutas y demás.
Perdón, me he equivocado en el comentario, quería decir que la más simple y extensible me parece es la de @rickyah así que voto por ella.
P.D Voy a modificar mi comentario anterior para expresarme bien.
La versón de @rickyah es objetivamente la mejor teniendo en cuenta las necesidades actuales, así que optaria por ella.
Esta noche iré mirando como mejorarlo, ya que como dije ese código esta hecho de cualquier manera y hay bastante que discutir, por ejemplo el hecho de que pidas un recurso con el tipo y te devuelva un puntero a ese tipo :P
Si no lo he entendido mal, realmente ya estás devolviendo un puntero al recurso del tipo, GDE::ImageResource. Lo que pasa es que implementamos GDE::ImageResource usando sf::Texture, de ahi que tengamos que usar el getData, correcto? Si la implementación Texture fuera nuestra, el getData no haria falta, me equivoco?
Me refiero a que haces resourceManager->getResource<AResource>("id1");
y esa llamada en realidad devuelve un AResource*
Quizá lo mejor sería devolver una referencia, que para devolver un puntero tengas que pedirle el puntero, (resourceManager->getResource<AResource*>("id1");
)
Se podría discutir a ver qué es lo más claro.
Sí, dado que los objetos SFML reciben referencias no punteros. Sería mejor devolver referencias a menos que se pida un puntero.
Oído! Aunque me temo que de momento dejaré que devuelva siempre una referencia, y cuando pueda desempolvo el Modern C++ design para saber cuando un tipo parametrizado es un puntero :P
@rickyah mejor aún!
Que pensáis sobre los nombres de las funciones? No os parecen mejor sin la palabra resource en cada uno?
Quiero decir, en la clase ResourceManager veo bien que se le añadan, por ejemplo: registerResource Pero en las clases Resource y sus subclases creo que estarían bien bonicas sin el nombre.
A mi me parece bien sin la palabra resource, pero entonces nombrar bien la variable de la instancia del manager:
Así si :+1:
ResourceManager resourceManager = new ResourceManager();
resourceManager->get<ImageResource>()
Así no :-1:
ResourceManager rm = new ResourceManager();
rm->get<ImageResource>()
Yo usaría más la palabra Asset que Resource. Resource los usan los sistemas para otros menesteres como iconos de la aplicación, manifiests... Además que Asset es más corto que Resource que puede parecer tonto, pero es una consideración.
En cuanto al uso reduandante de la palabra Asset/Resource estoy de acuerdo en que se puedo omitir. Yo usaria
assetManager->get
Mmm, yo preferiria que si diga Resource, creo que le da legibilidad al código, y que solo diga "get()", se me hace corto, :P además la mayoria de lo IDEs tienen autocompletado por lo que no se gana tiempo de tipeo digamos :P, Es decir, si se entiende qeu es lo que hace el método, no habría inconveniente en omitir Resource, por lo que es importante que usemos bien la nomenclatura de las variables y los tipos!!!
A parte de que forma sea más clara, os diré que, a menos desde mi punto de vista, me interesa que se haga uso de templates y formas de diseño avanzadas para aprender.
Usar clases de forma básica no es complicado, más bien es lo sencillo, lo realmente interesante y que cuesta es usar bien los templates y tener claras ciertas estructuras y su utilidad, por lo que veo muy interesante que cuando se haga el gestor de recursos, se explique por que de cada cosa y como funciona.
Soys unos cracks! :)
Ojo cuidao que los templates pueden ser un peligro, por un lado para entenderlos, que la metaprogramación con templates puede ser muy oscura. Y además pueden hacer subir el tiempo de compilación un huevo y la yema del otro.
Pero puestos a enfangarnos podemos empezar por aquí: http://loki-lib.sourceforge.net/
Hay una muy buena página para lo básico de C++03, y está en español!, http://c.conclase.net/curso/index.php, tiene ejemplos sencillos de practicamente todo el lenguaje, manejor de excepciones, templates, herencia etc etc. PD: si es tremendo offtopic pero en fin jaaj
Qué pasa con esto al final??, se va a mergear o no?? Así vamos creando el módulo que corresponde según la nueva organización y seguimos avanzando con el proyecto... que parece que está muriendo un poco...
Mañana voy a poner al día un poco el proyecto y a organizarlo un poco mejor, no sé si @rickyah al final se ha puesto o no, si no lo ha hecho hay que ponerse ya para como bien dices avanzar. Necesitamos empezar a organizarnos mejor para que el proyecto no se pare cuando alguno no esté disponible como ha sido mi caso estas últimas semanas.
Yo también he estado un poco ocupado pero ahora tengo vacaciones.
Voy a mirar cómo hacer todo esto por que mi solución usa RTTI (dynamic_cast), y eso tampoco suele ser aceptable.
@rickyah Qué es lo qué estás tratando de solucionar?? Así me lo pongo a ver también :P y de paso me voy metiendo un poco más en el código del ResourceManager
A ver ni caso que no se ni donde vivo últimamente xD.
Cosas que hay que hacer: implementar el gist partiendo de master con la nueva organización del fichero.
Como no tengo nada hecho creare una rama en mi repo para ello y lo pondré aquí para que podáis mirarlo/clonarlo
Cuando lo tenga hecho hago un PR y lo revisamos
Lo que pasa que acabo de llegar hace 3 dias a mi tierra por vacaciones y claro, visitar a la familia por un lado, comilona por otro, chupito por otro lado y no da tiempo. Mañana empezaré a estar más liberado :)
@adrigm en otro orden de cosas, como eres editor de genbetadev, mírate gameinstitute.com Una web con un curso de programación de juegos que tienen varios proyectos incluido un engine con fuente incluido. Lo que mola es que por oferta te dan todo el material de los cursos, pero no el curso en sí, por $49 hasta Navidad. Míratelo x si quieres ponerlo en la web, y si necesitas preguntar algo ponme un Mail que yo ya lo compré
Implementación de un TextureManager usando el template ResourceManager, como ejemplo. Modificada App para que cargue una textura a modo de ejemplo.