// Copyright (c) 2013 GitHub, Inc. All rights reserved. // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. #include "atom/common/api/atom_api_id_weak_map.h" #include #include "base/logging.h" #include "native_mate/constructor.h" #include "native_mate/object_template_builder.h" #include "atom/common/node_includes.h" namespace atom { namespace api { IDWeakMap::IDWeakMap() : next_id_(0) { } IDWeakMap::~IDWeakMap() { } int32_t IDWeakMap::Add(v8::Isolate* isolate, v8::Handle object) { int32_t key = GetNextID(); object->SetHiddenValue(mate::StringToV8(isolate, "IDWeakMapKey"), mate::Converter::ToV8(isolate, key)); map_[key] = new mate::RefCountedPersistent(isolate, object); map_[key]->SetWeak(this, WeakCallback); return key; } v8::Handle IDWeakMap::Get(v8::Isolate* isolate, int32_t key) { if (!Has(key)) { node::ThrowError("Invalid key"); return v8::Undefined(isolate); } return map_[key]->NewHandle(); } bool IDWeakMap::Has(int32_t key) const { return map_.find(key) != map_.end(); } std::vector IDWeakMap::Keys() const { std::vector keys; keys.reserve(map_.size()); for (auto it = map_.begin(); it != map_.end(); ++it) keys.push_back(it->first); return keys; } void IDWeakMap::Remove(int32_t key) { if (Has(key)) map_.erase(key); else LOG(WARNING) << "Object with key " << key << " is being GCed for twice."; } int IDWeakMap::GetNextID() { return ++next_id_; } // static void IDWeakMap::BuildPrototype(v8::Isolate* isolate, v8::Handle prototype) { mate::ObjectTemplateBuilder(isolate, prototype) .SetMethod("add", &IDWeakMap::Add) .SetMethod("get", &IDWeakMap::Get) .SetMethod("has", &IDWeakMap::Has) .SetMethod("keys", &IDWeakMap::Keys) .SetMethod("remove", &IDWeakMap::Remove); } // static void IDWeakMap::WeakCallback( const v8::WeakCallbackData& data) { int32_t key = data.GetValue()->GetHiddenValue( mate::StringToV8(data.GetIsolate(), "IDWeakMapKey"))->Int32Value(); data.GetParameter()->Remove(key); } } // namespace api } // namespace atom namespace { void Initialize(v8::Handle exports, v8::Handle unused, v8::Handle context, void* priv) { using atom::api::IDWeakMap; v8::Isolate* isolate = context->GetIsolate(); v8::Local constructor = mate::CreateConstructor( isolate, "IDWeakMap", base::Bind(&mate::NewOperatorFactory)); exports->Set(mate::StringToV8(isolate, "IDWeakMap"), constructor); } } // namespace NODE_MODULE_CONTEXT_AWARE_BUILTIN(atom_common_id_weak_map, Initialize)