Add WeakMap built-in module.
authorCheng Zhao <zcbenz@gmail.com>
Thu, 25 Apr 2013 13:46:04 +0000 (21:46 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Thu, 25 Apr 2013 13:46:04 +0000 (21:46 +0800)
atom.gyp
common/api/atom_api_id_weak_map.cc [new file with mode: 0644]
common/api/atom_api_id_weak_map.h [new file with mode: 0644]
common/api/atom_extensions.h
common/api/lib/id_weak_map.coffee [new file with mode: 0644]

index 2a1c6e1..4b67a4d 100644 (file)
--- a/atom.gyp
+++ b/atom.gyp
@@ -12,6 +12,7 @@
       'browser/atom/atom.coffee',
       'browser/atom/objects_registry.coffee',
       'browser/atom/rpc_server.coffee',
+      'common/api/lib/id_weak_map.coffee',
       'renderer/api/lib/ipc.coffee',
       'renderer/api/lib/remote.coffee',
     ],
@@ -44,6 +45,8 @@
       'common/api/api_messages.cc',
       'common/api/api_messages.h',
       'common/api/atom_api_idle_gc.cc',
+      'common/api/atom_api_id_weak_map.cc',
+      'common/api/atom_api_id_weak_map.h',
       'common/api/atom_api_v8_util.cc',
       'common/api/atom_bindings.cc',
       'common/api/atom_bindings.h',
