/* * msghandler.h by Matze Braun * * Copyright (C) 2001 Atomic Blue (info@planeshift.it, http://www.atomicblue.org) * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation (version 2 of the License) * This program 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 General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef __MSGHANDLER_H__ #define __MSGHANDLER_H__ #include #include #include #include "net/message.h" #include "net/netbase.h" // forward decls struct iNetSubscriber; class NetBase; #define MAX_MESSAGE_TYPES 255 // MSGTYPE enumeration in messages.h has less types than this // This little struct tracks who is interested in what. struct Subscription { /// type of the messages this listener listens to msgtype type; /// Flags for central testing uint32_t flags; /// pointer to the subscriber iNetSubscriber *subscriber; }; /** * This class handles the incoming network packets */ class MsgHandler : public csRefCount, public csRunnable { public: MsgHandler(); virtual ~MsgHandler(); /** Initializes the Handler */ bool Initialize(NetBase *nb, int queuelen = 500); /** Any subclass of iNetSubscriber can subscribe to incoming network messages * with this function */ virtual bool Subscribe(iNetSubscriber *subscriber, msgtype type, uint32_t flags=0); /// Remove subscriber from list virtual bool Unsubscribe(iNetSubscriber *subscriber, msgtype type); /// Distribute message to all subscribers void Publish(MsgEntry *msg); /// import the broadcasttype typedef NetBase::broadcasttype broadcasttype; /// Allows subscribers to respond with new messages virtual void SendMessage(MsgEntry *msg) { netbase->SendMessage(msg); } /// Send messages to many clients with one func call virtual void Broadcast(MsgEntry* msg, broadcasttype scope = NetBase::BC_EVERYONEBUTSELF, int guildID=-1) { netbase->Broadcast(msg, scope, guildID); } /// Send messages to all listed client nums. virtual void Multicast(MsgEntry* msg, csArray& multi, int except, float range) { netbase->Multicast(msg, multi, except, range); } /// Start the separate thread virtual bool StartThread(); /// Wait for the separate thread to stop virtual bool StopThread(); /// Detects multiple subscriptions on the same object bool IsSubscribed (Subscription* p ); virtual void IncRef () { csRefCount::IncRef (); } virtual void DecRef () { csRefCount::DecRef (); } virtual int GetRefCount() { return csRefCount::GetRefCount(); } void AddToLocalQueue(MsgEntry *me) { netbase->QueueMessage(me); } csTicks GetPing() { return netbase->GetPing(); } /// Flush the connected output queue. bool Flush() { return netbase->Flush(queue); } protected: /** thread main loop */ virtual void Run () = 0; NetBase *netbase; MsgQueue *queue; /** * Each message type now has an array of subscribers so we can publish * to them directly instead of searching the entire list of all subscribers. */ csPDelArray subscribers[MAX_MESSAGE_TYPES]; csRef thread; csRef mutex; bool stop_network; }; #endif