⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 custom_event_handler.hpp

📁 新版本TR1的stl
💻 HPP
📖 第 1 页 / 共 3 页
字号:
/* /////////////////////////////////////////////////////////////////////////
 * File:        acestl/reactor/custom_event_handler.hpp
 *
 * Purpose:     Event handler class for custom event notifications.
 *
 * Created:     1st October 2004
 * Updated:     2nd June 2007
 *
 * Home:        http://stlsoft.org/
 *
 * Copyright (c) 2004-2007, Matthew Wilson and Synesis Software
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
 *   any contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * ////////////////////////////////////////////////////////////////////// */


/** \file acestl/reactor/custom_event_handler.hpp
 *
 * \brief [C++ only] Definition of the acestl::custom_event_handler
 *   class template
 *   (\ref group__library__ace_reactor "ACE Reactor" Library).
 */

#ifndef ACESTL_INCL_ACESTL_REACTOR_HPP_CUSTOM_EVENT_HANDLER
#define ACESTL_INCL_ACESTL_REACTOR_HPP_CUSTOM_EVENT_HANDLER

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
# define ACESTL_VER_ACESTL_REACTOR_HPP_CUSTOM_EVENT_HANDLER_MAJOR     2
# define ACESTL_VER_ACESTL_REACTOR_HPP_CUSTOM_EVENT_HANDLER_MINOR     1
# define ACESTL_VER_ACESTL_REACTOR_HPP_CUSTOM_EVENT_HANDLER_REVISION  1
# define ACESTL_VER_ACESTL_REACTOR_HPP_CUSTOM_EVENT_HANDLER_EDIT      16
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

/* /////////////////////////////////////////////////////////////////////////
 * Includes
 */

#ifndef ACESTL_INCL_ACESTL_HPP_ACESTL
# include <acestl/acestl.hpp>
#endif /* !ACESTL_INCL_ACESTL_HPP_ACESTL */
#include <ace/Event_Handler.h>              // for ACE_Event_Handler
#include <ace/Reactor.h>                    // for ACE_Reactor

#ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SHARED_PTR
# include <stlsoft/smartptr/shared_ptr.hpp>
#endif /* !STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SHARED_PTR */

#include <map>

/* /////////////////////////////////////////////////////////////////////////
 * Compatibility
 */

#if defined(STLSOFT_COMPILER_IS_INTEL) || \
    (   defined(STLSOFT_COMPILER_IS_MSVC) && \
        _MSC_VER >= 1200)
# define ACESTL_CUSTOM_EVENT_HANDLER_CANCEL_EVENTS_MEMBER_CLEANUP_SUPPORT
#endif /* compiler */

/* /////////////////////////////////////////////////////////////////////////
 * Namespace
 */

#ifndef _ACESTL_NO_NAMESPACE
# if defined(_STLSOFT_NO_NAMESPACE) || \
     defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
