CAAD

Comunidad de Aventuras Conversacionales y Relatos Interactivos
Fecha actual 23 Oct 2017 19:58

Todos los horarios son UTC + 1 hora




Nuevo tema Responder al tema  [ 16 mensajes ]  Ir a página 1, 2  Siguiente
Autor Mensaje
NotaPublicado: 21 Ago 2014 09:38 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Hola,

Existe alguna forma de incluir o importar una clase propia. Por ejemplo tener la siguiente clase; Imprimir.class

Código:
package MiPack;


public class Imprimir
{   
   public String escribe()
   {
       return "¡Hola mundo!";
   }
}


Y desde el mundo AGE hacer algo parecido a:

Código:
import MiPack.Imprimir;
...
...

k=new Imprimir();

....


Estoy mirando documentación de beanshell, pero no llego a encontrar nada. Puede que no llegue a sacarle utilidad a lo que pretendo o puede que sí, pero por lo menos me gustaría tener la posibilidad de probarlo.

¡Gracias!

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 21 Ago 2014 10:16 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5272
Ubicación: Coruña
No lo he llegado a probar nunca, pero me parece que deberías poder hacer imports como dices añadiendo cosas al classpath de BeanShell:

addClassPath( "/home/pat/java/classes" );

Lo que sí que sé 100% seguro que puedes hacer es cargar clases (ya compiladas) explícitamente mediante reflection:

name="foo.bar.MyClass";
c = getClass( name );
c = BshClassManager.classForName( name ); // equivalent

Esto sí que lo probé en su momento y va sin problemas, permitiéndote cargar cualquier clase.

Tienes todo ello descrito aquí:

http://www.beanshell.org/manual/classpath.html

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 21 Ago 2014 11:33 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Estuve visitando la página que me comentas e intenté con la opción:

addClassPath( "MyPack/" );
reloadClasses("MyPack.Imprimir");

Pero no logré hacerlo funcionar.

He probado ahora con:

name="MyPack/Imprimir";
c = getClass( name );
mobile("jugador").write("\n\n" + c + "\n\n");

Y me retorna NULL.

También modificando name="Imprimir"; o bien name="Imprimir.class", y siempre NULL.

La clase Imprimir.class la tengo en la misma carpeta donde tengo el world, también probé con otra carpeta dentro de donde está el world MyPack/... bueno varias combinaciones.

También probé:

addClassPath( "MyPack/" );
x = getClassPath();
mobile("jugador").write("\n\n" + x + "\n\n");
name="MyPack/Imprimir";
c = getClass( name );
mobile("jugador").write("\n\n" + c + "\n\n");

y el resultado es:

