Inicializando el Motor
De CursosGpl
En esta primera parte del tutorial se muestra como realizar la inicialización básica del motor, sin llegar a mostrar nada por pantalla, simplemente se crea la ventana y podemos salir presionando "esc", todo en un solo archivo .cpp de 76 líneas (incluidas cabeceras y comentarios, en realidad es mucho menos).
Vamos a ver paso por paso todo el proceso, que consiste en inicializar una serie de componentes del motor.
Tabla de contenidos |
[editar] Conceptos
[editar] csInitializer
En esta primera parte del turorial utilizaremos este objeto para casi todo. csInitializer es una clase diseñada para ayudarnos a inicializar el motor.
[editar] Plugins
Lo más importante en esta parte es comprender que crystal tiene una arquitectura modular y que es importante indicar qué módulos cargaremos, ya que la mayoría son opcionales. Se pueden cargar en cualquier momento, pero si sabemos que los vamos a utilizar lo más apropiado es cargarlos ahora, utilizando la ayuda que nos proporciona csInitializer y el gestor de configuración.
[editar] Programación
[editar] Crear el Entorno de Crystal
Lo primero es crear una serie de elementos básicos del motor (el Registro de Objetos, el Gestor de Plugins, la cola de Eventos, el reloj Virtual, el parseador de linea de Comandos, el gestor de configuracion, los drivers de input).
Todo esto se puede hacer con una sola función de la clase de ayuda csInitializer,CreateEnvironment, pasándole los parámetros de entrada de la main.
object_reg = csInitializer::CreateEnvironment(argc,argv)
[editar] Iniciar el Gestor de Configuración
Lo siguiente es indicar al gestor de configuración el archivo que queremos usar. En este archivo podemos especificar plugins que queremos utilizar en la aplicación, así como diferentes variables que luego podremos leer desde el programa.
Este paso no es estrictamente necesario a estas alturas del tutorial, pero simplifica mucho la inicialización del motor, y con esto ya está todo dicho.
Para este paso volvemos a utilizar una función de csInitializer
csInitializer::SetupConfigManager(object_reg, "/config/walktest.cfg");
[editar] Pedir los plugins necesarios al motor
En este paso pedimos al motor que cargue una serie de plugins ampliamente utilizados, además de todos los indicados en el fichero de configuración. Le podemos pedir más plugins, pero aquí no es muy operativo, ya que podemos definir en el fichero de configuración los que necesitemos, así que no le pasamos nada más.
csInitializer::RequestPlugins (object_reg,CS_REQUEST_END)
[editar] Chequear los parámetros del programa
Ahora le tenemos que pasar a crystal space los parámetros del motor para mostrar ayuda en caso de que se haya pasado la opción -help. Además en este caso tenemos que salir del programa.
if (csCommandLineHelper::CheckHelp (object_reg))
{
csCommandLineHelper::Help (object_reg);
return false;
}
[editar] Iniciar el sistema principal
Ahora ya solo nos queda un último comando para arrancar propiamente todos los plugins pedidos al motor (les envía el evento cscmdSystemOpen).
csInitializer::OpenApplication (object_reg);
[editar] Definir un Gestor de eventos
Ya está todo inicializado, ya solo nos queda definir un gestor de eventos para poder responder a distintos eventos del motor antes de entrar en el loop principal de CrystalSpace.
En este caso simplemente vamos a responder a la tecla ESC y 'q' para salir del programa.
La rutina de gestión de eventos:
bool GestionaEvento (iEvent& ev)
{
if (ev.Type == csevKeyboard &&
csKeyEventHelper::GetEventType (&ev) == csKeyEventTypeDown &&
csKeyEventHelper::GetCookedCode (&ev) == CSKEY_ESC)
{
csRef<iEventQueue> q (CS_QUERY_REGISTRY (object_reg, iEventQueue));
if (q)
q->GetEventOutlet()->Broadcast (cscmdQuit);
return true;
}
return false;
}
Registramos la función:
csInitializer::SetupEventHandler(object_reg, GestionaEvento);
[editar] Entrar al loop de eventos del motor
Lo último es lanzar el loop principal de crystal space. A partir de entonces el motor pasa a controlar la aplicación y la única forma que tendremos de hacer algo es a través de la rutina de gestión de eventos que hayamos definido (por eso era importante hacerlo antes).
csDefaultRunLoop (object_reg);
[editar] Salir de la aplicación
Lo único que queda es cerrarlo todo antes de salir del programa (mandar a todos los sistemas el evento cscmdSystemClose)
csInitializer::DestroyApplication (object_reg);
[editar] Código c++
[editar] Cabecera
#include <cssysdef.h> //debe estar en todos los .cpp #include <iutil/objreg.h> //por el puntero a iObjectRegistry #include <cstool/initapp.h> //Por el csInitializer #include <csutil/sysfunc.h> //por el csDefaultRunLoop #include <csutil/event.h> //por csKeyEventHelper & CO #include <iutil/eventq.h> #include <csutil/cmdhelp.h> //por el csCommandLineHelper
// CS_IMPLEMENT_APPLICATION debe estar al principio de uno de los ficheros de código CS_IMPLEMENT_APPLICATION
// Puntero al registro de objetos iObjectRegistry* object_reg;
[editar] GestionaEvento
bool GestionaEvento (iEvent& ev)
{
if (ev.Type == csevKeyboard &&
csKeyEventHelper::GetEventType (&ev) == csKeyEventTypeDown &&
csKeyEventHelper::GetCookedCode (&ev) == CSKEY_ESC)
{
csRef<iEventQueue> q (CS_QUERY_REGISTRY (object_reg, iEventQueue));
if (q)
q->GetEventOutlet()->Broadcast (cscmdQuit);
return true;
}
return false;
}
[editar] main
int main(int argc, char const* argv[])
{
int error = 0;
//Crea el Registro de Objetos, el Gestor de Plugins, la cola de Eventos,
//el reloj Virtual, el parseador de linea de Comandos, el gestor de
//configuracion, los drivers de input
object_reg = csInitializer::CreateEnvironment(argc,argv);
//Configura el Gestor de Configuracion indicandole el fichero de configuración.
error = csInitializer::SetupConfigManager(object_reg, "/config/walktest.cfg");
// Carga los plugins
error = csInitializer::RequestPlugins (object_reg,CS_REQUEST_END);
// Chequea la linea de comandos por se pide ayuda
if (csCommandLineHelper::CheckHelp (object_reg))
{
csCommandLineHelper::Help (object_reg);
return false;
}
//Inicia el sistema principal
error = csInitializer::OpenApplication (object_reg);
// Define el gestor de eventos
error = csInitializer::SetupEventHandler(object_reg, GestionaEvento);
// El loop principal
csDefaultRunLoop (object_reg);
// Cuando termina el loop limpiamos la aplicación
csInitializer::DestroyApplication (object_reg);
return 0; }

