Add WeakMap built-in module.

This commit is contained in:
Cheng Zhao 2013-04-25 21:46:04 +08:00
parent bcfec7c8cd
commit e91d4c7c99
5 changed files with 196 additions and 0 deletions

View file

@ -12,6 +12,7 @@
'browser/atom/atom.coffee', 'browser/atom/atom.coffee',
'browser/atom/objects_registry.coffee', 'browser/atom/objects_registry.coffee',
'browser/atom/rpc_server.coffee', 'browser/atom/rpc_server.coffee',
'common/api/lib/id_weak_map.coffee',
'renderer/api/lib/ipc.coffee', 'renderer/api/lib/ipc.coffee',
'renderer/api/lib/remote.coffee', 'renderer/api/lib/remote.coffee',
], ],
@ -44,6 +45,8 @@
'common/api/api_messages.cc', 'common/api/api_messages.cc',
'common/api/api_messages.h', 'common/api/api_messages.h',
'common/api/atom_api_idle_gc.cc', '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_api_v8_util.cc',
'common/api/atom_bindings.cc', 'common/api/atom_bindings.cc',
'common/api/atom_bindings.h', 'common/api/atom_bindings.h',

View file

@ -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)

View file

@ -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_

View 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 // Module names start with `atom_common_` can be used by both browser and
// renderer processes. // renderer processes.
NODE_EXT_LIST_ITEM(atom_common_idle_gc) 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_ITEM(atom_common_v8_util)
NODE_EXT_LIST_END NODE_EXT_LIST_END

View file

@ -0,0 +1,3 @@
IDWeakMap = process.atom_binding('id_weak_map').IDWeakMap
module.exports = IDWeakMap