From a4127835a43a12fd648f9ce3e2cda74e02de0aee Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Thu, 15 Apr 2021 01:45:07 +0200 Subject: [PATCH] [DEV] better event loot --- src/org/atriasoft/gale/Gale.java | 8 +- src/org/atriasoft/gale/GaleApplication.java | 29 +++-- .../{Context.java => GaleContext.java} | 121 ++++++++++++------ .../context/LWJG_AWT/ContextLWJGLAWT.java | 10 +- src/org/atriasoft/gale/resource/Resource.java | 4 +- .../gale/test/sample1/Sample1Application.java | 6 +- .../gale/test/sample2/Sample2Application.java | 6 +- 7 files changed, 112 insertions(+), 72 deletions(-) rename src/org/atriasoft/gale/context/{Context.java => GaleContext.java} (89%) diff --git a/src/org/atriasoft/gale/Gale.java b/src/org/atriasoft/gale/Gale.java index 00594a4..2cccb49 100644 --- a/src/org/atriasoft/gale/Gale.java +++ b/src/org/atriasoft/gale/Gale.java @@ -1,16 +1,16 @@ package org.atriasoft.gale; import org.atriasoft.etk.Uri; -import org.atriasoft.gale.context.Context; +import org.atriasoft.gale.context.GaleContext; //import org.atriasoft.gale.context.JOGL.ContextJOGL; import org.atriasoft.gale.context.LWJG_AWT.ContextLWJGLAWT; //import org.atriasoft.gale.context.LWJGL.ContextLWJGL; import org.atriasoft.gale.internal.Log; public class Gale { - public static Context getContext() { + public static GaleContext getContext() { // TODO Auto-generated method stub - return Context.getContext(); + return GaleContext.getContext(); } /** @@ -40,7 +40,7 @@ public class Gale { public static int run(final GaleApplication application, final String[] arg) { init(); //etk::init(_argc, _argv); - Context context = null; + GaleContext context = null; String request = ""; //context = ContextLWJGL.create(application, arg); diff --git a/src/org/atriasoft/gale/GaleApplication.java b/src/org/atriasoft/gale/GaleApplication.java index 9274513..d283ac1 100644 --- a/src/org/atriasoft/gale/GaleApplication.java +++ b/src/org/atriasoft/gale/GaleApplication.java @@ -3,7 +3,7 @@ package org.atriasoft.gale; import org.atriasoft.etk.Uri; import org.atriasoft.etk.math.Vector2f; import org.atriasoft.gale.context.ClipboardList; -import org.atriasoft.gale.context.Context; +import org.atriasoft.gale.context.GaleContext; import org.atriasoft.gale.context.Cursor; import org.atriasoft.gale.internal.Log; import org.atriasoft.gale.key.KeyKeyboard; @@ -94,7 +94,7 @@ public class GaleApplication { * Hide the virtal keyboard (if possible : only on iOs/Android) */ public void keyboardHide() { - final Context context = Gale.getContext(); + final GaleContext context = Gale.getContext(); if (context == null) { return; } @@ -105,7 +105,7 @@ public class GaleApplication { * Show the virtal keyboard (if possible : only on iOs/Android) */ public void keyboardShow() { - final Context context = Gale.getContext(); + final GaleContext context = Gale.getContext(); if (context == null) { return; } @@ -128,7 +128,7 @@ public class GaleApplication { * The application is created. * @param context Current gale context. */ - public void onCreate(final Context context) { + public void onCreate(final GaleContext context) { Log.verbose("Create Gale Application"); } @@ -136,7 +136,7 @@ public class GaleApplication { * The application is removed (call destructor just adter it.). * @param context Current gale context. */ - public void onDestroy(final Context context) { + public void onDestroy(final GaleContext context) { Log.verbose("Destroy Gale Application"); } @@ -144,7 +144,7 @@ public class GaleApplication { * Real draw of the application * @param context Current gale context. */ - public void onDraw(final Context context) { + public void onDraw(final GaleContext context) { Log.verbose("draw Gale Application"); } @@ -163,7 +163,7 @@ public class GaleApplication { * The user request application removing. * @param context Current gale context. */ - public void onKillDemand(final Context context) { + public void onKillDemand(final GaleContext context) { Log.info("Gale request auto destroy ==> no applification specification"); System.exit(0); } @@ -180,7 +180,7 @@ public class GaleApplication { * The application is Hide / not visible. * @param context Current gale context. */ - public void onPause(final Context context) { + public void onPause(final GaleContext context) { Log.verbose("Pause Gale Application"); } @@ -205,7 +205,7 @@ public class GaleApplication { * call application to precalculate drawing. * @param context Current gale context. */ - public void onRegenerateDisplay(final Context context) { + public void onRegenerateDisplay(final GaleContext context) { //Log.verbose("Regenerate Gale Application"); markDrawingIsNeeded(); } @@ -220,13 +220,14 @@ public class GaleApplication { return; } this.windowsSize = size; + markDrawingIsNeeded(); } /** * The application is resumed (now visible). * @param context Current gale context. */ - public void onResume(final Context context) { + public void onResume(final GaleContext context) { Log.verbose("Start Gale Application"); } @@ -234,7 +235,7 @@ public class GaleApplication { * The application is started. * @param context Current gale context. */ - public void onStart(final Context context) { + public void onStart(final GaleContext context) { Log.verbose("Start Gale Application"); } @@ -242,7 +243,7 @@ public class GaleApplication { * The application is stopped. * @param context Current gale context. */ - public void onStop(final Context context) { + public void onStop(final GaleContext context) { Log.verbose("Stop Gale Application"); } @@ -291,7 +292,7 @@ public class GaleApplication { } Vector2f oldSize = this.windowsSize; this.windowsSize = size; - final Context context = Gale.getContext(); + final GaleContext context = Gale.getContext(); if (context == null) { return; } @@ -307,7 +308,7 @@ public class GaleApplication { */ public void setTitle(final String title) { this.title = title; - final Context context = Gale.getContext(); + final GaleContext context = Gale.getContext(); if (context == null) { return; } diff --git a/src/org/atriasoft/gale/context/Context.java b/src/org/atriasoft/gale/context/GaleContext.java similarity index 89% rename from src/org/atriasoft/gale/context/Context.java rename to src/org/atriasoft/gale/context/GaleContext.java index 51309ec..5fa8617 100644 --- a/src/org/atriasoft/gale/context/Context.java +++ b/src/org/atriasoft/gale/context/GaleContext.java @@ -1,14 +1,16 @@ package org.atriasoft.gale.context; import java.util.Vector; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import org.atriasoft.etk.Color; import org.atriasoft.etk.ThreadAbstract; import org.atriasoft.etk.Uri; import org.atriasoft.etk.math.Vector2f; -import org.atriasoft.gale.GaleApplication; import org.atriasoft.gale.Fps; import org.atriasoft.gale.Gale; +import org.atriasoft.gale.GaleApplication; import org.atriasoft.gale.Orientation; import org.atriasoft.gale.backend3d.OpenGL; import org.atriasoft.gale.internal.Log; @@ -19,16 +21,16 @@ import org.atriasoft.gale.key.KeyType; import org.atriasoft.gale.resource.ResourceManager; interface ActionToDoInAsyncLoop { - public void run(Context context); + public void run(GaleContext context); } enum ApplicationState { UNDEFINED, CREATE, RUNNING, DIED }; -public abstract class Context { +public abstract class GaleContext { protected static final int MAX_MANAGE_INPUT = 15; - private static Context globalContext = null; + private static GaleContext globalContext = null; // return true if a flush is needed private static int countMemeCheck = 0; @@ -36,14 +38,16 @@ public abstract class Context { * From everyware in the program, we can get the context inteface. * @return current reference on the instance. */ - public static Context getContext() { + public static GaleContext getContext() { return globalContext; } - public static void setContext(final Context context) { + public static void setContext(final GaleContext context) { globalContext = context; } + Lock lock = new ReentrantLock(); + protected ThreadAbstract periodicThread;; protected GaleApplication application; //!< Application handle protected ApplicationState applicationState = ApplicationState.UNDEFINED; // state of the application @@ -51,8 +55,8 @@ public abstract class Context { private final ResourceManager resourceManager = new ResourceManager(); //!< global resources Manager // simulation area: private long previousDisplayTime; // this is to limit framerate ... in case... - private final Vector msgSystem = new Vector<>(); private final boolean displayFps = true; + private final MessageSystem msgSystem = new MessageSystem(); private final Fps fpsSystemEvent = new Fps("SystemEvent", this.displayFps); private final Fps fpsSystemContext = new Fps("SystemContext", this.displayFps); private final Fps fpsSystem = new Fps("System", this.displayFps); @@ -61,7 +65,7 @@ public abstract class Context { protected boolean fullscreen = false; protected Vector2f windowsPos; //!< current size of the system - public Context(final GaleApplication application, final String[] args) { + public GaleContext(final GaleApplication application, final String[] args) { // set a basic this.application = application; this.applicationState = ApplicationState.CREATE; @@ -155,31 +159,25 @@ public abstract class Context { if (this.application == null) { return; } - if (this.windowsSize == Vector2f.ZERO) { + if (this.windowsSize.equals(Vector2f.ZERO)) { return; } this.application.onResize(this.windowsSize); } // Called by Consumer - public synchronized ActionToDoInAsyncLoop getAction() { - notify(); - while (this.msgSystem.size() == 0) { - try { - wait(); - } catch (final InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - return null; - } //By executing wait() from a synchronized block, a thread gives up its hold on the lock and goes to sleep. - } - final ActionToDoInAsyncLoop message = this.msgSystem.firstElement(); - this.msgSystem.removeElement(message); - return message; + public ActionToDoInAsyncLoop getAction() { + return this.msgSystem.getElementWait(); } public GaleApplication getApplication() { - return this.application; + + this.lock.lock(); + try { + return this.application; + } finally { + this.lock.unlock(); + } } public CommandLine getCmd() { @@ -487,13 +485,14 @@ public abstract class Context { * @param size new size of the windows. */ public void operatingSystemResize(final Vector2f size) { - if (this.windowsSize == size) { + Log.warning("Resize request: " + size + " old=" + this.windowsSize); + if (this.windowsSize.equals(size)) { return; } // TODO Better in the thread ... ==> but generate some init error ... //gale::Dimension::setPixelWindowsSize(size); postAction((context) -> { - Log.debug("Receive MSG : THREADRESIZE : " + context.windowsSize + " ==> " + size); + Log.error("Receive MSG : THREAD_RESIZE : " + context.windowsSize + " ==> " + size); context.windowsSize = size; //gale::Dimension::setPixelWindowsSize(context.windowsSize); final GaleApplication tmpAppl = context.getApplication(); @@ -608,9 +607,8 @@ public abstract class Context { unLockContext(); } - private synchronized void postAction(final ActionToDoInAsyncLoop data) { + private void postAction(final ActionToDoInAsyncLoop data) { this.msgSystem.addElement(data); - notify(); //Later, when the necessary event happens, the thread that is running it calls notify() from a block synchronized on the same object. } @@ -618,13 +616,15 @@ public abstract class Context { * Processing all the event arrived ... (commoly called in draw function) */ public void processEvents() { + if (!this.lock.tryLock()) { + return; + } try { int nbEvent = 0; - //Log.debug(" ******** Event " << this.msgSystem.count()); - while (this.msgSystem.size() > 0) { + while (this.msgSystem.getSize() > 0) { + //Log.error(" [" + nbEvent + "] event ..."); nbEvent++; - //Log.verbose(" [" << nbEvent << "] event ..."); - final ActionToDoInAsyncLoop func = getAction(); + final ActionToDoInAsyncLoop func = this.msgSystem.getElementWait(); if (func == null) { continue; } @@ -632,6 +632,8 @@ public abstract class Context { } } catch (Exception e) { Log.critical("Catch exception in main event Loop ...", e); + } finally { + this.lock.unlock(); } } @@ -778,12 +780,49 @@ public abstract class Context { } +} + +class MessageSystem { + private final Vector data = new Vector<>(); + + public synchronized void addElement(final ActionToDoInAsyncLoop data2) { + this.data.addElement(data2); + notifyAll(); + } + + public synchronized ActionToDoInAsyncLoop getElement() { + //Log.warning("+++++++++++++++++++++++++++++++++ getElement()"); + ActionToDoInAsyncLoop message = this.data.firstElement(); + this.data.removeElement(message); + //Log.warning("+++++++++++++++++++++++++++++++++ getElement() ===> done " + message); + return message; + } + + public synchronized ActionToDoInAsyncLoop getElementWait() { + if (this.data.isEmpty()) { + try { + wait(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + if (this.data.isEmpty()) { + return null; + } + return getElement(); + } + + public synchronized int getSize() { + return this.data.size(); + } }; class PeriodicThread extends ThreadAbstract { - private final Context context; + private final GaleContext context; - public PeriodicThread(final Context context) { + public PeriodicThread(final GaleContext context) { super("Galethread 2"); this.context = context; } @@ -807,13 +846,13 @@ class PeriodicThread extends ThreadAbstract { e.printStackTrace(); return; } - synchronized (this.context) { - this.context.processEvents(); - // call all the application for periodic request (the application manage multiple instance )... - final GaleApplication appl = this.context.getApplication(); - if (appl != null) { - appl.onPeriod(System.currentTimeMillis()); - } + ///synchronized (this.context) { + this.context.processEvents(); + // call all the application for periodic request (the application manage multiple instance )... + final GaleApplication appl = this.context.getApplication(); + if (appl != null) { + appl.onPeriod(System.currentTimeMillis()); } + //} } } diff --git a/src/org/atriasoft/gale/context/LWJG_AWT/ContextLWJGLAWT.java b/src/org/atriasoft/gale/context/LWJG_AWT/ContextLWJGLAWT.java index bab73a7..5203c8b 100644 --- a/src/org/atriasoft/gale/context/LWJG_AWT/ContextLWJGLAWT.java +++ b/src/org/atriasoft/gale/context/LWJG_AWT/ContextLWJGLAWT.java @@ -33,7 +33,7 @@ import org.atriasoft.etk.math.Vector2f; import org.atriasoft.gale.DisplayManagerDraw; import org.atriasoft.gale.Fps; import org.atriasoft.gale.GaleApplication; -import org.atriasoft.gale.context.Context; +import org.atriasoft.gale.context.GaleContext; import org.atriasoft.gale.internal.Log; import org.atriasoft.gale.key.KeyKeyboard; import org.atriasoft.gale.key.KeySpecial; @@ -48,7 +48,7 @@ import org.lwjgl.opengl.awt.AWTGLCanvas; //import org.lwjgl.system.MemoryStack; import org.lwjgl.opengl.awt.GLData; -public class ContextLWJGLAWT extends Context implements MouseListener, MouseMotionListener, KeyListener, MouseWheelListener { +public class ContextLWJGLAWT extends GaleContext implements MouseListener, MouseMotionListener, KeyListener, MouseWheelListener { private static final int WIDTH = 800; private static final int HEIGHT = 600; private static final int MAX_MANAGE_INPUT = 15; @@ -67,7 +67,7 @@ public class ContextLWJGLAWT extends Context implements MouseListener, MouseMoti private static double currentMousePositionX = 0; private static double currentMousePositionY = 0; - public static Context create(final GaleApplication application, final String[] arg) { + public static GaleContext create(final GaleApplication application, final String[] arg) { // TODO Auto-generated method stub return new ContextLWJGLAWT(application, arg); } @@ -170,8 +170,8 @@ public class ContextLWJGLAWT extends Context implements MouseListener, MouseMoti if (ContextLWJGLAWT.this.decoratedWindowsSize.x() != w || ContextLWJGLAWT.this.decoratedWindowsSize.y() != h) { ContextLWJGLAWT.this.decoratedWindowsSize = new Vector2f(w, h); final Rectangle bounds = ContextLWJGLAWT.this.canvas.getBounds(); - ContextLWJGLAWT.this.windowsSize = new Vector2f(bounds.width, bounds.height); - operatingSystemResize(ContextLWJGLAWT.this.windowsSize); + Vector2f tmpWindowsSize = new Vector2f(bounds.width, bounds.height); + operatingSystemResize(tmpWindowsSize); } operatingSystemDraw(true); swapBuffers(); diff --git a/src/org/atriasoft/gale/resource/Resource.java b/src/org/atriasoft/gale/resource/Resource.java index a72c3e3..97195ee 100644 --- a/src/org/atriasoft/gale/resource/Resource.java +++ b/src/org/atriasoft/gale/resource/Resource.java @@ -1,7 +1,7 @@ package org.atriasoft.gale.resource; import org.atriasoft.etk.Uri; -import org.atriasoft.gale.context.Context; +import org.atriasoft.gale.context.GaleContext; import org.atriasoft.gale.internal.Log; public abstract class Resource { @@ -13,7 +13,7 @@ public abstract class Resource { * Get the current resource Manager */ protected static ResourceManager getManager() { - return Context.getContext().getResourcesManager(); + return GaleContext.getContext().getResourcesManager(); } protected long uid = -1; //!< unique ID definition diff --git a/src/org/atriasoft/gale/test/sample1/Sample1Application.java b/src/org/atriasoft/gale/test/sample1/Sample1Application.java index 578c33a..e3eb705 100644 --- a/src/org/atriasoft/gale/test/sample1/Sample1Application.java +++ b/src/org/atriasoft/gale/test/sample1/Sample1Application.java @@ -7,7 +7,7 @@ import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.math.Vector3f; import org.atriasoft.gale.GaleApplication; import org.atriasoft.gale.backend3d.OpenGL; -import org.atriasoft.gale.context.Context; +import org.atriasoft.gale.context.GaleContext; import org.atriasoft.gale.key.KeyKeyboard; import org.atriasoft.gale.key.KeySpecial; import org.atriasoft.gale.key.KeyStatus; @@ -32,7 +32,7 @@ public class Sample1Application extends GaleApplication { private ResourceVirtualArrayObject verticesVBO; @Override - public void onCreate(final Context context) { + public void onCreate(final GaleContext context) { //setSize(new Vector2f(800, 600)); this.angle = 0.0f; this.oGLprogram = ResourceProgram.create(new Uri("DATA", "basic.vert"), new Uri("DATA", "basic.frag")); @@ -56,7 +56,7 @@ public class Sample1Application extends GaleApplication { } @Override - public void onDraw(final Context context) { + public void onDraw(final GaleContext context) { this.angle += 0.01; //Log.info("==> appl Draw ..."); Vector2f size = getSize(); diff --git a/src/org/atriasoft/gale/test/sample2/Sample2Application.java b/src/org/atriasoft/gale/test/sample2/Sample2Application.java index 2da6649..5de1950 100644 --- a/src/org/atriasoft/gale/test/sample2/Sample2Application.java +++ b/src/org/atriasoft/gale/test/sample2/Sample2Application.java @@ -7,7 +7,7 @@ import org.atriasoft.etk.math.Vector2f; import org.atriasoft.etk.math.Vector3f; import org.atriasoft.gale.GaleApplication; import org.atriasoft.gale.backend3d.OpenGL; -import org.atriasoft.gale.context.Context; +import org.atriasoft.gale.context.GaleContext; import org.atriasoft.gale.key.KeyKeyboard; import org.atriasoft.gale.key.KeySpecial; import org.atriasoft.gale.key.KeyStatus; @@ -28,7 +28,7 @@ public class Sample2Application extends GaleApplication { private ResourceTexture texture; @Override - public void onCreate(final Context context) { + public void onCreate(final GaleContext context) { setSize(new Vector2f(800, 600)); this.oGLprogram = ResourceProgram.create(new Uri("DATA", "basic.vert"), new Uri("DATA", "basic.frag")); if (this.oGLprogram != null) { @@ -106,7 +106,7 @@ public class Sample2Application extends GaleApplication { } @Override - public void onDraw(final Context context) { + public void onDraw(final GaleContext context) { this.angleX += 0.001; this.angleY += 0.005; this.angleZ += 0.01;