/*
* (c) 2000-2009 Carlos G�mez Rodr�guez, todos los derechos reservados / all rights reserved.
* Licencia en license/bsd.txt / License in license/bsd.txt
*/
package eu.irreality.age;
import java.util.*;
import eu.irreality.age.debug.Debug;
import eu.irreality.age.scripting.ScriptException;
public class AbstractEntity extends Entity implements SupportingCode, UniqueNamed
{
/*00*/ private String absentType;
/**ID del objeto.*/
/*01*/ private int idnumber;
/**Hereda de.*/
/*02*/ private int inheritsFrom;
/*03*/ // inherited protected int state;
// inherited protected long timeunitsleft;
/**Nombre sint�tico del objeto.*/
/*04*/ protected String title;
/**Es instancia de.*/
/*05*/ private int isInstanceOf;
/**C�digo en Ensamblador Virtual Aetheria (EVA)*/
/*80*/ protected ObjectCode itsCode;
//generador de numeros aleatorios
private Random aleat;
public Object clone( )
{
//do it!
AbstractEntity ae = new AbstractEntity();
copyAbstractEntityFieldsTo(ae);
return ae;
}
public void copyAbstractEntityFieldsTo ( AbstractEntity ae )
{
Debug.println("Copying fields.");
ae.copyEntityFields(this); //estados, propiedades, etc.
if ( itsCode != null ) ae.itsCode = itsCode.cloneIfNecessary();
ae.aleat = getRandom();
ae.absentType = absentType;
}
public int getID ( )
{
return idnumber;
}
/**
* @deprecated Use {@link #getUniqueName()} instead
*/
public String getTitle ( )
{
return getUniqueName();
}
public String getUniqueName ( )
{
return title;
}
/*ejecuta el codigo bsh del objeto correspondiente a la rutina dada si existe.
Si no existe, simplemente no ejecuta nada y devuelve false.*/
public boolean execCode ( String routine , Object[] args ) throws ScriptException
{
if ( itsCode != null )
return itsCode.run ( routine , this , args );
else return false;
}
/*ejecuta el codigo bsh del objeto correspondiente a la rutina dada si existe.
Si no existe, simplemente no ejecuta nada y devuelve false.*/
public boolean execCode ( String routine , Object[] args , ReturnValue retval ) throws ScriptException
{
//S/ystem.out.println("Mobile code runnin'.");
//System.out.println("Its Code: " + itsCode);
if ( itsCode != null )
return itsCode.run ( routine , this , args , retval );
else return false;
}
//legacy change-state
//[old!!]
public void changeState ( World mundo )
{
;
/*
try
{
execCode("event_endstate","this: "+ getID() + "state: " + getState() );
}
catch ( EVASemanticException exc )
{
mundo.escribir("EVASemanticException found at event_endstate , item number " + getID() );
}
*/
}
//important
//[define event here!! and do it for other entity types, too!]
//public /*abstract*/ boolean update ( PropertyEntry pe , World mundo )
//{
// return true;
//}
//done @ Entity
public void setID ( int newid )
{
if ( newid < Utility.absent_summand )
idnumber = newid + Utility.absent_summand;
else
idnumber = newid;
}
public void loadNumberGenerator ( World mundo )
{
aleat = mundo.getRandom();
}
public java.util.Random getRandom()
{
return aleat;
}
public org.w3c.dom.Node getXMLRepresentation ( org.w3c.dom.Document doc )
{
org.w3c.dom.Element suElemento = doc.createElement( "AbstractEntity" );
suElemento.setAttribute ( "id" , String.valueOf( idnumber ) );
suElemento.setAttribute ( "name" , String.valueOf ( title ) );
suElemento.setAttribute ( "extends" , String.valueOf ( inheritsFrom ) );
suElemento.setAttribute ( "clones" , String.valueOf ( isInstanceOf ) );
suElemento.setAttribute ( "type" , String.valueOf ( absentType ) );
suElemento.appendChild ( getPropListXMLRepresentation(doc) );
suElemento.appendChild ( getRelationshipListXMLRepresentation(doc) );
//object code
if ( itsCode != null )
suElemento.appendChild(itsCode.getXMLRepresentation(doc));
return suElemento;
}
/**
**
CONSTRUCTING CODE
**
**/
public AbstractEntity ( )
{
}
public static AbstractEntity getInstance ( World mundo , org.w3c.dom.Node n ) throws XMLtoWorldException
{
if ( ! ( n instanceof org.w3c.dom.Element ) )
{
throw ( new XMLtoWorldException("AbstractEntity node not Element") );
}
//{n is an Element}
org.w3c.dom.Element e = (org.w3c.dom.Element)n;
AbstractEntity ourNewAbstractEntity;
if ( !e.hasAttribute("type") )
{
ourNewAbstractEntity = new AbstractEntity ( mundo , n );
}
else if ( e.getAttribute("type").equalsIgnoreCase("effect") )
{
ourNewAbstractEntity = new Effect ( mundo , n );
}
else
{
ourNewAbstractEntity = new AbstractEntity ( mundo , n );
}
return ourNewAbstractEntity;
}
public AbstractEntity ( World mundo , org.w3c.dom.Node n ) throws XMLtoWorldException
{
constructAbstractEntity ( mundo , n , true , "none" );
}
public void constructAbstractEntity ( World mundo , org.w3c.dom.Node n , boolean allowInheritance , String absenttype ) throws XMLtoWorldException
{
if ( ! ( n instanceof org.w3c.dom.Element ) )
{
throw ( new XMLtoWorldException ( "AbstractEntity node not Element" ) );
}
//{n is an Element}
org.w3c.dom.Element e = (org.w3c.dom.Element) n;
//type
absentType = absenttype;
//attribs
//weak inheritance?
if ( e.hasAttribute("extends") && !e.getAttribute("extends").equals("0") && allowInheritance )
{
//item must extend from existing item.
//clonamos ese item y overrideamos lo overrideable
//(n�tese que la ID del item extendido ha de ser menor).
//por eso los associated nodes de los items quedan guardados [por ref] en el World hasta que
//haya concluido la construccion del mundo
//1. overrideamos el super-item usando su associated node para construirlo
constructAbstractEntity ( mundo , mundo.getAbstractEntityNode( e.getAttribute("extends") ) , true , absenttype );
//2. overrideamos lo que debamos overridear
constructAbstractEntity ( mundo , n , false , absenttype );
return;
}
//strong inheritance?
if ( e.hasAttribute("clones") && !e.getAttribute("clones").equals("0") && allowInheritance )
{
//funciona igual que la weak inheritance a este nivel.
//no deberian aparecer los dos; pero si asi fuera esta herencia (la fuerte) tendria precedencia.
//1. overrideamos el super-item usando su associated node para construirlo
constructAbstractEntity ( mundo , mundo.getAbstractEntityNode( e.getAttribute("clones") ) , true , absenttype );
//2. overrideamos lo que debamos overridear
constructAbstractEntity ( mundo , n , false , absenttype );
return;
}
//mandatory XML-attribs exceptions
if ( !e.hasAttribute("name") )
throw ( new XMLtoWorldException ( "Item node lacks attribute name" ) );
//mandatory XML-attribs parsing
//id no longer mandatory
try
{
if ( e.hasAttribute("id") )
idnumber = Integer.valueOf ( e.getAttribute("id") ).intValue();
}
catch ( NumberFormatException nfe )
{
throw ( new XMLtoWorldException ( "Bad number format at attribute id in abstract entity node" ) );
}
title = e.getAttribute("name");
//Entity parsing
readPropListFromXML ( mundo , n );
org.w3c.dom.NodeList codeNodes = e.getElementsByTagName ( "Code" );
if ( codeNodes.getLength() > 0 )
{
try
{
itsCode = new ObjectCode ( mundo , codeNodes.item(0) );
}
catch ( XMLtoWorldException ex )
{
throw ( new XMLtoWorldException ( "Exception at Code node: " + ex.getMessage() ) );
}
}
//FINALLY... type-specifics!!
if ( absentType.equalsIgnoreCase("effect") )
{
((Effect)this).readEffectSpecifics ( mundo , e );
}
//poner bien la id
if ( getID() < 10000000 )
idnumber += 40000000; //prefijo de abstr. ent.
//from 2014-10-22, onInit() is not executed when loading states, see issue #310
if ( !mundo.comesFromLoadedState() )
{
//eventos onInit()
try
{
boolean ejecutado = execCode ( "onInit" ,
new Object[]
{
}
);
}
catch ( ScriptException te )
{
te.printStackTrace();
mundo.write("BeanShell error on initting abstract entity " + this + ": error was " + te);
}
}
}
public AbstractEntity createNewInstance ( World mundo )
{
return createNewInstance(mundo,null);
}
public AbstractEntity createNewInstance( World mundo , String uniqueName )
{
Debug.println("Creatin' new instance.");
AbstractEntity it = (AbstractEntity) this.clone();
Debug.println("Clone made.");
it.inheritsFrom = 0;
if ( this.isInstanceOf == 0 )
{
it.isInstanceOf = idnumber;
Debug.println("1) instanceOf set to " + idnumber);
}
else
{
it.isInstanceOf = this.isInstanceOf;
Debug.println("2) instanceOf set to " + this.isInstanceOf);
}
if ( uniqueName == null ) it.title = mundo.generateUnusedUniqueName(this.getUniqueName());
else it.title = uniqueName;
mundo.addAbstractEntityAssigningID ( it );
return it;
}
public ObjectCode getAssociatedCode()
{
return itsCode;
}
public String toString()
{
String s = ("[ " + getClass().getName() + ":" + getID() );
//if ( this instanceof Nameable )
{
s += ":";
s += this.getUniqueName();
}
s+=" ]";
return s;
}
}