diff --git a/common/api/atom_api_id_weak_map.cc b/common/api/atom_api_id_weak_map.cc
new file mode 100644 (file)
index 0000000..1680024
--- /dev/null
@@ -0,0 +1,138 @@
+// Copyright (c) 2013 GitHub, Inc. All rights reserved.
+// Copyright (c) 2012 Intel Corp. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "common/api/atom_api_id_weak_map.h"
+
+namespace atom {
+
+namespace api {
+
+IDWeakMap::IDWeakMap()
+    : nextId_(0) {
+}
+
+IDWeakMap::~IDWeakMap() {
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
+  auto copied_map = map_;
+  for (auto el : copied_map)
+    Erase(isolate, el.first);
+}
+
+bool IDWeakMap::Has(int key) const {
+  return map_.find(key) != map_.end();
+}
+
+void IDWeakMap::Erase(v8::Isolate* isolate, int key) {
+  v8::Persistent<v8::Value> value = map_[key];
+  value.ClearWeak(isolate);
+  value.Dispose(isolate);
+  value.Clear();
+
+  map_.erase(key);
+}
+
+int IDWeakMap::GetNextID() {
+  return ++nextId_;
+}
+
+// static
+void IDWeakMap::WeakCallback(v8::Isolate* isolate,
+                             v8::Persistent<v8::Value> value,
+                             void *data) {
+  IDWeakMap* obj = static_cast<IDWeakMap*>(data);
+  int key = value->ToObject()->GetHiddenValue(
+      v8::String::New("IDWeakMapKey"))->IntegerValue();
+  obj->Erase(isolate, key);
+}
+
+// static
+v8::Handle<v8::Value> IDWeakMap::New(const v8::Arguments& args) {
+  IDWeakMap* obj = new IDWeakMap();
+  obj->Wrap(args.This());
+  return args.This();
+}
+
+// static
+v8::Handle<v8::Value> IDWeakMap::Add(const v8::Arguments& args) {
+  if (!args[0]->IsObject())
+    return node::ThrowTypeError("Bad argument");
+
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  IDWeakMap* obj = ObjectWrap::Unwrap<IDWeakMap>(args.This());
+  int key = obj->GetNextID();
+
+  v8::Handle<v8::Value> v8_key = v8::Integer::New(key);
+  v8::Persistent<v8::Value> value =
+      v8::Persistent<v8::Value>::New(isolate, args[0]);
+
+  value->ToObject()->SetHiddenValue(v8::String::New("IDWeakMapKey"), v8_key);
+  value.MakeWeak(isolate, obj, WeakCallback);
+  obj->map_[key] = value;
+
+  return v8_key;
+}
+
+// static
+v8::Handle<v8::Value> IDWeakMap::Get(const v8::Arguments& args) {
+  if (!args[0]->IsNumber())
+    return node::ThrowTypeError("Bad argument");
+
+  IDWeakMap* obj = ObjectWrap::Unwrap<IDWeakMap>(args.This());
+
+  int key = args[0]->IntegerValue();
+  if (!obj->Has(key))
+    return node::ThrowError("Invalid key");
+
+  return obj->map_[key];
+}
+
+// static
+v8::Handle<v8::Value> IDWeakMap::Has(const v8::Arguments& args) {
+  if (!args[0]->IsNumber())
+    return node::ThrowTypeError("Bad argument");
+
+  IDWeakMap* obj = ObjectWrap::Unwrap<IDWeakMap>(args.This());
+
+  int key = args[0]->IntegerValue();
+  return v8::Boolean::New(obj->Has(key));
+}
+
+// static
+v8::Handle<v8::Value> IDWeakMap::Remove(const v8::Arguments& args) {
+  if (!args[0]->IsNumber())
+    return node::ThrowTypeError("Bad argument");
+
+  IDWeakMap* obj = ObjectWrap::Unwrap<IDWeakMap>(args.This());
+
+  int key = args[0]->IntegerValue();
+  if (!obj->Has(key))
+    return node::ThrowError("Invalid key");
+
+  obj->Erase(v8::Isolate::GetCurrent(), key);
+  return v8::Undefined();
+}
+
+// static
+void IDWeakMap::Initialize(v8::Handle<v8::Object> target) {
+  v8::HandleScope scope;
+
+  v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(IDWeakMap::New);
+  t->InstanceTemplate()->SetInternalFieldCount(1);
+  t->SetClassName(v8::String::NewSymbol("IDWeakMap"));
+
+  NODE_SET_PROTOTYPE_METHOD(t, "add", Add);
+  NODE_SET_PROTOTYPE_METHOD(t, "get", Get);
+  NODE_SET_PROTOTYPE_METHOD(t, "has", Has);
+  NODE_SET_PROTOTYPE_METHOD(t, "remove", Remove);
+
+  target->Set(v8::String::NewSymbol("IDWeakMap"), t->GetFunction());
+}
+
+}  // namespace api
+
+}  // namespace atom
+
+NODE_MODULE(atom_common_id_weak_map, atom::api::IDWeakMap::Initialize)
diff --git a/common/api/atom_api_id_weak_map.h b/common/api/atom_api_id_weak_map.h
new file mode 100644 (file)
index 0000000..ec28d57
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (c) 2013 GitHub, Inc. All rights reserved.
+// Copyright (c) 2012 Intel Corp. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ATOM_BROWSER_API_ATOM_API_ID_WEAK_MAP_H_
+#define ATOM_BROWSER_API_ATOM_API_ID_WEAK_MAP_H_
+
+#include <map>
+
+#include "base/basictypes.h"
+#include "vendor/node/src/node_object_wrap.h"
+
+namespace atom {
+
+namespace api {
+
+class IDWeakMap : public node::ObjectWrap {
+ public:
+  static void Initialize(v8::Handle<v8::Object> target);
+
+ private:
+  IDWeakMap();
+  virtual ~IDWeakMap();
+
+  bool Has(int key) const;
+  void Erase(v8::Isolate* isolate, int key);
+  int GetNextID();
+
+  static void WeakCallback(v8::Isolate* isolate,
+                           v8::Persistent<v8::Value> value,
+                           void *data);
+
+  static v8::Handle<v8::Value> New(const v8::Arguments& args);
+  static v8::Handle<v8::Value> Add(const v8::Arguments& args);
+  static v8::Handle<v8::Value> Get(const v8::Arguments& args);
+  static v8::Handle<v8::Value> Has(const v8::Arguments& args);
+  static v8::Handle<v8::Value> Remove(const v8::Arguments& args);
+
+  int nextId_;
+
+  std::map<int, v8::Persistent<v8::Value>> map_;
+
+  DISALLOW_COPY_AND_ASSIGN(IDWeakMap);
+};
+
+}  // namespace api
+
+}  // namespace atom
+
+#endif  // ATOM_BROWSER_API_ATOM_API_ID_WEAK_MAP_H_
index 6e75609..4967dd4 100644 (file)
@@ -19,6 +19,7 @@ NODE_EXT_LIST_ITEM(atom_renderer_ipc)
 // Module names start with `atom_common_` can be used by both browser and
 // renderer processes.
 NODE_EXT_LIST_ITEM(atom_common_idle_gc)
+NODE_EXT_LIST_ITEM(atom_common_id_weak_map)
 NODE_EXT_LIST_ITEM(atom_common_v8_util)
 
 NODE_EXT_LIST_END
diff --git a/common/api/lib/id_weak_map.coffee b/common/api/lib/id_weak_map.coffee
new file mode 100644 (file)
index 0000000..4860a3e
--- /dev/null
@@ -0,0 +1,3 @@
+IDWeakMap = process.atom_binding('id_weak_map').IDWeakMap
+
+module.exports = IDWeakMap