//==================================================================================================
// S i m u l a t i o n                                                                    Interface
// E v e n t
//                                                                                By Bruno Bachelet
//==================================================================================================
// Copyright (c) 1999-2016
// Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net
//
// This file is part of the B++ Library. This library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Library General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
// the GNU Library General Public License for more details (http://www.gnu.org).

/*DESCRIPTION*/
/* This module provides basic classes to represent events in a simulation. */

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "simulation/event.hpp"

// Guardian //--------------------------------------------------------------------------------------
#ifndef guSimulationEvent
#define guSimulationEvent

// Headers //---------------------------------------------------------------------------------------
#include <bpp/simulation/common.hpp> /*INCLUDE*/
#include <bpp/simulation/object.hpp> /*INCLUDE*/

namespace bpp {

// Importation/Exportation //-----------------------------------------------------------------------
#ifdef SIMULATION_DLL
 #define dll_export DLL_EXPORT
#else
 #define dll_export DLL_IMPORT
#endif

// Namespaces //------------------------------------------------------------------------------------
#define public_area  simulationEvent
#define private_area simulationEvent_private

namespace public_area {
 /*NAMESPACE*/ using namespace simulationCommon;
 /*NAMESPACE*/ using namespace simulationObject;
}

namespace private_area { using namespace public_area; }

extern_module_name;

// Initialization //--------------------------------------------------------------------------------

// Macrocommands //---------------------------------------------------------------------------------

// Types & Classes //-------------------------------------------------------------------------------
namespace public_area {
 //------------------------------------------------------------------------------------------Classes
 class clEvent;

 template <class prClass> class clMethodEvent;
 //-----------------------------------------------------------------------------------Constant Types
 typedef const clEvent ctEvent;
}

namespace private_area {}

// Functions Interface //---------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// Errors //----------------------------------------------------------------------------------------
namespace public_area {}

// Constants & Variables //-------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// E v e n t  Interface //--------------------------------------------------------------------------
namespace public_area {
 /*CLASS clEvent */ /* Represents an event in a simulation. It is an abstract class. */
 class clEvent : public simulationObject::clObject {
  //-----------------------------------------------------------------------------------------Private
  private_property constructor clEvent(ctEvent &);
  private_property clEvent & operator=(ctEvent &);
  //------------------------------------------------------------------------------------------Public
  /*ATTRIBUTE clEvent */ /* Date of occurrence of the event. */
  read_only_attribute(tyCardinal,atDate,date);

  /*ATTRIBUTE clEvent */ /* Priority of the event. */
  read_only_attribute(tyCardinal,atPriority,priority);

  public_property constructor clEvent(simulationSimulator::clSimulator &,clAbstractPool *,
                                      tyCardinal,tyCardinal);

  public_property destructor clEvent(void);

