Add WeakMap built-in module.
This commit is contained in:
parent
bcfec7c8cd
commit
e91d4c7c99
5 changed files with 196 additions and 0 deletions
3
atom.gyp
3
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',
|
||||
|
|
138
common/api/atom_api_id_weak_map.cc
Normal file
138
common/api/atom_api_id_weak_map.cc
Normal 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)
|
51
common/api/atom_api_id_weak_map.h
Normal file
51
common/api/atom_api_id_weak_map.h
Normal 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_
|
|
@ -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
|
||||
|
|
3
common/api/lib/id_weak_map.coffee
Normal file
3
common/api/lib/id_weak_map.coffee
Normal file
|
@ -0,0 +1,3 @@
|
|||
IDWeakMap = process.atom_binding('id_weak_map').IDWeakMap
|
||||
|
||||
module.exports = IDWeakMap
|
Loading…
Reference in a new issue