Sistema de Plugins - plaa/Modular GitHub Wiki

Table of Contents

El problema

Hay muchos casos en los que es deseable añadir una característica a OpenRocket que puede ser muy util en un contexto específico, pero que no sería apropiado insertar en el código fuente de OpenRocket. Por este motivo, sería adecuado disponer de algún tipo de Plugin, tal como sucede con otras aplicaciones.

En nuestro caso, nos referimos a los Plugins como algo que se instala en el ordenador del usuario y que OpenRocket pueda encontrar para proporcionarle funcionalidades adicionales.

La funcionalidad podría consistir en Extensiones de la simulación, nuevos tipos de motores, etc.

Requisitos

  • Configuración : Debe ser posible configurar Plugins a través de la GUI de OpenRocket. Esto debe hacerse de forma coherente, como un menú de plugins en el que se listan todos los Plugins. Debe quedar claro para el usuario que funcionalidad es parte del Plugin y qué otras funcionalidades forman parte del código fuente de OpenRocket.
  • Detección automática : El usuario no tiene que modificar el camino hasta la clase o nada parecido para utilizar los Plugins. Probablemente la solución más sencilla sería que los Plugins pudieran ser descargados por el usuario y ubicados manualmente en un directorio de Plugins desde donde puedan cargarse automáticamente al iniciar la ejecución de OpenRocket. En un a fase posterior, alguna de las funcionalidades automáticas deben agregarse a la GUI de OpenRocket.
  • Soporte de localización.
  • Modificación de la simulación : como en las Extensiones actuales de la simulación, pero más extensas y con datos extra mejor integrados.
  • Modificación del árbol de diseño del cohete : los cambios aplicados autimáticamente a la figura del cohete, y otras ayudas como fuera necesario.
  • Componentes personalizados (Discusión) :
  • Gestión de la dependencia : Algunos Plugins pueden depender de otros y ser capaces de cargarlos automáticamente. Esto a su vez requiere que los Plugins tengan un identificador /URI coherente, y un número de versión.
  • Plugins implementados en otros lenguajes de programación (Discusión) :
  • Acceso simplificado a la documentación de OpenRocket : El autor de un Plugin debe tener acceso directo a los elementos más utiles del documento de OpenRocket. Por ejemplo, cosas tales como el componente actual seleccionado, o mostrar un cuadro de diálogo personalizado. Estas cosas deben ser posibles mediante la navegación a través de una compleja estructura de clases; esto puede requerir métodos ocasionales de ayuda.

Anti-requisitos

(Discusión)

Implementación

Marcos de Plugins

Existen diferentes marcos de Plugin en java, y pueden reducir significativamente el tiempo necesario para implementar la característica del Plugin.

Codificar directamente el Plugin requiere que la nueva interfaz amplíe la interfaz del Plugin, y agregue las anotaciones a la clase de implementación. Esta es una solución simple y rápida que bien puede realizarse.

