diff options
author | Sven Gothel <[email protected]> | 2013-07-04 20:19:35 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-07-04 20:19:35 +0200 |
commit | 99479bf3197cde8e89c5b499d135417863d521c7 (patch) | |
tree | fd4ae1f0532c750a3ac02af2edb74ed83ebf0743 /src/newt/classes/com | |
parent | 1d9e043f6e0acba2dde9d4afd57bc75141ed050f (diff) |
NEWT: Using WeakReferences for global cache of Display, Screen and Window instances; Removing ref. at API destroy() is wrong ; Allow GC to clear ..
- Removing ref. at API destroy() is wrong
- Since all instances can be recreated, removing ref at destroy() is simply wrong.
- Keep weak references until GC collects, i.e. user does not claim them anymore.
- Safe for Display, since it holds it's EDT thread.
- Window/Screen .. if user abandons reference .. nothing we can do here.
- Allow GC to clear ..
No need to hold ref loonger than user.
Diffstat (limited to 'src/newt/classes/com')
-rw-r--r-- | src/newt/classes/com/jogamp/newt/Display.java | 66 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/Screen.java | 56 |
2 files changed, 96 insertions, 26 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java index d6ddd9613..4f5df6c70 100644 --- a/src/newt/classes/com/jogamp/newt/Display.java +++ b/src/newt/classes/com/jogamp/newt/Display.java @@ -31,6 +31,7 @@ package com.jogamp.newt; import com.jogamp.newt.util.EDTUtil; import jogamp.newt.Debug; +import java.lang.ref.WeakReference; import java.util.*; import javax.media.nativewindow.AbstractGraphicsDevice; @@ -178,16 +179,16 @@ public abstract class Display { public abstract void dispatchMessages(); // Global Displays - protected static final ArrayList<Display> displayList = new ArrayList<Display>(); + protected static final ArrayList<WeakReference<Display>> displayList = new ArrayList<WeakReference<Display>>(); protected static int displaysActive = 0; public static void dumpDisplayList(String prefix) { synchronized(displayList) { - Iterator<Display> i = displayList.iterator(); System.err.println(prefix+" DisplayList[] entries: "+displayList.size()+" - "+getThreadName()); - for(int j=0; i.hasNext(); j++) { - Display d = i.next(); - System.err.println(" ["+j+"] : "+d); + final Iterator<WeakReference<Display>> ri = displayList.iterator(); + for(int j=0; ri.hasNext(); j++) { + final Display d = ri.next().get(); + System.err.println(" ["+j+"] : "+d+", GC'ed "+(null==d)); } } } @@ -216,29 +217,62 @@ public abstract class Display { return getDisplayOfImpl(type, name, fromIndex, -1, shared); } - private static Display getDisplayOfImpl(String type, String name, int fromIndex, int incr, boolean shared) { + private static Display getDisplayOfImpl(String type, String name, final int fromIndex, final int incr, boolean shared) { synchronized(displayList) { int i = fromIndex >= 0 ? fromIndex : displayList.size() - 1 ; while( ( incr > 0 ) ? i < displayList.size() : i >= 0 ) { - Display display = (Display) displayList.get(i); - if( display.getType().equals(type) && - display.getName().equals(name) && - ( !shared || shared && !display.isExclusive() ) - ) { - return display; + final Display display = (Display) displayList.get(i).get(); + if( null == display ) { + // Clear GC'ed dead reference entry! + displayList.remove(i); + if( incr < 0 ) { + // decrease + i+=incr; + } // else nop - remove shifted subsequent elements to the left + } else { + if( display.getType().equals(type) && + display.getName().equals(name) && + ( !shared || shared && !display.isExclusive() ) + ) { + return display; + } + i+=incr; } - i+=incr; } } return null; } - + + protected static void addDisplay2List(Display display) { + synchronized(displayList) { + // GC before add + int i=0; + while( i < displayList.size() ) { + if( null == displayList.get(i).get() ) { + displayList.remove(i); + } else { + i++; + } + } + displayList.add(new WeakReference<Display>(display)); + } + } + /** Returns the global display collection */ - @SuppressWarnings("unchecked") public static Collection<Display> getAllDisplays() { ArrayList<Display> list; synchronized(displayList) { - list = (ArrayList<Display>) displayList.clone(); + list = new ArrayList<Display>(); + int i = 0; + while( i < displayList.size() ) { + final Display d = displayList.get(i).get(); + if( null == d ) { + displayList.remove(i); + } else { + list.add( displayList.get(i).get() ); + i++; + } + } } return list; } diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java index cf8145561..f56ee344b 100644 --- a/src/newt/classes/com/jogamp/newt/Screen.java +++ b/src/newt/classes/com/jogamp/newt/Screen.java @@ -29,6 +29,8 @@ package com.jogamp.newt; import com.jogamp.newt.event.MonitorModeListener; import jogamp.newt.Debug; + +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -224,7 +226,7 @@ public abstract class Screen { public abstract void removeMonitorModeListener(MonitorModeListener sml); // Global Screens - protected static ArrayList<Screen> screenList = new ArrayList<Screen>(); + protected static final ArrayList<WeakReference<Screen>> screenList = new ArrayList<WeakReference<Screen>>(); protected static int screensActive = 0; /** @@ -253,26 +255,60 @@ public abstract class Screen { synchronized(screenList) { int i = fromIndex >= 0 ? fromIndex : screenList.size() - 1 ; while( ( incr > 0 ) ? i < screenList.size() : i >= 0 ) { - Screen screen = (Screen) screenList.get(i); - if( screen.getDisplay().equals(display) && - screen.getIndex() == idx ) { - return screen; + final Screen screen = (Screen) screenList.get(i).get(); + if( null == screen ) { + // Clear GC'ed dead reference entry! + screenList.remove(i); + if( incr < 0 ) { + // decrease + i+=incr; + } // else nop - remove shifted subsequent elements to the left + } else { + if( screen.getDisplay().equals(display) && + screen.getIndex() == idx ) { + return screen; + } + i+=incr; } - i+=incr; } } return null; } - /** Returns the global display collection */ - @SuppressWarnings("unchecked") + + protected static void addScreen2List(Screen screen) { + synchronized(screenList) { + // GC before add + int i=0; + while( i < screenList.size() ) { + if( null == screenList.get(i).get() ) { + screenList.remove(i); + } else { + i++; + } + } + screenList.add(new WeakReference<Screen>(screen)); + } + } + + /** Returns the global screen collection */ public static Collection<Screen> getAllScreens() { ArrayList<Screen> list; synchronized(screenList) { - list = (ArrayList<Screen>) screenList.clone(); + list = new ArrayList<Screen>(); + int i = 0; + while( i < screenList.size() ) { + final Screen s = screenList.get(i).get(); + if( null == s ) { + screenList.remove(i); + } else { + list.add( screenList.get(i).get() ); + i++; + } + } } return list; } - + public static int getActiveScreenNumber() { synchronized(screenList) { return screensActive; |