Index: ps/trunk/source/simulation2/components/CCmpAIManager.cpp =================================================================== --- ps/trunk/source/simulation2/components/CCmpAIManager.cpp +++ ps/trunk/source/simulation2/components/CCmpAIManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -216,7 +216,6 @@ m_CommandsComputed(true), m_HasLoadedEntityTemplates(false), m_HasSharedComponent(false), - m_SerializablePrototypes(new ObjectIdCache(g_ScriptRuntime)), m_EntityTemplates(g_ScriptRuntime->m_rt), m_SharedAIObj(g_ScriptRuntime->m_rt), m_PassabilityMapVal(g_ScriptRuntime->m_rt), @@ -227,7 +226,6 @@ m_ScriptInterface->SetCallbackData(static_cast (this)); - m_SerializablePrototypes->init(); JS_AddExtraGCRootsTracer(m_ScriptInterface->GetJSRuntime(), Trace, this); m_ScriptInterface->RegisterFunction("PostCommand"); @@ -660,8 +658,6 @@ else { CStdSerializer serializer(*m_ScriptInterface, stream); - // TODO: see comment in Deserialize() - serializer.SetSerializablePrototypes(m_SerializablePrototypes); SerializeState(serializer); } } @@ -782,12 +778,6 @@ m_Players.back()->m_Commands.push_back(m_ScriptInterface->WriteStructuredClone(val)); } - // TODO: this is yucky but necessary while the AIs are sharing data between contexts; - // ideally a new (de)serializer instance would be created for each player - // so they would have a single, consistent script context to use and serializable - // prototypes could be stored in their ScriptInterface - deserializer.SetSerializablePrototypes(m_DeserializablePrototypes); - bool hasCustomDeserialize = m_ScriptInterface->HasProperty(m_Players.back()->m_Obj, "Deserialize"); if (hasCustomDeserialize) { @@ -826,25 +816,6 @@ return m_Players.size(); } - void RegisterSerializablePrototype(std::wstring name, JS::HandleValue proto) - { - // Require unique prototype and name (for reverse lookup) - // TODO: this is yucky - see comment in Deserialize() - ENSURE(proto.isObject() && "A serializable prototype has to be an object!"); - - JSContext* cx = m_ScriptInterface->GetContext(); - JSAutoRequest rq(cx); - - JS::RootedObject obj(cx, &proto.toObject()); - if (m_SerializablePrototypes->has(obj) || m_DeserializablePrototypes.find(name) != m_DeserializablePrototypes.end()) - { - LOGERROR("RegisterSerializablePrototype called with same prototype multiple times: p=%p n='%s'", (void *)obj.get(), utf8_from_wstring(name)); - return; - } - m_SerializablePrototypes->add(cx, obj, name); - m_DeserializablePrototypes[name] = JS::Heap(obj); - } - private: static void Trace(JSTracer *trc, void *data) { @@ -853,8 +824,6 @@ void TraceMember(JSTracer *trc) { - for (std::pair>& prototype : m_DeserializablePrototypes) - JS_CallObjectTracer(trc, &prototype.second, "CAIWorker::m_DeserializablePrototypes"); for (std::pair>& metadata : m_PlayerMetadata) JS_CallValueTracer(trc, &metadata.second, "CAIWorker::m_PlayerMetadata"); } @@ -943,8 +912,6 @@ bool m_CommandsComputed; - shared_ptr > m_SerializablePrototypes; - std::map > m_DeserializablePrototypes; CTemplateLoader m_TemplateLoader; }; Index: ps/trunk/source/simulation2/serialization/BinarySerializer.h =================================================================== --- ps/trunk/source/simulation2/serialization/BinarySerializer.h +++ ps/trunk/source/simulation2/serialization/BinarySerializer.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -87,7 +87,6 @@ void ScriptString(const char* name, JS::HandleString string); void HandleScriptVal(JS::HandleValue val); - void SetSerializablePrototypes(shared_ptr > prototypes); private: const ScriptInterface& m_ScriptInterface; ISerializer& m_Serializer; @@ -95,11 +94,6 @@ ObjectIdCache m_ScriptBackrefs; u32 m_ScriptBackrefsNext; u32 GetScriptBackrefTag(JS::HandleObject obj); - - shared_ptr > m_SerializablePrototypes; - - bool IsSerializablePrototype(JS::HandleObject prototype); - std::wstring GetPrototypeName(JS::HandleObject prototype); }; /** @@ -127,11 +121,6 @@ { } - virtual void SetSerializablePrototypes(shared_ptr >& prototypes) - { - m_ScriptImpl->SetSerializablePrototypes(prototypes); - } - protected: /* The Put* implementations here are designed for subclasses Index: ps/trunk/source/simulation2/serialization/BinarySerializer.cpp =================================================================== --- ps/trunk/source/simulation2/serialization/BinarySerializer.cpp +++ ps/trunk/source/simulation2/serialization/BinarySerializer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -56,10 +56,9 @@ CBinarySerializerScriptImpl::CBinarySerializerScriptImpl(const ScriptInterface& scriptInterface, ISerializer& serializer) : m_ScriptInterface(scriptInterface), m_Serializer(serializer), m_ScriptBackrefs(scriptInterface.GetRuntime()), - m_SerializablePrototypes(new ObjectIdCache(scriptInterface.GetRuntime())), m_ScriptBackrefsNext(1) + m_ScriptBackrefsNext(1) { m_ScriptBackrefs.init(); - m_SerializablePrototypes->init(); } void CBinarySerializerScriptImpl::HandleScriptVal(JS::HandleValue val) @@ -153,51 +152,8 @@ if (protokey == JSProto_Object) { - // Object class - check for user-defined prototype - JS::RootedObject proto(cx); - JS_GetPrototype(cx, obj, &proto); - if (!proto) - throw PSERROR_Serialize_ScriptError("JS_GetPrototype failed"); - - if (m_SerializablePrototypes->empty() || !IsSerializablePrototype(proto)) - { - // Standard Object prototype - m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_OBJECT); - - // TODO: maybe we should throw an error for unrecognized non-Object prototypes? - // (requires fixing AI serialization first and excluding component scripts) - } - else - { - // User-defined custom prototype - m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_OBJECT_PROTOTYPE); - - const std::wstring prototypeName = GetPrototypeName(proto); - m_Serializer.String("proto name", prototypeName, 0, 256); - - // Does it have custom Serialize function? - // if so, we serialize the data it returns, rather than the object's properties directly - bool hasCustomSerialize; - if (!JS_HasProperty(cx, obj, "Serialize", &hasCustomSerialize)) - throw PSERROR_Serialize_ScriptError("JS_HasProperty failed"); - - if (hasCustomSerialize) - { - JS::RootedValue serialize(cx); - if (!JS_GetProperty(cx, obj, "Serialize", &serialize)) - throw PSERROR_Serialize_ScriptError("JS_GetProperty failed"); - - // If serialize is null, so don't serialize anything more - if (!serialize.isNull()) - { - JS::RootedValue data(cx); - if (!m_ScriptInterface.CallFunction(val, "Serialize", &data)) - throw PSERROR_Serialize_ScriptError("Prototype Serialize function failed"); - HandleScriptVal(data); - } - break; - } - } + // Standard Object prototype + m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_OBJECT); } else if (protokey == JSProto_Number) { @@ -474,21 +430,3 @@ // Return a non-tag number so callers know they need to serialize the object return 0; } - -bool CBinarySerializerScriptImpl::IsSerializablePrototype(JS::HandleObject prototype) -{ - return m_SerializablePrototypes->has(prototype); -} - -std::wstring CBinarySerializerScriptImpl::GetPrototypeName(JS::HandleObject prototype) -{ - std::wstring ret; - bool found = m_SerializablePrototypes->find(prototype, ret); - ENSURE(found); - return ret; -} - -void CBinarySerializerScriptImpl::SetSerializablePrototypes(shared_ptr > prototypes) -{ - m_SerializablePrototypes = prototypes; -} Index: ps/trunk/source/simulation2/serialization/SerializedScriptTypes.h =================================================================== --- ps/trunk/source/simulation2/serialization/SerializedScriptTypes.h +++ ps/trunk/source/simulation2/serialization/SerializedScriptTypes.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -31,7 +31,7 @@ SCRIPT_TYPE_BACKREF = 8, SCRIPT_TYPE_TYPED_ARRAY = 9, // ArrayBufferView subclasses - see below SCRIPT_TYPE_ARRAY_BUFFER = 10, // ArrayBuffer containing actual typed array data (may be shared by multiple views) - SCRIPT_TYPE_OBJECT_PROTOTYPE = 11, // user-defined prototype + SCRIPT_TYPE_OBJECT_PROTOTYPE = 11, // user-defined prototype - currently unused SCRIPT_TYPE_OBJECT_NUMBER = 12, // standard Number class SCRIPT_TYPE_OBJECT_STRING = 13, // standard String class SCRIPT_TYPE_OBJECT_BOOLEAN = 14, // standard Boolean class Index: ps/trunk/source/simulation2/serialization/StdDeserializer.h =================================================================== --- ps/trunk/source/simulation2/serialization/StdDeserializer.h +++ ps/trunk/source/simulation2/serialization/StdDeserializer.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -38,8 +38,6 @@ virtual std::istream& GetStream(); virtual void RequireBytesInStream(size_t numBytes); - virtual void SetSerializablePrototypes(std::map >& prototypes); - static void Trace(JSTracer *trc, void *data); void TraceMember(JSTracer *trc); @@ -60,11 +58,6 @@ const ScriptInterface& m_ScriptInterface; std::istream& m_Stream; - - std::map > m_SerializablePrototypes; - - bool IsSerializablePrototype(const std::wstring& name); - void GetSerializablePrototype(const std::wstring& name, JS::MutableHandleObject ret); }; #endif // INCLUDED_STDDESERIALIZER Index: ps/trunk/source/simulation2/serialization/StdDeserializer.cpp =================================================================== --- ps/trunk/source/simulation2/serialization/StdDeserializer.cpp +++ ps/trunk/source/simulation2/serialization/StdDeserializer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2020 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -56,9 +56,6 @@ { for (size_t i=0; i>& proto : m_SerializablePrototypes) - JS_CallObjectTracer(trc, &proto.second, "StdDeserializer::m_SerializablePrototypes"); } void CStdDeserializer::Get(const char* name, u8* data, size_t len) @@ -139,7 +136,6 @@ case SCRIPT_TYPE_ARRAY: case SCRIPT_TYPE_OBJECT: - case SCRIPT_TYPE_OBJECT_PROTOTYPE: { JS::RootedObject obj(cx); if (appendParent) @@ -152,51 +148,10 @@ NumberU32_Unbounded("array length", length); obj.set(JS_NewArrayObject(cx, length)); } - else if (type == SCRIPT_TYPE_OBJECT) + else // SCRIPT_TYPE_OBJECT { obj.set(JS_NewPlainObject(cx)); } - else // SCRIPT_TYPE_OBJECT_PROTOTYPE - { - std::wstring prototypeName; - String("proto name", prototypeName, 0, 256); - - // Get constructor object - JS::RootedObject proto(cx); - GetSerializablePrototype(prototypeName, &proto); - if (!proto) - throw PSERROR_Deserialize_ScriptError("Failed to find serializable prototype for object"); - - obj.set(JS_NewObjectWithGivenProto(cx, nullptr, proto)); - if (!obj) - throw PSERROR_Deserialize_ScriptError("JS_NewObject failed"); - - // Does it have custom Deserialize function? - // if so, we let it handle the deserialized data, rather than adding properties directly - bool hasCustomDeserialize, hasCustomSerialize; - if (!JS_HasProperty(cx, obj, "Serialize", &hasCustomSerialize) || !JS_HasProperty(cx, obj, "Deserialize", &hasCustomDeserialize)) - throw PSERROR_Serialize_ScriptError("JS_HasProperty failed"); - - if (hasCustomDeserialize) - { - AddScriptBackref(obj); - - JS::RootedValue serialize(cx); - if (!JS_GetProperty(cx, obj, "Serialize", &serialize)) - throw PSERROR_Serialize_ScriptError("JS_GetProperty failed"); - bool hasNullSerialize = hasCustomSerialize && serialize.isNull(); - - // If Serialize is null, we'll still call Deserialize but with undefined argument - JS::RootedValue data(cx); - if (!hasNullSerialize) - ScriptVal("data", &data); - - JS::RootedValue objVal(cx, JS::ObjectValue(*obj)); - m_ScriptInterface.CallFunctionVoid(objVal, "Deserialize", data); - - return JS::ObjectValue(*obj); - } - } if (!obj) throw PSERROR_Deserialize_ScriptError("Deserializer failed to create new object"); @@ -501,22 +456,3 @@ JS::RootedObject obj(cx, &objVal.toObject()); ReadScriptVal(name, obj); } - -void CStdDeserializer::SetSerializablePrototypes(std::map >& prototypes) -{ - m_SerializablePrototypes = prototypes; -} - -bool CStdDeserializer::IsSerializablePrototype(const std::wstring& name) -{ - return m_SerializablePrototypes.find(name) != m_SerializablePrototypes.end(); -} - -void CStdDeserializer::GetSerializablePrototype(const std::wstring& name, JS::MutableHandleObject ret) -{ - std::map >::iterator it = m_SerializablePrototypes.find(name); - if (it != m_SerializablePrototypes.end()) - ret.set(it->second); - else - ret.set(NULL); -}