Home | History | Annotate | Download | only in cpp
      1 /**
      2  * Copied from node_object_wrap.h
      3  * see http://www.nodejs.org/
      4  *
      5  * Node's license follows:
      6  *
      7  * Copyright 2009, 2010 Ryan Lienhart Dahl. All rights reserved.
      8  * Permission is hereby granted, free of charge, to any person obtaining a copy
      9  * of this software and associated documentation files (the "Software"), to
     10  * deal in the Software without restriction, including without limitation the
     11  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     12  * sell copies of the Software, and to permit persons to whom the Software is
     13  * furnished to do so, subject to the following conditions:
     14  *
     15  * The above copyright notice and this permission notice shall be included in
     16  * all copies or substantial portions of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     24  * IN THE SOFTWARE.
     25  */
     26 
     27 #ifndef MOCK_RIL_NODE_OBJECT_WRAP_H_
     28 #define MOCK_RIL_NODE_OBJECT_WRAP_H_
     29 
     30 #include <v8.h>
     31 #include <assert.h>
     32 
     33 class ObjectWrap {
     34  public:
     35   ObjectWrap ( ) {
     36     refs_ = 0;
     37   }
     38 
     39   virtual ~ObjectWrap ( ) {
     40     if (!handle_.IsEmpty()) {
     41       assert(handle_.IsNearDeath());
     42       handle_->SetInternalField(0, v8::Undefined());
     43       handle_.Dispose();
     44       handle_.Clear();
     45     }
     46   }
     47 
     48   template <class T>
     49   static inline T* Unwrap (v8::Handle<v8::Object> handle)
     50   {
     51     assert(!handle.IsEmpty());
     52     assert(handle->InternalFieldCount() > 0);
     53     return static_cast<T*>(v8::Handle<v8::External>::Cast(
     54         handle->GetInternalField(0))->Value());
     55   }
     56 
     57   v8::Persistent<v8::Object> handle_; // ro
     58 
     59  protected:
     60   inline void Wrap (v8::Handle<v8::Object> handle)
     61   {
     62     assert(handle_.IsEmpty());
     63     assert(handle->InternalFieldCount() > 0);
     64     handle_ = v8::Persistent<v8::Object>::New(handle);
     65     handle_->SetInternalField(0, v8::External::New(this));
     66     MakeWeak();
     67   }
     68 
     69   inline void MakeWeak (void)
     70   {
     71     handle_.MakeWeak(this, WeakCallback);
     72   }
     73 
     74   /* Ref() marks the object as being attached to an event loop.
     75    * Refed objects will not be garbage collected, even if
     76    * all references are lost.
     77    */
     78   virtual void Ref() {
     79     assert(!handle_.IsEmpty());
     80     refs_++;
     81     handle_.ClearWeak();
     82   }
     83 
     84   /* Unref() marks an object as detached from the event loop.  This is its
     85    * default state.  When an object with a "weak" reference changes from
     86    * attached to detached state it will be freed. Be careful not to access
     87    * the object after making this call as it might be gone!
     88    * (A "weak reference" means an object that only has a
     89    * persistant handle.)
     90    *
     91    * DO NOT CALL THIS FROM DESTRUCTOR
     92    */
     93   virtual void Unref() {
     94     assert(!handle_.IsEmpty());
     95     assert(!handle_.IsWeak());
     96     assert(refs_ > 0);
     97     if (--refs_ == 0) { MakeWeak(); }
     98   }
     99 
    100   int refs_; // ro
    101 
    102  private:
    103   static void WeakCallback (v8::Persistent<v8::Value> value, void *data)
    104   {
    105     ObjectWrap *obj = static_cast<ObjectWrap*>(data);
    106     assert(value == obj->handle_);
    107     assert(!obj->refs_);
    108     if (value.IsNearDeath()) delete obj;
    109   }
    110 };
    111 
    112 #endif // MOCK_RIL_NODE_OBJECT_WRAP_H_
    113