/* * msghandler.cpp * * 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. */ #include #include "util/sleep.h" #include "net/message.h" #include "net/messages.h" #include "net/netbase.h" #include "net/msghandler.h" #include "csutil/scopedmutexlock.h" #include "interface/subscriber.h" #include "util/psconst.h" class Client; MsgHandler::MsgHandler() { netbase = NULL; queue = NULL; mutex = csMutex::Create (CS_MUTEX_RECURSIVE); thread = NULL; } MsgHandler::~MsgHandler() { if ( thread ) thread->Stop (); if (queue) delete queue; } bool MsgHandler::Initialize(NetBase* nb, int queuelen) { if (!nb) return false; netbase = nb; queue = new MsgQueue(queuelen); if (!netbase->AddMsgQueue(queue)) return false; return true; } bool MsgHandler::StartThread() { thread = csThread::Create (this); if (!thread->Start ()) return false; return true; } bool MsgHandler::StopThread() { stop_network = true; thread->Wait(); thread = NULL; return true; } void MsgHandler::Publish(MsgEntry* me) { csScopedMutexLock lock(mutex); netbase->LogMessages("R",me); bool handled = false; int mtype = me->GetType(); for ( size_t x = 0; x < subscribers[mtype].Length(); x++ ) { Client *client; me->Reset(); if (subscribers[mtype][x]->subscriber->Verify(me,subscribers[mtype][x]->flags,client)) subscribers[mtype][x]->subscriber->HandleMessage(me,client); handled = true; } if (!handled) { Debug3(LOG_ANY,me->clientnum,"Unhandled message received 0x%04X from %d", me->GetType() ,me->clientnum); } } bool MsgHandler::Subscribe(iNetSubscriber *subscriber, msgtype type,uint32_t flags) { Subscription* p = new Subscription; p->subscriber = subscriber; p->type = type; p->flags = flags; csScopedMutexLock lock(mutex); if ( IsSubscribed(p) ) delete p; else subscribers[type].Push(p); return true; } bool MsgHandler::Unsubscribe(iNetSubscriber *subscriber, msgtype type) { csScopedMutexLock lock(mutex); for ( size_t x = 0; x < subscribers[type].Length(); x++ ) { if (subscribers[type][x]->subscriber == subscriber) { subscribers[type].DeleteIndex(x); return true; } } return false; } /*void MsgHandler::Run () { csRef msg; while(true) { msg = queue->GetWait(); if (msg) { Publish(msg); // don't forget to release the packet // msg->DecRef(); csRef does automatically } } Error1("BUG! This should never happen!"); } */ bool MsgHandler::IsSubscribed( Subscription* sub ) { for ( size_t x = 0; x < subscribers[sub->type].Length(); x++ ) { if (subscribers[sub->type][x]->subscriber == sub->subscriber) { return true; } } return false; }