⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 class.hpp

📁 魔兽世界的私服源程序
💻 HPP
📖 第 1 页 / 共 3 页
字号:

		// the following two functions are the ones that returns
		// a pointer to a const_held_type_constructor, or 0 if there
		// is no held_type
		template<class HolderType>
		struct const_holder_constructor
		{
			typedef void(*constructor)(void*,void*);
			template<class T>
			static constructor apply(detail::type<T>)
			{
				return get_const_holder_constructor(detail::type<T>(), luabind::get_const_holder(static_cast<HolderType*>(0)));
			}

		private:

			template<class T, class ConstHolderType>
				static constructor get_const_holder_constructor(detail::type<T>, ConstHolderType*)
			{
				return &internal_construct_holder<ConstHolderType, T>::apply;
			}
		};

		template<>
		struct const_holder_constructor<detail::null_type>
		{
			typedef void(*constructor)(void*,void*);
			template<class T>
			static constructor apply(detail::type<T>)
			{
				return 0;
			}
		};



		// this is a selector that returns the size of the held_type
		// or 0 if we don't have a held_type
		template <class HolderType>
		struct internal_holder_size
		{
			static int apply() { return get_internal_holder_size(luabind::get_const_holder(static_cast<HolderType*>(0))); }
		private:
			template<class ConstHolderType>
			static int get_internal_holder_size(ConstHolderType*)
			{
				return max<sizeof(HolderType), sizeof(ConstHolderType)>::value;
			}
		};

		template <>
		struct internal_holder_size<detail::null_type>
		{
			static int apply() {	return 0; }
		};


		// if we have a held type, return the destructor to it
		// note the difference. The held_type should only be destructed (not deleted)
		// since it's constructed in the lua userdata
		template<class HeldType>
		struct internal_holder_destructor
		{
			typedef void(*destructor_t)(void*);
			template<class T>
			static destructor_t apply(detail::type<T>)
			{
				return &detail::destruct_only_s<HeldType>::apply;
			}
		};

		// if we don't have a held type, return the destructor of the raw type
		template<>
		struct internal_holder_destructor<detail::null_type>
		{
			typedef void(*destructor_t)(void*);
			template<class T>
			static destructor_t apply(detail::type<T>)
			{
				return &detail::delete_s<T>::apply;
			}
		};

		
		// if we have a held type, return the destructor to it's const version
		template<class HolderType>
		struct internal_const_holder_destructor
		{
			typedef void(*destructor_t)(void*);
			template<class T>
			static destructor_t apply(detail::type<T>)
			{
				return const_holder_type_destructor(luabind::get_const_holder(static_cast<HolderType*>(0)));
			}

		private:

			template<class ConstHolderType>
			static destructor_t const_holder_type_destructor(ConstHolderType*)
			{
				return &detail::destruct_only_s<ConstHolderType>::apply;
			}

		};

		// if we don't have a held type, return the destructor of the raw type
		template<>
		struct internal_const_holder_destructor<detail::null_type>
		{
			typedef void(*destructor_t)(void*);
			template<class T>
			static destructor_t apply(detail::type<T>)
			{
				return 0;
			}
		};




		template<class HolderType>
		struct get_holder_alignment
		{
			static int apply()
			{
				return internal_alignment(luabind::get_const_holder(static_cast<HolderType*>(0)));
			}

		private:

			template<class ConstHolderType>
			static int internal_alignment(ConstHolderType*)
			{
				return detail::max<boost::alignment_of<HolderType>::value
					, boost::alignment_of<ConstHolderType>::value>::value;
			}
		};

		template<>
		struct get_holder_alignment<detail::null_type>
		{
			static int apply()
			{
				return 1;
			}
		};


	} // detail














	struct class_base: detail::scoped_object
	{
	protected:

		struct base_desc
		{
			LUABIND_TYPE_INFO type;
			int ptr_offset;
		};

	private:

#ifndef NDEBUG
		bool m_cloned;
#endif

		const char* m_name;

		std::map<const char*, detail::method_rep, detail::ltstr> m_methods;

		// datamembers, some members may be readonly, and
		// only have a getter function
		std::map<const char*, detail::class_rep::callback, detail::ltstr> m_getters;
		std::map<const char*, detail::class_rep::callback, detail::ltstr> m_setters;

		// the operators in lua
		std::vector<detail::class_rep::operator_callback> m_operators[detail::number_of_operators]; 
		std::map<const char*, int, detail::ltstr> m_static_constants;

		std::vector<base_desc> m_bases;
		detail::construct_rep m_constructor;

		void(*m_destructor)(void*);
		void(*m_const_holder_destructor)(void*);

		void*(*m_extractor)(void*);
		const void*(*m_const_extractor)(void*);

		void(*m_const_converter)(void*,void*);

		void(*m_construct_holder)(void*, void*);
		void(*m_construct_const_holder)(void*, void*);

		int m_holder_size;
		int m_holder_alignment;

		LUABIND_TYPE_INFO m_type;
		LUABIND_TYPE_INFO m_holder_type;
		LUABIND_TYPE_INFO m_const_holder_type;

#ifndef LUABIND_DONT_COPY_STRINGS
		// the maps that contains char pointers points into
		// this vector of strings. 
		std::vector<char*> m_strings;
#endif

	public:

		// public 'cause of enum_maker, FIX
		void add_static_constant(const char* name, int val)
		{
			m_static_constants[name] = val;
		}

	protected:

		void init(LUABIND_TYPE_INFO type
			, LUABIND_TYPE_INFO holder_type
			, void*(*extractor)(void*)
			, const void*(*const_extractor)(void*)
			, void(*const_converter)(void*,void*)
			, void(*holder_constructor)(void*,void*)
			, void(*const_holder_constructor)(void*,void*)
			, void(*destructor)(void*)
			, void(*const_holder_destructor)(void*)
			, int holder_size
			, int holder_alignment)
		{
			m_type = type;
			m_holder_type = holder_type;
			m_extractor = extractor;
			m_const_extractor = const_extractor;
			m_const_converter = const_converter;
			m_construct_holder = holder_constructor;
			m_construct_const_holder = const_holder_constructor;
			m_destructor = destructor;
			m_const_holder_destructor = const_holder_destructor;
			m_holder_size = holder_size;
			m_holder_alignment = holder_alignment;
		}

		template<class T>
		void set_const_holder_type(T*)
		{
			m_const_holder_type = LUABIND_TYPEID(T);
		}

		inline void add_getter(const char* name, const boost::function2<int, lua_State*, int>& g)
		{
			detail::class_rep::callback c;
			c.func = g;
			c.pointer_offset = 0;
#ifndef LUABIND_DONT_COPY_STRINGS
			m_strings.push_back(detail::dup_string(name));
			m_getters[m_strings.back()] = c;
#else
			m_getters[name] = c;
#endif
		}

		inline void add_setter(const char* name, const boost::function2<int, lua_State*, int>& s)
		{
			detail::class_rep::callback c;
			c.func = s;
			c.pointer_offset = 0;
#ifndef LUABIND_DONT_COPY_STRINGS
			m_strings.push_back(detail::dup_string(name));
			m_setters[m_strings.back()] = c;
#else
			m_setters[name] = c;
#endif
		}

		void add_base(const base_desc& b)
		{
			m_bases.push_back(b);
		}

	public:

		void add_constructor(const detail::construct_rep::overload_t& o)
		{
			m_constructor.overloads.push_back(o);
		}

		void add_method(const char* name, const detail::overload_rep& o)
		{
#ifdef LUABIND_DONT_COPY_STRINGS
			detail::method_rep& method = m_methods[name];
			method.name = name;
#else
			m_strings.push_back(detail::dup_string(name));
			detail::method_rep& method = m_methods[m_strings.back()];
			method.name = m_strings.back();
#endif
			method.add_overload(o);
			method.crep = 0;
		}

#ifndef LUABIND_NO_ERROR_CHECKING
		inline void add_operator(int op_id,  int(*func)(lua_State*), int(*matcher)(lua_State*), void(*sig)(lua_State*, std::string&), int arity)
#else
		inline void add_operator(int op_id,  int(*func)(lua_State*), int(*matcher)(lua_State*), int arity)
#endif
		{
			detail::class_rep::operator_callback o;
			o.set_fun(func);
			o.set_match_fun(matcher);
			o.set_arity(arity);

#ifndef LUABIND_NO_ERROR_CHECKING

			o.set_sig_fun(sig);

#endif
			m_operators[op_id].push_back(o);
		}







		const char* name() const { return m_name; }

		class_base(const char* name)
		{
#ifndef LUABIND_DONT_COPY_STRINGS
			m_strings.push_back(detail::dup_string(name));
			m_name = m_strings.back();
#else
			m_name = name;
#endif

#ifndef NDEBUG
			m_cloned = false;
#endif
		}

		virtual ~class_base()
		{
// if we are copying strings, we have to destroy them too
#ifndef LUABIND_DONT_COPY_STRINGS
			for (std::vector<char*>::iterator i = m_strings.begin(); i != m_strings.end(); ++i)
				delete[] *i;
#endif
		}

		// pushes the class_rep on the lua stack
		virtual void commit(lua_State* L)
		{
			assert(!m_cloned && "class already commited");
				  
			detail::getref(L, scope_stack::top(L));
			lua_pushstring(L, m_name);

			detail::class_rep* crep;

			detail::class_registry* r = detail::class_registry::get_registry(L);
			// create a class_rep structure for this class.
			// allocate it within lua to let lua collect it on
			// lua_close(). This is better than allocating it
			// as a static, since it will then be destructed
			// when the program exits instead.
			// warning: we assume that lua will not
			// move the userdata memory.
			lua_newuserdata(L, sizeof(detail::class_rep));
			crep = reinterpret_cast<detail::class_rep*>(lua_touserdata(L, -1));
			
			new(crep) detail::class_rep(	m_type
				, m_name
				, L
				, m_destructor
				, m_const_holder_destructor
				, m_holder_type
				, m_const_holder_type
				, m_extractor
				, m_const_extractor
				, m_const_converter
				, m_construct_holder
				, m_construct_const_holder
				, m_holder_size
				, m_holder_alignment);

			// register this new type in the class registry
			r->add_class(m_type, crep);
			if (!(LUABIND_TYPE_INFO_EQUAL(m_holder_type, LUABIND_INVALID_TYPE_INFO)))
			{
				// if we have a held type
				// we have to register it in the class-table
				// but only for the base class, if it already
				// exists, we don't have to register it
				detail::class_rep* c = r->find_class(m_holder_type);
				if (c == 0)
				{
					r->add_class(m_holder_type, crep);
					r->add_class(m_const_holder_type, crep);
				}
			}

			// add methods
			for (std::map<const char*, detail::method_rep, detail::ltstr>::iterator i = m_methods.begin();
				i != m_methods.end(); 
				++i)
			{
				i->second.crep = crep;
			}
			std::swap(crep->m_methods, m_methods);

			// constructors
			m_constructor.swap(crep->m_constructor);

			#ifndef LUABIND_DONT_COPY_STRINGS
				assert(crep->m_strings.empty() && "Internal error");
				std::swap(crep->m_strings, m_strings);
			#endif

			std::swap(crep->m_getters, m_getters);
			std::swap(crep->m_setters, m_setters);

			for(int i = 0; i < detail::number_of_operators; ++i)
				std::swap(crep->m_operators[i], m_operators[i]);
	
			std::swap(crep->m_static_constants, m_static_constants);

			for (std::vector<base_desc>::iterator i = m_bases.begin();
							i != m_bases.end(); 
							++i)
			{
				detail::class_registry* r = detail::class_registry::get_registry(L);

				// the baseclass' class_rep structure
				detail::class_rep* bcrep = r->find_class(i->type);

				detail::class_rep::base_info base;
				base.pointer_offset = i->ptr_offset;
				base.base = bcrep;

				crep->add_base_class(base);
			}

			lua_settable(L, -3);
			lua_pop(L, 1);
		}


⌨️ 快捷键说明

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