messager.h 3.2 KB
Newer Older
Hurstel's avatar
Hurstel committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
#ifndef _MESSAGER_H_
#define _MESSAGER_H_

#include <stdio.h>
#include <list>
#include <vector>
#include <string>
#include <thread>

#include <iostream>

#include <boost/shared_ptr.hpp>

class InAppMessage{
public:

		typedef unsigned int MESSAGE;
//		enum MESSAGE{
			static const MESSAGE EMPTY_MESSAGE= 0;
			static const MESSAGE LAUNCH_APP= 1;




			static const MESSAGE BASE_MESSAGE_LIMIT= 4096;
//		};

		class Args{
		public:
			Args(){}
			Args(const Args& args) :
				m_args(args.m_args)
			{}

			typedef boost::shared_ptr<void> ARG_T;

			template<typename T>
			Args& addArg(T arg){
				m_args.push_back(
					ARG_T(
						static_cast<void*>(
							new T{arg}
						)
					)
				);

				return (*this);
			}

			Args& operator=(const Args& o){
				if(this!= &o){
					m_args= o.m_args;
				}

				return (*this);
			}

			template<typename T>
			T getArg(unsigned int index= 0) const{
				assert(index<m_args.size()	);
				return (*(static_cast<T*>( m_args[index].get() )));
			}

			inline unsigned int count() const{return m_args.size();}

		protected:
			std::vector< ARG_T > m_args;
		};

		InAppMessage(MESSAGE msg_code= EMPTY_MESSAGE):
			m_code(msg_code)
		{}

		InAppMessage(MESSAGE msg_code, const Args &args):
			m_code(msg_code),
			m_args(args)
		{}

		template<typename T>
		void addArg(T arg){
			m_args.addArg(arg);
		}

		inline static InAppMessage create(MESSAGE msg_code= EMPTY_MESSAGE){
			return InAppMessage(msg_code);
		}

		inline static InAppMessage create(MESSAGE msg_code, const Args &args){
			return InAppMessage(msg_code, args);
		}

		static InAppMessage create(std::string messageHead, const Args& args);

		inline MESSAGE getCode() const{return m_code;}
		inline bool isEmpty() const { return m_code==EMPTY_MESSAGE; }
		inline const Args& getArgs() const{return m_args;}
		inline unsigned int countArgs() const{return m_args.count();}

protected:
		MESSAGE m_code;
		Args m_args;

		static MESSAGE strCodeConversion(std::string msg);
		static void* strArgsConversion(MESSAGE msg_code, const Args& args);
};

class InAppMessager{
public:
	inline InAppMessager(){}

	class Agent{
		friend class InAppMessager;
	public:
		typedef InAppMessage::MESSAGE OWN_MESSAGE;

		Agent(InAppMessager* iam= NULL):
			m_inAppMessager(iam)
		{
			if(iam){
				iam->addAgent(this);
			}
		}

		virtual ~Agent(){}

	protected:
		virtual void recieveMessage(const InAppMessage& iam){}

		virtual unsigned int getId() const= 0;

		inline void sendMessage(const InAppMessage& iam){
			m_inAppMessager->broadcastMessage(iam);
		}

		inline bool isRegistered(unsigned int agentID){
            return m_inAppMessager->isRegistered(agentID);
		}

	private:
		static const unsigned int m_ownMessageLimit= 1024;

		InAppMessager* m_inAppMessager;
	};

	bool addAgent(Agent* agent);
	inline void removeAgent(Agent* agent){if(agent) l_agents.remove(agent);}

	void broadcastMessage(const InAppMessage& iam);

	void Start();
	inline void Join(){if(m_msgThread){m_msgThread->join();}}
	inline void Stop(){b_run= false;}
	inline bool isRunning(){return b_run;}

	bool isRegistered(unsigned int agentID);

protected:
	std::list<Agent*> l_agents;

	std::list<InAppMessage> m_msgQueue;
	bool b_run= false;

	std::thread* m_msgThread=NULL;
};

#endif //_MESSAGER_H_