[Ljava.net.URL;@1fb42e6
null

Por lo que no sé si es que no sé donde ubicar la clase o debo cambiar el path... pero no doy con la tecla correcta.

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 21 Ago 2014 11:39 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5272
Ubicación: Coruña
El tema es que a addClassPath le tienes que pasar un path absoluto (en general, en Java, a todo lo que sea trabajar con classpaths o cargas de clases le tienes que pasar un path absoluto - lógico, porque los paths relativos tienen que ser relativos a algo, y en Java ese "algo" es precisamente el classpath, así que para modificar el propio classpath... pues los paths han de ser absolutos).

En AGE, puedes obtener el path absoluto a algo que está en el directorio del mundo con world.getResource("nombre.fichero"), y a algo del directorio del AGE con world.getGlobalResource("nombre.fichero").

Vamos, que para cargar clases puedes usar URL's como las que utilizas para cargar recursos del mundo.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 21 Ago 2014 12:38 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Vaya siento dar la paliza pero me sigue retornando null.

URL clases = world.getResource("MyPack/");

addClassPath( clases );
reloadClasses(clases + "Imprimir");
mobile("jugador").write("\n\n" + clases + "\n\n");
x = getClassPath();
mobile("jugador").write("\n\n" + x + "\n\n");
name=clases + "Imprimir.class"; // también he probado name=clases + "Imprimir";
mobile("jugador").write("\n\n" + name + "\n\n");
c = getClass( name );
mobile("jugador").write("\n\n" + c + "\n\n");

E imprime.

file:/home/edu/Aventuras/Proyectos%20Propios/Una20dragones%20versión%20AGE/world/MyPack/

[Ljava.net.URL;@15fa1ab

file:/home/edu/Aventuras/Proyectos%20Propios/Una20dragones%20versión%20AGE/world/MyPack/Imprimir.class

null

Lo dejo por hoy que me tengo que ir a trabajar. En cuanto tenga otro rato libre lo retomo.

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 21 Ago 2014 12:53 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5272
Ubicación: Coruña
Te has liado, a addClassPath le tienes que pasar un path (absoluto) porque es para añadir ese path al classpath, hasta ahí bien. Pero a getClass le tienes que pasar simplemente un nombre de clase ("Imprimir"), no un path. Precisamente la idea de que el path esté en el classpath es para no tener que andar pasando paths luego, las clases se cargan por nombre. Lo mismo con reloadClasses, tampoco le tienes que pasar de nuevo todo el path, sino un especificador similar al de los imports (está en el ejemplo del enlace de arriba).

Por cierto, la cadena rara [Ljava.net.URL;@15fa1ab es porque lo que estás imprimiendo es un array. Si quieres ver algo inteligible ahí, puedes imprimir cada uno de los elementos del array, desde 0 hasta length.

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 21 Ago 2014 15:18 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Vale, por fin conseguí algo. Tengo el problema que cuando me surge una duda me arde todo y no para de darle vueltas. Así que medio escaqueado me he puesto con ello.

Lo he conseguido de esta forma:

Código:
/*Introducción del juego para un jugador*/
void intro( Player aPlayer )
{
    //aPlayer: jugador al que le hacemos la introducción.

    aPlayer.write("Bienvenido a esta aventura...\n");   

    URL clases = world.getResource("Imprimir.jar");
    addClassPath( clases );   
    s = new Imprimir();
    aPlayer.write("\n\n" + s.escribe() + "\n\n");
}


La clase compilada la he tenido que empaquetar en un jar, en caso contrario no me dejaba. Imprimir.jar, está en la misma carpeta que el world.xml.

La clase Imprimir es:

Código:
public class Imprimir
{
   
    public Imprimir() {  }

    public String escribe()
    {
        return "Hola mundo AGE";
    }
}

Y este es el resultado:

Código:
Bienvenido a esta aventura...


Hola mundo AGE



La motivación para hacer esto, es que teniendo en cuenta que este año he tenido que estudiar Java, y para el próximo tendré otra asignatura un poco más complicada también en Java, pues poder practicar un poco a la vez que escribo alguna que otra aventura.

¡¡¡¡¡Gracias!!!!!!

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 21 Ago 2014 16:03 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5272
Ubicación: Coruña
Creo que con el directorio debería funcionar igual que con el jar, supongo que te fallaría por cualquier fallo tonto. En todo caso, con el jar mejor aún, que así las clases están comprimidas. Tienes todo el poder de Java en tus manos, a ver si haces algo chulo :P

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 21 Ago 2014 20:07 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Al-Khwarizmi escribió:
Creo que con el directorio debería funcionar igual que con el jar, supongo que te fallaría por cualquier fallo tonto. En todo caso, con el jar mejor aún, que así las clases están comprimidas. Tienes todo el poder de Java en tus manos, a ver si haces algo chulo :P


Ya te digo, acabo de hacer una prueba, con la práctica que tuve que hacer en Java, el juego de PacMan, y al teclear el jugador "jugar", te lanza el juego y te pones a jugar PacMan. :lol:

Lógicamente en un aventura no voy a poner a Jugar PacMan a ningún aventurero, pero si me da ideas de todas las posibilidades que se abren. :P

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 08 Nov 2015 09:13 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Puedo hacer esto de alguna manera...?¿

He creado la clase:

Código:
package agePrueba;

public class extenItem extends eu.irreality.age.Item {
   
   public extenItem () {
      super ();
   }
   
   public String  miItem () {
      return this.getBestReferenceName(true);
   }

}


Pero luego al llamarla desde AGE:

Código:
bsh.TargetError found at intro routine

**********BeanShell Runtime Error Report**********
*Error: java.lang.Error: Unresolved compilation problems:
   eu cannot be resolved to a type
   The method getBestReferenceName(boolean) is undefined for the type extenItem

*Location: inline evaluation of: ``/* *  * Redefinimos ciertos mensajes por defecto.  *   */ String getMessage ( St . . . ''
*Line: 133
*Offending text: new agePruebas .extenItem ( )
*Message: Sourced file: inline evaluation of: ``intro( arg0, arg1);'' : Object constructor
*Script stack trace:
Called from method: intro : at Line: 1 : in file: inline evaluation of: ``intro( arg0, arg1);'' : intro ( arg0 , arg1 )
*Exception was generated in native code. Stack trace follows: java.lang.Error: Unresolved compilation problems:
   eu cannot be resolved to a type
   The method getBestReferenceName(boolean) is undefined for the type extenItem

   at agePruebas.extenItem.<init>(extenItem.java:3)
   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
   at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
   at bsh.Reflect.constructObject(Unknown Source)
.....


No reconoce el tipo " eu.irreality.age.Item ". Intenté compilar con eclipse desde el propio proyecto de AGE que me descargué de git, pero da errores (no sé como hacerlo ), así que lo compilé desde un proyecto nuevo e independiente.

También supongo que debo usar otro constructor para el Item, he visto que existen:

Código:
public Item ( World mundo , String itemfile ) throws IOException , FileNotFoundException
   
public Item ( World mundo , org.w3c.dom.Node n ) throws XMLtoWorldException


Pero no sé lo que es "org.w3c.dom.Node n", ni "String itemfile".

EDITO:

Para ver si tenía el enlace con la clase compilada hice otra clase en el mismo proyecto:

Código:
package agePrueba;

public class Imprimir {

   public Imprimir() {
      // TODO Auto-generated constructor stub
   }

   public String comunicacion () {
      return "Comunicación ok";
   }
}


Y usando :

Código:

    URL clases = world.getResource("myItem.jar");
    addClassPath( clases ); 
    aux = new agePrueba.Imprimir();
    //oneItem = new agePrueba.extenItem ();   -> en cuanto quito el comentario de esta línea todo casca.

    mobile("jugador").write ( aux.comunicacion () );


E imprime correctamente el mensaje "Comunicación ok"

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 08 Nov 2015 12:04 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Siguiendo el post anterior...

ya conseguí compilar la clase que pretendo, la compilo dentro del proyecto de aetheria. No da errores al hacer la llamada desde AGE. Pero como he comentado en el anterior post no sé como usar el constructor de la clase, ya que al intentar acceder a algún método de la clase Item, salta la excepción.

Código:
URL clases = world.getResource("myItem.jar");
addClassPath( clases );
oneItem = new extenItem ();

// Aquí es cuando falla, cuando intento acceder a algún método de la clase Item (que extiende a Entity).
//oneItem.addSingularReferenceName("un nombre");
//mobile("jugador").write ( oneItem.myItem () );


_________________
Te quiero... lo siento Yoda sólo tenemos café.


Última edición por edlobez el 08 Nov 2015 12:05, editado 1 vez en total

Arriba
 Perfil  
 
NotaPublicado: 08 Nov 2015 12:05 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
edlobez escribió:
Siguiendo el post anterior...

ya conseguí compilar la clase que pretendo, la compilo dentro del proyecto de aetheria. No da errores al hacer la llamada desde AGE. Pero como he comentado en el anterior post no sé como usar el constructor de la clase, ya que al intentar acceder a algún método de la clase Item, salta la excepción.

Código:
URL clases = world.getResource("myItem.jar");
addClassPath( clases );
oneItem = new extenItem ();

// Aquí es cuando falla, cuando intento acceder a algún método de la clase Item (que extiende a Entity).
//oneItem.addSingularReferenceName("un nombre");
//mobile("jugador").write ( oneItem.myItem () );


_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 08 Nov 2015 12:49 
Desconectado
Samudio
Samudio
Avatar de Usuario

Registrado: 09 Mar 2004 16:16
Mensajes: 5272
Ubicación: Coruña
El constructor de Item que tendrías que usar sería el que coge un World y un org.w3c.dom.Node. El org.w3c.dom.Node es la clase que representa un nodo de un documento XML. Se obtiene con el parser DOM de Java. Se trata de que parsees la descripción XML del Item, de esa manera obtienes ese Node, y con eso AGE puede construir el Item.

Luego, para añadirlo al mundo, harías: mundo.addItemAssigningID ( miItem ).

¿Seguro que no hay una forma más sencilla de conseguir la funcionalidad que quieras conseguir? La arquitectura de AGE no está pensada para que haya que extender las clases nucleares. Si le quieres añadir funcionalidad a los items, seguramente sea más cómodo hacerlo con código BeanShell, mediante composición en lugar de herencia, y también crearía menos acoplamiento con el código de Item.

También ten en cuenta que Item en sí tiene varias subclases (Weapon y Wearable). Decisión de diseño de la que por cierto me arrepiento, pero en todo caso está ahí. Así que si quieres algo que funcione para todos los Items, extender Item no basta, porque tendrías una extensión del Item básico pero no de las armas y armaduras. Lo que te digo de la composición sí que valdría, independientemente de las subclases que tenga Item.

(por estas cosas se dice aquello de "Composition over inheritance" ( https://en.wikipedia.org/wiki/Compositi ... nheritance ), pena que cuando hice el diseño inicial de AGE, yo mismo no lo sabía...)

_________________
Actúa siempre de tal modo que las decisiones de tu voluntad pudiesen servir como preceptos de una legislación universal (E. Kant)


Arriba
 Perfil  
 
NotaPublicado: 08 Nov 2015 13:14 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Miraré lo que comentas de composición, puede que sea más cómodo y útil.

Explicando un poco a groso modo lo que pretendía era solventar el problema de "el gorro" "la pamela". Con el diseño que tenía hecho:

Código:
public boolean matchNombreOk(String byName) {

      byName = byName.trim();
      String[] words = byName.split(" ");

      for (int i = 0; i < words.length; i++) {
         words[i] = words[i].trim();
         for (PalYGen aName : nombresDeReferencia) {
            if (aName.palabra().equals(words[i])) {
               asignarGenero(aName);
               return true;
            }
         }
      }
      return false;// out; //referenceName.contains(byName);
   }


Cada vez que "matcheo" un nombre de referencia de un Item, le asigno un género. "aName" es un tipo que guarda el String con el nombre y el género del mismo.

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
NotaPublicado: 08 Nov 2015 15:24 
Desconectado
Betatester
Betatester
Avatar de Usuario

Registrado: 09 Feb 2012 20:33
Mensajes: 855
Bueno ... no te comas la cabeza, dejo el asunto aparcado. Eso de asignar género no es tan fácil como pensaba.

_________________
Te quiero... lo siento Yoda sólo tenemos café.


Arriba
 Perfil  
 
Mostrar mensajes previos:  Ordenar por  
Nuevo tema Responder al tema  [ 16 mensajes ]  Ir a página 1, 2  Siguiente

Todos los horarios son UTC + 1 hora


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 3 invitados


No puede abrir nuevos temas en este Foro
No puede responder a temas en este Foro
No puede editar sus mensajes en este Foro
No puede borrar sus mensajes en este Foro

Buscar:
Saltar a:  
Desarrollado por phpBB® Forum Software © phpBB Group
Traducción al español por Huan Manwë para phpBB-Es.COM