Entre los marcos de Plugins que existen, el más interesante es el JSPF (http://code.google.com/p/jspf/). Aquí tan sólo tendrá que declarar "load all JAR files from this

directory as plug-ins" y "add all plug-ins from the current classpath". Entoces puede encolar los Plugins utilizando diferentes métodos. Parece muy sencillo de utilizar, posee interfaces puros y planos, y los propios Plugins se construyen implementando la interfaz y agregando algunas anotaciones.

El JSPF también funciona con Android, aunque el sistema descubrimiento es algo disfuncional, y necesitará listar todas las clases del Plugin explicitamente(http://code.google.com/p/jspf/wiki/RunningOnAndroid). Esta debe ser correcta, necesitamos tener una implementación adicional para Android que liste los Plugins necesarios para las funcionalidades básicas. No veo que eso sea un problema si algunas de las Extensiones no existen en Android.

Se han considerado también otros marcos de Plugins:

  • La clase Serviceloader + el script de arranque. Es fácil incorporarlo, pero necesitamos implementar el sistema de Plugin nosotros mismos.
  • El JPF (http://jpf.sourceforge.net/), parece más personalizable y configurable que el JSPF, pero no estoy seguro de que necesitemos realizar un esfuerzo extra. Parece estar funcional, pero la útima actividad que tuvo fue en el 2007.
  • El OSGi (http://en.wikipedia.org/wiki/OSGi), es un mecanismo de descubrimiento del servicio más pesado, semejante (o utilizado por) el sistema de Plugins de Eclipse.
  • El Sistema Modular de Java (JSR 277), se pensó para su inclusión en Java7, pero al final no se llevó a cabo. Parece estar un poco inactivo (desde finales del 2006) y parece ser que han incluido algunos cambios en el lenguaje.

Un diseño áspero (desde el punto de vista de los programadores de Plugins)

Operación general:

El nombre para cada Plugin corresponderá a un item en el menú de Plugins. Los subitems de cada item en el menú de Plugins, se generarán automáticamente de la siguiente forma:

  • Acerca del Plugin: construye un casillero "Acerca de", disponible para todos los Plugins.
  • Para cada modificador "activable", se generará un casillero para marcar de la forma [X] Activar <nombre_del_modificador></nombre_del_modificador>. Cuando se marque, se invocará al método activador del modificador. Esto sería lo necesario para modificar OpenRocket y ejecutar el código del Plugin, por ejemplo: hacer que la simulación siempre cargue el modificador de la simulación.
  • Para cada modificador "configurable", se generará un item que abre la ventana de configuración.
  • Cualquier item adicional en el menú definido en cada modificador. Por ejemplo, un modificador del cohete deberá tener un item que cambie el componente seleccionado de alguna manera.
Diseño del código:
 Interfaz del Plugin:
  - Nombre, versión, URI, fecha, autor, licencia, descripción.
  - Lista de dependencia de los Plugins URI y versiones.
  - Lista de los Plugins URI en conflicto y versiones.
  - Lista de modificadores.
 Las clases abstractas ''AbstractPlugin'' que implementan las Plugins:
  * Todo lo necesario para la carga, el menú de configuración, traducciones, etc.
  - ''getSetting(&lt;tecla&gt;&lt;/tecla&gt;)'', ''setSetting(&lt;tecla&gt;&lt;/tecla&gt;, &lt;valor&gt;&lt;/valor&gt;)'' : Un mecanismo sencillo para almacenar localmente diferentes configuraciones.
  - ''getFile(&lt;nombre_de_archivo&gt;&lt;/nombre_de_archivo&gt;)'', ''storeFile(&lt;nombre_de_archivo&gt;&lt;/nombre_de_archivo&gt;)'', ''rmfile(&lt;nombre_de_archivo&gt;&lt;/nombre_de_archivo&gt;)'' : Un mecanismo sencillo para almacenar localmente los archivos en la caché, etc.
 Las clases estáticas ''MyPlugin'' que extienden a la clase ''AbstractPlugin'':
  * La implementación de los usuarios.
 Los archivos:
  messages_?.properties : Traducciones a utilizar, dentro del Plugin jar.
 Modificador de la interfaz:
  - Plugin ''this modifier is a member of''
  - Booleano ''enable''
  - Los métodos enable(), disable()
  - Booleano configurable
  - Configurador
  - Items adicionales del menú y acciones
 Clase abstracta '' RocketModifier'' que implementa el Modificador:
  - Los métodos enable(), diasble() :
  - El método getSelectedComponent() : devuelve el componente del cohete actualmente seleccionado.
  - El método onChange() : que se invoca cuando un componente se ha modificado.
  * Diferentes métodos de ayuda según sea necesario.
 Clase estática ''MyRocketModifier'':
  * La implementación de los usurios o algo que modifique el diseño del cohete
 Clase estática ''MySimulationModifier'' que extiende a la clase "AbstractSimulationModifier'':
  * La implementación de los usuarios.
 Configurador de la clase abstracta:
  Una clase que genera automáticamente una ventan de diálogo de configuración estándar con una lista sencilla de variables y selectores. las variables deberán guardarse automáticamente cuando se haga clik sobre el botón '''OK''', empleando el Plugin con el método ''setSettings()''.
⚠️ **GitHub.com Fallback** ⚠️