/* There is no stlsoft namespace, so must define ::acestl */
namespace acestl
{
# else
/* Define stlsoft::acestl_project */

namespace stlsoft
{

namespace acestl_project
{

# endif /* _STLSOFT_NO_NAMESPACE */
#endif /* !_ACESTL_NO_NAMESPACE */

/* ////////////////////////////////////////////////////////////////////// */

#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION

/** Utility class that establishes a root type for the
 *    acestl::cancel_adaptor and acestl::custom_event_handler classes.
 * \ingroup group__library__ace_reactor
 */
struct ceh_root
{
private:
    struct event_id_ {};
public:
    typedef event_id_*  event_id;
};

/** Adaptor class that facilitates the
 *    acestl::custom_event_handler::cancel_custom_events() member function
 *    template.
 * \ingroup group__library__ace_reactor
 */
template<ss_typename_param_k C>
struct cancel_adapter
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
    : public ceh_root
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
{
    typedef cancel_adapter<C>   class_type;

    cancel_adapter(C* obj, void (C::*pfn)(long code, event_id id, void* arg))
        : m_obj(obj)
        , m_pfn(pfn)
    {}

    static void proc(void* param, long code, event_id id, void* arg)
    {
        class_type* pThis = static_cast<class_type*>(param);

        ((pThis->m_obj)->*(pThis->m_pfn))(code, id, arg);
    }

private:
    C* const m_obj;
    void (C::*m_pfn)(long code, event_id id, void* arg);
};

#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */

/* /////////////////////////////////////////////////////////////////////////
 * Classes
 */

/** This class enhances
 *    the \ref group__library__ace_reactor "ACE Reactor" framework by
 *    providing custom event notifications for event handlers, with zero
 *    interference with existing reactor/handler functionality.
 *
 * \ingroup group__library__ace_reactor
 *
 * It provides the ability to schedule a custom event with a code, an optional
 * delay, and an optional argument
 *
 * To use, derive from it as you would from ACE_Event_Handler, and override the
 * handle_custom_event() method, e.g
 *
\code
using acestl::custom_event_handler;

// 1. Our custom event handler class
class MyHandler
  : public custom_event_handler
{
private:
  // 2. This method required by acestl::custom_event_handler
  virtual int handle_custom_event(ACE_Time_Value const& current_time
                              ,   long                  code
                              ,   void*                 arg)
  {
    fprintf(stdout, "Received custom event: %ld, %p\n", code, arg);

    if(300 == code)
    {
      std::string* str = static_cast<std::string*>(arg);

      delete str;
    }

    return 0;
  }
. . .
  // 3. This is one of several methods required by ACE_Event_Handler
  virtual int handle_timeout( const ACE_Time_Value  &current_time
                            , const void            *arg)
  {
    return 0;
  }
};

// 4. A cleanup function to ensure that the custom data associated with
// 300 events is not lost; see step 10.
void cleanup_300_proc(void *param, long code, custom_event_handler::event_id id, void *arg)
{
  assert(300 == code);

  int&          num300sCancelled  = *static_cast<int*>(param);
  std::string*  str               = static_cast<std::string*>(arg);

  ++num300sCancelled;

  delete str;
}


// 5. Create an instance of MyHandler
custom_event_handler* mh = new MyHandler();

// 6. Schedule an event with id 100, testing the return to ensure it's
// been scheduled without error
if(NULL == mh->schedule_custom_event(100))
{
  std::err << "Failed to scheduled event (code=100)!" << std::endl;
}
else
{
  // It's been scheduled ok
  //
  // This assert simply enforces what we know: that there is 1 or more
  // (1 in this case) pending events whose event code is 100
  //
  // Note: we can only assert this here because we have not yet
  // started the reactor event loop; see step 11.
  assert(mh->has_custom_events(100));
}

// 7. Schedule an event with id 200 to be dispatched in 10 seconds
custom_event_handler::event_id  id200 = mh->schedule_custom_event(200, ACE_Time_Value(10));

// 8. Schedule an event with id 300 to be dispatched in 20 seconds, with
// a custom argument (an instance of std::string)
mh->schedule_custom_event(300, ACE_Time_Value(20), new std::string("300"));

// 9. Cancel the 200 event
//
// Note: you can only cancel a single event via its unique event id.
mh->cancel_custom_event(id200);

// 10. Cancel all 300 events
//
// Remarks: this has to use a cancel handler to 'release' the resource
// associated with the custom argument. If this is not done, then
// the std::string instance would not be destroyed, and we'd have a
// memory leak
//
// Note: Cancelling via an event code cancels *all* pending events with
// that code.
int num300sCancelled = 0;

mh->cancel_custom_events(300, cleanup_300_proc, &num300sCancelled);

assert(1 == num300sCancelled); // Again, this is only valid because event loop not yet started

// 11. Start the reactor loop. Events will be dispatched from here on in
ACE_Reactor::instance()->run_reactor_event_loop();

\endcode
 *
 */
// [[synesis:class: acestl::custom_event_handler]]
class custom_event_handler
    : public ACE_Event_Handler
#ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
    , public ceh_root
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
{
/// \name Types
/// @{
private:
    struct event_id_ {};
public:
    typedef ACE_Event_Handler       parent_class_type;
    typedef custom_event_handler    class_type;
    typedef as_bool_t               bool_type;
#ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
    /// An opaque type that identifies pending event instances
    ///
    /// The only well-known value is \c NULL, which indicates no-event.
    typedef event_id_               *event_id;
#endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
    /// Type of the callback function that may be passed to 
    /// custom_event_handler::cancel_custom_events, which will
    /// receive information on each cancelled event instance.
    typedef void (*cancelled_event_code_fn)(void* param, long code, event_id id, void* arg);
/// @}

// Construction
protected:
    /** This protected constructor is used to pass initialisation parameters
     *   throught to the parent (\c ACE_Event_Handler) class from the
     *   concrete handler class.
     *
     * \param reactor The reactor instance with which this event-handler will interact
     * \param priority The priority for this handler
     *
     * \exception - Does not throw an exception
     */
    ss_explicit_k custom_event_handler( ACE_Reactor*    reactor     =   ACE_Reactor::instance()
                                    ,   int             priority    =   ACE_Event_Handler::LO_PRIORITY);
public:
    /// Destructor
    virtual ~custom_event_handler() stlsoft_throw_0();

/// \name Operations
/// @{
public:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -