Browse Source

Accroding the discuss on forum by Lasse and other users and refer to the json code in Lasse's Turso3D engine, rewrite JSONFile and JSONValue class, make it looks like JSON.

aster2013 10 years ago
parent
commit
c0014f40bb

+ 3 - 4
Source/Urho3D/LuaScript/pkgs/Resource/JSONFile.pkg

@@ -5,10 +5,11 @@ enum JSONValueType {};
 class JSONFile : Resource
 {
     JSONFile();
+    // JSONFile(const JSONValue& value);
     ~JSONFile();
 
-    JSONValue CreateRoot(JSONValueType valueType = JSON_OBJECT);
-    JSONValue GetRoot(JSONValueType valueType = JSON_ANY);
+    void SetRoot(const JSONValue& root);
+    const JSONValue& GetRoot() const;
 
     tolua_outside bool JSONFileSave @ Save(const String fileName, const String indentation = "\t") const;
 };
@@ -25,9 +26,7 @@ static int tolua_ResourceLuaAPI_JSONFile_new00_local(lua_State* tolua_S)
 {
     return ToluaNewObjectGC<JSONFile>(tolua_S);
 }
-$}
 
-${
 static bool JSONFileSave(const JSONFile* resource, const String& fileName, const String& indentation)
 {
     if (!resource)

+ 65 - 105
Source/Urho3D/LuaScript/pkgs/Resource/JSONValue.pkg

@@ -2,122 +2,82 @@ $#include "Resource/JSONValue.h"
 
 enum JSONValueType
 {
-    JSON_ANY = 0,
+    JSON_NULL,
+    JSON_BOOL,
+    JSON_NUMBER,
+    JSON_STRING,
+    JSON_ARRAY,
     JSON_OBJECT,
-    JSON_ARRAY
 };
 
 class JSONValue
 {
-    bool IsNull() const;
-    bool NotNull() const;
-    operator bool () const;
+	JSONValue();
+    JSONValue(bool value);
+    JSONValue(int value);
+    JSONValue(unsigned value);
+    JSONValue(float value);
+    JSONValue(double value);
+    JSONValue(const String value);
+    JSONValue(const char* value);
+    JSONValue(const JSONArray& value);
+    JSONValue(const JSONObject& value);    
+    JSONValue(const JSONValue& value);
+    ~JSONValue();
 
-    JSONValue CreateChild(const String name, JSONValueType valueType = JSON_OBJECT);
-    JSONValue GetChild(const String name, JSONValueType valueType = JSON_ANY) const;
-    void SetInt(const String name, int value);
-    void SetBool(const String name, bool value);
-    void SetFloat(const String name, float value);
-    void SetDouble(const String name, double value);
-    void SetVector2(const String name, const Vector2& value);
-    void SetVector3(const String name, const Vector3& value);
-    void SetVector4(const String name, const Vector4& value);
-    void SetVectorVariant(const String name, const Variant& value);
-    void SetQuaternion(const String name, const Quaternion& value);
-    void SetColor(const String name, const Color& value);
-    void SetString(const String name, const String value);
-    // void SetBuffer(const String name, const void* data, unsigned size);
-    // void SetBuffer(const String name, const PODVector<unsigned char>& value);
-    void SetResourceRef(const String name, const ResourceRef& value);
-    void SetResourceRefList(const String name, const ResourceRefList& value);
-    void SetIntRect(const String name, const IntRect& value);
-    void SetIntVector2(const String name, const IntVector2& value);
-    void SetMatrix3(const String name, const Matrix3& value);
-    void SetMatrix3x4(const String name, const Matrix3x4& value);
-    void SetMatrix4(const String name, const Matrix4& value);
-    void SetVariant(const String name, const Variant& value);
-    void SetVariantValue(const String name, const Variant& value);
+    void SetType(JSONValueType valueType);
+    // JSONValue& operator =(bool rhs);
+    // JSONValue& operator =(int rhs);
+    // JSONValue& operator =(unsigned rhs);
+    // JSONValue& operator =(float rhs);
+    // JSONValue& operator =(double rhs);
+    // JSONValue& operator =(const String rhs);
+    // JSONValue& operator =(const char* rhs);
+    // JSONValue& operator =(const JSONArray& rhs);
+    // JSONValue& operator =(const JSONObject& rhs);
+    // JSONValue& operator =(const JSONValue& rhs);
 
+    JSONValueType GetType() const;
+    bool IsNull() const;
+    bool IsBool() const;
+    bool IsNumber() const;
+    bool IsString() const;
+    bool IsArray() const;
     bool IsObject() const;
-    Vector<String> GetChildNames() const;
-    Vector<String> GetValueNames() const;
-    int GetInt(const String name) const;
-    bool GetBool(const String name) const;
-    float GetFloat(const String name) const;
-    double GetDouble(const String name) const;
-    Vector2 GetVector2(const String name) const;
-    Vector3 GetVector3(const String name) const;
-    Vector4 GetVector4(const String name) const;
-    Variant GetVectorVariant(const String name) const;
-    Quaternion GetQuaternion(const String name) const;
-    Color GetColor(const String name) const;
-    String GetString(const String name) const;
-    const char* GetCString(const String name) const;
-    // PODVector<unsigned char> GetBuffer(const String name) const;
-    // bool GetBuffer(const String name, void* dest, unsigned size) const;
-    ResourceRef GetResourceRef(const String name) const;
-    ResourceRefList GetResourceRefList(const String name) const;
-    IntRect GetIntRect(const String name) const;
-    IntVector2 GetIntVector2(const String name) const;
-    Matrix3 GetMatrix3(const String name) const;
-    Matrix3x4 GetMatrix3x4(const String name) const;
-    Matrix4 GetMatrix4(const String name) const;
-    Variant GetVariant(const String name) const;
-    Variant GetVariantValue(const String name, VariantType type) const;
 
-    JSONValue CreateChild(JSONValueType valueType = JSON_OBJECT);
-    JSONValue GetChild(unsigned index, JSONValueType valueType = JSON_ANY) const;
-    void AddInt(int value);
-    void AddBool(bool value);
-    void AddFloat(float value);
-    void AddDouble(double value);
-    void AddVector2(const Vector2& value);
-    void AddVector3(const Vector3& value);
-    void AddVector4(const Vector4& value);
-    void AddVectorVariant(const Variant& value);
-    void AddQuaternion(const Quaternion& value);
-    void AddColor(const Color& value);
-    void AddString(const String value);
-    // void AddBuffer(const PODVector<unsigned char>& value);
-    // void AddBuffer(const void* data, unsigned size);
-    void AddResourceRef(const ResourceRef& value);
-    void AddResourceRefList(const ResourceRefList& value);
-    void AddIntRect(const IntRect& value);
-    void AddIntVector2(const IntVector2& value);
-    void AddMatrix3(const Matrix3& value);
-    void AddMatrix3x4(const Matrix3x4& value);
-    void AddMatrix4(const Matrix4& value);
-    void AddVariant(const Variant& value);
-    void AddVariantValue(const Variant& value);
-    bool IsArray() const;
-    unsigned GetSize() const;
-    int GetInt(unsigned index) const;
-    bool GetBool(unsigned index) const;
-    float GetFloat(unsigned index) const;
-    double GetDouble(unsigned index) const;
-    Vector2 GetVector2(unsigned index) const;
-    Vector3 GetVector3(unsigned index) const;
-    Vector4 GetVector4(unsigned index) const;
-    Variant GetVectorVariant(unsigned index) const;
-    Quaternion GetQuaternion(unsigned index) const;
-    Color GetColor(unsigned index) const;
-    String GetString(unsigned index) const;
-    const char* GetCString(unsigned index) const;
-    // PODVector<unsigned char> GetBuffer(unsigned index) const;
-    // bool GetBuffer(unsigned index, void* dest, unsigned size) const;
-    ResourceRef GetResourceRef(unsigned index) const;
-    ResourceRefList GetResourceRefList(unsigned index) const;
-    IntRect GetIntRect(unsigned index) const;
-    IntVector2 GetIntVector2(unsigned index) const;
-    Matrix3 GetMatrix3(unsigned index) const;
-    Matrix3x4 GetMatrix3x4(unsigned index) const;
-    Matrix4 GetMatrix4(unsigned index) const;
-    Variant GetVariant(unsigned index) const;
-    Variant GetVariantValue(unsigned index, VariantType type) const;
+    bool GetBool() const;
+    int GetInt() const;
+    unsigned GetUint() const;
+    float GetFloat() const;
+    double GetDouble() const;
+    const String GetString() const;
+    const char* GetCString() const;
+    const JSONArray& GetArray() const;
+    const JSONObject& GetObject() const;
+
+    JSONValue& operator [](unsigned index);
+    const JSONValue& operator [](unsigned index) const;
+    JSONValue& At(unsigned index);
+    const JSONValue& At(unsigned index) const;
+    void Push(const JSONValue& value);
+    void Pop();
+    void Insert(unsigned pos, const JSONValue& value);
+    void Erase(unsigned pos, unsigned length = 1);
+    void Resize(unsigned newSize);
+    unsigned Size() const;
+
+    // JSONValue& operator [](const String key);
+    // const JSONValue& operator [](const String key) const;
+    void Set(const String key, const JSONValue& value);
+    const JSONValue& Get(const String key) const;
+    bool Erase(const String key);
+    bool Contains(const String key) const;
+
+    void Clear();
 
     static const JSONValue EMPTY;
+    static const JSONArray emptyArray;
+    static const JSONObject emptyObject;
 
     tolua_readonly tolua_property__is_set bool null;
-    tolua_readonly tolua_property__is_set bool object;
-    tolua_readonly tolua_property__is_set bool array;
 };

+ 123 - 32
Source/Urho3D/Resource/JSONFile.cpp

@@ -42,15 +42,19 @@ namespace Urho3D
 {
 
 JSONFile::JSONFile(Context* context) :
-    Resource(context),
-    document_(new Document())
+    Resource(context)
+    // , document_(new Document())
 {
 }
 
+JSONFile::JSONFile(Context* context, const JSONValue& value) :
+    Resource(context)
+{
+    SetRoot(value);
+}
+
 JSONFile::~JSONFile()
 {
-    delete document_;
-    document_ = 0;
 }
 
 void JSONFile::RegisterObject(Context* context)
@@ -58,6 +62,59 @@ void JSONFile::RegisterObject(Context* context)
     context->RegisterFactory<JSONFile>();
 }
 
+// Convert rapidjson value to JSON value.
+static void ToJSONValue(JSONValue& jsonValue, const rapidjson::Value& rapidjsonValue)
+{
+    switch (rapidjsonValue.GetType())
+    {
+    case kNullType:
+        jsonValue.SetType(JSON_NULL);
+        break;
+
+    case kFalseType:
+        jsonValue = false;
+        break;
+
+    case kTrueType:
+        jsonValue = true;
+        break;
+
+    case kNumberType:
+        jsonValue = rapidjsonValue.GetDouble();
+        break;
+
+    case kStringType:
+        jsonValue = rapidjsonValue.GetString();
+        break;
+
+    case kArrayType:
+        {
+            // JSON value will convert to array type
+            jsonValue.Resize(rapidjsonValue.Size());
+
+            for (unsigned i = 0; i < rapidjsonValue.Size(); ++i)
+            {
+                ToJSONValue(jsonValue[i], rapidjsonValue[i]);
+            }
+        }
+        break;
+
+    case kObjectType:
+        {
+            // JSON value will convert to object type
+            for (rapidjson::Value::ConstMemberIterator i = rapidjsonValue.MemberBegin(); i != rapidjsonValue.MemberEnd(); ++i)
+            {
+                JSONValue& value = jsonValue[String(i->name.GetString())];
+                ToJSONValue(value, i->value);
+            }
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
 bool JSONFile::BeginLoad(Deserializer& source)
 {
     unsigned dataSize = source.GetSize();
@@ -72,17 +129,73 @@ bool JSONFile::BeginLoad(Deserializer& source)
         return false;
     buffer[dataSize] = '\0';
 
-    if (document_->Parse<0>(buffer).HasParseError())
+    rapidjson::Document document;
+    if (document.Parse<0>(buffer).HasParseError())
     {
         LOGERROR("Could not parse JSON data from " + source.GetName());
         return false;
     }
 
+    document.GetAllocator();    
+    ToJSONValue(root_, document);
+
     SetMemoryUse(dataSize);
 
     return true;
 }
 
+static void ToRapidjsonValue(rapidjson::Value& rapidjsonValue, const JSONValue& jsonValue, rapidjson::MemoryPoolAllocator<>& allocator)
+{
+    switch (jsonValue.GetType())
+    {
+    case JSON_NULL:
+        rapidjsonValue.SetNull();
+        break;
+
+    case JSON_BOOL:
+        rapidjsonValue.SetBool(jsonValue.GetBool());
+        break;
+
+    case JSON_NUMBER:
+        rapidjsonValue.SetDouble(jsonValue.GetDouble());
+        break;
+
+    case JSON_STRING:
+        rapidjsonValue.SetString(jsonValue.GetCString(), allocator);
+        break;
+
+    case JSON_ARRAY:
+        {
+            const JSONArray& jsonArray = jsonValue.GetArray();
+
+            rapidjsonValue.SetArray();
+            rapidjsonValue.Reserve(jsonArray.Size(), allocator);
+
+            for (unsigned i = 0; i < jsonArray.Size(); ++i)
+                ToRapidjsonValue(rapidjsonValue[i], jsonArray[i], allocator);
+        }
+        break;
+
+    case JSON_OBJECT:
+        {
+            const JSONObject& jsonObject = jsonValue.GetObject();
+
+            rapidjsonValue.SetObject();
+            for (JSONObject::ConstIterator i = jsonObject.Begin(); i != jsonObject.End(); ++i)
+            {
+                const char* name = i->first_.CString();
+                rapidjson::Value value;
+                rapidjsonValue.AddMember(name, value, allocator);
+                ToRapidjsonValue(rapidjsonValue[name], i->second_, allocator);
+            }
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
 bool JSONFile::Save(Serializer& dest) const
 {
     return Save(dest, "\t");
@@ -90,38 +203,16 @@ bool JSONFile::Save(Serializer& dest) const
 
 bool JSONFile::Save(Serializer& dest, const String& indendation) const
 {
+    rapidjson::Document document;
+    ToRapidjsonValue(document, root_, document.GetAllocator());
+
     StringBuffer buffer;
-    PrettyWriter<StringBuffer> writer(buffer, &(document_->GetAllocator()));
+    PrettyWriter<StringBuffer> writer(buffer, &(document.GetAllocator()));
     writer.SetIndent(!indendation.Empty() ? indendation.Front() : '\0', indendation.Length());
 
-    document_->Accept(writer);
+    document.Accept(writer);
     unsigned size = (unsigned)buffer.GetSize();
     return dest.Write(buffer.GetString(), size) == size;
 }
 
-JSONValue JSONFile::CreateRoot(JSONValueType valueType)
-{
-    if (valueType == JSON_OBJECT)
-        document_->SetObject();
-    else
-        document_->SetArray();
-
-    return JSONValue(this, document_);
-}
-
-JSONValue JSONFile::GetRoot(JSONValueType valueType)
-{
-    if (!document_)
-        return JSONValue::EMPTY;
-
-    if ((valueType == JSON_OBJECT && document_->GetType() != kObjectType) ||
-        (valueType == JSON_ARRAY && document_->GetType() != kArrayType))
-    {
-        LOGERROR("Invalid root value type");
-        return JSONValue::EMPTY;
-    }
-
-    return JSONValue(this, document_);
-}
-
 }

+ 8 - 17
Source/Urho3D/Resource/JSONFile.h

@@ -25,14 +25,6 @@
 #include "../Resource/Resource.h"
 #include "../Resource/JSONValue.h"
 
-namespace rapidjson
-{
-
-template <typename Encoding, typename Allocator> class GenericDocument;
-typedef GenericDocument<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Document;
-
-}
-
 namespace Urho3D
 {
 
@@ -44,6 +36,8 @@ class URHO3D_API JSONFile : public Resource
 public:
     /// Construct.
     JSONFile(Context* context);
+    /// Construct with a JSON value.
+    JSONFile(Context* context, const JSONValue& value);
     /// Destruct.
     virtual ~JSONFile();
     /// Register object factory.
@@ -56,17 +50,14 @@ public:
     /// Save resource with user-defined indentation, only the first character (if any) of the string is used and the length of the string defines the character count. Return true if successful.
     bool Save(Serializer& dest, const String& indendation) const;
 
-    /// Clear the document and create a root value, default is object type.
-    JSONValue CreateRoot(JSONValueType valueType = JSON_OBJECT);
-    /// Return the root value with specific value type, Return null value if not found.
-    JSONValue GetRoot(JSONValueType valueType = JSON_ANY);
-
-    /// Return rapidjson document.
-    rapidjson::Document* GetDocument() const { return document_; }
+    /// Set root value.
+    void SetRoot(const JSONValue& root) { root_ = root; }
+    /// Return root value.
+    const JSONValue& GetRoot() const { return root_; }
 
 private:
-    /// Rapid JSON document.
-    rapidjson::Document* document_;
+    /// JSON root value.
+    JSONValue root_;
 };
 
 }

+ 155 - 699
Source/Urho3D/Resource/JSONValue.cpp

@@ -24,850 +24,306 @@
 
 #include "../Core/Context.h"
 #include "../IO/Log.h"
-#include "../Resource/JSONFile.h"
-
-#include <rapidjson/document.h>
+#include "../Resource/JSONValue.h"
 
 #include "../DebugNew.h"
 
-using namespace rapidjson;
-
 namespace Urho3D
 {
 
 const JSONValue JSONValue::EMPTY;
+const JSONArray JSONValue::EMPTY_ARRAY;
+const JSONObject JSONValue::EMPTY_OBJECT;
 
-static rapidjson::Type ToRapidJsonType(JSONValueType valueType)
-{
-    if (valueType == JSON_OBJECT)
-        return kObjectType;
-    else if (valueType == JSON_ARRAY)
-        return kArrayType;
-    return kNullType;
-}
-
-JSONValue::JSONValue() :
-    file_(0),
-    value_(0)
-{
-}
-
-JSONValue::JSONValue(JSONFile* file, rapidjson::Value* value) :
-    file_(file),
-    value_(value)
-{
-}
-
-JSONValue::JSONValue(const JSONValue& rhs) :
-    file_(rhs.file_),
-    value_(rhs.value_)
-{
-}
-
-JSONValue::~JSONValue()
-{
-}
-
-JSONValue& JSONValue::operator =(const JSONValue& rhs)
-{
-    file_ = rhs.file_;
-    value_ = rhs.value_;
-    return *this;
-}
-
-bool JSONValue::IsNull() const
-{
-    return value_ == 0;
-}
-
-bool JSONValue::NotNull() const
-{
-    return value_ != 0;
-}
-
-JSONValue::operator bool() const
-{
-    return NotNull();
-}
-
-JSONValue JSONValue::CreateChild(const String& name, JSONValueType valueType)
-{
-    assert(IsObject());
-    if (!IsObject())
-        return JSONValue::EMPTY;
-
-    Value jsonValue;
-    if (valueType == JSON_OBJECT)
-        jsonValue.SetObject();
-    else if (valueType == JSON_ARRAY)
-        jsonValue.SetArray();
-
-    AddMember(name, jsonValue);
-
-    return GetChild(name, valueType);
-}
-
-JSONValue JSONValue::GetChild(const String& name, JSONValueType valueType) const
+void JSONValue::SetType(JSONValueType valueType)
 {
-    assert(IsObject());
-
-    if (!value_->HasMember(name.CString()))
-        return JSONValue::EMPTY;
-
-    Value& value = GetMember(name);
-    if (valueType != JSON_ANY && value.GetType() != ToRapidJsonType(valueType))
-        return JSONValue::EMPTY;
-
-    return JSONValue(file_, &value);
-}
-
-void JSONValue::SetInt(const String& name, int value)
-{
-    Value jsonValue;
-    jsonValue.SetInt(value);
-    AddMember(name, jsonValue);
-}
-
-void JSONValue::SetBool(const String& name, bool value)
-{
-    Value jsonValue;
-    jsonValue.SetBool(value);
-    AddMember(name, jsonValue);
-}
-
-void JSONValue::SetFloat(const String& name, float value)
-{
-    Value jsonValue;
-    jsonValue.SetDouble((double)value);
-    AddMember(name, jsonValue);
-}
-
-void JSONValue::SetDouble(const String& name, double value)
-{
-    Value jsonValue;
-    jsonValue.SetDouble(value);
-    AddMember(name, jsonValue);
-}
-
-void JSONValue::SetVector2(const String& name, const Vector2& value)
-{
-    SetString(name, value.ToString());
-}
-
-void JSONValue::SetVector3(const String& name, const Vector3& value)
-{
-    SetString(name, value.ToString());
-}
-
-void JSONValue::SetVector4(const String& name, const Vector4& value)
-{
-    SetString(name, value.ToString());
-}
-
-void JSONValue::SetVectorVariant(const String& name, const Variant& value)
-{
-    VariantType type = value.GetType();
-    if (type == VAR_FLOAT || type == VAR_VECTOR2 || type == VAR_VECTOR3 || type == VAR_VECTOR4 || type == VAR_MATRIX3 ||
-        type == VAR_MATRIX3X4 || type == VAR_MATRIX4)
-        SetString(name, value.ToString());
-}
-
-void JSONValue::SetQuaternion(const String& name, const Quaternion& value)
-{
-    SetString(name, value.ToString());
-}
-
-void JSONValue::SetColor(const String& name, const Color& value)
-{
-    SetString(name, value.ToString());
-}
-
-void JSONValue::SetString(const String& name, const String& value)
-{
-    Value jsonValue;
-    jsonValue.SetString(value.CString(), value.Length(), file_->GetDocument()->GetAllocator());
-    AddMember(name, jsonValue);
-}
-
-void JSONValue::SetBuffer(const String& name, const void* data, unsigned size)
-{
-    String dataStr;
-    BufferToString(dataStr, data, size);
-    SetString(name, dataStr);
-}
-
-void JSONValue::SetBuffer(const String& name, const PODVector<unsigned char>& value)
-{
-    if (!value.Size())
-        SetString(name, String::EMPTY);
-    else
-        SetBuffer(name, &value[0], value.Size());
-}
-
-void JSONValue::SetResourceRef(const String& name, const ResourceRef& value)
-{
-    Context* context = file_->GetContext();
-    SetString(name, String(context->GetTypeName(value.type_)) + ";" + value.name_);
-}
-
-void JSONValue::SetResourceRefList(const String& name, const ResourceRefList& value)
-{
-    Context* context = file_->GetContext();
-    String str(context->GetTypeName(value.type_));
-    for (unsigned i = 0; i < value.names_.Size(); ++i)
-    {
-        str += ";";
-        str += value.names_[i];
-    }
-    SetString(name, str);
-}
-
-void JSONValue::SetIntRect(const String& name, const IntRect& value)
-{
-    SetString(name, value.ToString());
-}
-
-void JSONValue::SetIntVector2(const String& name, const IntVector2& value)
-{
-    SetString(name, value.ToString());
-}
-
-void JSONValue::SetMatrix3(const String& name, const Matrix3& value)
-{
-    SetString(name, value.ToString());
-}
-
-void JSONValue::SetMatrix3x4(const String& name, const Matrix3x4& value)
-{
-    SetString(name, value.ToString());
-}
-
-void JSONValue::SetMatrix4(const String& name, const Matrix4& value)
-{
-    SetString(name, value.ToString());
-}
-
-void JSONValue::SetVariant(const String& name, const Variant& value)
-{
-    // Create child object for variant
-    JSONValue child = CreateChild(name, JSON_OBJECT);
-    // Set type
-    child.SetString("type", value.GetTypeName());
-    // Set value
-    child.SetVariantValue("value", value);
-}
+    if (valueType == valueType_)
+        return;
 
-void JSONValue::SetVariantValue(const String& name, const Variant& value)
-{
-    switch (value.GetType())
+    switch (valueType_)
     {
-    case VAR_RESOURCEREF:
-        SetResourceRef(name, value.GetResourceRef());
+    case JSON_STRING:
+        delete stringValue_;
         break;
 
-    case VAR_RESOURCEREFLIST:
-        SetResourceRefList(name, value.GetResourceRefList());
+    case JSON_ARRAY:
+        delete arrayValue_;
         break;
 
-    case VAR_VARIANTVECTOR:
-    case VAR_STRINGVECTOR:
-    case VAR_VARIANTMAP:
-        LOGERROR("Unsupported value type");
+    case JSON_OBJECT:
+        delete objectValue_;
         break;
 
     default:
-        SetString(name, value.ToString());
-    }
-}
-
-bool JSONValue::IsObject() const
-{
-    return value_ && value_->IsObject();
-}
-
-Vector<String> JSONValue::GetChildNames() const
-{
-    Vector<String> ret;
-    if (!IsObject())
-        return ret;
-
-    for (Value::ConstMemberIterator i = value_->MemberBegin(); i != value_->MemberEnd(); ++i)
-    {
-        // Only reutrn name for child object and array
-        if (i->value.GetType() == kArrayType || i->value.GetType() == kObjectType)
-            ret.Push(i->name.GetString());
+        break;
     }
 
-    return ret;
-}
-
-Vector<String> JSONValue::GetValueNames() const
-{
-    Vector<String> ret;
-    if (!IsObject())
-        return ret;
+    valueType_ = valueType;
 
-    for (Value::ConstMemberIterator i = value_->MemberBegin(); i != value_->MemberEnd(); ++i)
+    switch (valueType_)
     {
-        if (i->value.GetType() != kArrayType && i->value.GetType() != kObjectType)
-            ret.Push(i->name.GetString());
-    }
-
-    return ret;
-}
-
-int JSONValue::GetInt(const String& name) const
-{
-    return GetMember(name).GetInt();
-}
-
-bool JSONValue::GetBool(const String& name) const
-{
-    return GetMember(name).GetBool();
-}
-
-float JSONValue::GetFloat(const String& name) const
-{
-    return (float)GetMember(name).GetDouble();
-}
-
-double JSONValue::GetDouble(const String& name) const
-{
-    return GetMember(name).GetDouble();
-}
-
-Vector2 JSONValue::GetVector2(const String& name) const
-{
-    return ToVector2(GetCString(name));
-}
-
-Vector3 JSONValue::GetVector3(const String& name) const
-{
-    return ToVector3(GetCString(name));
-}
-
-Vector4 JSONValue::GetVector4(const String& name) const
-{
-    return ToVector4(GetCString(name));
-}
-
-Variant JSONValue::GetVectorVariant(const String& name) const
-{
-    return ToVectorVariant(GetCString(name));
-}
-
-Quaternion JSONValue::GetQuaternion(const String& name) const
-{
-    return ToQuaternion(GetCString(name));
-}
-
-Color JSONValue::GetColor(const String& name) const
-{
-    return ToColor(GetCString(name));
-}
-
-String JSONValue::GetString(const String& name) const
-{
-    return GetMember(name).GetString();
-}
-
-const char* JSONValue::GetCString(const String& name) const
-{
-    return GetMember(name).GetString();
-}
-
-PODVector<unsigned char> JSONValue::GetBuffer(const String& name) const
-{
-    PODVector<unsigned char> buffer;
-    StringToBuffer(buffer, GetCString(name));
-    return buffer;
-}
-
-bool JSONValue::GetBuffer(const String& name, void* dest, unsigned size) const
-{
-    Vector<String> bytes = GetString(name).Split(' ');
-    unsigned char* destBytes = (unsigned char*)dest;
-    if (size < bytes.Size())
-        return false;
-
-    for (unsigned i = 0; i < bytes.Size(); ++i)
-        destBytes[i] = (unsigned char)ToInt(bytes[i]);
-    return true;
-}
-
-
-ResourceRef JSONValue::GetResourceRef(const String& name) const
-{
-    ResourceRef ret;
-
-    Vector<String> values = GetString(name).Split(';');
-    if (values.Size() == 2)
-    {
-        ret.type_ = values[0];
-        ret.name_ = values[1];
-    }
+    case JSON_STRING:
+        stringValue_ = new String();
+        break;
 
-    return ret;
-}
+    case JSON_ARRAY:
+        arrayValue_ = new JSONArray();
+        break;
 
-ResourceRefList JSONValue::GetResourceRefList(const String& name) const
-{
-    ResourceRefList ret;
+    case JSON_OBJECT:
+        objectValue_ = new JSONObject();
+        break;
 
-    Vector<String> values = GetString(name).Split(';');
-    if (values.Size() >= 1)
-    {
-        ret.type_ = values[0];
-        ret.names_.Resize(values.Size() - 1);
-        for (unsigned i = 1; i < values.Size(); ++i)
-            ret.names_[i - 1] = values[i];
+    default:
+        break;
     }
-
-    return ret;
 }
 
-IntRect JSONValue::GetIntRect(const String& name) const
+JSONValue& JSONValue::operator =(bool rhs)
 {
-    return ToIntRect(GetCString(name));
-}
+    SetType(JSON_NUMBER);
+    numberValue_ = rhs;
 
-IntVector2 JSONValue::GetIntVector2(const String& name) const
-{
-    return ToIntVector2(GetCString(name));
-}
-
-Matrix3 JSONValue::GetMatrix3(const String& name) const
-{
-    return ToMatrix3(GetCString(name));
-}
-
-Matrix3x4 JSONValue::GetMatrix3x4(const String& name) const
-{
-    return ToMatrix3x4(GetCString(name));
-}
-
-Matrix4 JSONValue::GetMatrix4(const String& name) const
-{
-    return ToMatrix4(GetCString(name));
-}
-
-Variant JSONValue::GetVariant(const String& name) const
-{
-    // Get child for variant
-    JSONValue child = GetChild(name, JSON_OBJECT);
-    if (child.IsNull())
-        return Variant::EMPTY;
-
-    // Get type
-    VariantType type = Variant::GetTypeFromName(child.GetString("type"));
-    // Get value
-    return child.GetVariantValue("value", type);
-}
-
-Variant JSONValue::GetVariantValue(const String& name, VariantType type) const
-{
-    Variant ret;
-
-    if (type == VAR_RESOURCEREF)
-        ret = GetResourceRef(name);
-    else if (type == VAR_RESOURCEREFLIST)
-        ret = GetResourceRefList(name);
-    else if (type == VAR_VARIANTVECTOR || type == VAR_STRINGVECTOR || type == VAR_VARIANTMAP)
-        LOGERROR("Unsupported value type");
-    else
-        ret.FromString(type, GetCString(name));
-
-    return ret;
+    return *this;
 }
 
-JSONValue JSONValue::CreateChild(JSONValueType valueType)
+JSONValue& JSONValue::operator =(int rhs)
 {
-    assert(IsArray());
-    if (!IsArray())
-        return JSONValue::EMPTY;
-
-    Value value(ToRapidJsonType(valueType));
-    value_->PushBack(value, file_->GetDocument()->GetAllocator());
+    SetType(JSON_NUMBER);
+    numberValue_ = rhs;
 
-    return GetChild(GetSize() - 1, valueType);
+    return *this;
 }
 
-JSONValue JSONValue::GetChild(unsigned index, JSONValueType valueType) const
+JSONValue& JSONValue::operator =(unsigned rhs)
 {
-    if (index >= GetSize())
-        return JSONValue::EMPTY;
-
-    const Value& value = (*value_)[(SizeType)index];
-    if (valueType != JSON_ANY && value.GetType() != ToRapidJsonType(valueType))
-        return JSONValue::EMPTY;
+    SetType(JSON_NUMBER);
+    numberValue_ = rhs;
 
-    return JSONValue(file_, (Value*)&value);
+    return *this;
 }
 
-void JSONValue::AddInt(int value)
+JSONValue& JSONValue::operator =(float rhs)
 {
-    Value jsonValue;
-    jsonValue.SetInt(value);
-    AddMember(jsonValue);
-}
+    SetType(JSON_NUMBER);
+    numberValue_ = rhs;
 
-void JSONValue::AddBool(bool value)
-{
-    Value jsonValue;
-    jsonValue.SetBool(value);
-    AddMember(jsonValue);
+    return *this;
 }
 
-void JSONValue::AddFloat(float value)
+JSONValue& JSONValue::operator =(double rhs)
 {
-    Value jsonValue;
-    jsonValue.SetDouble((double)value);
-    AddMember(jsonValue);
-}
+    SetType(JSON_NUMBER);
+    numberValue_ = rhs;
 
-void JSONValue::AddDouble(double value)
-{
-    Value jsonValue;
-    jsonValue.SetDouble(value);
-    AddMember(jsonValue);
+    return *this;
 }
 
-void JSONValue::AddVector2(const Vector2& value)
+JSONValue& JSONValue::operator =(const String& rhs)
 {
-    AddString(value.ToString());
-}
+    SetType(JSON_STRING);
+    *stringValue_ = rhs;
 
-void JSONValue::AddVector3(const Vector3& value)
-{
-    AddString(value.ToString());
+    return *this;
 }
 
-void JSONValue::AddVector4(const Vector4& value)
+JSONValue& JSONValue::operator =(const char* rhs)
 {
-    AddString(value.ToString());
-}
+    SetType(JSON_STRING);
+    *stringValue_ = rhs;
 
-void JSONValue::AddVectorVariant(const Variant& value)
-{
-    VariantType type = value.GetType();
-    if (type == VAR_FLOAT || type == VAR_VECTOR2 || type == VAR_VECTOR3 || type == VAR_VECTOR4 || type == VAR_MATRIX3 ||
-        type == VAR_MATRIX3X4 || type == VAR_MATRIX4)
-        AddString(value.ToString());
+    return *this;
 }
 
-void JSONValue::AddQuaternion(const Quaternion& value)
+JSONValue& JSONValue::operator =(const JSONArray& rhs)
 {
-    AddString(value.ToString());
-}
+    SetType(JSON_ARRAY);
+    *arrayValue_ = rhs;
 
-void JSONValue::AddColor(const Color& value)
-{
-    AddString(value.ToString());
+    return *this;
 }
 
-void JSONValue::AddString(const String& value)
+JSONValue& JSONValue::operator =(const JSONObject& rhs)
 {
-    Value jsonValue;
-    jsonValue.SetString(value.CString(), value.Length(), file_->GetDocument()->GetAllocator());
-    AddMember(jsonValue);
-}
+    SetType(JSON_OBJECT);
+    *objectValue_ = rhs;
 
-void JSONValue::AddBuffer(const PODVector<unsigned char>& value)
-{
-    if (!value.Size())
-        AddString(String::EMPTY);
-    else
-        AddBuffer(&value[0], value.Size());
+    return *this;
 }
 
-void JSONValue::AddBuffer(const void* data, unsigned size)
+JSONValue& JSONValue::operator =(const JSONValue& rhs)
 {
-    String dataStr;
-    BufferToString(dataStr, data, size);
-    AddString(dataStr);
-}
+    if (this == &rhs)
+        return *this;
 
-void JSONValue::AddResourceRef(const ResourceRef& value)
-{
-    Context* context = file_->GetContext();
-    AddString(String(context->GetTypeName(value.type_)) + ";" + value.name_);
-}
+    SetType(rhs.valueType_);
 
-void JSONValue::AddResourceRefList(const ResourceRefList& value)
-{
-    Context* context = file_->GetContext();
-    String str(context->GetTypeName(value.type_));
-    for (unsigned i = 0; i < value.names_.Size(); ++i)
+    switch (valueType_)
     {
-        str += ";";
-        str += value.names_[i];
-    }
-    AddString(str);
-}
-
-void JSONValue::AddIntRect(const IntRect& value)
-{
-    AddString(value.ToString());
-}
-
-void JSONValue::AddIntVector2(const IntVector2& value)
-{
-    AddString(value.ToString());
-}
-
-void JSONValue::AddMatrix3(const Matrix3& value)
-{
-    AddString(value.ToString());
-}
-
-void JSONValue::AddMatrix3x4(const Matrix3x4& value)
-{
-    AddString(value.ToString());
-}
-
-void JSONValue::AddMatrix4(const Matrix4& value)
-{
-    AddString(value.ToString());
-}
-
-void JSONValue::AddVariant(const Variant& value)
-{
-    // Create child object for variant
-    JSONValue child = CreateChild(JSON_OBJECT);
-    // Set type
-    child.SetString("type", value.GetTypeName());
-    // Set value
-    child.SetVariantValue("value", value);
-}
+    case JSON_BOOL:
+        boolValue_ = rhs.boolValue_;
+        break;
 
-void JSONValue::AddVariantValue(const Variant& value)
-{
-    switch (value.GetType())
-    {
-    case VAR_RESOURCEREF:
-        AddResourceRef(value.GetResourceRef());
+    case JSON_NUMBER:
+        numberValue_ = rhs.numberValue_;
         break;
 
-    case VAR_RESOURCEREFLIST:
-        AddResourceRefList(value.GetResourceRefList());
+    case JSON_STRING:
+        *stringValue_ = *rhs.stringValue_;
         break;
 
-    case VAR_VARIANTVECTOR:
-    case VAR_STRINGVECTOR:
-    case VAR_VARIANTMAP:
-        LOGERROR("Unsupported value type");
+    case JSON_ARRAY:
+        *arrayValue_ = *rhs.arrayValue_;
         break;
 
+    case JSON_OBJECT:
+        *objectValue_ = *rhs.objectValue_;
+
     default:
-        AddString(value.ToString());
+        break;
     }
-}
 
-unsigned JSONValue::GetSize() const
-{
-    if (IsArray())
-        return (unsigned)value_->Size();
-    else
-        return 0;
+    return *this;
 }
 
-bool JSONValue::IsArray() const
+JSONValue& JSONValue::operator [](unsigned index)
 {
-    return value_ && value_->IsArray();
-}
+    // Convert to array type
+    SetType(JSON_ARRAY);
 
-int JSONValue::GetInt(unsigned index) const
-{
-    return GetMember(index).GetInt();
+    return (*arrayValue_)[index];
 }
 
-bool JSONValue::GetBool(unsigned index) const
+const JSONValue& JSONValue::operator [](unsigned index) const
 {
-    return GetMember(index).GetBool();
-}
+    if (valueType_ != JSON_ARRAY)
+        return EMPTY;
 
-float JSONValue::GetFloat(unsigned index) const
-{
-    return (float)GetMember(index).GetDouble();
+    return (*arrayValue_)[index];
 }
 
-double JSONValue::GetDouble(unsigned index) const
+JSONValue& JSONValue::At(unsigned index)
 {
-    return GetMember(index).GetDouble();
-}
+    // Convert to array type
+    SetType(JSON_ARRAY);
 
-Vector2 JSONValue::GetVector2(unsigned index) const
-{
-    return ToVector2(GetCString(index));
+    return arrayValue_->At(index);
 }
 
-Vector3 JSONValue::GetVector3(unsigned index) const
+const JSONValue& JSONValue::At(unsigned index) const
 {
-    return ToVector3(GetCString(index));
-}
+    if (valueType_ != JSON_ARRAY)
+        return EMPTY;
 
-Vector4 JSONValue::GetVector4(unsigned index) const
-{
-    return ToVector4(GetCString(index));
+    return arrayValue_->At(index);
 }
 
-Variant JSONValue::GetVectorVariant(unsigned index) const
+void JSONValue::Push(const JSONValue& value)
 {
-    return ToVectorVariant(GetCString(index));
-}
+    // Convert to array type
+    SetType(JSON_ARRAY);
 
-Quaternion JSONValue::GetQuaternion(unsigned index) const
-{
-    return ToQuaternion(GetCString(index));
+    arrayValue_->Push(value);
 }
 
-Color JSONValue::GetColor(unsigned index) const
+void JSONValue::Pop()
 {
-    return ToColor(GetCString(index));
-}
+    if (valueType_ != JSON_ARRAY)
+        return;
 
-String JSONValue::GetString(unsigned index) const
-{
-    return GetMember(index).GetString();
+    arrayValue_->Pop();
 }
 
-const char* JSONValue::GetCString(unsigned index) const
+void JSONValue::Insert(unsigned pos, const JSONValue& value)
 {
-    return GetMember(index).GetString();
-}
+    if (valueType_ != JSON_ARRAY)
+        return;
 
-PODVector<unsigned char> JSONValue::GetBuffer(unsigned index) const
-{
-    PODVector<unsigned char> buffer;
-    StringToBuffer(buffer, GetCString(index));
-    return buffer;
+    arrayValue_->Insert(pos, value);
 }
 
-bool JSONValue::GetBuffer(unsigned index, void* dest, unsigned size) const
+void JSONValue::Erase(unsigned pos, unsigned length)
 {
-    Vector<String> bytes = GetString(index).Split(' ');
-    unsigned char* destBytes = (unsigned char*)dest;
-    if (size < bytes.Size())
-        return false;
+    if (valueType_ != JSON_ARRAY)
+        return;
 
-    for (unsigned i = 0; i < bytes.Size(); ++i)
-        destBytes[i] = (unsigned char)ToInt(bytes[i]);
-    return true;
+    arrayValue_->Erase(pos, length);
 }
 
-ResourceRef JSONValue::GetResourceRef(unsigned index) const
+void JSONValue::Resize(unsigned newSize)
 {
-    ResourceRef ret;
-
-    Vector<String> values = GetString(index).Split(';');
-    if (values.Size() == 2)
-    {
-        ret.type_ = values[0];
-        ret.name_ = values[1];
-    }
+    // Convert to array type
+    SetType(JSON_ARRAY);
 
-    return ret;
+    arrayValue_->Resize(newSize);
 }
 
-ResourceRefList JSONValue::GetResourceRefList(unsigned index) const
+unsigned JSONValue::Size() const
 {
-    ResourceRefList ret;
-
-    Vector<String> values = GetString(index).Split(';');
-    if (values.Size() >= 1)
-    {
-        ret.type_ = values[0];
-        ret.names_.Resize(values.Size() - 1);
-        for (unsigned i = 1; i < values.Size(); ++i)
-            ret.names_[i - 1] = values[i];
-    }
+    if (valueType_ == JSON_ARRAY)
+        return arrayValue_->Size();
 
-    return ret;
+    return 0;
 }
 
-IntRect JSONValue::GetIntRect(unsigned index) const
+JSONValue& JSONValue::operator [](const String& key)
 {
-    return ToIntRect(GetCString(index));
-}
+    // Convert to object type
+    SetType(JSON_OBJECT);
 
-IntVector2 JSONValue::GetIntVector2(unsigned index) const
-{
-    return ToIntVector2(GetCString(index));
+    return (*objectValue_)[key];
 }
 
-Matrix3 JSONValue::GetMatrix3(unsigned index) const
+const JSONValue& JSONValue::operator [](const String& key) const
 {
-    return ToMatrix3(GetCString(index));
-}
+    if (valueType_ != JSON_OBJECT)
+        return EMPTY;
 
-Matrix3x4 JSONValue::GetMatrix3x4(unsigned index) const
-{
-    return ToMatrix3x4(GetCString(index));
+    return (*objectValue_)[key];
 }
 
-Matrix4 JSONValue::GetMatrix4(unsigned index) const
+void JSONValue::Set(const String& key, const JSONValue& value)
 {
-    return ToMatrix4(GetCString(index));
-}
+    // Convert to object type
+    SetType(JSON_OBJECT);
 
-Variant JSONValue::GetVariant(unsigned index) const
-{
-    // Get child for variant
-    JSONValue child = GetChild(index, JSON_OBJECT);
-    if (child.IsNull())
-        return Variant::EMPTY;
-
-    // Get type
-    VariantType type = Variant::GetTypeFromName(child.GetString("type"));
-    // Get value
-    return child.GetVariantValue("value", type);
+    objectValue_->Insert(MakePair<String, JSONValue>(key, value));
 }
 
-Variant JSONValue::GetVariantValue(unsigned index, VariantType type) const
+const JSONValue& JSONValue::Get(const String& key) const
 {
-    Variant ret;
-
-    if (type == VAR_RESOURCEREF)
-        ret = GetResourceRef(index);
-    else if (type == VAR_RESOURCEREFLIST)
-        ret = GetResourceRefList(index);
-    else if (type == VAR_VARIANTVECTOR || type == VAR_STRINGVECTOR || type == VAR_VARIANTMAP)
-        LOGERROR("Unsupported value type");
-    else
-        ret.FromString(type, GetCString(index));
-
-    return ret;
-}
+    if (valueType_ != JSON_OBJECT)
+        return EMPTY;
 
-void JSONValue::AddMember(const String& name, rapidjson::Value& jsonValue)
-{
-    if (!IsObject())
-        return;
+    JSONObject::ConstIterator i = objectValue_->Find(key);
+    if (i == objectValue_->End())
+        return EMPTY;
 
-    Value jsonName;
-    jsonName.SetString(name.CString(), name.Length(), file_->GetDocument()->GetAllocator());
-    value_->AddMember(jsonName, jsonValue, file_->GetDocument()->GetAllocator());
+    return i->second_;
 }
 
-rapidjson::Value& JSONValue::GetMember(const String& name) const
+bool JSONValue::Erase(const String& key)
 {
-    assert(IsObject());
+    if (valueType_ != JSON_OBJECT)
+        return false;
 
-    return (*value_)[name.CString()];
+    return objectValue_->Erase(key);
 }
 
-void JSONValue::AddMember(rapidjson::Value& jsonValue)
+bool JSONValue::Contains(const String& key) const
 {
-    assert(IsArray());
+    if  (valueType_ != JSON_OBJECT)
+        return false;
 
-    value_->PushBack(jsonValue, file_->GetDocument()->GetAllocator());
+    return objectValue_->Contains(key);
 }
 
-rapidjson::Value& JSONValue::GetMember(unsigned index) const
+void JSONValue::Clear()
 {
-    assert(IsArray());
-
-    return (*value_)[(SizeType)index];
+    if (valueType_ == JSON_ARRAY)
+        arrayValue_->Clear();
+    else if (valueType_ == JSON_OBJECT)
+        objectValue_->Clear();
 }
 
-}
+}

+ 203 - 256
Source/Urho3D/Resource/JSONValue.h

@@ -22,281 +22,228 @@
 
 #pragma once
 
-#include "../Container/Ptr.h"
-#include "../Core/Variant.h"
-#include "../Math/BoundingBox.h"
-#include "../Math/Rect.h"
-
-namespace rapidjson
-{
-
-template <typename CharType> struct UTF8;
-class CrtAllocator;
-template <typename BaseAllocator> class MemoryPoolAllocator;
-template <typename Encoding, typename Allocator> class GenericValue;
-typedef GenericValue<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Value;
-
-}
-
 namespace Urho3D
 {
 
-class JSONFile;
-
 /// JSON value type.
 enum JSONValueType
 {
-    /// Any type (use type in JSON value).
-    JSON_ANY = 0,
-    /// Object type (Hash Map).
+    /// JSON null type.
+    JSON_NULL = 0,
+    /// JSON boolean type.
+    JSON_BOOL,
+    /// JSON number type.
+    JSON_NUMBER,
+    /// JSON string type.
+    JSON_STRING,
+    /// JSON array type.
+    JSON_ARRAY,
+    /// JSON object type.
     JSON_OBJECT,
-    /// Array type.
-    JSON_ARRAY
 };
 
+class JSONValue;
+
+/// JSON array type.
+typedef Vector<JSONValue> JSONArray;
+/// JSON object type.
+typedef HashMap<String, JSONValue> JSONObject;
+
 /// JSON value class.
 class URHO3D_API JSONValue
 {
 public:
     /// Construct null value.
-    JSONValue();
-    /// Construct with document and JSON value pointers.
-    JSONValue(JSONFile* file, rapidjson::Value* value);
-    /// Copy-construct from another value.
-    JSONValue(const JSONValue& rhs);
+    JSONValue() : 
+        valueType_(JSON_NULL)
+    {
+    }
+    /// Construct with a boolean.
+    JSONValue(bool value) :
+        valueType_(JSON_NULL)
+    {
+        *this = value;
+    }
+    /// Construct with a integer.
+    JSONValue(int value) :
+        valueType_(JSON_NULL)
+    {
+        *this = value;
+    }
+    /// Construct with a unsigned integer.
+    JSONValue(unsigned value) :
+        valueType_(JSON_NULL)
+    {
+        *this = value;
+    }
+    /// Construct with a float.
+    JSONValue(float value) :
+        valueType_(JSON_NULL)
+    {
+        *this = value;
+    }
+    /// Construct with a double.
+    JSONValue(double value) :
+        valueType_(JSON_NULL)
+    {
+        *this = value;
+    }
+    /// Construct with a string.
+    JSONValue(const String& value) :
+        valueType_(JSON_NULL)
+    {
+        *this = value;
+    }
+    /// Construct with a C string.
+    JSONValue(const char* value) :
+        valueType_(JSON_NULL)
+    {
+        *this = value;
+    }
+    /// Construct with a JSON array.
+    JSONValue(const JSONArray& value) :
+        valueType_(JSON_NULL)
+    {
+        *this = value;
+    }
+    /// Construct with a JSON object.
+    JSONValue(const JSONObject& value) :
+        valueType_(JSON_NULL)
+    {
+        *this = value;
+    }    
+    /// Copy-construct from another JSON value.
+    JSONValue(const JSONValue& value) :
+        valueType_(JSON_NULL)
+    {
+        *this = value;
+    }
     /// Destruct.
-    ~JSONValue();
-
-    /// Assignment operator.
+    ~JSONValue()
+    {
+        SetType(JSON_NULL);
+    }
+
+    /// Set value type.
+    void SetType(JSONValueType valueType);
+    /// Assign from a boolean.
+    JSONValue& operator =(bool rhs);
+    /// Assign from an integer.
+    JSONValue& operator =(int rhs);
+    /// Assign from an unsigned integer.
+    JSONValue& operator =(unsigned rhs);
+    /// Assign from a float.
+    JSONValue& operator =(float rhs);
+    /// Assign from a double.
+    JSONValue& operator =(double rhs);
+    /// Assign from a string.
+    JSONValue& operator =(const String& rhs);
+    /// Assign from a C string.
+    JSONValue& operator =(const char* rhs);
+    /// Assign from a JSON array.
+    JSONValue& operator =(const JSONArray& rhs);
+    /// Assign from a JSON object.
+    JSONValue& operator =(const JSONObject& rhs);
+    /// Assign from another JSON value.
     JSONValue& operator =(const JSONValue& rhs);
 
-    /// Return whether does not refer to JSON value.
-    bool IsNull() const;
-    /// Return whether refers to JSON value.
-    bool NotNull() const;
-    /// Return true if refers to JSON value.
-    operator bool() const;
-
-    // JSON object value functions
-    /// Create a child value.
-    JSONValue CreateChild(const String& name, JSONValueType valueType = JSON_OBJECT);
-    /// Return a child value by name. Return null if not exist.
-    JSONValue GetChild(const String& name, JSONValueType valueType = JSON_ANY) const;
-    /// Set int.
-    void SetInt(const String& name, int value);
-    /// Set bool.
-    void SetBool(const String& name, bool value);
-    /// Set float.
-    void SetFloat(const String& name, float value);
-    /// Set double.
-    void SetDouble(const String& name, double value);
-    /// Set vector2.
-    void SetVector2(const String& name, const Vector2& value);
-    /// Set vector3.
-    void SetVector3(const String& name, const Vector3& value);
-    /// Set vector4.
-    void SetVector4(const String& name, const Vector4& value);
-    /// Set vector variant.
-    void SetVectorVariant(const String& name, const Variant& value);
-    /// Set quaternion.
-    void SetQuaternion(const String& name, const Quaternion& value);
-    /// Set color.
-    void SetColor(const String& name, const Color& value);
-    /// Set string.
-    void SetString(const String& name, const String& value);
-    /// Set buffer.
-    void SetBuffer(const String& name, const void* data, unsigned size);
-    /// Set buffer.
-    void SetBuffer(const String& name, const PODVector<unsigned char>& value);
-    /// Set resource ref.
-    void SetResourceRef(const String& name, const ResourceRef& value);
-    /// Set resource ref list.
-    void SetResourceRefList(const String& name, const ResourceRefList& value);
-    /// Set int rect.
-    void SetIntRect(const String& name, const IntRect& value);
-    /// Set int vector2.
-    void SetIntVector2(const String& name, const IntVector2& value);
-    /// Set matrix3.
-    void SetMatrix3(const String& name, const Matrix3& value);
-    /// Set matrix3x4.
-    void SetMatrix3x4(const String& name, const Matrix3x4& value);
-    /// Set matrix4.
-    void SetMatrix4(const String& name, const Matrix4& value);
-    /// Set variant (include type).
-    void SetVariant(const String& name, const Variant& value);
-    /// Set variant value.
-    void SetVariantValue(const String& name, const Variant& value);
-
-    /// Is object type.
-    bool IsObject() const;
-    /// Return child names (only object and array child name).
-    Vector<String> GetChildNames() const;
-    /// Return member value names.
-    Vector<String> GetValueNames() const;
-    /// Return int.
-    int GetInt(const String& name) const;
-    /// Return bool.
-    bool GetBool(const String& name) const;
-    /// Return float.
-    float GetFloat(const String& name) const;
-    /// Return double.
-    double GetDouble(const String& name) const;
-    /// Return vector2.
-    Vector2 GetVector2(const String& name) const;
-    /// Return vector3.
-    Vector3 GetVector3(const String& name) const;
-    /// Return vector4.
-    Vector4 GetVector4(const String& name) const;
-    /// Return vector variant.
-    Variant GetVectorVariant(const String& name) const;
-    /// Return quaternion.
-    Quaternion GetQuaternion(const String& name) const;
-    /// Return color.
-    Color GetColor(const String& name) const;
-    /// Return string.
-    String GetString(const String& name) const;
-    /// Return C string.
-    const char* GetCString(const String& name) const;
-    /// Return buffer.
-    PODVector<unsigned char> GetBuffer(const String& name) const;
-    /// Return buffer.
-    bool GetBuffer(const String& name, void* dest, unsigned size) const;
-    /// Return resource ref.
-    ResourceRef GetResourceRef(const String& name) const;
-    /// Return resource ref list.
-    ResourceRefList GetResourceRefList(const String& name) const;
-    /// Return int rect.
-    IntRect GetIntRect(const String& name) const;
-    /// Return int vector2.
-    IntVector2 GetIntVector2(const String& name) const;
-    /// Return matrix3.
-    Matrix3 GetMatrix3(const String& name) const;
-    /// Return matrix3x4.
-    Matrix3x4 GetMatrix3x4(const String& name) const;
-    /// Return matrix4.
-    Matrix4 GetMatrix4(const String& name) const;
-    /// Return variant.
-    Variant GetVariant(const String& name) const;
-    /// Return variant value.
-    Variant GetVariantValue(const String& name, VariantType type) const;
-
-    // JSON array value functions
-    /// Create a child value in array.
-    JSONValue CreateChild(JSONValueType valueType = JSON_OBJECT);
-    /// Remove a child value in array. Return null if not exist.
-    JSONValue GetChild(unsigned index, JSONValueType valueType = JSON_ANY) const;
-    /// Add int.
-    void AddInt(int value);
-    /// Add bool.
-    void AddBool(bool value);
-    /// Add float.
-    void AddFloat(float value);
-    /// Add double.
-    void AddDouble(double value);
-    /// Add vector2.
-    void AddVector2(const Vector2& value);
-    /// Add vector3.
-    void AddVector3(const Vector3& value);
-    /// Add vector4.
-    void AddVector4(const Vector4& value);
-    /// Add vector variant.
-    void AddVectorVariant(const Variant& value);
-    /// Add quaternion.
-    void AddQuaternion(const Quaternion& value);
-    /// Add color.
-    void AddColor(const Color& value);
-    /// Add string.
-    void AddString(const String& value);
-    /// Add buffer.
-    void AddBuffer(const PODVector<unsigned char>& value);
-    /// Add buffer.
-    void AddBuffer(const void* data, unsigned size);
-    /// Add resource ref.
-    void AddResourceRef(const ResourceRef& value);
-    /// Add resource ref list.
-    void AddResourceRefList(const ResourceRefList& value);
-    /// Add int rect.
-    void AddIntRect(const IntRect& value);
-    /// Add int vector2.
-    void AddIntVector2(const IntVector2& value);
-    /// Add matrix3.
-    void AddMatrix3(const Matrix3& value);
-    /// Add matrix3x4.
-    void AddMatrix3x4(const Matrix3x4& value);
-    /// Add matrix4.
-    void AddMatrix4(const Matrix4& value);
-    /// Add variant.
-    void AddVariant(const Variant& value);
-    /// Add variant value.
-    void AddVariantValue(const Variant& value);
-    /// Is array type.
-    bool IsArray() const;
-    /// Return array size.
-    unsigned GetSize() const;
-    /// Return int.
-    int GetInt(unsigned index) const;
-    /// Return bool.
-    bool GetBool(unsigned index) const;
-    /// Return float.
-    float GetFloat(unsigned index) const;
-    /// Return double.
-    double GetDouble(unsigned index) const;
-    /// Return vector2.
-    Vector2 GetVector2(unsigned index) const;
-    /// Return vector3.
-    Vector3 GetVector3(unsigned index) const;
-    /// Return vector4.
-    Vector4 GetVector4(unsigned index) const;
-    /// Return vector variant.
-    Variant GetVectorVariant(unsigned index) const;
-    /// Return quaternion.
-    Quaternion GetQuaternion(unsigned index) const;
-    /// Return color.
-    Color GetColor(unsigned index) const;
-    /// Return string.
-    String GetString(unsigned index) const;
-    /// Return C string.
-    const char* GetCString(unsigned index) const;
-    /// Return buffer.
-    PODVector<unsigned char> GetBuffer(unsigned index) const;
-    /// Return buffer.
-    bool GetBuffer(unsigned index, void* dest, unsigned size) const;
-    /// Return resource ref.
-    ResourceRef GetResourceRef(unsigned index) const;
-    /// Return resource ref list.
-    ResourceRefList GetResourceRefList(unsigned index) const;
-    /// Return int rect.
-    IntRect GetIntRect(unsigned index) const;
-    /// Return int vector2.
-    IntVector2 GetIntVector2(unsigned index) const;
-    /// Return matrix3.
-    Matrix3 GetMatrix3(unsigned index) const;
-    /// Return matrix3x4.
-    Matrix3x4 GetMatrix3x4(unsigned index) const;
-    /// Return matrix4.
-    Matrix4 GetMatrix4(unsigned index) const;
-    /// Return variant.
-    Variant GetVariant(unsigned index) const;
-    /// Return variant.
-    Variant GetVariantValue(unsigned index, VariantType type) const;
-
-    /// Empty JSONValue.
+    /// Return value type.
+    JSONValueType GetType() const { return valueType_; }
+    /// Check is null.
+    bool IsNull() const { return valueType_ == JSON_NULL; }
+    /// Check is boolean.
+    bool IsBool() const { return valueType_ == JSON_BOOL; }
+    /// Check is number.
+    bool IsNumber() const { return valueType_ == JSON_NUMBER; }
+    /// Check is string.
+    bool IsString() const { return valueType_ == JSON_STRING; }
+    /// Check is array.
+    bool IsArray() const { return valueType_ == JSON_ARRAY; }
+    /// Check is object.
+    bool IsObject() const { return valueType_ == JSON_OBJECT; }
+
+    /// Return boolean value.
+    bool GetBool() const { return IsBool() ? boolValue_ : false;}
+    /// Return integer value.
+    int GetInt() const { return IsNumber() ? (int)numberValue_ : 0; }
+    /// Return unsigned integer value.
+    unsigned GetUint() const { return IsNumber() ? (unsigned)numberValue_ : 0; }
+    /// Return float value.
+    float GetFloat() const { return IsNumber() ? (float)numberValue_ : 0.0f; }
+    /// Return double value.
+    double GetDouble() const { return IsNumber() ? numberValue_ : 0.0; }
+    /// Return string value.
+    const String& GetString() const { return IsString() ? *stringValue_ : String::EMPTY;}
+    /// Return C string value.
+    const char* GetCString() const { return IsString() ? stringValue_->CString() : 0;}
+    /// Return JSON array value.
+    const JSONArray& GetArray() const { return IsArray() ? *arrayValue_ : EMPTY_ARRAY; }
+    /// Return JSON object value.
+    const JSONObject& GetObject() const { return IsObject() ? *objectValue_ : EMPTY_OBJECT; }
+
+	// JSON array functions
+    /// Return JSON value at index.
+    JSONValue& operator [](unsigned index);
+    /// Return JSON value at index.
+    const JSONValue& operator [](unsigned index) const;
+    /// Return JSON value at index.
+    JSONValue& At(unsigned index);
+    /// Return JSON value at index.
+    const JSONValue& At(unsigned index) const;
+    /// Add JSON value at end.
+    void Push(const JSONValue& value);
+    /// Remove the last JSON value.
+    void Pop();
+    /// Insert an JSON value at position.
+    void Insert(unsigned pos, const JSONValue& value);
+    /// Erase a range of JSON values.
+    void Erase(unsigned pos, unsigned length = 1);
+    /// Resize array.
+    void Resize(unsigned newSize);
+    /// Return size of array .
+    unsigned Size() const;
+
+	// JSON object functions
+    /// Return JSON value with key.
+    JSONValue& operator [](const String& key);
+    /// Return JSON value with key.
+    const JSONValue& operator [](const String& key) const;
+    /// Set JSON value with key.
+    void Set(const String& key, const JSONValue& value);
+    /// Return JSON value with key.
+    const JSONValue& Get(const String& key) const;
+    /// Erase a pair by key.
+    bool Erase(const String& key);
+    /// Return whether contains a pair with key.
+    bool Contains(const String& key) const;
+    
+    /// Clear array or object (user for array and object types).
+    void Clear();
+
+    /// Empty JSON value.
     static const JSONValue EMPTY;
+    /// Empty JSON array.
+    static const JSONArray EMPTY_ARRAY;
+    /// Empty JSON object.
+    static const JSONObject EMPTY_OBJECT;
 
 private:
-    /// Set JSON value for object type.
-    void AddMember(const String& name, rapidjson::Value& jsonValue);
-    /// Return JSON value by name for object type.
-    rapidjson::Value& GetMember(const String& name) const;
-    /// Add JSON value to array type.
-    void AddMember(rapidjson::Value& jsonValue);
-    /// Return JSON value by index for array type.
-    rapidjson::Value& GetMember(unsigned index) const;
-
-    /// JSON file.
-    WeakPtr<JSONFile> file_;
-    /// Rapid JSON value.
-    rapidjson::Value* value_;
+    /// Value type.
+    JSONValueType valueType_;
+    /// Values.
+    union
+    {
+        /// Boolean value.
+        bool boolValue_;
+        /// Number value.
+        double numberValue_;
+        /// String value.
+        String* stringValue_;
+        /// Array value.
+        JSONArray* arrayValue_;
+        /// Object value.
+        JSONObject* objectValue_;
+    };
 };
 
-}
+}

+ 10 - 11
Source/Urho3D/Resource/Localization.cpp

@@ -154,38 +154,37 @@ void Localization::Reset()
     strings_.Clear();
 }
 
-void Localization::LoadJSON(const JSONValue &source)
+void Localization::LoadJSON(const JSONValue& source)
 {
-    Vector<String> ids = source.GetChildNames();
-    for (unsigned i = 0; i < ids.Size(); i++)
+    const JSONObject& ids = source.GetObject();
+    for (JSONObject::ConstIterator i = ids.Begin(); i != ids.End(); ++i)
     {
-        String id = ids[i];
+        String id = i->first_;
         if (id.Empty())
         {
             LOGWARNING("Localization::LoadJSON(source): string ID is empty");
             continue;
         }
-        JSONValue value = source.GetChild(id);
-        Vector<String> langs = value.GetValueNames();
-        for (unsigned j = 0; j < langs.Size(); j++)
+        const JSONObject& langs = i->second_.GetObject();
+        for (JSONObject::ConstIterator j = langs.Begin(); j != langs.End(); ++j)
         {
-            String lang = langs[j];
+            const String& lang = j->first_;
             if (lang.Empty())
             {
                 LOGWARNING("Localization::LoadJSON(source): language name is empty, string ID=\"" + id + "\"");
                 continue;
             }
-            String string = value.GetString(lang);
+            const String& string = j->second_.GetString();
             if (string.Empty())
             {
                 LOGWARNING("Localization::LoadJSON(source): translation is empty, string ID=\"" + id +
-                           "\", language=\"" + lang + "\"");
+                    "\", language=\"" + lang + "\"");
                 continue;
             }
             if (strings_[StringHash(lang)][StringHash(id)] != String::EMPTY)
             {
                 LOGWARNING("Localization::LoadJSON(source): override translation, string ID=\"" + id +
-                           "\", language=\"" + lang + "\"");
+                    "\", language=\"" + lang + "\"");
             }
             strings_[StringHash(lang)][StringHash(id)] = string;
             if (!languages_.Contains(lang))

+ 110 - 103
Source/Urho3D/Script/ResourceAPI.cpp

@@ -239,6 +239,51 @@ static void ConstructJSONValue(JSONValue* ptr)
     new(ptr) JSONValue();
 }
 
+static void ConstructJSONValueBool(bool value, JSONValue* ptr)
+{
+    new (ptr) JSONValue(value);
+}
+
+static void ConstructJSONValueInt(int value, JSONValue* ptr)
+{
+    new (ptr) JSONValue(value);
+}
+
+static void ConstructJSONValueUnsigned(unsigned value, JSONValue* ptr)
+{
+    new (ptr) JSONValue(value);
+}
+
+static void ConstructJSONValueFloat(float value, JSONValue* ptr)
+{
+    new (ptr) JSONValue(value);
+}
+
+static void ConstructJSONValueDouble(double value, JSONValue* ptr)
+{
+    new (ptr) JSONValue(value);
+}
+
+static void ConstructJSONValueString(const String& value, JSONValue* ptr)
+{
+    new (ptr) JSONValue(value);
+}
+
+static void ConstructJSONValueCString(const char* value, JSONValue* ptr)
+{
+    new (ptr) JSONValue(value);
+}
+
+static void ConstructJSONValueArray(const JSONArray& value, JSONValue* ptr)
+{
+    new (ptr) JSONValue(value);
+}
+
+static void ConstructJSONValueObject(const JSONObject& value, JSONValue* ptr)
+{
+    new (ptr) JSONValue(value);
+}
+
 static void ConstructJSONValueCopy(const JSONValue& value, JSONValue* ptr)
 {
     new(ptr) JSONValue(value);
@@ -249,124 +294,86 @@ static void DestructJSONValue(JSONValue* ptr)
     ptr->~JSONValue();
 }
 
-static CScriptArray* JSONValueGetValueNames(JSONValue* ptr)
+static JSONValue& JSONValueAtPosition(unsigned position, JSONValue& jsonValue)
 {
-    Vector<String> names = ptr->GetValueNames();
-    return VectorToArray<String>(names, "Array<String>");
+    return jsonValue[position];
 }
 
-static CScriptArray* JSONValueGetChildNames(JSONValue* ptr)
+static JSONValue& JSONValueAtKey(const String& key, JSONValue& jsonValue)
 {
-    Vector<String> names = ptr->GetChildNames();
-    return VectorToArray<String>(names, "Array<String>");
+    return jsonValue[key];
 }
 
 static void RegisterJSONValue(asIScriptEngine* engine)
 {
     engine->RegisterEnum("JSONValueType");
-    engine->RegisterEnumValue("JSONValueType", "JSON_ANY", JSON_ANY);
-    engine->RegisterEnumValue("JSONValueType", "JSON_OBJECT", JSON_OBJECT);
+    engine->RegisterEnumValue("JSONValueType", "JSON_NULL", JSON_NULL);
+    engine->RegisterEnumValue("JSONValueType", "JSON_BOOL", JSON_BOOL);
+    engine->RegisterEnumValue("JSONValueType", "JSON_NUMBER", JSON_NUMBER);
+    engine->RegisterEnumValue("JSONValueType", "JSON_STRING", JSON_STRING);
     engine->RegisterEnumValue("JSONValueType", "JSON_ARRAY", JSON_ARRAY);
+    engine->RegisterEnumValue("JSONValueType", "JSON_OBJECT", JSON_OBJECT);
 
     engine->RegisterObjectType("JSONValue", sizeof(JSONValue), asOBJ_VALUE | asOBJ_APP_CLASS_CDAK);
     engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructJSONValue), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f(const JSONValue&in)", asFUNCTION(ConstructJSONValueCopy), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f(bool)", asFUNCTION(ConstructJSONValueBool), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f(int)", asFUNCTION(ConstructJSONValueInt), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f(uint)", asFUNCTION(ConstructJSONValueUnsigned), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f(float)", asFUNCTION(ConstructJSONValueFloat), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f(double)", asFUNCTION(ConstructJSONValueDouble), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f(string)", asFUNCTION(ConstructJSONValueString), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f(const char*)", asFUNCTION(ConstructJSONValueCString), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f(const JSONArray&)", asFUNCTION(ConstructJSONValueArray), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f(const JSONObject&)", asFUNCTION(ConstructJSONValueObject), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_CONSTRUCT, "void f(const JSONValue&)", asFUNCTION(ConstructJSONValueCopy), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectBehaviour("JSONValue", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructJSONValue), asCALL_CDECL_OBJLAST);
 
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opAssign(bool)", asMETHODPR(JSONValue, operator =, (bool), JSONValue&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opAssign(int)", asMETHODPR(JSONValue, operator =, (int), JSONValue&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opAssign(uint)", asMETHODPR(JSONValue, operator =, (unsigned), JSONValue&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opAssign(float)", asMETHODPR(JSONValue, operator =, (float), JSONValue&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opAssign(double)", asMETHODPR(JSONValue, operator =, (double), JSONValue&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opAssign(string)", asMETHODPR(JSONValue, operator =, (const String&), JSONValue&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opAssign(const char*)", asMETHODPR(JSONValue, operator =, (const char*), JSONValue&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opAssign(const JSONArray&in)", asMETHODPR(JSONValue, operator =, (const JSONArray&), JSONValue&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opAssign(const JSONObject&in)", asMETHODPR(JSONValue, operator =, (const JSONObject&), JSONValue&), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opAssign(const JSONValue&in)", asMETHODPR(JSONValue, operator =, (const JSONValue&), JSONValue&), asCALL_THISCALL);
+
+    engine->RegisterObjectMethod("JSONValue", "JSONValueType get_type() const", asMETHOD(JSONValue, GetType), asCALL_THISCALL);
     engine->RegisterObjectMethod("JSONValue", "bool get_isNull() const", asMETHOD(JSONValue, IsNull), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "bool get_notNull() const", asMETHOD(JSONValue, NotNull), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "JSONValue& opAssign(const JSONValue&in)", asMETHOD(JSONValue, operator =), asCALL_THISCALL);
-
-    engine->RegisterObjectMethod("JSONValue", "JSONValue CreateChild(const String&in, JSONValueType valueType = JSON_OBJECT)", asMETHODPR(JSONValue, CreateChild,(const String&, JSONValueType), JSONValue), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "JSONValue GetChild(const String&in, JSONValueType valueType = JSON_ANY) const", asMETHODPR(JSONValue, GetChild, (const String&, JSONValueType) const, JSONValue), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetInt(const String&in, int)", asMETHOD(JSONValue, SetInt), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetBool(const String&in, bool)", asMETHOD(JSONValue, SetBool), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetFloat(const String&in, float)", asMETHOD(JSONValue, SetFloat), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetDouble(const String&in, double)", asMETHOD(JSONValue, SetDouble), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetVector2(const String&in, const Vector2&in)", asMETHOD(JSONValue, SetVector2), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetVector3(const String&in, const Vector3&in)", asMETHOD(JSONValue, SetVector3), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetVector4(const String&in, const Vector4&in)", asMETHOD(JSONValue, SetVector4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetVectorVariant(const String&in, const Variant&in)", asMETHOD(JSONValue, SetVectorVariant), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetQuaternion(const String&in, const Quaternion&in)", asMETHOD(JSONValue, SetQuaternion), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetColor(const String&in, const Color&in)", asMETHOD(JSONValue, SetColor), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetString(const String&in, const String)", asMETHOD(JSONValue, SetString), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetResourceRef(const String&in, const ResourceRef&in)", asMETHOD(JSONValue, SetResourceRef), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetResourceRefList(const String&in, const ResourceRefList&in)", asMETHOD(JSONValue, SetResourceRefList), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetIntRect(const String&in, const IntRect&in)", asMETHOD(JSONValue, SetIntRect), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetIntVector2(const String&in, const IntVector2&in)", asMETHOD(JSONValue, SetIntVector2), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetMatrix3(const String&in, const Matrix3&in)", asMETHOD(JSONValue, SetMatrix3), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetMatrix3x4(const String&in, const Matrix3x4&in)", asMETHOD(JSONValue, SetMatrix3x4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetMatrix4(const String&in, const Matrix4&in)", asMETHOD(JSONValue, SetMatrix4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetVariant(const String&in, const Variant&in)", asMETHOD(JSONValue, SetVariant), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void SetVariantValue(const String&in, const Variant&in)", asMETHOD(JSONValue, SetVariantValue), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "bool get_isObject() const", asMETHOD(JSONValue, IsObject), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Array<String>@ GetValueNames() const", asFUNCTION(JSONValueGetValueNames), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("JSONValue", "Array<String>@ GetChildNames() const", asFUNCTION(JSONValueGetChildNames), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("JSONValue", "int GetInt(const String&in) const", asMETHODPR(JSONValue, GetInt, (const String&) const, int), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "bool GetBool(const String&in) const", asMETHODPR(JSONValue, GetBool, (const String&) const, bool), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "float GetFloat(const String&in) const", asMETHODPR(JSONValue, GetFloat, (const String&) const, float), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "double GetDouble(const String&in) const", asMETHODPR(JSONValue, GetDouble, (const String&) const, double), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Vector2 GetVector2(const String&in) const", asMETHODPR(JSONValue, GetVector2, (const String&) const, Vector2), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Vector3 GetVector3(const String&in) const", asMETHODPR(JSONValue, GetVector3, (const String&) const, Vector3), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Vector4 GetVector4(const String&in) const", asMETHODPR(JSONValue, GetVector4, (const String&) const, Vector4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Variant GetVectorVariant(const String&in) const", asMETHODPR(JSONValue, GetVectorVariant, (const String&) const, Variant), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Quaternion GetQuaternion(const String&in) const", asMETHODPR(JSONValue, GetQuaternion, (const String&) const, Quaternion), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Color GetColor(const String&in) const", asMETHODPR(JSONValue, GetColor, (const String&) const, Color), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "String GetString(const String&in) const", asMETHODPR(JSONValue, GetString, (const String&) const, String), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "ResourceRef GetResourceRef(const String&in) const", asMETHODPR(JSONValue, GetResourceRef, (const String&) const, ResourceRef), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "ResourceRefList GetResourceRefList(const String&in) const", asMETHODPR(JSONValue, GetResourceRefList, (const String&) const, ResourceRefList), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "IntRect GetIntRect(const String&in) const", asMETHODPR(JSONValue, GetIntRect, (const String&) const, IntRect), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "IntVector2 GetIntVector2(const String&in) const", asMETHODPR(JSONValue, GetIntVector2, (const String&) const, IntVector2), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Matrix3 GetMatrix3(const String&in) const", asMETHODPR(JSONValue, GetMatrix3, (const String&) const, Matrix3), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Matrix3x4 GetMatrix3x4(const String&in) const", asMETHODPR(JSONValue, GetMatrix3x4, (const String&) const, Matrix3x4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Matrix4 GetMatrix4(const String&in) const", asMETHODPR(JSONValue, GetMatrix4, (const String&) const, Matrix4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Variant GetVariant(const String&in) const", asMETHODPR(JSONValue, GetVariant, (const String&) const, Variant), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Variant GetVariantValue(const String&in, VariantType type) const", asMETHODPR(JSONValue, GetVariantValue, (const String&, VariantType) const, Variant), asCALL_THISCALL);
-
-    engine->RegisterObjectMethod("JSONValue", "JSONValue CreateChild(JSONValueType valueType = JSON_OBJECT)", asMETHODPR(JSONValue, CreateChild, (JSONValueType), JSONValue), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "JSONValue GetChild(uint, JSONValueType valueType = JSON_ANY) const", asMETHODPR(JSONValue, GetChild, (unsigned, JSONValueType) const, JSONValue), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddInt(int)", asMETHOD(JSONValue, AddInt), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddBool(bool)", asMETHOD(JSONValue, AddBool), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddFloat(float)", asMETHOD(JSONValue, AddFloat), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddDouble(double)", asMETHOD(JSONValue, AddDouble), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddVector2(const Vector2&in)", asMETHOD(JSONValue, AddVector2), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddVector3(const Vector3&in)", asMETHOD(JSONValue, AddVector3), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddVector4(const Vector4&in)", asMETHOD(JSONValue, AddVector4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddVectorVariant(const Variant&in)", asMETHOD(JSONValue, AddVectorVariant), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddQuaternion(const Quaternion&in)", asMETHOD(JSONValue, AddQuaternion), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddColor(const Color&in)", asMETHOD(JSONValue, AddColor), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddString(const String)", asMETHOD(JSONValue, AddString), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddResourceRef(const ResourceRef&in)", asMETHOD(JSONValue, AddResourceRef), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddResourceRefList(const ResourceRefList&in)", asMETHOD(JSONValue, AddResourceRefList), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddIntRect(const IntRect&in)", asMETHOD(JSONValue, AddIntRect), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddIntVector2(const IntVector2&in)", asMETHOD(JSONValue, AddIntVector2), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddMatrix3(const Matrix3&in)", asMETHOD(JSONValue, AddMatrix3), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddMatrix3x4(const Matrix3x4&in)", asMETHOD(JSONValue, AddMatrix3x4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddMatrix4(const Matrix4&in)", asMETHOD(JSONValue, AddMatrix4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddVariant(const Variant&in)", asMETHOD(JSONValue, AddVariant), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "void AddVariantValue(const Variant&in)", asMETHOD(JSONValue, AddVariantValue), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "bool get_isBool() const", asMETHOD(JSONValue, IsBool), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "bool get_isNumber() const", asMETHOD(JSONValue, IsNumber), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "bool get_isString() const", asMETHOD(JSONValue, IsString), asCALL_THISCALL);
     engine->RegisterObjectMethod("JSONValue", "bool get_isArray() const", asMETHOD(JSONValue, IsArray), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "uint get_size() const", asMETHOD(JSONValue, GetSize), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "int GetInt(uint) const", asMETHODPR(JSONValue, GetInt, (unsigned) const, int), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "bool GetBool(uint) const", asMETHODPR(JSONValue, GetBool, (unsigned) const, bool), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "float GetFloat(uint) const", asMETHODPR(JSONValue, GetFloat, (unsigned) const, float), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "double GetDouble(uint) const", asMETHODPR(JSONValue, GetDouble, (unsigned) const, double), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Vector2 GetVector2(uint) const", asMETHODPR(JSONValue, GetVector2, (unsigned) const, Vector2), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Vector3 GetVector3(uint) const", asMETHODPR(JSONValue, GetVector3, (unsigned) const, Vector3), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Vector4 GetVector4(uint) const", asMETHODPR(JSONValue, GetVector4, (unsigned) const, Vector4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Variant GetVectorVariant(uint) const", asMETHODPR(JSONValue, GetVectorVariant, (unsigned) const, Variant), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Quaternion GetQuaternion(uint) const", asMETHODPR(JSONValue, GetQuaternion, (unsigned) const, Quaternion), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Color GetColor(uint) const", asMETHODPR(JSONValue, GetColor, (unsigned) const, Color), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "String GetString(uint) const", asMETHODPR(JSONValue, GetString, (unsigned) const, String), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "ResourceRef GetResourceRef(uint) const", asMETHODPR(JSONValue, GetResourceRef, (unsigned) const, ResourceRef), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "ResourceRefList GetResourceRefList(uint) const", asMETHODPR(JSONValue, GetResourceRefList, (unsigned) const, ResourceRefList), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "IntRect GetIntRect(uint) const", asMETHODPR(JSONValue, GetIntRect, (unsigned) const, IntRect), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "IntVector2 GetIntVector2(uint) const", asMETHODPR(JSONValue, GetIntVector2, (unsigned) const, IntVector2), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Matrix3 GetMatrix3(uint) const", asMETHODPR(JSONValue, GetMatrix3, (unsigned) const, Matrix3), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Matrix3x4 GetMatrix3x4(uint) const", asMETHODPR(JSONValue, GetMatrix3x4, (unsigned) const, Matrix3x4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Matrix4 GetMatrix4(uint) const", asMETHODPR(JSONValue, GetMatrix4, (unsigned) const, Matrix4), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Variant GetVariant(uint) const", asMETHODPR(JSONValue, GetVariant, (unsigned) const, Variant), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONValue", "Variant GetVariantValue(uint, VariantType type) const", asMETHODPR(JSONValue, GetVariantValue, (unsigned, VariantType) const, Variant), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "bool get_isObject() const", asMETHOD(JSONValue, IsObject), asCALL_THISCALL);
+
+    engine->RegisterObjectMethod("JSONValue", "bool GetBool() const", asMETHOD(JSONValue, GetBool), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "int GetInt() const", asMETHOD(JSONValue, GetInt), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "uint GetUint() const", asMETHOD(JSONValue, GetUint), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "float GetFloat() const", asMETHOD(JSONValue, GetFloat), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "double GetDouble() const", asMETHOD(JSONValue, GetDouble), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "const String& GetString() const", asMETHOD(JSONValue, GetString), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "const char* GetCString() const", asMETHOD(JSONValue, GetCString), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "const JSONArray& GetArray() const", asMETHOD(JSONValue, GetArray), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "const JSONObject& GetObject() const", asMETHOD(JSONValue, GetObject), asCALL_THISCALL);
+
+    
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opIndex(unsigned)", asFUNCTION(JSONValueAtPosition), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("JSONValue", "const JSONValue& opIndex(unsigned) const", asFUNCTION(JSONValueAtPosition), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("JSONValue", "void Push(const JSONValue&in)", asMETHOD(JSONValue, Push), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "void Pop()", asMETHOD(JSONValue, Pop), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "void Insert(uint, const JSONValue&in)", asMETHODPR(JSONValue, Insert, (unsigned, const JSONValue&), void), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "void Erase(uint, uint length = 1)", asMETHODPR(JSONValue, Erase, (unsigned, unsigned), void), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "void Resize(uint)", asMETHOD(JSONValue, Resize), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "uint get_size()", asMETHOD(JSONValue, Size), asCALL_THISCALL);
+
+    engine->RegisterObjectMethod("JSONValue", "JSONValue& opIndex(const String&in)", asFUNCTION(JSONValueAtKey), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("JSONValue", "const JSONValue& opIndex(const String&in) const", asFUNCTION(JSONValueAtKey), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("JSONValue", "void Set(const String&in, const JSONValue&in)", asMETHOD(JSONValue, Set), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "const JSONValue& Get(const String&in) const", asMETHOD(JSONValue, Get), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "void Erase(const String&in)", asMETHODPR(JSONValue, Erase, (const String&), bool), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "bool Contains(const String&in) const", asMETHOD(JSONValue, Contains), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONValue", "void Clear()", asMETHOD(JSONValue, Clear), asCALL_THISCALL);
 }
 
 static bool JSONFileSave(File* file, const String& indendation, JSONFile* ptr)
@@ -377,8 +384,8 @@ static bool JSONFileSave(File* file, const String& indendation, JSONFile* ptr)
 static void RegisterJSONFile(asIScriptEngine* engine)
 {
     RegisterResource<JSONFile>(engine, "JSONFile");
-    engine->RegisterObjectMethod("JSONFile", "JSONValue CreateRoot(JSONValueType valueType = JSON_ANY)", asMETHOD(JSONFile, CreateRoot), asCALL_THISCALL);
-    engine->RegisterObjectMethod("JSONFile", "JSONValue GetRoot(JSONValueType valueType = JSON_ANY)", asMETHOD(JSONFile, GetRoot), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONFile", "void SetRoot(const JSONValue&)", asMETHOD(JSONFile, SetRoot), asCALL_THISCALL);
+    engine->RegisterObjectMethod("JSONFile", "const JSONValue& GetRoot()", asMETHOD(JSONFile, GetRoot), asCALL_THISCALL);
     engine->RegisterObjectMethod("JSONFile", "bool Save(File@+, const String&in) const", asFUNCTION(JSONFileSave), asCALL_CDECL_OBJLAST);
 }