La clase que se encarga de mantener el control de la aplicación en su nivel más bajo es Controller, ya que mantiene una relación con el objeto NSApp. Esto implica que un objeto Controller se encarga de establecer las interacciones entre el ambiente de trabajo (del sistema y de la aplicación) y la parte de control del objeto red de Petri (PNController). Esta clase también se encarga de manejar al menos un panel (el panel Tools), además puede manejar otros paneles como Inspector y Preferences, y mantiene una relación con un objeto PNInspectorController. Los objetos de la clase Controller tienen una relación con cero o más objetos PNController --esto es porque se puede tener la aplicación cargada sin ningún documento abierto, o con varios--.
Esta clase se encarga de atender los mensajes que manda el usuario a través del menú principal. Se ha mencionado que las redes de Petri se manejaran como documentos, así pues, el objeto Controller atiende mensajes que provienen del menú que manejan documentos para crear, abrir, salvar e imprimir documentos (redes de Petri). También mantiene opciones para desplegar los paneles Preferences e Inspector, para controlar aspectos generales y particulares de una red de Petri.
Sólo se crea un objeto de la clase Controller cuando se ejecuta PetrA. Este objeto tiene varias variables de instancia y métodos sender-target:
@interface Controller : NSObject { id tools; //Identificador del panel Tools id currentDoc; //Identificador del documento actual id infoPanel; //Identificador del panel Info id preferencesPanel; //Identificador del panel Preferences id inspectorPanel; //Identificador del panel Inspector id inspector; //Identificador del controlador del Inspector ... Class currentGraphic;//Identificador de la clase de herramienta } - (void)newDoc:(id)sender; - (void)openTheFile:(id)sender; - (void)showInfoPanel:(id)sender; - (void)showInspectorPanel:(id)sender; - (void)showPreferencesPanel:(id)sender; - (void)setCurrentGraph:(id)sender; ... @end
Los identificadores tools, infoPanel, preferencesPanel e inspectorPanel hacen refrencia a los paneles que llevan el nombre del identificador. El identificador currentDoc hace referencia al documento actual de trabajo. Cuando un usuario crea o carga un nuevo documento, entonces este identificador hace referencia a él. Cuando un usuario cambia de documento de trabajo con el ratón (se puede tener múltiples documentos abiertos al mismo tiempo), el objeto delegado de la ventana asociada al documento (que es el controlador de un documeto red de Petri: PNController), se encarga de enviarle un mensaje al objeto Controller, indicándole que ahora el documento actual (currentDoc) es el que a recibido el evento de ratón.
El identificador inspector hace referencia el objeto controlador del panel Inspector donde se muestran los artibutos principales de los objetos que componen la red de Petri (lugares, transiciones, arcos y la misma red de Petri). Debido a que la información que muestra este panel cambia dinámicamente conforme el usuario trabaja con la red de Petri, los objetos PNController mantienen una comunicación indirecta con este objeto, a través del objeto COntroller.
El identificador currentGraphic hace referencia a la clase del objeto de la red de Petri, que corresponde a la herramienta que selecciona el usuario cuando elige el elemento gráfico, en el panel Tools. Esta referencia a la clase se mantiene con el nombre del icono que representa al objeto gráfico y el nombre de la clase. Por ejemplo, si se selecciona en el panel Tools, el icono correspondiente a un objeto Place, el icono tiene el nombre Place, que también corresponde con el nombre de la clase del objeto que se va a agregar a la red de Petri. Esto permitirá a los usuarios que deseen incorporar nuevos objetos que se elijan desde el panel Tools, para utilizarse en la red de Petri, que sólo tengan que incorporar un botón con un icono con el nombre de la clase que van a agregar, en el panel Tools, e incorporar al proyecto PetrA, los archivos de la clase correspondiente. Esto es, PetrA reconocerá automáticamente a la nueva clase y no se deben agregar líneas de código para reconocerla.
PetrA responde a los eventos que le envía el usuario a través del menú de la aplicación, con sus métodos sender-target, los cuales actúan de la siguiente manera:
1 - (void)setCurrentGraph:(id)sender { 2 id cell; 3 NSString *className; 4 cell = [sender selectedCell]; 5 if ((className = [[cell image] name])) 6 currentGraphic = NSClassFromString(className); 7 else 8 currentGraphic = nil; 9 }
En la línea 4 se oberva que en la variable cell se almacena la referencia al objeto que recibió el evento de ratón (los botones con los iconos de los objetos gráficos están agrupados en un objeto NSMatrix). La línea cinco muestra que se extrae el nombre de la imagen asociada al botón y se almacena el nombre en el objeto cadena referenciado por className. Después, en la línea 6 se actualiza el valor de la variable instancia currentGraphic, del objeto Controller, con el contructor de la clase del objeto seleccionado. Si no se encuentra una clase que corresponda con el nombre de la imagen, entonces currentGraphic tendrá el valor nulo (en el caso de Objective C:nil).