/* Copyright (C) 2015 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * 0 A.D. is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ #ifndef INCLUDED_SERIALIZETEMPLATES #define INCLUDED_SERIALIZETEMPLATES /** * @file * Helper templates for serializing/deserializing common objects. */ #include "simulation2/components/ICmpPathfinder.h" template struct SerializeVector { template void operator()(ISerializer& serialize, const char* name, std::vector& value) { size_t len = value.size(); serialize.NumberU32_Unbounded("length", (u32)len); for (size_t i = 0; i < len; ++i) ELEM()(serialize, name, value[i]); } template void operator()(IDeserializer& deserialize, const char* name, std::vector& value) { value.clear(); u32 len; deserialize.NumberU32_Unbounded("length", len); value.reserve(len); // TODO: watch out for out-of-memory for (size_t i = 0; i < len; ++i) { T el; ELEM()(deserialize, name, el); value.push_back(el); } } }; template struct SerializeMap { template void operator()(ISerializer& serialize, const char* UNUSED(name), std::map& value) { size_t len = value.size(); serialize.NumberU32_Unbounded("length", (u32)len); for (typename std::map::iterator it = value.begin(); it != value.end(); ++it) { KS()(serialize, "key", it->first); VS()(serialize, "value", it->second); } } template void operator()(ISerializer& serialize, const char* UNUSED(name), std::map& value, C& context) { size_t len = value.size(); serialize.NumberU32_Unbounded("length", (u32)len); for (typename std::map::iterator it = value.begin(); it != value.end(); ++it) { KS()(serialize, "key", it->first); VS()(serialize, "value", it->second, context); } } template void operator()(IDeserializer& deserialize, const char* UNUSED(name), M& value) { typedef typename M::key_type K; typedef typename M::value_type::second_type V; // M::data_type gives errors with gcc value.clear(); u32 len; deserialize.NumberU32_Unbounded("length", len); for (size_t i = 0; i < len; ++i) { K k; V v; KS()(deserialize, "key", k); VS()(deserialize, "value", v); value.insert(std::make_pair(k, v)); } } template void operator()(IDeserializer& deserialize, const char* UNUSED(name), M& value, C& context) { typedef typename M::key_type K; typedef typename M::value_type::second_type V; // M::data_type gives errors with gcc value.clear(); u32 len; deserialize.NumberU32_Unbounded("length", len); for (size_t i = 0; i < len; ++i) { K k; V v; KS()(deserialize, "key", k); VS()(deserialize, "value", v, context); value.insert(std::make_pair(k, v)); } } }; // We have to order the map before serializing to make things consistent template struct SerializeUnorderedMap { template void operator()(ISerializer& serialize, const char* name, boost::unordered_map& value) { std::map ordered_value(value.begin(), value.end()); SerializeMap()(serialize, name, ordered_value); } template void operator()(IDeserializer& deserialize, const char* name, boost::unordered_map& value) { SerializeMap()(deserialize, name, value); } }; template struct SerializeU8_Enum { void operator()(ISerializer& serialize, const char* name, T value) { serialize.NumberU8(name, value, 0, max); } void operator()(IDeserializer& deserialize, const char* name, T& value) { u8 val; deserialize.NumberU8(name, val, 0, max); value = (T)val; } }; struct SerializeU16_Unbounded { void operator()(ISerializer& serialize, const char* name, u16 value) { serialize.NumberU16_Unbounded(name, value); } void operator()(IDeserializer& deserialize, const char* name, u16& value) { deserialize.NumberU16_Unbounded(name, value); } }; struct SerializeU32_Unbounded { void operator()(ISerializer& serialize, const char* name, u32 value) { serialize.NumberU32_Unbounded(name, value); } void operator()(IDeserializer& deserialize, const char* name, u32& value) { deserialize.NumberU32_Unbounded(name, value); } }; struct SerializeI32_Unbounded { void operator()(ISerializer& serialize, const char* name, i32 value) { serialize.NumberI32_Unbounded(name, value); } void operator()(IDeserializer& deserialize, const char* name, i32& value) { deserialize.NumberI32_Unbounded(name, value); } }; struct SerializeBool { void operator()(ISerializer& serialize, const char* name, bool value) { serialize.Bool(name, value); } void operator()(IDeserializer& deserialize, const char* name, bool& value) { deserialize.Bool(name, value); } }; struct SerializeString { void operator()(ISerializer& serialize, const char* name, const std::string& value) { serialize.StringASCII(name, value, 0, UINT32_MAX); } void operator()(IDeserializer& deserialize, const char* name, std::string& value) { deserialize.StringASCII(name, value, 0, UINT32_MAX); } }; struct SerializeWaypoint { void operator()(ISerializer& serialize, const char* UNUSED(name), const Waypoint& value) { serialize.NumberFixed_Unbounded("waypoint x", value.x); serialize.NumberFixed_Unbounded("waypoint z", value.z); } void operator()(IDeserializer& deserialize, const char* UNUSED(name), Waypoint& value) { deserialize.NumberFixed_Unbounded("waypoint x", value.x); deserialize.NumberFixed_Unbounded("waypoint z", value.z); } }; struct SerializeGoal { template void operator()(S& serialize, const char* UNUSED(name), PathGoal& value) { SerializeU8_Enum()(serialize, "type", value.type); serialize.NumberFixed_Unbounded("goal x", value.x); serialize.NumberFixed_Unbounded("goal z", value.z); serialize.NumberFixed_Unbounded("goal u x", value.u.X); serialize.NumberFixed_Unbounded("goal u z", value.u.Y); serialize.NumberFixed_Unbounded("goal v x", value.v.X); serialize.NumberFixed_Unbounded("goal v z", value.v.Y); serialize.NumberFixed_Unbounded("goal hw", value.hw); serialize.NumberFixed_Unbounded("goal hh", value.hh); serialize.NumberFixed_Unbounded("maxdist", value.maxdist); } }; #endif // INCLUDED_SERIALIZETEMPLATES