001/* ----------------------------------------------------------------------------
002 * This file was automatically generated by SWIG (http://www.swig.org).
003 * Version 4.0.2
004 *
005 * Do not make changes to this file unless you know what you are doing--modify
006 * the SWIG interface file instead.
007 * ----------------------------------------------------------------------------- */
008
009package com.avpkit.ferry;
010
011/**
012 * Parent of all Ferry objects -- it mains reference counts<br>
013 * in native code.<br>
014 * <p><br>
015 * RefCounted objects cannot be made with new.  They must be<br>
016 * constructed with special factory methods, usually called<br>
017 * make(...).<br>
018 * </p><br>
019 * <h2>Special note for developers in languages other than C++</h2><br>
020 * <p><br>
021 * You should not need to worry about this class very much.  Feel<br>
022 * free to ignore it.<br>
023 * </p><br>
024 * <h2>Special note for C++ Users</h2><br>
025 * <p><br>
026 * Users of RefCounted objects in Native (C++) code must make<br>
027 * sure they acquire() a reference to an object if they<br>
028 * intend to keep using it after they have returned from<br>
029 * the method it was passed to, and<br>
030 * must call release() when done to ensure memory is freed.<br>
031 * </p><br>
032 * <p><br>
033 * Methods that return RefCounted objects on the stack are<br>
034 * expected to acquire() the reference for the caller, and<br>
035 * callers <b>must</b> release() any RefCounted object<br>
036 * returned on the stack.<br>
037 * <p><br>
038 * For example:<br>
039 * </p><br>
040 * <code><br>
041 * <pre><br>
042 * RefCounted * methodReturningRefCountedObject();<br>
043 * {<br>
044 *   mValueToReturn-&gt;acquire(); // acquire for caller<br>
045 *   return mValueToReturn; // and return<br>
046 * }<br>
047 * <br>
048 * {<br>
049 *   RefCounted *value = methodReturningRefCountedObject();<br>
050 *   ...<br>
051 *   // caller must release<br>
052 *   if (value)<br>
053 *     value-&gt;release();<br>
054 * }<br>
055 * </pre><br>
056 * </code>
057 */
058public class RefCounted {
059  // JNIHelper.swg: Start generated code
060  // >>>>>>>>>>>>>>>>>>>>>>>>>>>
061  private volatile long swigCPtr;
062  /**
063   * Internal Only.
064   */
065  protected boolean swigCMemOwn;
066  private com.avpkit.ferry.JNIReference mRefCounter;
067  private Long mLifecycleReference;
068
069  // the next object looks like it is unused by the compiler, but that's not true; it most
070  // definitely is used :)
071  @SuppressWarnings("unused")
072  private com.avpkit.ferry.JNINativeFinalizer mObjectToForceFinalize;
073  private java.util.concurrent.atomic.AtomicLong mJavaRefCount;
074
075  /**
076   * Internal Only.  Not part of public API.
077   */
078  protected RefCounted(long cPtr, boolean cMemoryOwn) {
079    this(cPtr, cMemoryOwn, new java.util.concurrent.atomic.AtomicLong(0L));
080  }
081  
082  /**
083   * Internal Only.  Not part of public API.
084   */
085  protected RefCounted(long cPtr, boolean cMemoryOwn,
086      java.util.concurrent.atomic.AtomicLong ref)
087  {
088    swigCMemOwn = cMemoryOwn;
089    swigCPtr = cPtr;
090    // Create the reference count that java-only objects will use
091    // to avoid calling acquire and release on copyReference
092    ref.incrementAndGet();
093    mJavaRefCount = ref;
094    if (swigCPtr != 0)
095    {
096      // This object must:
097      // (a) have no references to any other java object
098      // (b) Have a finalizer that just calls gc() on our JNIMemoryManager
099      // It exists only to force gc() to be called even if someone calls the AVPKit
100      // libraries once and never again
101      mObjectToForceFinalize = new com.avpkit.ferry.JNINativeFinalizer();
102      // This is what the weak reference will watch; this object should
103      // (a) have no references to any other Java object
104      // (b) MUST NOT have a finalizer
105      // (c) MUST NOT acquire any other references to it except for the strong reference
106      //     right here, and the weak reference in mRefCounter
107      mLifecycleReference = new Long(swigCPtr);      
108      // Force the creation of a new weak reference, will will actually pin itself
109      // inside the reference class.
110      mRefCounter = JNIReference.createReference(
111          this,
112          mLifecycleReference, swigCPtr,
113          mJavaRefCount);
114    }
115  }
116
117  /**
118   * Internal Only.  Not part of public API.
119   *
120   * Get the raw value of the native object that obj is proxying for.
121   *   
122   * @param obj The java proxy object for a native object.
123   * @return The raw pointer obj is proxying for.
124   */
125  public static long getCPtr(RefCounted obj) {
126    if (obj == null) return 0;
127    return obj.getMyCPtr();
128  }
129  
130  /**
131   * Internal Only.  Not part of public API.
132   *
133   * Get the raw value of the native object that we're proxying for.
134   *   
135   * @return The raw pointer we're proxying for.
136   */
137  public long getMyCPtr() {
138    if (swigCPtr == 0) throw new NullPointerException("underlying native object already deleted");
139    return swigCPtr;
140  }
141  
142  /**
143   * Releases any underlying native memory and marks this object
144   * as invalid.
145   * <p>
146   * Normally Ferry manages when to release native memory.
147   * </p>
148   * <p>
149   * In the unlikely event you want to control EXACTLY when a native 
150   * object is released, each AVPKit object has a {@link #delete()}
151   * method that you can use. Once you call {@link #delete()},
152   * you must ENSURE your object is never referenced again from
153   * that Java object -- Ferry tries to help you avoid crashes if you
154   * accidentally use an object after deletion but on this but we
155   * cannot offer 100% protection (specifically if another thread
156   *  is accessing that object EXACTLY when you {@link #delete()} it). 
157   * </p>
158   */
159   
160   public void delete()
161   {
162     if(swigCPtr != 0) {
163       // assigning to an object removes an incorrect java
164       // compiler warning for some
165       // generated files
166       Object object = this;
167       if (object instanceof RefCounted && mRefCounter != null) {
168         mRefCounter.delete();
169       } else if (swigCMemOwn) {
170         swigCMemOwn = false;
171       }
172
173     }
174     mJavaRefCount = null;
175     mRefCounter = null;
176     mObjectToForceFinalize = null;
177     mLifecycleReference = null;
178     swigCPtr = 0;
179   }
180   
181  /**
182   * Create a new RefCounted object that is actually referring to the
183   * exact same underlying native object.
184   *
185   * @return the new Java object.
186   */
187  public RefCounted copyReference() {
188    if (swigCPtr == 0)
189      return null;
190    else
191      return new RefCounted(swigCPtr, swigCMemOwn, getJavaRefCount());
192  }
193
194  /**
195   * Internal Only.  Do not use.
196   */
197  protected java.util.concurrent.atomic.AtomicLong getJavaRefCount()
198  {
199    return mJavaRefCount;
200  }
201   
202
203    /**
204     * Return the current reference count on this object.
205     * <p>
206     * The number returned represents the value at the instant
207     * the message was called, and the value can change even
208     * before this method returns.  Callers are advised not to
209     * depend on the value of this except to check that
210     * the value == 1.
211     * </p>
212     * <p>
213     * If the value returned is one, and you know you have a valid
214     * reference to that object, then congratulations; you are the
215     * only person referencing that object.
216     * </p>
217     * @return The current ref count.
218     */
219  public long getCurrentRefCount()
220  {
221    return mJavaRefCount.get()+getCurrentNativeRefCount()-1;
222  }
223     // <<<<<<<<<<<<<<<<<<<<<<<<<<<
224   // JNIHelper.swg: End generated code
225  
226 
227 
228  /**
229   * Internal Only.  <strong>DO NOT USE FROM JAVA</strong>.<br>
230   * <p><br>
231   * Acquire a reference to this object.<br>
232   * This increments the native internal ref count in native code by +1.  <br>
233   *  </p><br>
234   * <p><br>
235   * This method is called internally by Ferry in Java, and you should<br>
236   * not call it without knowing what you are doing.  But if you do<br>
237   * call it, make sure you call {#release()} once for each call<br>
238   * you make to this method.<br>
239   * </p><br>
240   * @return The refcount after the acquire.  Note due to multi-threaded issues, you should not rely on this value,<br>
241   * as it may change before the method returns to you.
242   */
243  public int acquire() {
244    return FerryJNI.RefCounted_acquire(swigCPtr, this);
245  }
246
247  /**
248   * Internal Only.  <strong>DO NOT USE FROM JAVA</strong>.<br>
249   * <p><br>
250   * This decrements the native internal ref count by -1; the object is destroyed if its ref count reaches zero.<br>
251   * </p><br>
252   * <p><br>
253   * This method is called internally by Ferry in Java, and you should<br>
254   * not call it without knowing what you are doing.  But if you do<br>
255   * call it, make sure you had previously called {#acquire()} once for each call<br>
256   * to {#release()} you make.<br>
257   * </p><br>
258   * @return The ref count after the release.  Note due to multi-threaded issues, you should not rely on this value,<br>
259   * as it may change before the method returns to you.
260   */
261  public int release() {
262    return FerryJNI.RefCounted_release(swigCPtr, this);
263  }
264
265  /**
266   * Return the current reference count on this object.<br>
267   * <br>
268   * The number returned represents the value at the instant<br>
269   * the message was called, and the value can change even<br>
270   * before this method returns.  Callers are advised not to<br>
271   * depend on the value of this except to check that<br>
272   * the value == 1.<br>
273   * <p><br>
274   * If the value returned is one, and you know you have a valid<br>
275   * reference to that object, then congratulations; you are the<br>
276   * only person referencing that object.<br>
277   * </p><br>
278   * @return The current ref count.
279   */
280  private int getCurrentNativeRefCount() {
281    return FerryJNI.RefCounted_getCurrentNativeRefCount(swigCPtr, this);
282  }
283
284}