| 59 | | |
| 60 | | //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ |
| 61 | | /// Handler Base. |
| 62 | | /// Used to make the destructor visible. |
| 63 | | struct handler_base |
| | 62 | /// base response handler. |
| | 63 | /// Used to make the I_ResponseHandler destructor public. |
| | 64 | class base_response_handler |
| | 65 | : public I_ResponseHandler |
| | 66 | { |
| | 67 | public: |
| | 68 | virtual ~base_response_handler() |
| | 69 | { |
| | 70 | } |
| | 71 | |
| | 72 | }; // class base_response_handler |
| | 73 | |
| | 74 | //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ |
| | 75 | /// Server side response handler. |
| | 76 | /// When the server recieves a request as a message (i.e. not as an |
| | 77 | /// internal request, but as a request recieved via a protocol adapter) |
| | 78 | /// a server_response_handler is created and the request is dispatched |
| | 79 | /// to the appropriate request handler. When the request handler |
| | 80 | /// is finished and has a reply, it invokes I_ResponseHandler::handleReponse() |
| | 81 | /// with the reply. This lightweight handler simply sends the response |
| | 82 | /// back to the application server which in turn (filters?) and then sends |
| | 83 | /// the message to the client. |
| | 84 | class server_response_handler |
| | 85 | : public base_response_handler |
| | 86 | { |
| | 87 | public: |
| | 88 | virtual void handleResponse(pResponse_type _pResponse) |
| | 89 | { |
| | 90 | // Send the response back to the app server. |
| | 91 | m_appServer.handleMessage(_pResponse); |
| | 92 | } |
| | 93 | |
| | 94 | server_response_handler(I_ApplicationServer& _appServer) |
| | 95 | : m_appServer(_appServer) |
| | 96 | { |
| | 97 | } |
| | 98 | |
| | 99 | virtual ~server_response_handler() |
| | 100 | { |
| | 101 | } |
| | 102 | |
| | 103 | static inline void destroy(Memory::managed_weak_ptr<I_ResponseHandler> _pResponseHandler) |
| | 104 | { |
| | 105 | delete dynamic_cast<base_response_handler*>(_pResponseHandler.get()); |
| | 106 | } |
| | 107 | |
| | 108 | private: |
| | 109 | I_ApplicationServer& m_appServer; |
| | 110 | }; |
| | 111 | |
| | 112 | //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ |
| | 113 | /// Response handler for the client side. |
| | 114 | /// When a client sends a request, it creates this response handler and |
| | 115 | /// associates a request, payload and handler function with the request. |
| | 116 | /// When the reply comes back from the server, the function is invoked, |
| | 117 | /// passing the original request, the response and the payload. |
| | 118 | /// This provides a mechanism by which the client application can |
| | 119 | /// have additional data associated with the request. |
| | 120 | template<typename Request_type, typename Payload_type> |
| | 121 | struct client_response_handler |
| 101 | | }; // struct response_handler |
| | 149 | }; // struct client_response_handler |
| | 150 | |
| | 151 | //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ |
| | 152 | struct request_handler_base |
| | 153 | : public I_RequestHandler |
| | 154 | { |
| | 155 | virtual ~request_handler_base() |
| | 156 | { |
| | 157 | } |
| | 158 | }; // struct request_handler_base |
| | 159 | |
| | 160 | //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ |
| | 161 | struct request_handler |
| | 162 | : public request_handler_base |
| | 163 | { |
| | 164 | typedef boost::function<void(pRequest_type, pResponseHandler_type)> Function_type; |
| | 165 | |
| | 166 | virtual void handleRequest(pRequest_type _pRequest, pResponseHandler_type _pResponseHandler) |
| | 167 | { |
| | 168 | m_function(_pRequest, _pResponseHandler); |
| | 169 | } |
| | 170 | |
| | 171 | request_handler(Function_type _function) |
| | 172 | : m_function(_function) |
| | 173 | { |
| | 174 | } |
| | 175 | |
| | 176 | virtual ~request_handler() |
| | 177 | { |
| | 178 | } |
| | 179 | |
| | 180 | public: |
| | 181 | |
| | 182 | Function_type m_function; |
| | 183 | }; // struct request_handler |
| 341 | | // TODO If this is a request, create a lightweight response handler then |
| 342 | | // dispatch to scriptable_generic_service::handleRequest. |
| 343 | | // This code path is invoked only when the message is coming from a |
| 344 | | // protocol adapter. When the response handler handleResponse() is called, |
| 345 | | // it should simply dispatch to AppServer::handleMessage(). Since |
| 346 | | // the destination endpoint is outbound, the app server will send it |
| 347 | | // via the appropriate protocol adapter. |
| | 442 | // Check to see if it's a request |
| | 443 | Zen::Memory::managed_ptr<I_Request> pRequest( |
| | 444 | _pMessage.as<Zen::Memory::managed_ptr<I_Request> >()); |
| | 445 | |
| | 446 | if( pRequest.isValid() ) |
| | 447 | { |
| | 448 | // TODO If this is a request, create a lightweight response handler then |
| | 449 | // dispatch to scriptable_generic_service::handleRequest. |
| | 450 | // This code path is invoked only when the message is coming from a |
| | 451 | // protocol adapter. When the response handler handleResponse() is called, |
| | 452 | // it should simply dispatch to AppServer::handleMessage(). Since |
| | 453 | // the destination endpoint is outbound, the app server will send it |
| | 454 | // via the appropriate protocol adapter. |
| | 455 | |
| | 456 | // If we use detail::client_response_handler here, where do payload and function |
| | 457 | // come from? |
| | 458 | RequestHandlers_type::iterator iter = m_requestHandlers.find(pRequest->getMessageType()); |
| | 459 | |
| | 460 | if (iter != m_requestHandlers.end()) |
| | 461 | { |
| | 462 | pResponseHandler_type pResponseHandler |
| | 463 | ( |
| | 464 | new detail::server_response_handler(this->getApplicationServer()), |
| | 465 | &detail::server_response_handler::destroy |
| | 466 | ); |
| | 467 | iter->second->handleRequest(pRequest, pResponseHandler); |
| | 468 | } |
| | 469 | else |
| | 470 | { |
| | 471 | // No request handler. |
| | 472 | // TODO Pass the request to a default request handler. |
| | 473 | throw Utility::runtime_exception("scriptable_generic_service::handleMessage(): Error, no handler specified for message type"); |
| | 474 | } |
| | 475 | } |
| | 476 | |
| 366 | | detail::response_handler<Request_type, Payload_type>* pRawHandler = new detail::response_handler<Request_type, Payload_type>(_request.m_pRequest, _request.m_payload, _function); |
| 367 | | |
| 368 | | Memory::managed_ptr<I_ResponseHandler> pHandler(pRawHandler, destroyHandler); |
| | 495 | detail::client_response_handler<Request_type, Payload_type>* pRawHandler = |
| | 496 | new detail::client_response_handler<Request_type, Payload_type>( |
| | 497 | _request.m_pRequest, |
| | 498 | _request.m_payload, |
| | 499 | _function |
| | 500 | ); |
| | 501 | |
| | 502 | Memory::managed_ptr<I_ResponseHandler> pHandler(pRawHandler, destroyResponseHandler); |
| | 544 | inline void destroyRequestHandler(Memory::managed_weak_ptr<I_RequestHandler> _pRequestHandler) |
| | 545 | { |
| | 546 | delete dynamic_cast<detail::request_handler_base*>(_pRequestHandler.get()); |
| | 547 | } |
| | 548 | |
| | 549 | //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ |
| | 550 | template<typename BaseClass_type, typename Class_type> |
| | 551 | inline |
| | 552 | void |
| | 553 | scriptable_generic_service<BaseClass_type, Class_type>::registerRequestHandler(pMessageType_type _pMessageType, boost::function<void(pRequest_type, pResponseHandler_type)> _function) |
| | 554 | { |
| | 555 | RequestHandlers_type::iterator iter = m_requestHandlers.find(_pMessageType); |
| | 556 | if( iter == m_requestHandlers.end() ) |
| | 557 | { |
| | 558 | I_RequestHandler* pRaw = new detail::request_handler(_function); |
| | 559 | |
| | 560 | pRequestHandler_type pRequestHandler( |
| | 561 | pRaw, |
| | 562 | destroyRequestHandler |
| | 563 | ); |
| | 564 | m_requestHandlers[_pMessageType] = pRequestHandler; |
| | 565 | } |
| | 566 | |
| | 567 | /// TODO Exception? |
| | 568 | } |
| | 569 | |
| | 570 | //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ |
| | 571 | template<typename BaseClass_type, typename Class_type> |
| | 572 | inline |
| | 573 | void |
| | 574 | scriptable_generic_service<BaseClass_type, Class_type>::unregisterRequestHandler(pMessageType_type _pMessageType) |
| | 575 | { |
| | 576 | RequestHandlers_type::iterator iter = m_requestHandlers.find(_pMessageType); |
| | 577 | if( iter != m_requestHandlers.end() ) |
| | 578 | { |
| | 579 | m_requestHandlers.erase(iter); |
| | 580 | } |
| | 581 | |
| | 582 | /// TODO Exception? |
| | 583 | } |
| | 584 | |
| | 585 | //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ |
| | 586 | template<typename BaseClass_type, typename Class_type> |
| | 587 | inline |
| | 588 | void |
| | 589 | scriptable_generic_service<BaseClass_type, Class_type>::registerMessageHandler(pMessageType_type _pMessageType, boost::function<void(pMessage_type)> _function) |
| | 590 | { |
| | 591 | throw Zen::Utility::runtime_exception("scriptable_generic_service::registerMessageHandler() : Error, not implemented."); |
| | 592 | } |
| | 593 | |
| | 594 | //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ |
| | 595 | template<typename BaseClass_type, typename Class_type> |
| | 596 | inline |
| | 597 | void |
| | 598 | scriptable_generic_service<BaseClass_type, Class_type>::unregisterMessageHandler(pMessageType_type _pMessageType) |
| | 599 | { |
| | 600 | throw Zen::Utility::runtime_exception("scriptable_generic_service::unregisterMessageHandler() : Error, not implemented."); |
| | 601 | } |
| | 602 | |
| | 603 | //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ |