summaryrefslogtreecommitdiff
path: root/src/node_object_wrap.h
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2009-10-27 11:46:58 +0100
committerRyan Dahl <ry@tinyclouds.org>2009-10-27 11:46:58 +0100
commita5df0f6a65edda02aa70732de0321fae188d03ae (patch)
treea6454e54fa1ad81cbf41809d5a5886824c76f71f /src/node_object_wrap.h
parent2bac299aed28d3aa03a06f5588bb451be941069f (diff)
downloadandroid-node-v8-a5df0f6a65edda02aa70732de0321fae188d03ae.tar.gz
android-node-v8-a5df0f6a65edda02aa70732de0321fae188d03ae.tar.bz2
android-node-v8-a5df0f6a65edda02aa70732de0321fae188d03ae.zip
Prefix all source files with node_
Diffstat (limited to 'src/node_object_wrap.h')
-rw-r--r--src/node_object_wrap.h92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/node_object_wrap.h b/src/node_object_wrap.h
new file mode 100644
index 0000000000..686961406a
--- /dev/null
+++ b/src/node_object_wrap.h
@@ -0,0 +1,92 @@
+#ifndef object_wrap_h
+#define object_wrap_h
+
+#include <v8.h>
+#include <assert.h>
+
+namespace node {
+
+class ObjectWrap {
+ public:
+ ObjectWrap ( ) {
+ attached_ = 0;
+ }
+
+ virtual ~ObjectWrap ( ) {
+ if (!handle_.IsEmpty()) {
+ assert(handle_.IsNearDeath());
+ handle_->SetInternalField(0, v8::Undefined());
+ handle_.Dispose();
+ handle_.Clear();
+ }
+ }
+
+ protected:
+ template <class T>
+ static inline T* Unwrap (v8::Handle<v8::Object> handle)
+ {
+ assert(!handle.IsEmpty());
+ assert(handle->InternalFieldCount() > 0);
+ return static_cast<T*>(v8::Handle<v8::External>::Cast(
+ handle->GetInternalField(0))->Value());
+ }
+
+ inline void Wrap (v8::Handle<v8::Object> handle)
+ {
+ assert(handle_.IsEmpty());
+ assert(handle->InternalFieldCount() > 0);
+ handle_ = v8::Persistent<v8::Object>::New(handle);
+ handle_->SetInternalField(0, v8::External::New(this));
+ MakeWeak();
+ }
+
+ inline void MakeWeak (void)
+ {
+ handle_.MakeWeak(this, WeakCallback);
+ }
+
+ /* Attach() marks the object as being attached to an event loop.
+ * Attached objects will not be garbage collected, even if
+ * all references are lost.
+ */
+ virtual void Attach() {
+ assert(!handle_.IsEmpty());
+ assert(handle_.IsWeak());
+ attached_++;
+ }
+
+ /* Detach() marks an object as detached from the event loop. This is its
+ * default state. When an object with a "weak" reference changes from
+ * attached to detached state it will be freed. Be careful not to access
+ * the object after making this call as it might be gone!
+ * (A "weak reference" is v8 terminology for an object that only has a
+ * persistant handle.)
+ *
+ * DO NOT CALL THIS FROM DESTRUCTOR
+ */
+ virtual void Detach() {
+ assert(!handle_.IsEmpty());
+ assert(handle_.IsWeak());
+ assert(attached_ > 0);
+ attached_--;
+ if (attached_ == 0 && handle_.IsNearDeath()) delete this;
+ }
+
+ v8::Persistent<v8::Object> handle_; // ro
+ int attached_; // ro
+
+ private:
+ static void WeakCallback (v8::Persistent<v8::Value> value, void *data)
+ {
+ ObjectWrap *obj = static_cast<ObjectWrap*>(data);
+ assert(value == obj->handle_);
+ if (obj->attached_ == 0) {
+ delete obj;
+ } else {
+ obj->MakeWeak();
+ }
+ }
+};
+
+} // namespace node
+#endif // object_wrap_h