mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-01-17 00:05:07 -05:00
1048 lines
26 KiB
Java
1048 lines
26 KiB
Java
/*
|
|
Title: obj_id
|
|
Description: Wrapper for an object id.
|
|
*/
|
|
|
|
package script;
|
|
|
|
import java.io.IOException;
|
|
import java.io.ByteArrayInputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.ObjectInputStream;
|
|
import java.io.ObjectOutputStream;
|
|
import java.io.ObjectStreamException;
|
|
import java.io.Serializable;
|
|
import java.lang.ref.Reference;
|
|
import java.lang.ref.ReferenceQueue;
|
|
import java.lang.ref.WeakReference;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Enumeration;
|
|
import java.util.Hashtable;
|
|
import java.util.HashSet;
|
|
import java.util.Iterator;
|
|
import java.util.LinkedList;
|
|
import java.util.Vector;
|
|
|
|
public final class obj_id implements Comparable, Serializable
|
|
{
|
|
private final static long serialVersionUID = 84998777444285203L;
|
|
|
|
private final static boolean DEBUG = false;
|
|
private final static boolean VALIDATE_SCRIPTS = true;
|
|
public final static obj_id NULL_ID = new obj_id(0);
|
|
public final static String SCRIPT_PREFIX = "script.";
|
|
|
|
private static long m_nextSerializedId = -1; // temporary id storage for deserialization
|
|
private static HashSet potentiallyDirtyObjects = new HashSet(); // list of ids whose scriptvars may have changed
|
|
private static Hashtable m_factory = new Hashtable(100003); // keeps track of all ids currently in the game
|
|
private static obj_id_cleanup m_cleanup; // removes obj_ids from the factory after all references to the id have been cleared
|
|
|
|
private transient Long m_id; // the actual id
|
|
private transient boolean m_authoritative; // flag if the object is authoritative on this server
|
|
private transient int m_processId; // process id of the authoritative game server for this object
|
|
private transient boolean m_loaded; // flag if the object is loaded
|
|
private transient boolean m_initialized; // flag if the object is initialized
|
|
private transient boolean m_loggedIn; // flag if the object is logged in (if a player)
|
|
private transient boolean m_beingDestroyed; // flag that the object is in the process of being destroyed
|
|
private transient ArrayList m_scripts; // list of scripts attached to this object
|
|
private transient int m_scriptLock; // semaphore-type counter to prevent modification of the script list
|
|
private transient ArrayList m_pendingScripts;
|
|
private transient deltadictionary scriptVars = null;
|
|
private transient dictionary scriptDictionary = null;
|
|
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
//
|
|
// Internal classes
|
|
//
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
|
|
// class to keep track of modifications made to the script list while locked
|
|
private final class pending_script
|
|
{
|
|
public boolean add; // true = add the script, false = remove it
|
|
public String script; // the script to add/remove
|
|
public pending_script(boolean add, String script) { this.add = add; this.script = script; }
|
|
} // class pending_script
|
|
|
|
/**
|
|
* Used to help remove an obj_id from the factory table when all references to it have been removed.
|
|
*/
|
|
private final static class obj_id_reference extends WeakReference
|
|
{
|
|
private Long m_id;
|
|
|
|
public obj_id_reference(obj_id id, ReferenceQueue q)
|
|
{
|
|
super(id, q);
|
|
m_id = id.m_id;
|
|
}
|
|
|
|
public Long getId()
|
|
{
|
|
return m_id;
|
|
}
|
|
} // class obj_id_reference
|
|
|
|
/**
|
|
* Cleanup thread that removes obj_ids from the factory table.
|
|
*/
|
|
private final static class obj_id_cleanup extends Thread
|
|
{
|
|
ReferenceQueue m_clearedObjectQueue;
|
|
|
|
obj_id_cleanup()
|
|
{
|
|
super("obj_id_cleanup_Thread");
|
|
m_clearedObjectQueue = new ReferenceQueue();
|
|
setDaemon(true);
|
|
}
|
|
|
|
public ReferenceQueue getClearedObjectQueue()
|
|
{
|
|
return m_clearedObjectQueue;
|
|
}
|
|
|
|
public synchronized void run()
|
|
{
|
|
// the thread exists when all other threads are removed
|
|
for (; ; )
|
|
{
|
|
try
|
|
{
|
|
// wait for a obj_id reference to be cleared
|
|
Reference ref = m_clearedObjectQueue.remove();
|
|
if (ref instanceof obj_id_reference)
|
|
{
|
|
// remove the reference from the factory
|
|
if (obj_id.DEBUG)
|
|
{
|
|
System.out.println("Removing obj_id " + ((obj_id_reference)ref).getId() + " from factory");
|
|
}
|
|
obj_id.m_factory.remove(((obj_id_reference)ref).getId());
|
|
}
|
|
}
|
|
catch (InterruptedException err)
|
|
{
|
|
System.err.println("Java obj_id.obj_id_cleanup error: " + err);
|
|
}
|
|
}
|
|
}
|
|
} // class obj_id_cleanup
|
|
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
//
|
|
// Public methods
|
|
//
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
|
|
/**
|
|
* Returns an obj_id for a given id number. If an obj_id with that number
|
|
* has already been created, will return a reference to that obj_id.
|
|
*
|
|
* @param id the object id number
|
|
*
|
|
* @return the obj_id for that number
|
|
*/
|
|
static public obj_id getObjId(long id)
|
|
{
|
|
if (id == 0)
|
|
return NULL_ID;
|
|
|
|
return getObjId(new Long(id));
|
|
} // getObjId
|
|
|
|
/**
|
|
* Returns an obj_id for a given id number. If an obj_id with that number
|
|
* has already been created, will return a reference to that obj_id.
|
|
*
|
|
* @param id the object id number
|
|
*
|
|
* @return the obj_id for that number
|
|
*/
|
|
static public obj_id getObjId(Long id)
|
|
{
|
|
if (id == null || id.longValue() == 0)
|
|
return NULL_ID;
|
|
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("obj_id factory request for id " + id);
|
|
}
|
|
|
|
Object value = m_factory.get(id);
|
|
if (value == null)
|
|
{
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("obj_id factory creating new id " + id);
|
|
}
|
|
|
|
obj_id newId = new obj_id(id);
|
|
value = newId;
|
|
// store the id as a weak reference; if it is later marked loaded, we will replace it with a hard reference
|
|
m_factory.put(id, new obj_id_reference(newId, m_cleanup.getClearedObjectQueue()));
|
|
}
|
|
else if (value instanceof obj_id_reference)
|
|
{
|
|
value = ((obj_id_reference)value).get();
|
|
}
|
|
|
|
return (obj_id)value;
|
|
} // getObjId
|
|
|
|
public dictionary getScriptDictionary()
|
|
{
|
|
if (scriptDictionary == null)
|
|
{
|
|
scriptDictionary = new dictionary();
|
|
}
|
|
return scriptDictionary;
|
|
}
|
|
|
|
public void clearScriptDictionary()
|
|
{
|
|
if(scriptDictionary != null)
|
|
{
|
|
scriptDictionary.clear();
|
|
}
|
|
}
|
|
|
|
public deltadictionary getScriptVars()
|
|
{
|
|
if (scriptVars == null)
|
|
{
|
|
scriptVars = new deltadictionary();
|
|
}
|
|
potentiallyDirtyObjects.add(this);
|
|
return scriptVars;
|
|
}
|
|
|
|
public void clearScriptVars()
|
|
{
|
|
if (scriptVars != null)
|
|
{
|
|
scriptVars.removeAll();
|
|
potentiallyDirtyObjects.add(this);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Note: the 3 setScriptVar functions below were written so that the C code could set script vars for these data types.
|
|
* If wanted feel free to add other scriptvar setters/getters.
|
|
*/
|
|
public void setScriptVar(String name, int value)
|
|
{
|
|
if (scriptVars != null)
|
|
{
|
|
scriptVars.put(name, value);
|
|
potentiallyDirtyObjects.add(this);
|
|
}
|
|
}
|
|
|
|
public void setScriptVar(String name, float value)
|
|
{
|
|
if (scriptVars != null)
|
|
{
|
|
scriptVars.put(name, value);
|
|
potentiallyDirtyObjects.add(this);
|
|
}
|
|
}
|
|
|
|
public void setScriptVar(String name, String value)
|
|
{
|
|
if (scriptVars != null)
|
|
{
|
|
scriptVars.put(name, value);
|
|
potentiallyDirtyObjects.add(this);
|
|
}
|
|
}
|
|
|
|
public boolean hasScriptDictionary(Object key)
|
|
{
|
|
return scriptDictionary != null && scriptDictionary.containsKey(key);
|
|
}
|
|
|
|
public boolean hasScriptVar(Object key)
|
|
{
|
|
return scriptVars != null && scriptVars.hasKey(key);
|
|
}
|
|
|
|
/**
|
|
* Accessor function.
|
|
*
|
|
* @return the object id
|
|
*/
|
|
public long getValue()
|
|
{
|
|
return m_id.longValue();
|
|
} // getValue
|
|
|
|
public int getProcessId()
|
|
{
|
|
return m_processId;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the object was loaded from the buildout
|
|
* Note it will return false if the object was exported from the
|
|
* gold data into buildout files.
|
|
*/
|
|
|
|
public boolean isBuildoutObject()
|
|
{
|
|
return m_id.longValue() < 0;
|
|
}
|
|
|
|
/**
|
|
* Returns if this object is authoritative on the server or not.
|
|
*
|
|
* @return true if authoritative, false if not
|
|
*/
|
|
public boolean isAuthoritative()
|
|
{
|
|
return m_authoritative;
|
|
} // isAuthoritative
|
|
|
|
/**
|
|
* Returns if this object has been loaded or not.
|
|
*
|
|
* @return true if loaded, false if not
|
|
*/
|
|
public boolean isLoaded()
|
|
{
|
|
return m_loaded;
|
|
} // isLoaded
|
|
|
|
/**
|
|
* Returns if this object has been initialized or not.
|
|
*
|
|
* @return true if initialized, false if not
|
|
*/
|
|
public boolean isInitialized()
|
|
{
|
|
return m_initialized;
|
|
} // isInitialized
|
|
|
|
/**
|
|
* Returns if this object is being destroyed or not.
|
|
*
|
|
* @return true if it is being destroyed, false if not
|
|
*/
|
|
public boolean isBeingDestroyed()
|
|
{
|
|
return m_beingDestroyed;
|
|
} // isBeingDestroyed
|
|
|
|
public ArrayList getScriptArrayList()
|
|
{
|
|
return m_scripts;
|
|
} // getScripts
|
|
|
|
/**
|
|
* Returns the scripts attached to this object.
|
|
*
|
|
* @return string array of script names, or null on error
|
|
*/
|
|
public String[] getScripts()
|
|
{
|
|
if (m_scripts == null)
|
|
return null;
|
|
if (m_scripts.size() == 0)
|
|
return new String[0];
|
|
|
|
String[] strings = null;
|
|
if (m_scriptLock > 0)
|
|
{
|
|
// we have to set up a list of our scripts, adding and removing scripts from the pending list as needed
|
|
LinkedList scriptList = getAllScriptsWithPending();
|
|
if (scriptList != null)
|
|
{
|
|
strings = new String[scriptList.size()];
|
|
scriptList.toArray(strings);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strings = new String[m_scripts.size()];
|
|
m_scripts.toArray(strings);
|
|
}
|
|
return strings;
|
|
} // getScripts()
|
|
|
|
/**
|
|
* Checks to see if the object has a script attached.
|
|
*
|
|
* @param scriptName the name of the script to look for
|
|
*
|
|
* @return true if the script is attached, false if not
|
|
*/
|
|
public boolean hasScript(String scriptName)
|
|
{
|
|
if (m_scripts == null)
|
|
return false;
|
|
|
|
String fullPath = SCRIPT_PREFIX + scriptName;
|
|
if (m_scriptLock > 0)
|
|
{
|
|
LinkedList scriptList = getAllScriptsWithPending();
|
|
if (scriptList != null)
|
|
return scriptList.contains(fullPath);
|
|
}
|
|
return m_scripts.contains(fullPath);
|
|
} // hasScript()
|
|
|
|
public void lockScripts()
|
|
{
|
|
++m_scriptLock;
|
|
} // lockScripts
|
|
|
|
public int getLockCount()
|
|
{
|
|
return m_scriptLock;
|
|
}
|
|
|
|
public void unlockScripts()
|
|
{
|
|
if (m_scriptLock > 0)
|
|
{
|
|
if (--m_scriptLock == 0)
|
|
{
|
|
// update the script list for the pending scripts
|
|
if (DEBUG)
|
|
System.out.println("Updating pending scripts on object " + m_id);
|
|
for (int i = 0; i < m_pendingScripts.size(); ++i)
|
|
{
|
|
pending_script pending = (pending_script)m_pendingScripts.get(i);
|
|
if (pending.add)
|
|
attachScript(pending.script);
|
|
else
|
|
detachScript(pending.script);
|
|
}
|
|
m_pendingScripts.clear();
|
|
}
|
|
}
|
|
} // unlockScripts
|
|
|
|
/**
|
|
* Conversion function.
|
|
*
|
|
* @return the id as a string.
|
|
*/
|
|
public String toString()
|
|
{
|
|
return m_id.toString();
|
|
} // toString
|
|
|
|
/**
|
|
* Compares this to a generic object.
|
|
*
|
|
* @returns <, =, or > 0 if the object is a obj_id, else throws
|
|
* ClassCastException
|
|
*/
|
|
public int compareTo(Object o) throws ClassCastException
|
|
{
|
|
return compareTo((obj_id)o);
|
|
} // compareTo(Object)
|
|
|
|
/**
|
|
* Compares this to another obj_id.
|
|
*
|
|
* @returns <, =, or > 0
|
|
*/
|
|
public int compareTo(obj_id id)
|
|
{
|
|
if (id == null)
|
|
return 1;
|
|
|
|
if (m_id.longValue() > id.m_id.longValue())
|
|
return 1;
|
|
else if (m_id.longValue() < id.m_id.longValue())
|
|
return -1;
|
|
return 0;
|
|
} // compareTo(obj_id)
|
|
|
|
/**
|
|
* Compares this to a generic object.
|
|
*
|
|
* @returns true if the objects have the same data, false if not
|
|
*/
|
|
public boolean equals(Object o)
|
|
{
|
|
if (o == null)
|
|
return false;
|
|
|
|
try
|
|
{
|
|
int result = compareTo(o);
|
|
if (result == 0)
|
|
return true;
|
|
}
|
|
catch (ClassCastException err)
|
|
{
|
|
}
|
|
return false;
|
|
} // equals
|
|
|
|
/**
|
|
* Returns a hash code value for the obj_id.
|
|
*
|
|
* @return a hash code value for this obj_id
|
|
*/
|
|
public int hashCode()
|
|
{
|
|
// hash code from Effective Java, item 8, page 38
|
|
int result = 17;
|
|
result = 37 * result + (int)(m_id.longValue() ^ (m_id.longValue() >>> 32));
|
|
return result;
|
|
} // hashCode
|
|
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
//
|
|
// Default access methods
|
|
//
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
|
|
/**
|
|
* Called when an object is going to be destroyed, but hasn't actually been removed from the game yet.
|
|
*/
|
|
void flagDestroyed()
|
|
{
|
|
m_beingDestroyed = true;
|
|
}
|
|
|
|
private static void flagDestroyed(long id)
|
|
{
|
|
flagDestroyed((id == 0) ? null : obj_id.getObjId(id));
|
|
}
|
|
|
|
private static void flagDestroyed(obj_id id)
|
|
{
|
|
if (id == null || id.getValue() == 0)
|
|
return;
|
|
|
|
id.flagDestroyed();
|
|
}
|
|
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
//
|
|
// Private methods
|
|
//
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
|
|
/**
|
|
* Class constructor.
|
|
*
|
|
* @param id the object id value
|
|
*/
|
|
private obj_id(long id)
|
|
{
|
|
m_id = new Long(id);
|
|
m_authoritative = false;
|
|
m_loaded = false;
|
|
m_initialized = false;
|
|
m_loggedIn = false;
|
|
m_beingDestroyed = false;
|
|
m_scripts = new ArrayList();
|
|
m_pendingScripts = new ArrayList();
|
|
m_scriptLock = 0;
|
|
} // obj_id
|
|
|
|
/**
|
|
* Class constructor.
|
|
*
|
|
* @param id the object id value
|
|
*/
|
|
private obj_id(Long id)
|
|
{
|
|
m_id = id;
|
|
m_authoritative = false;
|
|
m_loaded = false;
|
|
m_initialized = false;
|
|
m_loggedIn = false;
|
|
m_beingDestroyed = false;
|
|
m_scripts = new ArrayList();
|
|
m_pendingScripts = new ArrayList();
|
|
m_scriptLock = 0;
|
|
} // obj_id
|
|
|
|
private static void packAllScriptVars()
|
|
{
|
|
Iterator i = potentiallyDirtyObjects.iterator();
|
|
if (i != null)
|
|
{
|
|
while (i.hasNext())
|
|
{
|
|
obj_id pdo = (obj_id)i.next();
|
|
if (pdo != null)
|
|
{
|
|
// don't need to push out scriptvars if object doesn't exist on any other game server
|
|
if (!base_class.hasProxyOrAuthObject(pdo))
|
|
{
|
|
if (pdo.scriptVars != null)
|
|
pdo.scriptVars.clearDelta();
|
|
|
|
continue;
|
|
}
|
|
|
|
byte[] deltaBuffer = pdo.packDeltaScriptVars();
|
|
if (deltaBuffer != null && deltaBuffer.length > 0)
|
|
{
|
|
boolean res = base_class.sendScriptVarsToProxies(pdo, deltaBuffer);
|
|
|
|
if (res == false) {
|
|
System.err.println("WARNING: Java packAllScriptVars - sendScriptVarsToProxies returned false!");
|
|
// if we ever hit this condition, testing with the below should be dont e
|
|
//pdo.scriptVars.clearDelta();
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
potentiallyDirtyObjects.clear();
|
|
}
|
|
|
|
private static byte[] packScriptVars(long target)
|
|
{
|
|
return packScriptVars((target == 0) ? null : obj_id.getObjId(target));
|
|
}
|
|
private static byte[] packScriptVars(obj_id target)
|
|
{
|
|
byte[] result = null;
|
|
if (target != null && target.scriptVars != null && target.scriptVars.size() > 0)
|
|
{
|
|
result = target.scriptVars.pack();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private byte[] packDeltaScriptVars()
|
|
{
|
|
byte[] result = null;
|
|
if (scriptVars != null)
|
|
{
|
|
try
|
|
{
|
|
result = scriptVars.packDelta();
|
|
}
|
|
catch (IOException x)
|
|
{
|
|
System.err.println(x.toString());
|
|
return null;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static void unpackScriptVars(long target, byte[] input)
|
|
{
|
|
unpackScriptVars((target == 0) ? null : obj_id.getObjId(target), input);
|
|
}
|
|
private static void unpackScriptVars(obj_id target, byte[] input)
|
|
{
|
|
if (target != null && input != null)
|
|
{
|
|
deltadictionary sv = target.getScriptVars();
|
|
sv.unpack(input);
|
|
}
|
|
}
|
|
|
|
private static void unpackDeltaScriptVars(long target, byte[] input)
|
|
{
|
|
unpackDeltaScriptVars((target == 0) ? null : obj_id.getObjId(target), input);
|
|
}
|
|
private static void unpackDeltaScriptVars(obj_id target, byte[] input)
|
|
{
|
|
if (target != null && input != null)
|
|
{
|
|
deltadictionary sv = target.getScriptVars();
|
|
try
|
|
{
|
|
// ByteArrayInputStream byteInput = new ByteArrayInputStream(input.getBytes());
|
|
// ObjectInputStream objectInput = new ObjectInputStream(byteInput);
|
|
sv.unpackDelta(input);
|
|
}
|
|
catch (ClassNotFoundException c)
|
|
{
|
|
System.err.println(c);
|
|
}
|
|
catch (IOException x)
|
|
{
|
|
System.err.println("IOException: " + x);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Called when an obj_id is removed from the game. Note that the obj_id will
|
|
* stick around until all references to it have been removed.
|
|
*
|
|
* @param id the object id
|
|
*/
|
|
private static void clearObjId(long id)
|
|
{
|
|
clearObjId((id == 0) ? null : obj_id.getObjId(id));
|
|
}
|
|
private static void clearObjId(obj_id id)
|
|
{
|
|
if (id == null || id.getValue() == 0)
|
|
return;
|
|
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("obj_id factory request to clear id " + id);
|
|
}
|
|
|
|
script_entry.removeScriptListenee(id);
|
|
id.m_authoritative = false;
|
|
id.m_loaded = false;
|
|
id.m_initialized = false;
|
|
id.m_loggedIn = false;
|
|
id.m_beingDestroyed = false;
|
|
|
|
id.clearScriptVars();
|
|
id.clearScriptDictionary();
|
|
|
|
Object value = m_factory.get(id.m_id);
|
|
if (value != null)
|
|
{
|
|
if (value instanceof obj_id)
|
|
{
|
|
if (value != id)
|
|
{
|
|
System.err.println("***ERROR: id passed to obj_id.clearObjId is not the id stored in the factory map!!! Id #" +
|
|
Long.toString(id.getValue()));
|
|
}
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("obj_id factory clearing id");
|
|
}
|
|
|
|
// replace the obj_id with a weak reference to itself; if there are no other references to it, it will be removed
|
|
m_factory.put(id.m_id, new obj_id_reference(id, m_cleanup.getClearedObjectQueue()));
|
|
}
|
|
}
|
|
} // clearObjId
|
|
|
|
/**
|
|
* Sets the authoritative flag for the obj_id.
|
|
*
|
|
* @param authoritative flag that the object is authoritative
|
|
*/
|
|
private void setAuthoritative(boolean authoritative, int processId)
|
|
{
|
|
m_authoritative = authoritative;
|
|
m_processId = processId;
|
|
if (m_authoritative)
|
|
setLoaded(); // if it's authoritative, it better be loaded!
|
|
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("Java obj_id " + this + " authority set to " + m_authoritative);
|
|
}
|
|
} // setAuthoritative
|
|
|
|
/**
|
|
* Sets the loaded flag for the object. The flag cannot be cleared, the obj_id
|
|
* must be cleared instead.
|
|
**/
|
|
private void setLoaded()
|
|
{
|
|
m_loaded = true;
|
|
|
|
// replace the soft reference to this id with a hard reference
|
|
m_factory.put(m_id, this);
|
|
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("Java obj_id " + this + " loaded");
|
|
}
|
|
} // setLoaded
|
|
|
|
/**
|
|
* Sets the initialized flag for the object. The flag cannot be cleared, the obj_id
|
|
* must be cleared instead.
|
|
**/
|
|
private void setInitialized()
|
|
{
|
|
m_initialized = true;
|
|
|
|
// replace the soft reference to this id with a hard reference
|
|
m_factory.put(m_id, this);
|
|
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("Java obj_id " + this + " initialized");
|
|
}
|
|
} // setInitialized
|
|
|
|
/**
|
|
* Sets/clears the logged in flag for the object.
|
|
**/
|
|
private void setLoggedIn(boolean loggedIn)
|
|
{
|
|
if (!m_loggedIn && loggedIn)
|
|
{
|
|
}
|
|
|
|
m_loggedIn = loggedIn;
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("Java obj_id " + this + " logged in = " + m_loggedIn);
|
|
}
|
|
} // setInitialized
|
|
|
|
/**
|
|
* Adds a single script to this object. The script is put on the end of the script list.
|
|
*
|
|
* @param script the script to attach
|
|
*/
|
|
private void attachScript(String script)
|
|
{
|
|
if (DEBUG)
|
|
System.out.println("Java obj_id.attachScript enter, script = " + script);
|
|
|
|
if (m_scripts == null)
|
|
{
|
|
System.err.println("ERROR: Java obj_id.attachScript: m_scripts == null!");
|
|
return;
|
|
}
|
|
if (script == null || script.length() == 0)
|
|
{
|
|
System.err.println("Java obj_id.attachScript trying to attach empty script name to object " + m_id);
|
|
return;
|
|
}
|
|
|
|
if (m_scriptLock > 0)
|
|
{
|
|
m_pendingScripts.add(new pending_script(true, script));
|
|
if (DEBUG)
|
|
System.out.println("Java obj_id.attachScript pending attach script " + script + " to object " + m_id);
|
|
return;
|
|
}
|
|
|
|
if (DEBUG)
|
|
System.out.println("Java obj_id.attachScript attaching script " + script + " to object " + m_id);
|
|
|
|
// System.out.println("Java obj_id.attachScript m_scripts before add, size = " + Integer.toString(m_scripts.size()) + ", items = ");
|
|
// for (int i = 0; i < m_scripts.size(); ++i)
|
|
// System.out.println(m_scripts.get(i).toString());
|
|
|
|
if (!script.startsWith(SCRIPT_PREFIX))
|
|
script = SCRIPT_PREFIX + script;
|
|
|
|
if (VALIDATE_SCRIPTS)
|
|
{
|
|
if (m_scripts.contains(script))
|
|
{
|
|
System.err.println("WARNING: Java obj_id.attachScript(single) tried to add script " +
|
|
script + " to object " + this + " more than once!");
|
|
return;
|
|
}
|
|
}
|
|
m_scripts.add(0, script);
|
|
|
|
// System.out.println("Java obj_id.attachScript m_scripts after add, size = " + Integer.toString(m_scripts.size()) + ", items = ");
|
|
// for (int i = 0; i < m_scripts.size(); ++i)
|
|
// System.out.println(m_scripts.get(i).toString());
|
|
|
|
// System.out.println("Java obj_id.attachScript exit");
|
|
} // attachScript(String)
|
|
|
|
/**
|
|
* Adds multiple scripts to this object. The scripts are put on the end of the script list.
|
|
*
|
|
* @param scripts the scripts to attach
|
|
*/
|
|
private void attachScript(String[] scripts)
|
|
{
|
|
if (m_scripts == null)
|
|
{
|
|
System.err.println("ERROR: Java obj_id.attachScript[]: m_scripts == null!");
|
|
return;
|
|
}
|
|
if (scripts == null)
|
|
{
|
|
System.err.println("ERROR: Java obj_id.attachScript[]: scripts == null!");
|
|
return;
|
|
}
|
|
|
|
// the scripts need to be added in reverse order to the front of the list
|
|
for (int i = 0; i < scripts.length; ++i)
|
|
{
|
|
if (scripts[i] == null || scripts[i].length() == 0)
|
|
{
|
|
System.err.println("Java obj_id.attachScript[] trying to attach empty script name to object " + m_id);
|
|
continue;
|
|
}
|
|
|
|
String script = scripts[i];
|
|
if (!script.startsWith(SCRIPT_PREFIX))
|
|
script = SCRIPT_PREFIX + script;
|
|
|
|
if (VALIDATE_SCRIPTS)
|
|
{
|
|
if (m_scripts.contains(script))
|
|
{
|
|
System.err.println("WARNING: Java obj_id.attachScript(array) tried to add script " +
|
|
script + " to object " + this + " more than once!");
|
|
continue;
|
|
}
|
|
}
|
|
if (DEBUG)
|
|
System.out.println("Java obj_id.attachScript[] attaching script " + script + " to object " + m_id);
|
|
m_scripts.add(0, script);
|
|
}
|
|
} // attachScript(String[])
|
|
|
|
/**
|
|
* Removes a script from this object.
|
|
*
|
|
* @param script the script to detach
|
|
*/
|
|
private void detachScript(String script)
|
|
{
|
|
// System.out.println("Java obj_id.detachScript enter");
|
|
if (m_scripts == null)
|
|
{
|
|
System.err.println("ERROR: Java obj_id.detachScript: m_scripts == null!");
|
|
return;
|
|
}
|
|
if (script == null)
|
|
{
|
|
System.err.println("ERROR: Java obj_id.detachScript: script == null!");
|
|
return;
|
|
}
|
|
if (m_scriptLock > 0)
|
|
{
|
|
m_pendingScripts.add(new pending_script(false, script));
|
|
if (DEBUG)
|
|
System.out.println("Java obj_id.detachScript pending detach script " + script);
|
|
return;
|
|
}
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("Java obj_id.detachScript detaching script " + script);
|
|
}
|
|
int index = m_scripts.indexOf(SCRIPT_PREFIX + script);
|
|
if (index >= 0)
|
|
m_scripts.remove(index);
|
|
|
|
// System.out.println("Java obj_id.detachScript exit");
|
|
} // detachScript()
|
|
|
|
/**
|
|
* Removes all the scripts from this object.
|
|
*/
|
|
private void detachAllScripts()
|
|
{
|
|
// System.out.println("Java obj_id.detachAllScripts enter");
|
|
if (m_scripts == null)
|
|
{
|
|
System.err.println("ERROR: Java obj_id.detachAllScripts: m_scripts == null!");
|
|
return;
|
|
}
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("Java obj_id.detachAllScripts detaching all scripts");
|
|
}
|
|
m_scripts.clear();
|
|
|
|
// System.out.println("Java obj_id.detachAllScripts exit");
|
|
} // detachAllScripts()
|
|
|
|
private LinkedList getAllScriptsWithPending()
|
|
{
|
|
if (m_scripts == null)
|
|
return null;
|
|
|
|
// we have to set up a list of our scripts, adding and removing scripts from the pending list as needed
|
|
LinkedList scriptList = new LinkedList(m_scripts);
|
|
|
|
if (m_pendingScripts != null)
|
|
{
|
|
int count = m_pendingScripts.size();
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
pending_script pending = (pending_script)m_pendingScripts.get(i);
|
|
String scriptName = null;
|
|
if (!pending.script.startsWith(SCRIPT_PREFIX))
|
|
scriptName = SCRIPT_PREFIX + pending.script;
|
|
else
|
|
scriptName = pending.script;
|
|
if (pending.add)
|
|
scriptList.addFirst(scriptName);
|
|
else
|
|
scriptList.remove(scriptName);
|
|
}
|
|
}
|
|
return scriptList;
|
|
}
|
|
|
|
/**
|
|
* \defgroup serialize Serialize support functions
|
|
* @{ */
|
|
|
|
private void writeObject(ObjectOutputStream out) throws IOException
|
|
{
|
|
out.defaultWriteObject();
|
|
// write the obj_id value
|
|
out.writeLong(m_id.longValue());
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("obj_id Serialize writeObject writing id #" + m_id.longValue());
|
|
}
|
|
}
|
|
|
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
|
|
{
|
|
in.defaultReadObject();
|
|
if (m_nextSerializedId == -1)
|
|
{
|
|
// read the obj_id value
|
|
m_nextSerializedId = in.readLong();
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("obj_id Serialize readObject reading id #" + m_nextSerializedId);
|
|
}
|
|
}
|
|
else
|
|
System.err.println("ERROR: Reading new obj_id while serializedId still pending!!!");
|
|
}
|
|
|
|
private Object readResolve() throws ObjectStreamException
|
|
{
|
|
if (m_nextSerializedId != -1)
|
|
{
|
|
if (DEBUG)
|
|
{
|
|
System.out.println("obj_id Serialize readResolve creating obj_id #" + m_nextSerializedId);
|
|
}
|
|
obj_id result = obj_id.getObjId(m_nextSerializedId);
|
|
m_nextSerializedId = -1;
|
|
return result;
|
|
}
|
|
System.err.println("ERROR: Deserializing readResolve obj_id while serializedId == -1!!!");
|
|
return null;
|
|
}
|
|
|
|
/*@}*/
|
|
|
|
static
|
|
{
|
|
// start the cleanup thread
|
|
m_cleanup = new obj_id_cleanup();
|
|
m_cleanup.start();
|
|
}
|
|
|
|
} // class obj_id
|