summaryrefslogtreecommitdiff
path: root/core/dictionary.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/dictionary.cpp')
-rw-r--r--core/dictionary.cpp136
1 files changed, 77 insertions, 59 deletions
diff --git a/core/dictionary.cpp b/core/dictionary.cpp
index 6770b798f1..3b4d3b65d0 100644
--- a/core/dictionary.cpp
+++ b/core/dictionary.cpp
@@ -5,7 +5,7 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -29,7 +29,6 @@
#include "dictionary.h"
#include "safe_refcount.h"
#include "variant.h"
-#include "io/json.h"
struct _DictionaryVariantHash {
@@ -37,62 +36,96 @@ struct _DictionaryVariantHash {
};
+
+
+
struct DictionaryPrivate {
+ struct Data {
+ Variant variant;
+ int order;
+ };
+
SafeRefCount refcount;
- HashMap<Variant,Variant,_DictionaryVariantHash> variant_map;
- bool shared;
+ HashMap<Variant,Data,_DictionaryVariantHash> variant_map;
+ int counter;
};
+struct DictionaryPrivateSort {
-void Dictionary::get_key_list( List<Variant> *p_keys) const {
+ bool operator()(const HashMap<Variant,DictionaryPrivate::Data,_DictionaryVariantHash>::Pair *A,const HashMap<Variant,DictionaryPrivate::Data,_DictionaryVariantHash>::Pair *B) const {
- _p->variant_map.get_key_list(p_keys);
-}
+ return A->data.order < B->data.order;
+ }
+};
-void Dictionary::_copy_on_write() const {
+void Dictionary::get_key_list( List<Variant> *p_keys) const {
- //make a copy of what we have
- if (_p->shared)
+ if (_p->variant_map.empty())
return;
- DictionaryPrivate *p = memnew(DictionaryPrivate);
- p->shared=_p->shared;
- p->variant_map=_p->variant_map;
- p->refcount.init();
- _unref();
- _p=p;
+ int count = _p->variant_map.size();
+ const HashMap<Variant,DictionaryPrivate::Data,_DictionaryVariantHash>::Pair **pairs = (const HashMap<Variant,DictionaryPrivate::Data,_DictionaryVariantHash>::Pair**)alloca( count * sizeof(HashMap<Variant,DictionaryPrivate::Data,_DictionaryVariantHash>::Pair *) );
+ _p->variant_map.get_key_value_ptr_array(pairs);
+
+ SortArray<const HashMap<Variant,DictionaryPrivate::Data,_DictionaryVariantHash>::Pair*,DictionaryPrivateSort> sort;
+ sort.sort(pairs,count);
+
+ for(int i=0;i<count;i++) {
+ p_keys->push_back(pairs[i]->key);
+ }
+
}
Variant& Dictionary::operator[](const Variant& p_key) {
- _copy_on_write();
- return _p->variant_map[p_key];
+ DictionaryPrivate::Data *v =_p->variant_map.getptr(p_key);
+
+ if (!v) {
+
+ DictionaryPrivate::Data d;
+ d.order=_p->counter++;
+ _p->variant_map[p_key]=d;
+ v =_p->variant_map.getptr(p_key);
+
+ }
+ return v->variant;
}
const Variant& Dictionary::operator[](const Variant& p_key) const {
- return _p->variant_map[p_key];
+ return _p->variant_map[p_key].variant;
}
const Variant* Dictionary::getptr(const Variant& p_key) const {
- return _p->variant_map.getptr(p_key);
+ const DictionaryPrivate::Data *v =_p->variant_map.getptr(p_key);
+ if (!v)
+ return NULL;
+ else
+ return &v->variant;
}
+
Variant* Dictionary::getptr(const Variant& p_key) {
- _copy_on_write();
- return _p->variant_map.getptr(p_key);
+ DictionaryPrivate::Data *v =_p->variant_map.getptr(p_key);
+ if (!v)
+ return NULL;
+ else
+ return &v->variant;
+
+
}
Variant Dictionary::get_valid(const Variant& p_key) const {
- const Variant *v = getptr(p_key);
+ DictionaryPrivate::Data *v =_p->variant_map.getptr(p_key);
if (!v)
return Variant();
- return *v;
+ else
+ return v->variant;
}
@@ -121,7 +154,8 @@ bool Dictionary::has_all(const Array& p_keys) const {
}
void Dictionary::erase(const Variant& p_key) {
- _copy_on_write();
+
+
_p->variant_map.erase(p_key);
}
@@ -149,13 +183,8 @@ void Dictionary::_ref(const Dictionary& p_from) const {
void Dictionary::clear() {
- _copy_on_write();
_p->variant_map.clear();
-}
-
-bool Dictionary::is_shared() const {
-
- return _p->shared;
+ _p->counter=0;
}
@@ -203,11 +232,20 @@ Array Dictionary::values() const {
Array varr;
varr.resize(size());
- const Variant *key=NULL;
- int i=0;
- while((key=next(key))){
- varr[i++] = _p->variant_map[*key];
+ if (_p->variant_map.empty())
+ return varr;
+
+ int count = _p->variant_map.size();
+ const HashMap<Variant,DictionaryPrivate::Data,_DictionaryVariantHash>::Pair **pairs = (const HashMap<Variant,DictionaryPrivate::Data,_DictionaryVariantHash>::Pair**)alloca( count * sizeof(HashMap<Variant,DictionaryPrivate::Data,_DictionaryVariantHash>::Pair *) );
+ _p->variant_map.get_key_value_ptr_array(pairs);
+
+ SortArray<const HashMap<Variant,DictionaryPrivate::Data,_DictionaryVariantHash>::Pair*,DictionaryPrivateSort> sort;
+ sort.sort(pairs,count);
+
+ for(int i=0;i<count;i++) {
+ varr[i]=pairs[i]->data.variant;
}
+
return varr;
}
@@ -216,25 +254,9 @@ const Variant* Dictionary::next(const Variant* p_key) const {
return _p->variant_map.next(p_key);
}
-
-Error Dictionary::parse_json(const String& p_json) {
-
- String errstr;
- int errline=0;
- if (p_json != ""){
- Error err = JSON::parse(p_json,*this,errstr,errline);
- if (err!=OK) {
- ERR_EXPLAIN("Error parsing JSON: "+errstr+" at line: "+itos(errline));
- ERR_FAIL_COND_V(err!=OK,err);
- }
- }
-
- return OK;
-}
-
Dictionary Dictionary::copy() const {
- Dictionary n(is_shared());
+ Dictionary n;
List<Variant> keys;
get_key_list(&keys);
@@ -246,11 +268,6 @@ Dictionary Dictionary::copy() const {
return n;
}
-String Dictionary::to_json() const {
-
- return JSON::print(*this);
-}
-
void Dictionary::operator=(const Dictionary& p_dictionary) {
@@ -265,11 +282,12 @@ Dictionary::Dictionary(const Dictionary& p_from) {
}
-Dictionary::Dictionary(bool p_shared) {
+Dictionary::Dictionary() {
_p=memnew( DictionaryPrivate );
_p->refcount.init();
- _p->shared=p_shared;
+ _p->counter=0;
+
}
Dictionary::~Dictionary() {