diff --git a/src/murmur/Murmur.ice b/src/murmur/Murmur.ice index e0656bb13..07f70f583 100644 --- a/src/murmur/Murmur.ice +++ b/src/murmur/Murmur.ice @@ -185,6 +185,21 @@ module Murmur exception InvalidPlayerException extends MurmurException {}; /** This is thrown when you try to set an invalid texture. */ exception InvalidTextureException extends MurmurException {}; + /** This is thrown when you supply an invalid callback. */ + exception InvalidCallbackException extends MurmurException {}; + + /** Callback interface for servers. You can supply an implementation of this to receive notification + * messages from the server. + * If an added callback ever throws an exception or goes away, it will be automatically removed. + */ + ["ami"] interface ServerCallback { + idempotent void newPlayer(Player p); + idempotent void changedPlayer(Player p); + idempotent void deletedPlayer(Player p); + idempotent void newChannel(Channel c); + idempotent void changedChannel(Channel c); + idempotent void deletedChannel(Channel c); + }; /** Per-server interface. This includes all methods for configuring and altering * the state of a single virtual server. You can retrieve a pointer to this interface @@ -212,6 +227,18 @@ module Murmur */ idempotent int id(); + /** Add a callback. + * + * @param cb Callback interface which receives messages. + */ + void addCallback(ServerCallback *cb) throws ServerBootedException, InvalidCallbackException; + + /** Remove a callback. + * + * @param cb Callback interface to be removed. + */ + void removeCallback(ServerCallback *cb) throws ServerBootedException, InvalidCallbackException; + /** Retrieve configuration item. * @param key Configuration key. * @return Configuration value. If this is empty, see [Meta::getDefaultConf] diff --git a/src/murmur/MurmurI.h b/src/murmur/MurmurI.h index 453c13ee2..b86191ea8 100644 --- a/src/murmur/MurmurI.h +++ b/src/murmur/MurmurI.h @@ -20,6 +20,9 @@ class ServerI : virtual public Server { virtual void delete_async(const ::Murmur::AMD_Server_deletePtr&, const Ice::Current&); + virtual void addCallback_async(const ::Murmur::AMD_Server_addCallbackPtr&, const ::Murmur::ServerCallbackPrx&, const ::Ice::Current&); + virtual void removeCallback_async(const ::Murmur::AMD_Server_removeCallbackPtr&, const ::Murmur::ServerCallbackPrx&, const ::Ice::Current&); + virtual void id_async(const ::Murmur::AMD_Server_idPtr&, const Ice::Current&); diff --git a/src/murmur/MurmurIce.cpp b/src/murmur/MurmurIce.cpp index 3bb58af96..bb9be16e5 100644 --- a/src/murmur/MurmurIce.cpp +++ b/src/murmur/MurmurIce.cpp @@ -42,6 +42,7 @@ static MurmurIce *mi = NULL; static Ice::ObjectPtr iopServer; class IceEvent : public QEvent { + Q_DISABLE_COPY(IceEvent); protected: boost::function func; public: @@ -119,6 +120,12 @@ void MurmurIce::customEvent(QEvent *evt) { } } +void MurmurIce::serverDeleted(QObject *o) { + ::Server *s = qobject_cast< ::Server *>(o); + if (s) + qmCallbacks.remove(s->iServerNum); +} + Ice::ObjectPtr ServerLocator::locate(const Ice::Current &, Ice::LocalObjectPtr &) { return iopServer; } @@ -258,6 +265,16 @@ static void impl_Server_delete(const ::Murmur::AMD_Server_deletePtr cb, int serv cb->ice_response(); } +static void impl_Server_addCallback(const Murmur::AMD_Server_addCallbackPtr &cb, int server_id, const Murmur::ServerCallbackPrx& cbptr) { + NEED_SERVER; + mi->qmCallbacks[server_id].append(cbptr); +} + +static void impl_Server_removeCallback(const Murmur::AMD_Server_removeCallbackPtr &cb, int server_id, const Murmur::ServerCallbackPrx& cbptr) { + NEED_SERVER; + mi->qmCallbacks[server_id].removeAll(cbptr); +} + static void impl_Server_id(const ::Murmur::AMD_Server_idPtr cb, int server_id) { NEED_SERVER_EXISTS; cb->ice_response(server_id); diff --git a/src/murmur/MurmurIce.h b/src/murmur/MurmurIce.h index 9fd92a5a8..2624ecad3 100644 --- a/src/murmur/MurmurIce.h +++ b/src/murmur/MurmurIce.h @@ -35,6 +35,7 @@ #include #include +#include "MurmurI.h" #define ICE_QEVENT (QEvent::User + 959) @@ -48,7 +49,10 @@ class MurmurIce : public QObject { Ice::CommunicatorPtr communicator; void customEvent(QEvent *evt); public: + QMap > qmCallbacks; MurmurIce(); ~MurmurIce(); + public slots: + void serverDeleted(QObject *); }; #endif diff --git a/src/murmur/MurmurIceWrapper.cpp b/src/murmur/MurmurIceWrapper.cpp index 85b17bccf..b01cd4b81 100644 --- a/src/murmur/MurmurIceWrapper.cpp +++ b/src/murmur/MurmurIceWrapper.cpp @@ -18,6 +18,14 @@ void ::Murmur::ServerI::id_async(const ::Murmur::AMD_Server_idPtr &cb, const ::I IceEvent *ie = new IceEvent(boost::bind(&impl_Server_id, cb, QString::fromStdString(current.id.name).toInt())); QCoreApplication::instance()->postEvent(mi, ie); }; +void ::Murmur::ServerI::addCallback_async(const ::Murmur::AMD_Server_addCallbackPtr &cb, const ::Murmur::ServerCallbackPrx& p1, const ::Ice::Current ¤t) { + IceEvent *ie = new IceEvent(boost::bind(&impl_Server_addCallback, cb, QString::fromStdString(current.id.name).toInt(), p1)); + QCoreApplication::instance()->postEvent(mi, ie); +}; +void ::Murmur::ServerI::removeCallback_async(const ::Murmur::AMD_Server_removeCallbackPtr &cb, const ::Murmur::ServerCallbackPrx& p1, const ::Ice::Current ¤t) { + IceEvent *ie = new IceEvent(boost::bind(&impl_Server_removeCallback, cb, QString::fromStdString(current.id.name).toInt(), p1)); + QCoreApplication::instance()->postEvent(mi, ie); +}; void ::Murmur::ServerI::getConf_async(const ::Murmur::AMD_Server_getConfPtr &cb, const ::std::string& p1, const ::Ice::Current ¤t) { IceEvent *ie = new IceEvent(boost::bind(&impl_Server_getConf, cb, QString::fromStdString(current.id.name).toInt(), p1)); QCoreApplication::instance()->postEvent(mi, ie);