genbetadev / Genbeta-Dev-Engine

Desarrollo de un Game Engine básico sobre C++ y SFML 2.1
MIT License
63 stars 32 forks source link

Crear sistema de Log para el Engine #20

Open adrigm opened 11 years ago

adrigm commented 11 years ago

Sería bueno crear un archivo de Log que registre la actividad del engine, pero sin hacer uso de librerías externas y sin complicarlo demasiado.

InExtremaRes commented 10 years ago

@rickyah Comprendo completamente lo que dices y tu preocupación. Estoy de acuerdo contigo cuando dices que el sistema sigue haciendo cosas innecesarias, como la llamada al método y el retorno de un objeto temporal. Pero ni te imaginas la de veces que esto se hace en el STL o librerías como Boost. Por supuesto que es un ejemplo un poco descabellado (son proyectos inmensos comparados con el nuestro), pero el costo de la llamada y del retorno del objeto no es preocupante. En lo que sí coincido contigo completamente es que las constantes (como el texto) se mantendrían en el ejecutable final, lo cual se soluciona con la macro.

Pero ambas propuestas se pueden mezclar pefectamente. Solo que yo mantendría el retorno del objeto temporal dado que el destructor puede realizar acciones sobre la cadena que no son posibles si se expone directamente el stream:

LOG_INFO("etiqueta", "hola" << "mundo");

que se expanda en:

GDE::Log::info("etiqueta") << "hola" << "mundo";

o se expanda en nada en los otros builds.

Cuando la línea acabe, el objeto temporal creado por Log::info() se destruye, pero ya tiene toda la cadena completa y no solo trozos. Cualquier manipulación se podría realizar ahora sobre la cadena completa, incluyendo el colocar un salto de línea, volcar el buffer del archivo o cerrarlo si es que se quiere abrir y cerrar por cada línea.

adrigm commented 10 years ago

Yo comenté eso al principio de este hilo, que hacíamos en modo Release. Algunos dijeron que era mejor que el log se generara incluso en modo Release como fuente de información para el usuario si algo fallaba. Por eso no se planteó que hacer en modo Release, pero si ahora queréis eliminarlo del modo Release, adelante.

rickyah commented 10 years ago

@InExtremaRes estoy de acuerdo excepto en lo de un objeto temporal, eso de estar creando y liberando memoria cada vez que haces un log me parece un killer y una manera preciosa de fragmentar memoria. Usar el destructor para hacer un flash tampoco me parece eficiente, si preocupa hacer el flash al final para eso hacemos que la macro sustituya por:

GDE::Log::info << "hola" << "mundo" << std::flash;

@adrigm No es excluyente, podemos hacer una build release con log y otra sin él. De hecho tampoco es raro tener una build release con el código optimizado, con los logs, asserts, etc, y otra Release ya con todo quitado (que llamaríamos Producción, por ejemplo)

InExtremaRes commented 10 years ago

@rickyah Por supuesto que se puede hacer sin el objeto temporal, pero te equivocas en lo de la fragmentación de la memoria. Un objeto temporal retornado por valor no usa el heap, se coloca y se quita de la pila, memoria que se reutiliza y está reservada por el sistema operativo desde el inicio del proceso. Si fuera por eso, nadie usaría iteradores en bucles for como si nada. Quien por supuesto utiliza el heap es el string (que debe crecer indefinidamente), pero ese es un problema inherente a menos que se utilicen strings de largo fijo. Fuera de eso, el costo de llamar al constructor y al destructor, en este caso, es similar a llamar a cualquier método (sumándo el incremento y decremento de la pila), y es similar al costo que se tiene con las llamadas actuales que genera la clase Log, es tan solo una forma más abstracta.

rickyah commented 10 years ago

@InExtremaRes había entendido que generabas el objeto con memoria en el heap, vamos que ::info() por dentro hacía un new. En ese caso no hay problema.

InExtremaRes commented 10 years ago

Ahora bien. Aun nadie se pronuncia en si les interesa que modifique el sistema para usar streams. Puedo hacer una propuesta y mi rama y presentarla para su evaluación.

@rickyah Tu idea de la macro nos permite, además, poder registrar el nombre de archivo, la función y la línea en caso de que se requiera. Puede ser útil en los logs de error para encontrarlos con rapidez.

adrigm commented 10 years ago

@InExtremaRes, haznos tu propuesta. Yo estoy a favor del uso de Streams, es más natural en C++. Sería un lujo añadir a los erres archivos y líneas para saber que ha fallado

RdlP commented 10 years ago

Yo estoy a favor del cambio, así de paso aprendo.

P.D De todas maneras también creo que deberíamos dejar cosas zanjadas porque sino no avanzamos, y el sistema de log que se diga no es del todo crucial para el engine en general.

danigomez commented 10 years ago

Idem @RdlP, por lo que puedo ver de usar streams es que evitamos la preocuparnos de las conversiones, lo que seguramente, a la larga simplificaria los logs. No se si esa es la única ventaja ...