1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    WrappingCommand.h
11 /// @author  Christian Roessel
12 /// @author  Daniel Krajzewicz
13 /// @date    Thu, 20 Dec 2001
14 /// @version $Id$
15 ///
16 // A wrapper for a Command function
17 /****************************************************************************/
18 #ifndef WrappingCommand_h
19 #define WrappingCommand_h
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 
26 #include "Command.h"
27 
28 
29 // ===========================================================================
30 // class definition
31 // ===========================================================================
32 /**
33  * @class WrappingCommand
34  * @brief A wrapper for a Command function
35  *
36  * In order to ease life, this class may encapsulate a method of a class which
37  *  in order to be used as a Command. This allows to use a member methods
38  *  of a class to be called as Commands are, avoiding that the instance itself
39  *  is destroyed by the EventHandler.
40  *
41  * Because in some cases, the Command may live longer than the instance class,
42  *  a boolean value indicates that the Command is "descheduled". It should
43  *  be set via "deschedule" as soon as the class instance of which a method
44  *  is encapsulated is destroyed and forces that the command (calling of this
45  *  instace's method) is not executed.
46  *
47  * @see Design Patterns, Gamma et al.
48  * @see Command
49  * @see MSEventControl
50  */
51 template< class T  >
52 class WrappingCommand : public Command {
53 public:
54     /// @brief Type of the function to execute.
55     typedef SUMOTime(T::* Operation)(SUMOTime);
56 
57 
58 public:
59     /**
60      * @brief Constructor.
61      *
62      * @param[in] receiver Pointer to object of type T that will receive a call to one of it's methods.
63      * @param[in] operation The objects' method that will be called on execute()
64      */
WrappingCommand(T * receiver,Operation operation)65     WrappingCommand(T* receiver, Operation operation)
66         : myReceiver(receiver), myOperation(operation),
67           myAmDescheduledByParent(false) {}
68 
69 
70     /// @brief Destructor
~WrappingCommand()71     ~WrappingCommand() {}
72 
73 
74     /** @brief Marks this Command as being descheduled
75      *
76      * A simple boolean marker ("myAmDescheduledByParent") is set which
77      *  prevents this command from being executed.
78      */
deschedule()79     void deschedule() {
80         myAmDescheduledByParent = true;
81     }
82 
83     /// @brief whether this command has been descheduled
isDescheduled()84     bool isDescheduled() {
85         return myAmDescheduledByParent;
86     }
87 
88 
89     /// @name Derived from Command
90     /// @{
91 
92     /** @brief Executes the command.
93      *
94      * If the command is not descheduled, the stored method of the stored instance
95      *  is called.
96      *
97      * @param[in] currentTime The current simulation time
98      * @return The time after which the command shall be executed again, 0 if this command shall be descheduled.
99      * @exception ProcessError Derived actions may throw this exception
100      */
execute(SUMOTime currentTime)101     SUMOTime execute(SUMOTime currentTime) {
102         // do not execute if the command was descheduled
103         if (myAmDescheduledByParent) {
104             return 0;
105         }
106         // execute if stil valid
107         return (myReceiver->*myOperation)(currentTime);
108     }
109     /// @}
110 
111 
112 private:
113     /// @brief The object the action is directed to.
114     T* myReceiver;
115 
116     /// @brief The object's operation to perform.
117     Operation myOperation;
118 
119     /// @brief Whether this command was descheduled (is invalid) and shall not be executed
120     bool myAmDescheduledByParent;
121 
122 
123 };
124 
125 
126 #endif
127 
128 /****************************************************************************/
129 
130