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

📄 signal_v1.h

📁 这是一款2d游戏引擎
💻 H
字号:
/*  $Id: signal_v1.h,v 1.18 2004/01/09 22:55:33 mbn Exp $
**
**  ClanLib Game SDK
**  Copyright (C) 2003  The ClanLib Team
**  For a total list of contributers see the file CREDITS.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This library 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
**  Lesser General Public License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
**
*/

//! clanSignal="System"
//! header=signals.h

#ifndef header_signal_v1
#define header_signal_v1

#if _MSC_VER > 1000
#pragma once
#endif

#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#endif

#include "slot.h"
#include "slot_v1.h"
#include <list>

//: CL Signal V1 class
//- !group=Signal/System!
//- !header=signals.h!
template <class PARAM1>
class CL_Signal_v1
{
public:
	typedef CL_Slot_v1<PARAM1> *Slot;
	typedef typename std::list<Slot>::iterator SlotIterator;

	class CL_Signal_v1_Generic
	{
	public:
		CL_Signal_v1_Generic() : in_call(false), deleted(false) { return; }

		~CL_Signal_v1_Generic()
		{
			for (SlotIterator slot_it = slots.begin(); slot_it != slots.end(); slot_it++)
			{
				Slot slot = *slot_it;
				slot->release_signal_ref();
			}
		}

		bool in_call, deleted;
		std::list<Slot> slots;
	};

//! Construction:
public:
	//: CL Signal V1 constructor
	CL_Signal_v1() : impl(new CL_Signal_v1_Generic)
	{
	}

	CL_Signal_v1(const CL_Signal_v1 &copy) : impl(new CL_Signal_v1_Generic)
	{
		impl->slots = copy.impl->slots;
		for (SlotIterator slot_it = impl->slots.begin(); slot_it != impl->slots.end(); slot_it++)
		{
			Slot slot = *slot_it;
			slot->add_signal_ref();
		}
	}

	//: CL Signal V1 destructor
	~CL_Signal_v1()
	{
		if (impl->in_call) impl->deleted = true;
		else delete impl;
	}

//! Operations:
public:
	CL_Signal_v1 &operator =(const CL_Signal_v1 &copy)
	{
		if (impl->in_call) impl->deleted = true;
		else delete impl;

		impl = new CL_Signal_v1_Generic;
		impl->slots = copy.impl->slots;
		for (SlotIterator slot_it = impl->slots.begin(); slot_it != impl->slots.end(); slot_it++)
		{
			Slot slot = *slot_it;
			slot->add_signal_ref();
		}
		return *this;
	}

	//: Operator
	void operator() (PARAM1 param1)
	{
		call(param1);
	}

	//: Call
	void call(PARAM1 param1)
	{
		CL_Signal_v1_Generic *data = impl;
		data->in_call = true;

		std::list<SlotIterator> remove_slots;

		// call slots connected to signal:
		for (SlotIterator slot_it = data->slots.begin(); slot_it != data->slots.end(); slot_it++)
		{
			Slot slot = *slot_it;

			// skip slot if it has no more references left in application.
			// (make it pending for removal)
			if (slot->get_slot_ref() == 0)
			{
				remove_slots.push_back(slot_it);
				continue;
			}
			
			slot->call(param1);
			if (data->deleted) break;
		}

		// remove all slots no longer connected to any CL_Slot.
		typename std::list<SlotIterator>::iterator remove_it;
		for (remove_it = remove_slots.begin(); remove_it != remove_slots.end(); remove_it++)
		{
			Slot slot = **remove_it;
			slot->release_signal_ref();
			data->slots.erase(*remove_it);
		}

		data->in_call = false;
		if (data->deleted) delete data;
	}

	//: Connect slot.
	CL_Slot connect(Slot slot)
	{
		slot->add_signal_ref();
		impl->slots.push_back(slot);
		return CL_Slot(slot);
	}

	//: Connect callback function slot.
	CL_Slot connect(void (*callback)(PARAM1))
	{
		return connect(new CL_FunctionSlot_v1<PARAM1>(callback));
	}

	//: Connect functor slot.
	template<class Functor>
	CL_Slot connect_functor(const Functor &functor)
	{
		return connect(new CL_FunctorSlot_v1<Functor, PARAM1>(functor));
	}

	//: Connect member function slot.
	template <class CallbackClass>
	CL_Slot connect(
		CallbackClass *cb_class,
		void (CallbackClass::*callback)(PARAM1))
	{
		return connect(new CL_MethodSlot_v1<CallbackClass, PARAM1>(cb_class, callback));
	}

	//: Connect member function with user data slot.
	template <class CallbackClass, class UserData>
	CL_Slot connect(
		CallbackClass *cb_class,
		void (CallbackClass::*callback)(PARAM1, UserData),
		UserData user_data)
	{
		return connect(new CL_UserDataMethodSlot_v1<CallbackClass, PARAM1, UserData>(cb_class, callback, user_data));
	}

	//: Disconnect
	void disconnect(CL_Slot &disconnect_slot)
	{
		for (SlotIterator slot_it = impl->slots.begin(); slot_it != impl->slots.end();)
		{
			Slot slot = *slot_it;
			if (disconnect_slot.impl == slot)
			{
				slot->release_signal_ref();
				slot_it = impl->slots.erase(slot_it);
			}
			else
				slot_it++;
		}
	}

//! Implementation:
private:
	CL_Signal_v1_Generic *impl;
};

#endif

⌨️ 快捷键说明

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