serializer.h

来自「这是整套横扫千军3D版游戏的源码」· C头文件 代码 · 共 166 行

H
166
字号

#ifndef SERIALIZER_IMPL_H
#define SERIALIZER_IMPL_H

#include "ISerializer.h"
#include <map>
#include <vector>
#include <list>

namespace creg {
	/**
	 * Output stream serializer
	 * Usage: create an instance of this class and call SavePackage
	 * @see SavePackage
	 */
	class COutputStreamSerializer : public ISerializer
	{
	protected:
		struct ObjectRef {
			ObjectRef() {
				ptr = 0;
				id=0;
				classIndex=0;
				isEmbedded=false;
				class_=0;
			}
			ObjectRef(void *ptr,int id,bool isEmbedded,creg::Class *class_) {
				this->ptr = ptr;
				this->id=id;
				classIndex=0;
				this->isEmbedded=isEmbedded;
				this->class_=class_;
			}
			ObjectRef(const ObjectRef&src) {
				ptr=src.ptr;
				id=src.id;
				classIndex=src.classIndex;
				isEmbedded=src.isEmbedded;
				class_=src.class_;
			}
			void *ptr;
			int id, classIndex;
			bool isEmbedded;
			creg::Class *class_;
			bool isThisObject(void *objPtr,creg::Class *objClass,bool objEmbedded) const
			{
				if (ptr!=objPtr) return false;
				if (class_==objClass) return true;
				if (isEmbedded&&objEmbedded) return false;
				if (!objEmbedded) {
					for (creg::Class *base=class_->base;base;base=base->base)
						if (base==objClass) return true;
				} 
				if (!isEmbedded) {
					for (creg::Class *base=objClass->base;base;base=base->base)
						if (base==class_) return true;
				}
				return false;
			}
		};

		// Temporary class reference
		struct ClassRef;

		std::ostream *stream;
		std::map <void*,std::vector<ObjectRef*> > ptrToId;
		std::list <ObjectRef> objects;
		std::vector <ObjectRef*> pendingObjects; // these objects still have to be saved

		// Serialize all class names
		void WriteObjectInfo ();
		// Helper for instance/ptr saving
		void WriteObjectRef (void *inst, creg::Class *cls, bool embedded);

		ObjectRef* FindObjectRef(void *inst, creg::Class *objClass, bool isEmbedded);

	public:
		COutputStreamSerializer ();

		/** Create a package of the given root object and all the objects that it references
		 * @param s stream to serialize the data to
		 * @param rootObj the rootObj: the starting point for finding all the objects to save
		 * @param cls the class of the root object
		 * This method throws an std::runtime_error when something goes wrong
		 */
		void SavePackage (std::ostream *s, void *rootObj, creg::Class *cls);

		/** @see ISerializer::IsWriting */
		bool IsWriting ();

		/** @see ISerializer::SerializeObjectPtr */
		void SerializeObjectPtr (void **ptr, creg::Class *cls);
		
		/** @see ISerializer::SerializeObjectInstance */
		void SerializeObjectInstance (void *inst, creg::Class *cls);

		/** @see ISerializer::Serialize */
		void Serialize (void *data, int byteSize);

		/** Empty function, only applies to loading */
		void AddPostLoadCallback (void (*cb)(void *d), void *d) {}
	};

	/** Input stream serializer
	 * Usage: Create an instance of this class and call LoadPackage
	 * @see LoadPackage
	 */
	class CInputStreamSerializer : public ISerializer
	{
	protected:
		std::istream* stream;
		std::vector <creg::Class *> classRefs;

		struct UnfixedPtr {
			void **ptrAddr;
			int objID;
		};
		std::vector <UnfixedPtr> unfixedPointers; // pointers to embedded objects that haven't been filled yet, because they are not yet loaded

		struct StoredObject
		{
			void *obj;
			int classRef;
			bool isEmbedded;
		};
		std::vector <StoredObject> objects;

		struct PostLoadCallback
		{
			void (*cb)(void *d);
			void *userdata;
		};
		std::vector <PostLoadCallback> callbacks;

	public:
		CInputStreamSerializer ();
		~CInputStreamSerializer ();

		/** @see ISerializer::IsWriting */
		bool IsWriting ();

		/** @see ISerializer::SerializeObjectPtr */
		void SerializeObjectPtr (void **ptr, creg::Class *cls);
		
		/** @see ISerializer::SerializeObjectInstance */
		void SerializeObjectInstance (void *inst, creg::Class *cls);

		/** @see ISerializer::Serialize */
		void Serialize (void *data, int byteSize);

		/** @see ISerializer::AddPostLoadCallback */
		void AddPostLoadCallback (void (*cb)(void *userdata), void *userdata);

		/** Load a package that is saved by CInputStreamSerializer
		 * @param s the input stream to read from
		 * @param root the root object address will be assigned to this
		 * @param rootCls the root object class will be assigned to this
		 * This method throws an std::runtime_error when something goes wrong */
		void LoadPackage (std::istream *s, void *&root, creg::Class *&rootCls);
	};

};


#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?