[Yake-svn] SF.net SVN: yake: [1619] trunk/yake/samples
Status: Beta
Brought to you by:
psyclonist
From: <psy...@us...> - 2007-02-11 00:14:21
|
Revision: 1619 http://svn.sourceforge.net/yake/?rev=1619&view=rev Author: psyclonist Date: 2007-02-10 16:14:19 -0800 (Sat, 10 Feb 2007) Log Message: ----------- changes due to modified logging API, two new demos 'commClient' and 'commServer' Modified Paths: -------------- trunk/yake/samples/net/inprocess/common.h trunk/yake/samples/net/roclient/ROClient.cpp trunk/yake/samples/net/roserver/ROServer.cpp Added Paths: ----------- trunk/yake/samples/bin/debug/commclient.cfg trunk/yake/samples/bin/debug/commserver.cfg trunk/yake/samples/net/commclient/ trunk/yake/samples/net/commclient/demo.cpp trunk/yake/samples/net/commserver/ trunk/yake/samples/net/commserver/demo.cpp trunk/yake/samples/net/inprocess/demo.cpp Added: trunk/yake/samples/bin/debug/commclient.cfg =================================================================== --- trunk/yake/samples/bin/debug/commclient.cfg (rev 0) +++ trunk/yake/samples/bin/debug/commclient.cfg 2007-02-11 00:14:19 UTC (rev 1619) @@ -0,0 +1,7 @@ +commclient +{ + client + { + server 192.168.1.33:40000 + } +} Added: trunk/yake/samples/bin/debug/commserver.cfg =================================================================== --- trunk/yake/samples/bin/debug/commserver.cfg (rev 0) +++ trunk/yake/samples/bin/debug/commserver.cfg 2007-02-11 00:14:19 UTC (rev 1619) @@ -0,0 +1,7 @@ +commserver +{ + server + { + bind 192.168.1.33:40000 + } +} Added: trunk/yake/samples/net/commclient/demo.cpp =================================================================== --- trunk/yake/samples/net/commclient/demo.cpp (rev 0) +++ trunk/yake/samples/net/commclient/demo.cpp 2007-02-11 00:14:19 UTC (rev 1619) @@ -0,0 +1,223 @@ +#include <yake/base/yakeConfigFile.h> + +#include <yake/net/net.h> // basic networking +#include <yake/netsvc/netSvc.h> // networking services and service hosts +#include <yake/netsvc/service/netClientCommService.h> + +#include <samples/net/roclient/ROClient.h> + +namespace yake { + struct ThreadedApp : public boost::noncopyable + { + ThreadedApp() : stop_app_(false) + { + } + void requestStop() + { + stop_app_ = true; + } + bool stopRequested() const + { + return stop_app_; + } + void run() + { + try { + this->onRun(); + } + catch (const yake::net::Exception& e) + { + YAKE_LOG_ERROR("app",String("Caught net exception: ") << e.what()); + } + catch (const std::exception& e) + { + YAKE_LOG_ERROR("app",String("Caught exception: ") << e.what()); + } + catch (...) + { + YAKE_LOG_ERROR("app",String("Caught unknown exception.")); + } + } + private: + virtual void onRun() = 0; + private: + volatile bool stop_app_; + }; + struct NetServerApp : public ThreadedApp + { + NetServerApp() + { + } + typedef SignalX<void(void)> StepSignal; + yake::SignalConnection connectToStep(const StepSignal::slot_type& slot) + { + return stepSig_.connect(slot); + } + yake::SignalConnection connectToSynchronizedNetStep(const StepSignal::slot_type& slot) + { + return netStepSig_.connect(slot); + } + private: + virtual void onInit() = 0; + virtual void onStep() = 0; + virtual void onShutdown() = 0; + private: + StepSignal stepSig_; + StepSignal netStepSig_; + virtual void onRun() + { + ::SetThreadAffinityMask( ::GetCurrentThread(), 0x1 ); + this->onInit(); + + // main loop + while (!stopRequested()) + { + net::update(); + { + net::scoped_lock lck; + netStepSig_(); + } + stepSig_(); + this->onStep(); + net::native::sleep(0); + } + + this->onShutdown(); + //stepSig_.disconnectAll(); + } + }; +} // namespace yake + +using namespace yake; + +struct ClientApp : public yake::NetServerApp +{ + ClientApp(const std::string& serverIpAndPort) : host_(net::Address(serverIpAndPort)) + {} +private: + virtual void onInit() + { + // add comm service + commService_.reset(new net::ClientCommService(CHANNELID_COMM)); + host_.addService( net::IServicePtr(commService_), "comm" ); + + // start client + if (!host_.start()) + { + YAKE_LOG_ERROR("client","failed to connect"); + return; + } + + // join a few comm channels... + commService_->joinChannel("#lobby"); + commService_->sendMessageToChannel("#lobby","hello, folks!"); + + commService_->sendMessageToChannel("$svc:comm","createchannel #support GetSupport"); + commService_->sendMessageToChannel("$svc:comm","createchannel #test asd asd asd"); + + // + stepSigConns_.push_back( this->connectToSynchronizedNetStep( + boost::bind(&ro::client::step,boost::ref(host_)) ) ); + } + virtual void onStep() + { + // example of querying & forwarding information (e.g. to UI) + if (commService_->hasMessages("#lobby")) + { + for(net::ClientCommService::const_message_iterator itMsg = + commService_->beginMessages("#lobby"); + itMsg != commService_->endMessages("#lobby"); ++itMsg) + { + //YAKE_LOG("app","#lobby: " << itMsg->from_ << " said: " << itMsg->msg_); + std::cout << '\n' << itMsg->from_ << ": " << itMsg->msg_ << "\n"; + } + commService_->clearMessages("#lobby"); + } + + // + if (_kbhit()) + { + char key = _getch(); + if (key == 'q' || key == 'Q') + { + this->requestStop(); + } + else if (key == '\n' || key == '0x13' || key == '1') + { + commService_->sendMessageToChannel("#lobby",currInput_); + std::cout << '\n' << "I said: " << currInput_ << "\n"; + currInput_.clear(); + } + else + { + currInput_ += key; + std::cout << key;//'\f' << currInput_; + } + } + } + virtual void onShutdown() + { + stepSigConns_.clear(); + + { + net::scoped_lock lck; + host_.stop(); + host_.removeAllServices(); + } + commService_.reset(); + } +private: + ro::client host_; + SharedPtr<net::ClientCommService> commService_; + + typedef std::deque<yake::SignalConnection> SignalConnectionList; + SignalConnectionList stepSigConns_; + + String currInput_; +}; + +int main(int argc, char* argv[]) +{ + try { + Configuration cfg; + + if (argc > 1) + cfg.readFromFile(argv[1]); + else + cfg.readFromFile("commclient.cfg"); + + Configuration clientCfg( cfg, "commclient/client/" ); + + if (!net::initialize()) + throw net::Exception("failed to initialize"); + + // read configuration + const yake::String serverIpAndPort = clientCfg.get("server","127.0.0.1:40000"); + + // start client(s) + SharedPtr<ClientApp> clientObject; + clientObject.reset( new ClientApp(serverIpAndPort) ); + clientObject->run(); + clientObject.reset(); + + // clean up + net::shutdown(); + } + catch (const net::Exception& e) + { + YAKE_LOG_ERROR("demoe",String("Caught net exception: ") << e.what()); + net::shutdown(); + } + catch (const std::exception& e) + { + YAKE_LOG_ERROR("demoe",String("Caught exception: ") << e.what()); + net::shutdown(); + } + catch (...) + { + YAKE_LOG_ERROR("demoe",String("Caught unknown exception.")); + net::shutdown(); + } + return 0; +} + Added: trunk/yake/samples/net/commserver/demo.cpp =================================================================== --- trunk/yake/samples/net/commserver/demo.cpp (rev 0) +++ trunk/yake/samples/net/commserver/demo.cpp 2007-02-11 00:14:19 UTC (rev 1619) @@ -0,0 +1,231 @@ +#include <yake/base/yakeConfigFile.h> +#include <yake/net/net.h> // basic networking +#include <yake/netsvc/netSvc.h> // networking services and service hosts +#include <yake/netsvc/service/netServerCommService.h> + +#include <samples/net/roserver/ROServer.h> + + +namespace yake { + struct ThreadedApp : public boost::noncopyable + { + ThreadedApp() : stop_app_(false) + { + } + void requestStop() + { + stop_app_ = true; + } + bool stopRequested() const + { + return stop_app_; + } + void run() + { + try { + this->onRun(); + } + catch (const net::Exception& e) + { + YAKE_LOG_ERROR("app",String("Caught yake::net exception: ") + e.what()); + } + catch (const Exception& e) + { + YAKE_LOG_ERROR("app",String("Caught yake exception: ") + e.what()); + } + catch (const std::exception& e) + { + YAKE_LOG_ERROR("app",String("Caught exception: ") + e.what()); + } + catch (...) + { + YAKE_LOG_ERROR("app",String("Caught unknown exception.")); + } + } + private: + virtual void onRun() = 0; + private: + volatile bool stop_app_; + }; + struct NetServerApp : public ThreadedApp + { + NetServerApp() + { + } + typedef SignalX<void(void)> StepSignal; + yake::SignalConnection connectToStep(const StepSignal::slot_type& slot) + { + return stepSig_.connect(slot); + } + yake::SignalConnection connectToSynchronizedNetStep(const StepSignal::slot_type& slot) + { + return netStepSig_.connect(slot); + } + private: + virtual void onInit() = 0; + virtual void onStep() = 0; + virtual void onShutdown() = 0; + private: + StepSignal stepSig_; + StepSignal netStepSig_; + virtual void onRun() + { + ::SetThreadAffinityMask( ::GetCurrentThread(), 0x1 ); + this->onInit(); + + // main loop + while (!stopRequested()) + { + net::update(); + { + net::scoped_lock lck; + netStepSig_(); + } + stepSig_(); + this->onStep(); + net::native::sleep(0); + } + + this->onShutdown(); + //stepSig_.disconnectAll(); + } + }; +} // namespace yake + +using namespace yake; + +struct ServerApp : public yake::NetServerApp +{ + ServerApp(const Configuration& cfg) + { + // We need a copy to be threadsafe! + cfg_.copyFrom( cfg ); + } +private: + virtual void onInit() + { + YAKE_LOG("app","starting COMM server..."); + + // register services + { + net::ServerCommService* commService = new net::ServerCommService(CHANNELID_COMM); + host_.subscribeToClientAccepted( + boost::bind(&net::ServerCommService::onClientConnected,commService,_1) ); + host_.subscribeToClientDisconnected( + boost::bind(&net::ServerCommService::onClientDisconnected,commService,_1) ); + host_.addService( net::IServicePtr(commService), "comm" ); + + /* + Configuration::const_iterator itChannelEnd = cfg_.end("comm/autocreate"); + for (Configuration::const_iterator itChannel = cfg_.begin("comm/autocreate"); itChannel != itChannelEnd; ++itChannel) + { + COUTLN(itChannel->first); + const String path = "comm/autocreate/"+itChannel->first+"/"; + const String name = cfg_.get(path+"name",""); + if (name.empty()) + { + COUTLN("server-comm: configuration: invalid channel name"); + continue; + } + const String desc = cfg_.get(path+"description",""); + COUTLN("server-comm: configuration: " << name << " : " << desc); + try { + commService->createChannel(name,desc); + } + catch (yake::Exception& ex) + { + COUTLN("server-comm: failed to create channel '" << name << "': " << ex.what()); + } + } + */ + try { + commService->createChannel("#lobby","Hello, spacemen!"); + } + catch (net::AlreadyExistsException& ex) + { + YAKE_LOG_WARNING("demo",String("createChannel() failed: ") + ex.what()); + } + } + + // start + host_.setInterface( cfg_.get("bind","127.0.0.1:40000") ); + host_.start(); + + stepSigConns_.push_back( this->connectToSynchronizedNetStep( + boost::bind(&ro::server::step,boost::ref(host_)) ) ); + } + virtual void onStep() + { + // most callbacks are triggered by base class' signals + + // + if (_kbhit()) + { + this->requestStop(); + _getch(); + } + } + virtual void onShutdown() + { + { + net::scoped_lock lck; + host_.stop(); + host_.removeAllServices(); + } + stepSigConns_.clear(); + } +private: + ro::server host_; + Configuration cfg_; + + typedef std::deque<yake::SignalConnection> SignalConnectionList; + SignalConnectionList stepSigConns_; +}; + + +int main(int argc, char* argv[]) +{ + try { + Configuration cfg; + if (argc > 1) + cfg.readFromFile(argv[1]); + else + cfg.readFromFile("commserver.cfg"); + + Configuration serverCfg( cfg, "commserver/server/" ); + + if (!net::initialize()) + throw net::Exception("failed to initialize"); + + // start server + SharedPtr<ServerApp> serverObject; + serverObject.reset( new ServerApp(serverCfg) ); + serverObject->run(); + serverObject.reset(); + + // clean up + net::shutdown(); + } + catch (const net::Exception& e) + { + YAKE_LOG("demo",String("Caught yake::net exception: ") + e.what()); + net::shutdown(); + } + catch (const Exception& e) + { + YAKE_LOG("demo",String("Caught yake exception: ") + e.what()); + net::shutdown(); + } + catch (const std::exception& e) + { + YAKE_LOG("demo",String("Caught exception: ") + e.what()); + net::shutdown(); + } + catch (...) + { + YAKE_LOG("demo","Caught unknown exception."); + net::shutdown(); + } + return 0; +} + Modified: trunk/yake/samples/net/inprocess/common.h =================================================================== --- trunk/yake/samples/net/inprocess/common.h 2007-02-10 22:27:29 UTC (rev 1618) +++ trunk/yake/samples/net/inprocess/common.h 2007-02-11 00:14:19 UTC (rev 1619) @@ -7,5 +7,4 @@ #include <yake/net/net.h> #include <yake/samples/net/common/common.h> -#define COUTLN(X) YAKE_LOG_INFORMATION("app",X) #endif Added: trunk/yake/samples/net/inprocess/demo.cpp =================================================================== --- trunk/yake/samples/net/inprocess/demo.cpp (rev 0) +++ trunk/yake/samples/net/inprocess/demo.cpp 2007-02-11 00:14:19 UTC (rev 1619) @@ -0,0 +1,606 @@ +#include <samples/net/inprocess/common.h> + +#include <yake/base/yakeConfigFile.h> + +#include <yake/net/net.h> // basic networking +#include <yake/netsvc/netSvc.h> // networking services and service hosts +#include <yake/netsvc/service/netClientCommService.h> +#include <yake/netsvc/service/netServerCommService.h> +#include <yake/netsvc/service/netClientTimeService.h> +#include <yake/netsvc/service/netServerTimeService.h> + +#include <yake/netrepsvc/netRepSvc.h> + +//#include <samples/net/common/common.h> +#include <samples/net/roserver/ROServer.h> +#include <samples/net/roclient/ROClient.h> + +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> + +#include <boost/lexical_cast.hpp> + +namespace yake { + + //server-side, atm. + struct NetObject : public boost::noncopyable + { + virtual ~NetObject() {} + ent::ObjectId objectId() const; + protected: + NetObject(ent::Object*); + }; + struct NetServerObject : public NetObject + { + NetServerObject(ent::Object*); + + void writeCreateData(const net::obitstream&); + void writeUpdateData(const net::obitstream&); + }; + struct NetClientObject : public NetObject + { + NetClientObject(ent::Object*); + + void onCreate(const net::ibitstream&); + void onUpdate(const net::ibitstream&); + }; + typedef SharedPtr<NetObject> NetObjectPtr; + struct NetObjectServer : public boost::noncopyable + { + NetObjectServer(); + ~NetObjectServer(); + + bool empty() const; + void clear(); + + //void addPeer(const net::PeerId); + + /** Queues all replicated objects to be destroyed for this client + and subsequently removes the client id from the manager. + */ + void removePeer(const net::PeerId); + + /** Create a network wrapper for the given ent::Object. */ + NetObjectPtr createObject(ent::Object*); + + /** Destroy the network wrapper. + @note The NetObjectPtr has to have been created using createObject(). + @note Remote objects are destroyed prior to destruction of the network wrapper object. + Note that this can take some time (one or more update()s). + */ + void destroyObject(const NetObjectPtr&); + + /** Queue object for publishing to given client. */ + void publish(const NetObjectPtr&, const net::PeerId); + /** Queue object for "unpublishing" to given client id. */ + void unpublish(const NetObjectPtr&, const net::PeerId); + + /** Execute queued tasks (e.g. publishing, unpublishing ...) */ + void update(); + private: + typedef std::deque<NetObjectPtr> NetObjectPtrList; + NetObjectPtrList netObjs_; + + typedef std::map<net::PeerId,NetObjectPtrList> ClientObjectsMap; + ClientObjectsMap published_; + + ClientObjectsMap qForPublish_; + ClientObjectsMap qForUnpublish_; + }; + struct NetObjectClient : public boost::noncopyable + { + NetObjectClient(); + ~NetObjectClient(); + + //NetObjectPtr create(); + //void destroy(const NetObjectPtr&); + + void update(); + + void onPublishObject(const ent::ObjectId); + void onUnpublishObject(const ent::ObjectId); + + typedef SignalX<void(const ent::ObjectId,const NetObjectPtr&)> ObjectIdPtrSignal; + SignalConnection connectToObjectPublished(const ObjectIdPtrSignal::slot_type&); + SignalConnection connectToObjectUnpublished(const ObjectIdPtrSignal::slot_type&); + private: + }; +namespace net { +namespace svc { // aka services + void initCreateClassTableMessage(yake::ent::ObjectManager& objMgr, s2cEvtClassTable& clsTbl) + { + using namespace yake; + + typedef ent::ObjectManager::ClassNameIdMap ClassNameIdMap; + const ent::ObjectManager::ClassNameIdMap& clsNamesAndIds = objMgr.getClassNamesAndIds(); + for (ClassNameIdMap::const_iterator itCls = clsNamesAndIds.begin(); itCls != clsNamesAndIds.end(); ++itCls) + { + clsTbl.globalClassIds_[ itCls->first ] = itCls->second; + } + } + +} // namespace svc +} // namespace net +} // namespace yake + +struct ThreadedApp : public boost::noncopyable +{ + ThreadedApp() : stop_app_(false) + { + } + void requestStop() + { + stop_app_ = true; + } + bool stopRequested() const + { + return stop_app_; + } + void run() + { + try { + this->onRun(); + } + catch (const yake::net::Exception& e) + { + COUTLN("Caught net exception: " << e.what()); + } + catch (const std::exception& e) + { + COUTLN("Caught exception: " << e.what()); + } + catch (...) + { + COUTLN("Caught unknown exception."); + } + } +private: + virtual void onRun() = 0; +private: + volatile bool stop_app_; +}; +namespace yake { + struct NetServerApp : public ThreadedApp + { + NetServerApp() + { + } + typedef SignalX<void(void)> StepSignal; + yake::SignalConnection connectToStep(const StepSignal::slot_type& slot) + { + return stepSig_.connect(slot); + } + yake::SignalConnection connectToSynchronizedNetStep(const StepSignal::slot_type& slot) + { + return netStepSig_.connect(slot); + } + private: + virtual void onInit() = 0; + virtual void onStep() = 0; + virtual void onShutdown() = 0; + private: + StepSignal stepSig_; + StepSignal netStepSig_; + virtual void onRun() + { + ::SetThreadAffinityMask( ::GetCurrentThread(), 0x1 ); + this->onInit(); + + // main loop + while (!stopRequested()) + { + net::update(); + { + net::scoped_lock lck; + netStepSig_(); + } + stepSig_(); + this->onStep(); + net::native::sleep(0); + } + + this->onShutdown(); + //stepSig_.disconnectAll(); + } + }; +} // namespace yake + +using namespace yake; + +struct ObjectReplicationViewManager +{ + void addPeer(const net::PeerId); + void removePeer(const net::PeerId); +private: + void _checkVisibileObjectsForPeer(const net::PeerId); +}; + +struct ServerApp : public yake::NetServerApp +{ + ServerApp(const Configuration& cfg) + { + // We need a copy to be threadsafe! + cfg_.copyFrom( cfg ); + } +private: + void _onClientSimulationStarted(const net::PeerId pid) + { + YAKE_LOG_INFORMATION("app","client connected - starting replication"); + YAKE_ASSERT( repService_ ); + repService_->startReplicationToClient( pid ); + + // Replicate global objects + //@todo replicates everything, at the moment. restrict to global! + ent::ObjectManager::const_object_iterator itEnd = objMgr_->endObjects(); + for (ent::ObjectManager::const_object_iterator it = objMgr_->beginObjects(); it != itEnd; ++it) + { + YAKE_LOG_INFORMATION("app"," replicating object"); + repService_->publish( pid, (*it)->getId() ); + } + } + virtual void onInit() + { + COUTLN("starting RO server..."); + + ent::RegistrationResult ret; + objMgr_.reset( new ent::ObjectManager() ); + objMgr_->setClassIdGenerationRange( 10000, 19999 ); + ret = objMgr_->registerClass<ent::Entity>("entity"); + objMgr_->makeObject("entity"); + objMgr_->makeObject("entity"); + + // register services + { + repService_ = new net::ServerReplicationService(CHANNELID_CONTROL); + replicationSvr_.addService( net::IServicePtr(repService_), "rep" ); + replicationSvr_.subscribeToClientAccepted( + boost::bind(&ServerApp::_onClientSimulationStarted,this,_1) ); + + net::s2cEvtClassTable clsTbl; + net::svc::initCreateClassTableMessage(*objMgr_,clsTbl); + repService_->setClassTableData(clsTbl); + + stepSigConns_.push_back( this->connectToSynchronizedNetStep( + boost::bind(&net::ServerReplicationService::update,repService_) ) ); + } + { + net::ServerCommService* commService = new net::ServerCommService(CHANNELID_COMM); + replicationSvr_.subscribeToClientAccepted( + boost::bind(&net::ServerCommService::onClientConnected,commService,_1) ); + replicationSvr_.subscribeToClientDisconnected( + boost::bind(&net::ServerCommService::onClientDisconnected,commService,_1) ); + replicationSvr_.addService( net::IServicePtr(commService), "comm" ); + + /* + Configuration::const_iterator itChannelEnd = cfg_.end("comm/autocreate"); + for (Configuration::const_iterator itChannel = cfg_.begin("comm/autocreate"); itChannel != itChannelEnd; ++itChannel) + { + COUTLN(itChannel->first); + const String path = "comm/autocreate/"+itChannel->first+"/"; + const String name = cfg_.get(path+"name",""); + if (name.empty()) + { + COUTLN("server-comm: configuration: invalid channel name"); + continue; + } + const String desc = cfg_.get(path+"description",""); + COUTLN("server-comm: configuration: " << name << " : " << desc); + try { + commService->createChannel(name,desc); + } + catch (yake::Exception& ex) + { + COUTLN("server-comm: failed to create channel '" << name << "': " << ex.what()); + } + } + */ + commService->createChannel("#lobby","Hello, spacemen!"); + } + { + net::ServerTimeService* timeService = new net::ServerTimeService(CHANNELID_CONTROL); + replicationSvr_.subscribeToClientAccepted( + boost::bind(&net::ServerTimeService::onClientConnected,timeService,_1) ); + replicationSvr_.subscribeToClientDisconnected( + boost::bind(&net::ServerTimeService::onClientDisconnected,timeService,_1) ); + replicationSvr_.addService( net::IServicePtr(timeService), "time" ); + + stepSigConns_.push_back( this->connectToSynchronizedNetStep( + boost::bind(&net::ServerTimeService::update,timeService) ) ); + } + + // start + replicationSvr_.setInterface( cfg_.get("bind","127.0.0.1:40000") ); + replicationSvr_.start(); + + stepSigConns_.push_back( this->connectToSynchronizedNetStep( + boost::bind(&ro::server::step,boost::ref(replicationSvr_)) ) ); + } + virtual void onStep() + { + // most callbacks are triggered by base class' signals + } + virtual void onShutdown() + { + repService_ = 0; + { + net::scoped_lock lck; + replicationSvr_.stop(); + replicationSvr_.removeAllServices(); + } + stepSigConns_.clear(); + } +private: + SharedPtr<ent::ObjectManager> objMgr_; + ro::server replicationSvr_; + Configuration cfg_; + net::ServerReplicationService* repService_; + + typedef std::deque<yake::SignalConnection> SignalConnectionList; + SignalConnectionList stepSigConns_; +}; +struct ClientApp : public yake::NetServerApp +{ + ClientApp(const std::string& serverIpAndPort) : client_(net::Address(serverIpAndPort)) + {} +private: + void onUpdateClassTable(const net::s2cEvtClassTable& tbl) + { + YAKE_LOG_INFORMATION("app","Updating class table..."); + COUTLN(" " << int(tbl.globalClassIds_.size()) << " class(es)"); + for (std::map<std::string,ent::ClassId>::const_iterator it = tbl.globalClassIds_.begin(); + it != tbl.globalClassIds_.end(); ++it) + { + const std::string& clsName = it->first; + const ent::ClassId globalClsId = it->second; + COUTLN(" ['" << clsName << "'] = " << int(globalClsId)); + if (!objMgr_) + { + COUTLN(" -> no object manager"); + } + else + { + ent::ObjectManager::ClassIdLookupResult ret = objMgr_->getClassId( clsName ); + if (ret.first) + { + const ent::ClassId localClsId = ret.second; + if (localClsId != it->second) + { + if (objMgr_->registerClassAlias( globalClsId, localClsId )) + { + COUTLN(" -> successfully registered alias"); + } + else + { + YAKE_LOG_ERROR("app"," -> failed to register alias"); + } + } + else + { + COUTLN(" -> no need to register an alias (global id = local id; and names match)"); + } + } + else + { + YAKE_LOG_WARNING("app"," -> class with this name not registered locally!"); + } + } + } + } + void onCreateObject(const ent::ObjectId& id) + { + YAKE_ASSERT( objMgr_.get() ); + + COUTLN("onCreateObject()"); + COUTLN(" object class='" << int(id.classId()) << "' serNo='" << int(id.serialNo()) << "'"); + if (objMgr_) + { + ent::Object* o = objMgr_->makeObject( id ); + if (o) + { + COUTLN(" successfully created! (class='" << o->isA()->name() << "')"); + objMgr_->destroyObject( o ); + } + else + COUTLN(" failed to create!"); + } + } + void onDestroyObject(const ent::ObjectId& id) + { + YAKE_ASSERT( objMgr_.get() ); + + COUTLN("onDestroyObject()"); + if (objMgr_) + { + ent::Object* o = objMgr_->getObject(id); + if (!o) + { + YAKE_LOG_WARNING("app"," object to destroy not found!"); + } + else + objMgr_->destroyObject(o); + } + } + virtual void onInit() + { + objMgr_.reset( new ent::ObjectManager() ); + + // set class id range for local classes. + // global classes will use ids outside of this range. + objMgr_->setClassIdGenerationRange( 1000, 9999 ); + + ent::RegistrationResult ret; + ret = objMgr_->registerClass<ent::Entity>("entity"); + + namespace netsvc = yake::net::svc; + + // add comm service + commService_.reset(new net::ClientCommService(CHANNELID_COMM)); + client_.addService( net::IServicePtr(commService_), "comm" ); + + // add replication service + repService_.reset(new net::ClientReplicationService(CHANNELID_CONTROL)); + client_.addService( net::IServicePtr(repService_), "rep" ); + + stepSigConns_.push_back( this->connectToSynchronizedNetStep( + boost::bind(&net::ClientReplicationService::update,repService_) ) ); + + repService_->connectToUpdateClassTable( boost::bind(&ClientApp::onUpdateClassTable,this,_1) ); + repService_->connectToObjectPublished( boost::bind(&ClientApp::onCreateObject,this,_1) ); + repService_->connectToObjectUnpublished( boost::bind(&ClientApp::onDestroyObject,this,_1) ); + + // start client + if (!client_.start()) + { + COUTLN("client failed to connect"); + objMgr_.reset(); + return; + } + + // add time service + { + net::ClientTimeService* timeService = new net::ClientTimeService(CHANNELID_CONTROL); + client_.addService( net::IServicePtr(timeService), "time" ); + } + + commService_->joinChannel("#lobby"); + commService_->sendMessageToChannel("#lobby","hello, folks!"); + + commService_->sendMessageToChannel("$svc:comm","createchannel #support GetSupport"); + commService_->sendMessageToChannel("$svc:comm","createchannel #test asd asd asd"); + + // + stepSigConns_.push_back( this->connectToSynchronizedNetStep( + boost::bind(&ro::client::step,boost::ref(client_)) ) ); + } + virtual void onStep() + { + // example of querying & forwarding information (e.g. to UI) + if (commService_->hasMessages("#lobby")) + { + for(net::ClientCommService::const_message_iterator itMsg = + commService_->beginMessages("#lobby"); + itMsg != commService_->endMessages("#lobby"); ++itMsg) + { + COUTLN("client: #lobby: " << itMsg->from_ << " said: " << itMsg->msg_); + } + commService_->clearMessages("#lobby"); + } + } + virtual void onShutdown() + { + stepSigConns_.clear(); + + { + net::scoped_lock lck; + client_.stop(); + client_.removeAllServices(); + } + commService_.reset(); + repService_.reset(); + + objMgr_.reset(); + } +private: + SharedPtr<ent::ObjectManager> objMgr_; + ro::client client_; + SharedPtr<net::ClientCommService> commService_; + SharedPtr<net::ClientReplicationService> repService_; + + typedef std::deque<yake::SignalConnection> SignalConnectionList; + SignalConnectionList stepSigConns_; +}; + +int main(int argc, char* argv[]) +{ + ::SetThreadAffinityMask( ::GetCurrentThread(), 0x1 ); + try { + Configuration cfg; +#if 0 + cfg.set("rodemo/server/start",true); + cfg.set("rodemo/client/count",3); + cfg.writeToFile("rodemo.cfg"); + return 0; +#endif + + if (argc > 1) + cfg.readFromFile(argv[1]); + else + cfg.readFromFile("rodemo.cfg"); + //cfg.writeToXML("rodemo.xml.cfg"); + + Configuration serverCfg( cfg, "rodemo/server/" ); + Configuration clientCfg( cfg, "rodemo/client/" ); + + if (!net::initialize()) + throw net::Exception("failed to initialize"); + + typedef SharedPtr<boost::thread> ThreadPtr; + + // start server ? + typedef SharedPtr<ServerApp> ServerAppPtr; + typedef std::pair<ServerAppPtr,ThreadPtr> ServerAppData; + + ServerAppData serverObject; + const bool bStartServer = serverCfg.get("start",false); + if (bStartServer) + { + serverObject.first.reset( new ServerApp(serverCfg) ); + serverObject.second.reset( new boost::thread( + boost::bind(&ServerApp::run,serverObject.first.get())) ); + } + + // start client(s) + typedef SharedPtr<ClientApp> ClientAppPtr; + typedef std::deque<std::pair<ClientAppPtr,ThreadPtr> > ClientAppList; + + ClientAppList clientApps; + const size_t numClients = clientCfg.get("count",1); + const yake::String serverIpAndPort = clientCfg.get("server","127.0.0.1:40000"); + for (size_t i=0; i<numClients; ++i) + { + std::pair<ClientAppPtr,ThreadPtr> appThreadPair; + appThreadPair.first.reset( new ClientApp(serverIpAndPort) ); + appThreadPair.second.reset( new boost::thread( boost::bind(&ClientApp::run,appThreadPair.first.get()) ) ); + clientApps.push_back( appThreadPair ); + } + + while (!_kbhit()) + net::native::sleep(0); + _getch(); + + COUTLN("stopping..."); + YAKE_FOR_EACH(ClientAppList::iterator,itApp,clientApps) + itApp->first->requestStop(); + YAKE_FOR_EACH(ClientAppList::iterator,itApp,clientApps) + itApp->second->join(); + clientApps.clear(); + + // shutdown server + if (bStartServer) + { + if (serverObject.first) + serverObject.first->requestStop(); + if (serverObject.second) + serverObject.second->join(); + } + + net::shutdown(); + } + catch (const net::Exception& e) + { + COUTLN("Caught net exception: " << e.what()); + net::shutdown(); + } + catch (const std::exception& e) + { + COUTLN("Caught exception: " << e.what()); + net::shutdown(); + } + catch (...) + { + COUTLN("Caught unknown exception."); + net::shutdown(); + } + return 0; +} + Modified: trunk/yake/samples/net/roclient/ROClient.cpp =================================================================== --- trunk/yake/samples/net/roclient/ROClient.cpp 2007-02-10 22:27:29 UTC (rev 1618) +++ trunk/yake/samples/net/roclient/ROClient.cpp 2007-02-11 00:14:19 UTC (rev 1619) @@ -25,7 +25,7 @@ conn_->addStartedCallback( boost::bind(&client::onClientStarted,this) ); // attempt to connect to server - COUTLN("trying to connect to '" << serverAddr_.ip() << ":" << serverAddr_.port() << "' ..."); + YAKE_LOG("ClientHost","trying to connect to '" << serverAddr_.ip() << ":" << serverAddr_.port() << "' ..."); /* conn_->connect( serverAddr_, true, 2000 ); */ @@ -39,7 +39,7 @@ } catch (const net::Exception& e) { - COUTLN("Caught net exception: " << e.what()); + YAKE_LOG("ClientHost","Caught net exception: " << e.what()); conn_.reset(); } return false; @@ -127,12 +127,12 @@ } void client::onClientStarted() { - COUTLN("client started."); + YAKE_LOG("ClientHost","client started."); packetConnStarted_ = true; } void client::onTimeOut() { - COUTLN("client could not connect to server. destroying connection object."); + YAKE_LOG("ClientHost","client could not connect to server. destroying connection object."); // Do NOT destroy the connection object here! It may still be inside the callback loop! // We can call disconnect(), though. @@ -141,11 +141,11 @@ } void client::running_onProcessEvent(const net::PeerId, const net::NetEvent& evt, const net::ChannelId) { - COUTLN("client (running) received event (" << (int)evt.id() << ")."); + YAKE_LOG("ClientHost","client (running) received event (" << (int)evt.id() << ")."); } void client::init_onProcessEvent(const net::PeerId, const net::NetEvent& evt, const net::ChannelId) { - COUTLN("client (init) received event (" << (int)evt.id() << ")."); + YAKE_LOG("ClientHost","client (init) received event (" << (int)evt.id() << ")."); if (stage_ == CS_JOINING) { if (evt.id() == s2cEvtJoinReqReply::ID) @@ -153,13 +153,13 @@ const s2cEvtJoinReqReply& reply = static_cast<const s2cEvtJoinReqReply&>( evt ); if (reply.accepted) { - COUTLN("client: CONNECTED TO SERVER."); + YAKE_LOG("ClientHost","client: CONNECTED TO SERVER."); stage_ = CS_RUNNING; currEvtProcessFn_ = boost::bind(&client::running_onProcessEvent,this,_1,_2,_3); } else { - COUTLN("client: SERVER DENIED ACCESS!"); + YAKE_LOG("ClientHost","client: SERVER DENIED ACCESS!"); stage_ = CS_DEAD; currEvtProcessFn_ = boost::bind(&client::init_onProcessEvent,this,_1,_2,_3); } @@ -168,7 +168,7 @@ } void client::onProcessEvent(const net::PeerId pId, const net::NetEvent& evt, const net::ChannelId cId) { - COUTLN("client (dispatcher) received event (" << (int)evt.id() << ")."); + YAKE_LOG("ClientHost","client (dispatcher) received event (" << (int)evt.id() << ")."); if (!currEvtProcessFn_.empty()) currEvtProcessFn_(pId,evt,cId); this->dispatchNetEvent(pId,evt,cId); Modified: trunk/yake/samples/net/roserver/ROServer.cpp =================================================================== --- trunk/yake/samples/net/roserver/ROServer.cpp 2007-02-10 22:27:29 UTC (rev 1618) +++ trunk/yake/samples/net/roserver/ROServer.cpp 2007-02-11 00:14:19 UTC (rev 1619) @@ -104,7 +104,7 @@ const size_t maxClients = 32; const String strServer = bindInterface_.ip() + ":" + boost::lexical_cast<String>(bindInterface_.port()); - YAKE_LOG_INFORMATION("serv-host","starting server at '" << strServer << "' with max. " << maxClients << " clients..."); + YAKE_LOG("ServerHost","starting server at '" << strServer << "' with max. " << maxClients << " clients..."); conn_.reset( net::createServerPacketConnection() ); YAKE_ASSERT( conn_ ); @@ -122,7 +122,7 @@ net::update(); net::native::sleep(0); } - YAKE_LOG_INFORMATION("serv-host","server is up at '" << strServer << "'"); + YAKE_LOG("ServerHost","server is up at '" << strServer << "'"); return true; } void server::onStop() @@ -152,8 +152,8 @@ } void server::onServerStarted() { - COUTLN("server packet connection started."); - COUTLN("server: starting event connection..."); + YAKE_LOG("ServerHost","server packet connection started."); + YAKE_LOG("ServerHost","server: starting event connection..."); YAKE_ASSERT( !evtConn_ ); evtConn_.reset( net::createEventConnection() ); YAKE_ASSERT( evtConn_ ); @@ -170,20 +170,20 @@ evtConn_->setPacketConnection( conn_.get(), net::NetEvent::DIR_ANY ); evtConn_->start(); - COUTLN("server: event connection started."); + YAKE_LOG("ServerHost","server: event connection started."); packetConnStarted_ = true; } void server::onReceivePacket(const net::PeerId peerId, const net::PacketPtr&, const net::ChannelId channel) { - COUTLN("server received packet."); + YAKE_LOG("ServerHost","server received packet."); //echoing... //conn_->send( peerId, data, len, net::SendOptions().channel(channel) ); } void server::onProcessEvent(const net::PeerId peerId, const net::NetEvent& evt, const net::ChannelId channel) { try { - COUTLN("server received event (" << (int)evt.id() << ")."); + YAKE_LOG("ServerHost","server received event (" << (int)evt.id() << ")."); // 1. Let client object handle the event. If no client object exists // for this peer, create it. @@ -210,12 +210,12 @@ } catch (...) { - COUTLN("server: CAUGHT UNHANDLED EXCEPTION!\n"); + YAKE_LOG_ERROR("ServerHost","server: CAUGHT UNHANDLED EXCEPTION!\n"); } } void server::onClientDisconnected(const net::PeerId pId) { - COUTLN("ro::server: client '" << pId << "' disconnected."); + YAKE_LOG("ServerHost","ro::server: client '" << pId << "' disconnected."); ClientPtrMap::iterator it = this->clients_.find( pId ); YAKE_ASSERT(it != this->clients_.end())(pId).warning("unknown client disconnected. lookup failed."); if (it == this->clients_.end()) @@ -234,10 +234,10 @@ if (evt.id() == c2sEvtJoinReq::ID) { const c2sEvtJoinReq& evtJoinReq = static_cast<const c2sEvtJoinReq&>(evt); - COUTLN("server: evt: Join Request"); + YAKE_LOG("ServerHost","server: evt: Join Request"); // send reply: OK - COUTLN("server: accepted join request by client"); + YAKE_LOG("ServerHost","server: accepted join request by client"); s2cEvtJoinReqReply joinReply; joinReply.accepted = true; evtConn->sendEvent( this->id, joinReply, net::SendOptions().channel(CHANNELID_CONTROL).ordered().reliable() ); @@ -247,7 +247,7 @@ #endif // use different event callback for the CS_RUNNING stage: - COUTLN("server: => CLIENT: RUNNING"); + YAKE_LOG("ServerHost","server: => CLIENT: RUNNING"); processEventFn_ = boost::bind(&client::running_onProcessEvent,this,_1,_2); this->stage = CS_RUNNING; @@ -257,7 +257,7 @@ } void client::running_onProcessEvent(const net::NetEvent& evt, const net::ChannelId channel) { - COUTLN("server::client::running_onProcessEvent()"); + YAKE_LOG("ServerHost","server::client::running_onProcessEvent()"); YAKE_ASSERT( stage == CS_RUNNING ); if (stage != CS_RUNNING) return; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |