<commit_before>﻿/*
Copyright 2018 creatorlxd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include "MetaData.h"
#include "Common/StringConverter.h"

namespace SpaceGameEngine
{
	class SerializeObjectManager
	{
	public:
		template<typename T, bool b>
		friend struct SerializeCore;
		template<typename T>
		friend inline void Serialize(T& obj, SerializeInterface& si);
		friend class MemoryManager;

		~SerializeObjectManager();
	private:
		SerializeObjectManager();

		void AddObject(void* ptr, void* now_ptr);
		void QueryObject(void* query_ptr, void ** ptr);
	private:
		Map<void*, void*> m_ObjectMap;
		Map<void*, Vector<void**>> m_QueryList;
	};

	SerializeObjectManager& GetSerializeObjectManager();

	class SerializeInterface
	{
	public:
		enum class IOFlag
		{
			Input,
			Output
		};
		SerializeInterface(IOFlag ioflag);
		virtual ~SerializeInterface();
		IOFlag GetIOFlag();

		template<typename T, bool b>
		friend struct SerializeCore;
	private:
		virtual String Read() = 0;
		virtual void Write(const String& str) = 0;
	private:
		IOFlag m_IOFlag;
	};

	template<typename T>
	inline void Serialize(T& obj, SerializeInterface& si);

	template<typename T>
	struct SerializeMethod
	{
		static void In(T& obj, const String& str) = 0;
		static String Out(const T& obj) = 0;
	};

	template<typename T, bool b>
	struct SerializeCore
	{

	};

	template<typename T>
	struct SerializeCore<T, true>
	{
		static void Run(T& obj, SerializeInterface& si)
		{
			for (auto& i : T::GetMetaDataCore().m_DirectInheritanceRelation)
			{
				i.second.m_pMetaData->m_SerializeAction(i.second.CastToMetaObject(obj.T::CastToMetaObject()), si);
			}
			for (auto& i : T::GetMetaDataCore().m_MemberVariable)
			{
				if (i.second.m_IfSerialize)
					i.second.m_pMetaData->m_SerializeAction(i.second.CastToMetaObject(obj.T::CastToMetaObject()), si);
			}
		}
	};

	template<typename T>
	struct SerializeCore<T, false>
	{
		static void Run(T& obj, SerializeInterface& si)
		{
			if (si.m_IOFlag == SerializeInterface::IOFlag::Input)
			{
				SerializeMethod<T>::In(obj, si.Read());
			}
			else
			{
				si.Write(SerializeMethod<T>::Out(obj));
			}
		}
	};

	template<typename T>
	struct SerializeCore<T*, false>	//pointer serialize
	{
		static void Run(T*& obj, SerializeInterface& si)
		{
			if (si.m_IOFlag == SerializeInterface::IOFlag::Input)
			{
				T* ptr;
				SerializeMethod<T*>::In(ptr, si.Read());
				if (ptr)
					GetSerializeObjectManager().QueryObject(ptr, (void**)&obj);
				else
					obj = ptr;
			}
			else
			{
				si.Write(SerializeMethod<T*>::Out(obj));
			}
		}
	};

	template<typename T>
	struct SerializeCore<T*, true>	//pointer serialize:just read ptr directly
	{
		static void Run(T*& obj, SerializeInterface& si)
		{
			if (si.m_IOFlag == SerializeInterface::IOFlag::Input)<commit_msg>fix some little thing in serialize<commit_after>﻿/*
Copyright 2018 creatorlxd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include "MetaData.h"
#include "Common/StringConverter.h"

namespace SpaceGameEngine
{
	class SerializeObjectManager
	{
	public:
		template<typename T, bool b>
		friend struct SerializeCore;
		template<typename T>
		friend inline void Serialize(T& obj, SerializeInterface& si);
		friend class MemoryManager;

		~SerializeObjectManager();
	private:
		SerializeObjectManager();

		void AddObject(void* ptr, void* now_ptr);
		void QueryObject(void* query_ptr, void ** ptr);
	private:
		Map<void*, void*> m_ObjectMap;
		Map<void*, Vector<void**>> m_QueryList;
	};

	SerializeObjectManager& GetSerializeObjectManager();

	class SerializeInterface
	{
	public:
		enum class IOFlag
		{
			Input,
			Output
		};
		SerializeInterface(IOFlag ioflag);
		virtual ~SerializeInterface();
		IOFlag GetIOFlag();

		template<typename T, bool b>
		friend struct SerializeCore;
	private:
		virtual String Read() = 0;
		virtual void Write(const String& str) = 0;
	private:
		IOFlag m_IOFlag;
	};

	template<typename T>
	inline void Serialize(T& obj, SerializeInterface& si);

	template<typename T>
	struct SerializeMethod
	{
		static void In(T& obj, const String& str) = 0;
		static String Out(const T& obj) = 0;
	};

	template<typename T, bool b>
	struct SerializeCore
	{

	};

	template<typename T>
	struct SerializeCore<T, true>
	{
		static void Run(T& obj, SerializeInterface& si)
		{
			for (auto& i : T::GetMetaDataCore().m_DirectInheritanceRelation)
			{
				i.second.m_pMetaData->m_SerializeAction(i.second.CastToMetaObject(obj.T::CastToMetaObject()), si);
			}
			for (auto& i : T::GetMetaDataCore().m_MemberVariable)
			{
				if (i.second.m_IfSerialize)
					i.second.m_pMetaData->m_SerializeAction(i.second.CastToMetaObject(obj.T::CastToMetaObject()), si);
			}
		}
	};

	template<typename T>
	struct SerializeCore<T, false>
	{
		static void Run(T& obj, SerializeInterface& si)
		{
			if (si.m_IOFlag == SerializeInterface::IOFlag::Input)
			{
				SerializeMethod<T>::In(obj, si.Read());
			}
			else
			{
				si.Write(SerializeMethod<T>::Out(obj));
			}
		}
	};

	template<typename T>
	struct SerializeCore<T*, false>	//pointer serialize
	{
		static void Run(T*& obj, SerializeInterface& si)
		{
			if (si.m_IOFlag == SerializeInterface::IOFlag::Input)
			{
				T* ptr = nullptr;
				SerializeMethod<T*>::In(ptr, si.Read());
				if (ptr)
					GetSerializeObjectManager().QueryObject(ptr, (void**)&obj);
				else
					obj = ptr;
			}
			else
			{
				si.Write(SerializeMethod<T*>::Out(obj));
			}
		}
	};

	template<typename T>
	struct SerializeCore<T*, true>	//pointer serialize:just serialize ptr directly
	{
		static void Run(T*& obj, SerializeInterface& si)
		{
			if (si.m_IOFlag == SerializeInterface::IOFlag::Input)
{'fraction_non_alphanumeric': 0.11770927772741009, 'fraction_numerical': 0.003626473254759746, 'mean_word_length': 4.2699044585987265, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '124304', 'n_tokens_mistral': 2438, 'n_tokens_neox': 2188, 'n_words': 589}