Click here to Skip to main content
15,891,529 members
Articles / Programming Languages / C++

Writing Win32 Apps with C++: V2 - part 1

Rate me:
Please Sign up or sign in to vote.
4.70/5 (34 votes)
20 Jun 2005CPOL14 min read 107.9K   1.2K   73  
An independent framework to handle Win32 objects inside C++ classes.
//events.h
//	events and syncs

#pragma once
namespace GE_{namespace stdx1{

	/// event and sync paradign
	class event_source;

	class event_handler_base //wil be tha virtual base for all receivers
	{
	private:
		typedef std::list<event_source*> lstsrc_type;
		lstsrc_type lstsrc;
	public:
		//forwarded - see beyond
		void Hook(event_source& src);
		void Unhook(event_source& src);
		void Unhook();

		virtual ~event_handler_base() { Unhook(); }
	};

	class event_source
	{
		friend class event_handler_base;
	protected:
		typedef std::list<event_handler_base*> rcvlist_type;
		rcvlist_type rcvlist;
	public:
		typedef rcvlist_type::iterator rcvptr_iterator;

		struct state
		{
			virtual bool do_next()=0;
		};
	private:

		//will represent the iteration state
		template<class Hint>
		struct state_tpl: public state
		{
		private:
			rcvptr_iterator cur, end; //list iterators
			const Hint* phint;	//the "event" hint
			event_source* psource;	//ourself
			friend class event_source;
		public:
			bool do_next()	//recourse the event into the next receiver
			{
				while(cur != end)
				{
					//seek an appropriate receiver for the hint
					event_handler<Hint>* prcv = dynamic_cast<event_handler<Hint>*>(*cur);
					cur++; //prepare for the next
					if(!prcv) continue;
					if(prcv->on_event(*phint, this)) return true; //fires and halt if returned true
				}
				return false;
			}
		};

	public:

		template<class Hint>
		bool fire(const Hint& _hint)
		{
			state_tpl<Hint> st;
			st.cur = rcvlist.begin();
			st.end = rcvlist.end();
			st.phint = &_hint;
			return st.do_next();
		}

        virtual ~event_source()
		{
			while(!rcvlist.empty())
				(*rcvlist.begin())->Unhook(*this);
		}
	};

	template<class Hint>
	class event_handler: //derive as many time required for as many Hint-s you have to RefcountableW32Handle
		public virtual event_handler_base
	{
	public:
		virtual bool on_event(const Hint& _hint, event_source::state* pState) {return false;}
	};


	inline void event_handler_base::Hook(event_source& src)
	{
		if(std::find(lstsrc.begin(), lstsrc.end(), &src) != lstsrc.end()) return;
		lstsrc.push_front(&src);
		if(std::find(src.rcvlist.begin(), src.rcvlist.end(), this) != src.rcvlist.end()) return;
		src.rcvlist.push_front(this);
	}
	
	inline void event_handler_base::Unhook(event_source& src)
	{
		lstsrc.remove(&src);
		src.rcvlist.remove(this);
	}

	inline void event_handler_base::Unhook()
	{
		lstsrc_type::iterator i;
		for(i = lstsrc.begin(); i!= lstsrc.end(); ++i)
            (**i).rcvlist.remove(this);
		lstsrc.clear();
	}
}}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Italy Italy
Born and living in Milan (Italy), I'm an engineer in electronics actually working in the ICT department of an important oil/gas & energy company as responsible for planning and engineering of ICT infrastructures.
Interested in programming since the '70s, today I still define architectures for the ICT, deploying dedicated specific client application for engineering purposes, working with C++, MFC, STL, and recently also C# and D.

Comments and Discussions