  /*AMETHOD clEvent */ /* Executes the action associated with the event. Abstract method. */
  public_property virtual void action(void) const = 0;
  //--------------------------------------------------------------------------------------Reflection
  class_indexer(clEvent);
 };
}

// M e t h o d E v e n t  Interface //--------------------------------------------------------------
namespace public_area {
 /*CLASS clMethodEvent */
 /* Represents an event in a simulation that is a method call (with no argument). */
 template <class prClass> class clMethodEvent : public clEvent {
  //-------------------------------------------------------------------------------------------Types
  /*TYPE clMethodEvent */ /* Type of the method pointer. */
  public_property typedef void (prClass::*tyMethodPointer)(void);
  //-----------------------------------------------------------------------------------------Private
  private_property prClass *       atObject;
  private_property tyMethodPointer atMethod;

  private_property constructor clMethodEvent(const clMethodEvent &);
  private_property clMethodEvent operator=(const clMethodEvent &);
  //------------------------------------------------------------------------------------------Public
  public_property constructor clMethodEvent(simulationSimulator::clSimulator &,clAbstractPool *,
                                            tyCardinal,tyCardinal,prClass *,tyMethodPointer);

  public_property destructor clMethodEvent(void);

  public_property void action(void) const;
 };
}

// M e t h o d E v e n t _ X  Interface & Implementation //-----------------------------------------
#define mpattern_clMethodEvent_X(X)                                                                \
 /*CLASS clMethodEvent_X */                                                                        \
 /* Pattern to generate classes that model method call events (with <I>X</I> arguments). */        \
 template <X(parameterize)> class X(class) : public clEvent {                                      \
  /*---------------------------------------------------------------------------------------Types */\
  /*TYPE clMethodEvent_X */ /* Type of the method pointer. */                                      \
  public_property typedef void (prClass::*tyMethodPointer)(X(signature));                          \
  /*-------------------------------------------------------------------------------------Private */\
  private_property prClass *       atObject;                                                       \
  private_property tyMethodPointer atMethod;                                                       \
                                                                                                   \
  X(attribute);                                                                                    \
                                                                                                   \
  private_property constructor X(class)(const X(class) &);                                         \
  private_property X(class) operator = (const X(class) &);                                         \
  /*--------------------------------------------------------------------------------------Public */\
  /*METHOD clMethodEvent_X */                                                                      \
  /* Builds a method call event. The object, the method and its arguments must be provided. */     \
  public_property constructor X(class)(simulationSimulator::clSimulator & agSimulator,             \
                                       clAbstractPool * agPool,tyCardinal agDate,                  \
                                       tyCardinal agPriority,prClass * agObject,                   \
                                       tyMethodPointer agMethod,X(signature))                      \
  : clEvent(agSimulator,agPool,agDate,agPriority),atObject(agObject),atMethod(agMethod),           \
            X(construction) {}                                                                     \
                                                                                                   \
  /*METHOD clMethodEvent_X */ /* Destructs the event. */                                           \
  public_property destructor X(class)(void) {}                                                     \
                                                                                                   \
  /*METHOD clMethodEvent_X */ /* Executes the method associated with the event. */                 \
  public_property void action(void) const { (atObject->*atMethod)(X(argument2)); }                 \
 };                                                                                                \

namespace public_area { one_to_n(clMethodEvent_X); }

// Functions Inline //------------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// E v e n t  Inline //-----------------------------------------------------------------------------
namespace public_area {
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clEvent */ /* Builds an event in a simulator with given date and priority. */
 inline clEvent::clEvent(simulationSimulator::clSimulator & agSimulator,clAbstractPool * agPool,
                         tyCardinal agDate,tyCardinal agPriority)
 : clObject(agSimulator,agPool),atDate(agDate),atPriority(agPriority) {}
 //---------------------------------------------------------------------------------------Destructor
 /*METHOD clEvent */ /* Destructs the event. */
 inline clEvent::~clEvent(void) {}
}

// M e t h o d E v e n t  Inline //-----------------------------------------------------------------
namespace public_area {
 //--------------------------------------------------------------------------------------Constructor
 /*METHOD clMethodEvent */
 /* Builds a method call event. The object and its method must be provided. */
 template <class prClass> inline clMethodEvent<prClass>::
 clMethodEvent(simulationSimulator::clSimulator & agSimulator,clAbstractPool * agPool,
               tyCardinal agDate,tyCardinal agPriority,prClass * agObject,tyMethodPointer agMethod)
 : clEvent(agSimulator,agPool,agDate,agPriority),atObject(agObject),atMethod(agMethod) {}
 //---------------------------------------------------------------------------------------Destructor
 /*METHOD clMethodEvent */ /* Destructs the event. */
 template <class prClass> inline clMethodEvent<prClass>::~clMethodEvent(void) {}
 //-------------------------------------------------------------------------------------------Action
 /*METHOD clMethodEvent */ /* Executes the method associated with the event. */
 template <class prClass> inline void clMethodEvent<prClass>::action(void) const
 { (atObject->*atMethod)(); }
}

// End //-------------------------------------------------------------------------------------------
}
#undef dll_export
#undef mpattern_clMethodEvent_X
#undef public_area
#undef private_area
#endif
 
//==================================================================================================
// S i m u l a t i o n                                                               Implementation
// E v e n t
//                                                                                By Bruno Bachelet
//==================================================================================================
// Copyright (c) 1999-2016
// Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net
//
// This file is part of the B++ Library. This library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Library General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
// the GNU Library General Public License for more details (http://www.gnu.org).

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "simulation/event.cpp"

// DLL Belonging //---------------------------------------------------------------------------------
#define SIMULATION_DLL

// Headers //---------------------------------------------------------------------------------------
#include <bpp/simulation/event.hpp> /*INTERFACE*/

namespace bpp {

// Namespaces //------------------------------------------------------------------------------------
#define public_area  simulationEvent
#define private_area simulationEvent_private
#define dll_export   DLL_EXPORT

namespace public_area  {}
namespace private_area {}

static_module_name("Simulation/Event");

// Initialization //--------------------------------------------------------------------------------

// Errors //----------------------------------------------------------------------------------------
namespace public_area {}

// Constants & Variables //-------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// Static Members //--------------------------------------------------------------------------------
namespace public_area  { static_class_indexer(clEvent); }
namespace private_area {}

// Functions Implementation //----------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// X X X  Implementation //-------------------------------------------------------------------------
namespace {}

// End //-------------------------------------------------------------------------------------------
}