View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2004 Kevin Rogers
4   //
5   // This file is part of MillScript.
6   //
7   // MillScript is free software; you can redistribute it and/or modify it under
8   // the terms of the GNU General Public License as published by the Free
9   // Software Foundation; either version 2 of the License, or (at your option)
10  // any later version.
11  //
12  // MillScript is distributed in the hope that it will be useful, but WITHOUT
13  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  // more details.
16  //
17  // You should have received a copy of the GNU General Public License along with
18  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
19  // Place, Suite 330, Boston, MA  02111-1307  USA
20  ////////////////////////////////////////////////////////////////////////////////
21  package org.millscript.millscript.datatypes;
22  
23  import java.lang.ref.SoftReference;
24  
25  /**
26   * This is a specific type of deferred object, whose value is held in a soft
27   * reference. This allows the garbage collector to reclaim the memory used by
28   * this object, providing there are no hard references left.
29   * <p>
30   * Using this type of object allows MillScript to autoload large objects
31   * without having to literally load them into memory. These objects will be
32   * loaded on demand and their memory freed when they are no longer in use. e.g.
33   * you can autoload a large number of images without having to hold them all in
34   * memory.
35   * </p>
36   */
37  public abstract class DeferredSoftReference< T > extends Deferred< T > {
38  
39      /**
40       * This soft reference to our object.
41       */
42      private SoftReference< T > ref = null;
43  
44      /**
45       * Calculates the value that should be held in this deferred soft
46       * reference.
47       *
48       * @return  the calculated value of this deferred object.
49       */
50      public abstract T calculate();
51  
52      /**
53       * Returns the calculated value for this deferred object, making a new soft
54       * reference to the new calculated value in the process.
55       *
56       * @return  the calculated value for this deferred object
57       */
58      private T force() {
59          final T x = this.calculate();
60          ref = new SoftReference< T >( x );
61          return x;
62      }
63  
64      /**
65       * @see org.millscript.millscript.datatypes.Deferred#get()
66       */
67      @Override
68      public final T get() {
69          if ( ref == null ) {
70              // No reference setup yet, so force it for the first time.
71              return this.force();
72          } else {
73              final T x = ref.get();
74              if ( x == null ) {
75                  // The reference has been cleared, so force it again.
76                  return this.force();
77              } else {
78                  // The reference is still valid, so return it's value.
79                  return x;
80              }
81          }
82      }
83  
84  }