SIMLIB/C++  3.07
zdelay.cc
Go to the documentation of this file.
1 /////////////////////////////////////////////////////////////////////////////
2 //! \file zdelay.cc unit delay block implementation
3 //
4 // Copyright (c) 1998-2018 Petr Peringer
5 //
6 // This library is licensed under GNU Library GPL. See the file COPYING.
7 //
8 
9 //
10 // This module contains experimental implementation of discrete-time delay class
11 //
12 // Classes:
13 // ZDelay -- discrete-time delay blocks
14 // ZDelayTimer -- clock generating class for ZDelay objects
15 // SIMLIB_ZDelayTimer -- internal class
16 //
17 // FIXME: improve design
18 // TODO: add dividers, add example
19 
20 ////////////////////////////////////////////////////////////////////////////
21 // interface
22 //
23 
24 #include "simlib.h"
25 #include "zdelay.h"
26 #include "internal.h"
27 
28 #include <set> // for ZDelay objects container implementation
29 #include <list> // for list of ZDelayTimers
30 
31 ////////////////////////////////////////////////////////////////////////////
32 // implementation
33 //
34 namespace simlib3 {
35 
37 
38 ////////////////////////////////////////////////////////////////////////////
39 // SIMLIB_ZDelayTimer --- register of all ZDelayTimer objects
40 //
42  typedef std::list<ZDelayTimer *> container_t; // type of container we use
43  static container_t *container; // list of delay objects -- singleton
44  public: // interface
45  static void Register(ZDelayTimer *p) { // called from ZDelayTimer constructor
46  if( container == nullptr )
47  Initialize();
48  container->push_back(p);
49  }
50  static void UnRegister(ZDelayTimer *p) { // called from ZDelayTimer destructor
51  container->remove(p);
52  if( container->empty() )
53  Destroy();
54  }
55  private: // implementation
56  static void Initialize() { // initialize delay subsystem
57  container = new container_t(); // create new list of delays
58  // install hook in simulation control algorithm:
59  INSTALL_HOOK( ZDelayTimerInit, SIMLIB_ZDelayTimer::InitAll );
60  }
61  static void Destroy() { // FIXME: should be called by ExitSimulation()?
62  delete container; // remove list
63  container = nullptr;
64  // disable hook in simulation control algorithm
65  INSTALL_HOOK( ZDelayTimerInit, 0 );
66  }
67  // InitAll --- function to initialize all ZDelayTimer objects
68  static void InitAll() { // called by Init()
69  if( container == nullptr ) return; // no delay blocks registered
70  container_t::iterator i;
71  for( i=container->begin(); i!=container->end(); ++i) // for each delay object
72  (*i)->Init(); // set initial value
73  }
74 };
75 
76 // SINGLETON: static member must be initializad
78 
79 
80 /////////////////////////////////////////////////////////////////////////////
81 // ZDelayTimer --- discrete-time delay block timer implementation
82 //
83 
84 // singleton -- default ZDelayTimer
86 
87 /////////////////////////////////////////////////////////////////////////////
88 // ZDelayTimer::ZDelayContainer --- container for associated ZDelay blocks
89 //
90 class ZDelayTimer::ZDelayContainer { // implementation-defined container
91  typedef std::set<ZDelay*> container_t;
92  container_t c;
93  public:
94  ZDelayContainer(): c() {}
95  typedef container_t::iterator iterator;
96  iterator begin() { return c.begin(); }
97  iterator end() { return c.end(); }
98  void insert(ZDelay * p) { c.insert(p); }
99  void erase(ZDelay * p) { c.erase(p); }
100  void clear() { c.clear(); }
101 }; // class ZDelayTimer::ZDelayContainer
102 
103 /////////////////////////////////////////////////////////////////////////////
104 // constructor --- init & insert into global register
105 //
106 ZDelayTimer::ZDelayTimer(double step, bool is_default) :
107  dt(step),
108  c(new ZDelayContainer)
109 { // constructor body
110  if(is_default) {
111  ZDelay::default_clock = this;
112  }
113  SIMLIB_ZDelayTimer::Register(this); // register in list
114 }
115 
117 {
118  if( ZDelay::default_clock == this)
119  ZDelay::default_clock = 0; // default timer deleted
120  // clear all items
122  for( ; i!=c->end(); ++i) // unregister all ZDelays
123  (*i)->clock = 0;
124  c->clear(); // remove all items
125  delete c;
126  SIMLIB_ZDelayTimer::UnRegister(this); // remove from list
127 }
128 
129 /////////////////////////////////////////////////////////////////////////////
130 // ZDelayTimer::Init --- initialize all connected ZDelays and activate
131 //
132 void ZDelayTimer::Init() // called each Run()
133 {
135  for( ; i!=c->end(); ++i) // init all associated ZDelays
136  (*i)->Init();
137  Start();
138 }
139 
140 /////////////////////////////////////////////////////////////////////////////
141 // ZDelayTimer::Start --- activate
142 //
143 void ZDelayTimer::Start() // clock activation
144 {
145  Activate();
146 }
147 
148 /////////////////////////////////////////////////////////////////////////////
149 // ZDelayTimer::Stop --- passivate
150 //
151 void ZDelayTimer::Stop() // clock deactivation
152 {
153  Passivate();
154 }
155 
156 /////////////////////////////////////////////////////////////////////////////
157 // ZDelayTimer::Behavior --- sample all associated ZDelays, reschedule
158 //
160 {
162  for( i=c->begin(); i!=c->end(); ++i) // evaluate all inputs
163  (*i)->SampleIn();
164  for( i=c->begin(); i!=c->end(); ++i) // store all new output values
165  (*i)->SampleOut();
166  Activate( Time + dt );
167 }
168 
169 /////////////////////////////////////////////////////////////////////////////
170 // ZDelayTimer::Register --- add ZDelay to list
171 //
173 {
174  c->insert(p);
175  p->clock = this;
176 }
177 
178 /////////////////////////////////////////////////////////////////////////////
179 // ZDelayTimer::UnRegister --- remove ZDelay from list
180 //
182 {
183  c->erase(p);
184  p->clock = 0;
185 }
186 
187 
188 
189 /////////////////////////////////////////////////////////////////////////////
190 /////////////////////////////////////////////////////////////////////////////
191 // ZDelay --- discrete-time delay block implementation
192 //
193 
194 /////////////////////////////////////////////////////////////////////////////
195 // ZDelay constructor --- initialize and register delay block
196 //
197 ZDelay::ZDelay(Input i, ZDelayTimer *p, double ival) :
198  aContiBlock1( i ), // input expression
199  input_value( ival ),
200  clock( p ),
201  new_value( ival ),
202  old_value( ival ),
203  initval( ival ) // initial value of delay
204 { // constructor body
205  Dprintf(("ZDelay::ZDelay%p(in=%p, timer=%p, ival=%g)", this, &i, p, ival));
206  if(clock==0)
207  SIMLIB_internal_error(); // change ##############!!!!!
208  clock->Register( this ); // register in timer
209  Init(); // initialize -- important for dynamically created delays
210 }
211 
212 ZDelay::ZDelay( Input i, double ival ) :
213  aContiBlock1( i ), // input expression
214  input_value( ival ),
215  clock( default_clock ),
216  new_value( ival ),
217  old_value( ival ),
218  initval( ival ) // initial value of delay
219 { // constructor body
220  Dprintf(("ZDelay::ZDelay%p(in=%p, ival=%g)", this, &i, ival));
221  if(clock==0)
222  SIMLIB_internal_error(); // change ##############!!!!!
223  clock->Register( this ); // register in timer
224  Init(); // initialize -- important for dynamically created delays
225 }
226 
227 
228 /////////////////////////////////////////////////////////////////////////////
229 // ZDelay destructor --- remove buffer and delay from list
230 //
232 {
233  Dprintf(("ZDelay::~ZDelay%p()", this));
234  if(clock)
235  clock->UnRegister( this ); // remove from delay list
236 }
237 
238 /////////////////////////////////////////////////////////////////////////////
239 // ZDelay::Init --- initialize delay status
240 // called automatically by Run()
241 void ZDelay::Init() {
242  Dprintf(("ZDelay::Init()"));
244 }
245 
246 void ZDelay::Init(double iv) { // set initial value of ZDelay block
247  initval = iv;
248  Init();
249 }
250 
251 /////////////////////////////////////////////////////////////////////////////
252 // ZDelay::Sample --- sample input value
253 //
255 {
256  Dprintf(("ZDelay::SampleIn()"));
257  input_value = InputValue(); // store new input value
258 }
259 
261 {
262  Dprintf(("ZDelay::SampleOut()"));
263  old_value = new_value; // set output value (delayed)
264  new_value = input_value; // store new input value for delay
265 }
266 
267 /////////////////////////////////////////////////////////////////////////////
268 // ZDelay::Value --- get delay output value
269 //
271 {
272  Dprintf(("ZDelay::Value()"));
273  return old_value; // delayed value
274 }
275 
276 }
277 // end
278 
static ZDelayTimer * default_clock
Definition: zdelay.h:69
static void Destroy()
Definition: zdelay.cc:61
continuous block connection (transparent reference) wrapper for pointer to objects of aContiBlock der...
Definition: simlib.h:895
virtual void Init()
Definition: zdelay.cc:241
static void InitAll()
Definition: zdelay.cc:68
std::set< ZDelay * > container_t
Definition: zdelay.cc:91
virtual void Passivate()
deactivation
Definition: entity.cc:68
double initval
Definition: zdelay.h:68
Implementation of class CalendarList interface is static - using global functions in SQS namespace...
Definition: algloop.cc:32
void UnRegister(ZDelay *)
Definition: zdelay.cc:181
const double & Time
model time (is NOT the block)
Definition: run.cc:48
static container_t * container
Definition: zdelay.cc:43
double new_value
Definition: zdelay.h:65
container_t::iterator iterator
Definition: zdelay.cc:95
double old_value
Definition: zdelay.h:66
#define SIMLIB_internal_error()
Definition: internal.h:167
Internal header file for SIMLIB/C++.
ZDelayTimer * clock
Definition: zdelay.h:59
static void Register(ZDelayTimer *p)
Definition: zdelay.cc:45
Main SIMLIB/C++ interface.
ZDelayTimer(const ZDelayTimer &)
ZDelayContainer * c
Definition: zdelay.h:34
static void Initialize()
Definition: zdelay.cc:56
#define INSTALL_HOOK(name, function)
Definition: internal.h:255
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
ZDelay(const ZDelay &)
void Behavior() override
behavior description
Definition: zdelay.cc:159
double InputValue()
Definition: simlib.h:944
base for continuous blocks with single input and algebraic loop check
Definition: simlib.h:940
void Activate()
activate now
Definition: simlib.h:408
unit delay block interface
static void UnRegister(ZDelayTimer *p)
Definition: zdelay.cc:50
#define Dprintf(f)
Definition: internal.h:100
void Register(ZDelay *)
Definition: zdelay.cc:172
virtual double Value() override
get block output value this method should be defined in classes derived from aContiBlock ...
Definition: zdelay.cc:270
double input_value
Definition: zdelay.h:58
std::list< ZDelayTimer * > container_t
Definition: zdelay.cc:42
virtual void SampleOut()
Definition: zdelay.cc:260
virtual void SampleIn()
Definition: zdelay.cc:254