Sirikata
|
00001 // Copyright (c) 2012 Sirikata Authors. All rights reserved. 00002 // Use of this source code is governed by a BSD-style license that can 00003 // be found in the LICENSE file. 00004 00005 #ifndef _SIRIKATA_LIBPROX_MANUAL_REPLICATED_REQUEST_MANAGER_HPP_ 00006 #define _SIRIKATA_LIBPROX_MANUAL_REPLICATED_REQUEST_MANAGER_HPP_ 00007 00008 #include <sirikata/pintoloc/ProxSimulationTraits.hpp> 00009 #include <sirikata/core/service/Service.hpp> 00010 #include <sirikata/core/service/Context.hpp> 00011 00012 #include <boost/multi_index_container.hpp> 00013 #include <boost/multi_index/member.hpp> 00014 #include <boost/multi_index/ordered_index.hpp> 00015 #include <boost/multi_index/hashed_index.hpp> 00016 00017 #include <prox/manual/Query.hpp> 00018 00019 namespace Sirikata { 00020 00035 class ManualReplicatedRequestManager : 00036 public Service 00037 { 00038 public: 00039 typedef Prox::ManualQuery<ObjectProxSimulationTraits> ProxQuery; 00040 00041 ManualReplicatedRequestManager(Context* ctx, Network::IOStrandPtr strand); 00042 ManualReplicatedRequestManager(Context* ctx, Network::IOStrand* strand); 00043 virtual ~ManualReplicatedRequestManager(); 00044 00045 // Service Interface 00046 virtual void start(); 00047 virtual void stop(); 00048 00049 // Add a failed refinement request. 00050 void addFailedRefine(ProxQuery* query, const ObjectReference& objid); 00051 // Lookup any queries waiting on the object to be refined. Note that when 00052 // you call this, you should be asking for the queries waiting on the 00053 // *parent* of node/object that you just added since that's the node for 00054 // which data is now available. 00055 void lookupWaitingQueries(const ObjectReference& objid, std::vector<ProxQuery*>* queries_out); 00056 // Clear out any requests by the given querier 00057 void removeQuerier(ProxQuery* query); 00058 00059 private: 00060 00061 // Track each request for refinement 00062 struct Request { 00063 Request(ProxQuery* _query, const ObjectReference& _objid, Time _expires) 00064 : query(_query), 00065 objid(_objid), 00066 expires(_expires) 00067 {} 00068 ProxQuery* query; 00069 ObjectReference objid; 00070 Time expires; 00071 }; 00072 struct query_tag {}; 00073 struct objid_tag {}; 00074 struct expires_tag {}; 00075 typedef boost::multi_index_container< 00076 Request, 00077 boost::multi_index::indexed_by< 00078 boost::multi_index::hashed_non_unique< boost::multi_index::tag<query_tag>, BOOST_MULTI_INDEX_MEMBER(Request,ProxQuery*,query) >, 00079 boost::multi_index::hashed_non_unique< boost::multi_index::tag<objid_tag>, BOOST_MULTI_INDEX_MEMBER(Request,ObjectReference,objid), ObjectReference::Hasher >, 00080 boost::multi_index::ordered_non_unique< boost::multi_index::tag<expires_tag>, BOOST_MULTI_INDEX_MEMBER(Request,Time,expires) > 00081 > 00082 > RequestIndex; 00083 typedef RequestIndex::index<query_tag>::type RequestsByQuery; 00084 typedef RequestIndex::index<objid_tag>::type RequestsByObject; 00085 typedef RequestIndex::index<expires_tag>::type RequestsByExpiration; 00086 00087 00088 Context* mContext; 00089 // This is unfortunate, but we need to be able to accept both raw 00090 // IOStrand*'s and IOStrandPtrs, so we store both, and sometimes the 00091 // IOStrandPtr is just empty (we always use the sanely-named raw ptr). 00092 Network::IOStrandPtr doNotUse___mStrand; 00093 Network::IOStrand* mStrand; 00094 00095 RequestIndex mRequestIndex; 00096 Network::IOTimerPtr mExpiryTimer; 00097 00098 00099 00100 void processExpiredRequests(); 00101 }; 00102 00103 } // namespace Sirikata 00104 00105 #endif //_SIRIKATA_LIBPROX_MANUAL_REPLICATED_REQUEST_MANAGER_HPP_