--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/m3g_qt/javasrc/javax/microedition/m3g/Interface.java Fri Jun 11 13:33:44 2010 +0300
@@ -0,0 +1,403 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+package javax.microedition.m3g;
+
+import java.lang.ref.WeakReference;
+import java.util.Hashtable;
+import org.eclipse.swt.widgets.Display;
+//#ifdef RD_JAVA_OMJ
+import com.nokia.mj.impl.rt.support.Finalizer;
+//#endif // RD_JAVA_OMJ
+
+/**
+ * M3G interface object. An interface is automatically created for
+ * each MIDlet using the 3D API to keep track of Java-side object
+ * lifetimes etc.
+ */
+class Interface
+{
+ //------------------------------------------------------------------
+ // Static data
+ //------------------------------------------------------------------
+
+ // Common class enumeration for Java and native code
+
+ private static final int ANIMATION_CONTROLLER = 0x01;
+ private static final int ANIMATION_TRACK = 0x02;
+ private static final int APPEARANCE = 0x03;
+ private static final int BACKGROUND = 0x04;
+ private static final int CAMERA = 0x05;
+ private static final int COMPOSITING_MODE = 0x06;
+ private static final int FOG = 0x07;
+ private static final int GROUP = 0x08;
+ private static final int IMAGE_2D = 0x09;
+ private static final int INDEX_BUFFER = 0x0A;
+ private static final int KEYFRAME_SEQUENCE = 0x0B;
+ private static final int LIGHT = 0x0C;
+ private static final int LOADER = 0x0D;
+ private static final int MATERIAL = 0x0E;
+ private static final int MESH = 0x0F;
+ private static final int MORPHING_MESH = 0x10;
+ private static final int POLYGON_MODE = 0x11;
+ private static final int RENDER_CONTEXT = 0x12;
+ private static final int SKINNED_MESH = 0x13;
+ private static final int SPRITE_3D = 0x14;
+ private static final int TEXTURE_2D = 0x15;
+ private static final int VERTEX_ARRAY = 0x16;
+ private static final int VERTEX_BUFFER = 0x17;
+ private static final int WORLD = 0x18;
+
+ // Once created, the interface singleton currently remains in
+ // memory until VM exit. By using a WeakReference here, with hard
+ // references stored in each object, it could be GC'd when no more
+ // objects exist, but that probably isn't worth the extra memory
+ // overhead.
+
+ //private static Hashtable s_instances = new Hashtable();
+ private static Interface instance = null;
+
+ //------------------------------------------------------------------
+ // Instance data
+ //------------------------------------------------------------------
+
+ /**
+ * Handle of the native interface object.
+ */
+ private int handle;
+
+ /**
+ * Global handle-to-Object3D map used to both find the Java
+ * counterparts of objects returned from the native methods, and
+ * keep certain objects from being garbage collected.
+ */
+ private final Hashtable liveObjects = new Hashtable();
+
+ /**
+ * Flag for shutdown signal
+ */
+ private boolean iShutdown = false;
+
+ /**
+ * Flag for native peer init state
+ */
+ private boolean iNativeInitialized = false;
+
+
+//#ifdef RD_JAVA_OMJ
+ private Finalizer mFinalizer;
+//#endif // RD_JAVA_OMJ
+
+ //------------------------------------------------------------------
+ // Constructors
+ //------------------------------------------------------------------
+
+ private Interface()
+ {
+
+ // Contruct native peer
+ initNativePeer();
+
+//#ifdef RD_JAVA_OMJ
+ mFinalizer = new Finalizer()
+ {
+ public void finalizeImpl()
+ {
+ doFinalize();
+ }
+ };
+//#else // RD_JAVA_OMJ
+// Platform.registerFinalizer(this);
+//#endif // RD_JAVA_OMJ
+ }
+
+ //------------------------------------------------------------------
+ // Package methods
+ //------------------------------------------------------------------
+
+ /**
+ * Returns the M3G interface instance for the current MIDlet.
+ */
+ static final Interface getInstance()
+ {
+ if (instance == null)
+ {
+ instance = new Interface();
+ }
+ return instance;
+ }
+
+ /**
+ * Returns the native handle of the current Interface instance.
+ */
+ static final int getHandle()
+ {
+ getInstance().integrityCheck();
+ return getInstance().handle;
+ }
+
+ /**
+ * Registers an Object3D with this interface. The object is added
+ * to the global handle-to-object map, and the native finalization
+ * callback is set up. The handle of the object must already be
+ * set at this point!
+ */
+ static final void register(Object3D obj)
+ {
+ Platform.registerFinalizer(obj);
+ getInstance().liveObjects.put(new Integer(obj.handle),
+ new WeakReference(obj));
+ }
+
+ static final void register(Loader obj)
+ {
+ Platform.registerFinalizer(obj);
+ getInstance().liveObjects.put(new Integer(obj.handle),
+ new WeakReference(obj));
+ }
+
+ /**
+ * Finds an Object3D in the global handle-to-object map. Also
+ * removes dead objects (that is, null references) from the map
+ * upon encountering them.
+ */
+ static final Object3D findObject(int handle)
+ {
+ Interface self = getInstance();
+ Integer iHandle = new Integer(handle);
+ Object ref = self.liveObjects.get(iHandle);
+
+ if (ref != null)
+ {
+ Object3D obj = (Object3D)((WeakReference)ref).get();
+ if (obj == null)
+ {
+ self.liveObjects.remove(iHandle);
+ }
+ return obj;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the Java object representing a native object, or
+ * creates a new proxy/peer if one doesn't exist yet.
+ */
+ static final Object3D getObjectInstance(int handle)
+ {
+
+ // A zero handle equals null
+
+ if (handle == 0)
+ {
+ return null;
+ }
+
+ // Then try to find an existing Java representative for the
+ // object
+
+ Object3D obj = findObject(handle);
+ if (obj != null)
+ {
+ return obj;
+ }
+
+ // Not found, create a new Java object. Note that only
+ // non-abstract classes can possibly be returned.
+
+ switch (_getClassID(handle))
+ {
+ case ANIMATION_CONTROLLER:
+ return new AnimationController(handle);
+ case ANIMATION_TRACK:
+ return new AnimationTrack(handle);
+ case APPEARANCE:
+ return new Appearance(handle);
+ case BACKGROUND:
+ return new Background(handle);
+ case CAMERA:
+ return new Camera(handle);
+ case COMPOSITING_MODE:
+ return new CompositingMode(handle);
+ case FOG:
+ return new Fog(handle);
+ case GROUP:
+ return new Group(handle);
+ case IMAGE_2D:
+ return new Image2D(handle);
+ case INDEX_BUFFER:
+ return new TriangleStripArray(handle);
+ case KEYFRAME_SEQUENCE:
+ return new KeyframeSequence(handle);
+ case LIGHT:
+ return new Light(handle);
+ //case LOADER:
+ case MATERIAL:
+ return new Material(handle);
+ case MESH:
+ return new Mesh(handle);
+ case MORPHING_MESH:
+ return new MorphingMesh(handle);
+ case POLYGON_MODE:
+ return new PolygonMode(handle);
+ //case RENDER_CONTEXT:
+ case SKINNED_MESH:
+ return new SkinnedMesh(handle);
+ case SPRITE_3D:
+ return new Sprite3D(handle);
+ case TEXTURE_2D:
+ return new Texture2D(handle);
+ case VERTEX_ARRAY:
+ return new VertexArray(handle);
+ case VERTEX_BUFFER:
+ return new VertexBuffer(handle);
+ case WORLD:
+ return new World(handle);
+ default:
+ throw new Error();
+ }
+ }
+
+ /**
+ * Forces removal of an object from the handle-to-object map.
+ */
+ static final void deregister(Object3D obj, Interface self)
+ {
+ self.liveObjects.remove(new Integer(obj.handle));
+ if (self.liveObjects.isEmpty() && self.iShutdown)
+ {
+ self.registeredFinalize();
+ }
+ }
+
+ /**
+ * Forces removal of an object from the handle-to-object map.
+ */
+ static final void deregister(Loader obj, Interface self)
+ {
+ self.liveObjects.remove(new Integer(obj.handle));
+ if (self.liveObjects.isEmpty() && self.iShutdown)
+ {
+ self.registeredFinalize();
+ }
+ }
+
+ /**
+ * Sets shutdown indication flag. Actual native
+ * cleanup occurs when liveObjects count is zero
+ */
+ void signalShutdown()
+ {
+ iShutdown = true;
+ }
+
+ /**
+ * Gets the state of this interface
+ * @return true if interface is fully constructed, otherwise false
+ */
+ boolean isFullyInitialized()
+ {
+ return iNativeInitialized;
+ }
+
+ //------------------------------------------------------------------
+ // Private methods
+ //------------------------------------------------------------------
+
+ /**
+ * Checks the status of the native interface
+ */
+ private void integrityCheck()
+ {
+ if (!iNativeInitialized)
+ {
+ // If native interface cannot be initialized we cannot recover from it
+ if (!initNativePeer())
+ {
+ throw new Error("UI thread not available");
+ }
+ }
+ }
+
+ /**
+ * Initializes native peer
+ * @return true if native interface was succesfully inialized otherwise false
+ */
+ private boolean initNativePeer()
+ {
+ if (iNativeInitialized)
+ {
+ return true;
+ }
+ if (Platform.uiThreadAvailable())
+ {
+ Platform.executeInUIThread(
+ new M3gRunnable()
+ {
+ public void doRun()
+ {
+ handle = _ctor();
+ }
+ });
+ iNativeInitialized = true;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+//#ifdef RD_JAVA_OMJ
+ private void doFinalize()
+ {
+ if (mFinalizer != null)
+ {
+ registeredFinalize();
+ mFinalizer = null;
+ }
+ }
+//#endif // RD_JAVA_OMJ
+
+ // Native finalization hook, for Symbian only
+ final private void registeredFinalize()
+ {
+ if (Interface.instance != null)
+ {
+ // Finalize M3G interface
+ Platform.executeInUIThread(
+ new M3gRunnable()
+ {
+ public void doRun()
+ {
+ Platform.finalizeInterface(handle);
+ }
+ });
+ Interface.instance = null;
+ }
+ }
+
+ // Native constructor
+ private static native int _ctor();
+
+ // Native class ID resolver
+ private static native int _getClassID(int hObject);
+}