SIMLIB/C++ 3.09
Loading...
Searching...
No Matches
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//
34namespace 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//
90class ZDelayTimer::ZDelayContainer { // implementation-defined container
91 typedef std::set<ZDelay*> container_t;
93 public:
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//
106ZDelayTimer::ZDelayTimer(double step, bool is_default) :
107 dt(step),
108 c(new ZDelayContainer)
109{ // constructor body
110 if(is_default) {
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//
132void 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//
143void ZDelayTimer::Start() // clock activation
144{
145 Activate();
146}
147
148/////////////////////////////////////////////////////////////////////////////
149// ZDelayTimer::Stop --- passivate
150//
151void 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//
197ZDelay::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
212ZDelay::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()
242 Dprintf(("ZDelay::Init()"));
244}
245
246void 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
virtual void Passivate()
deactivation
Definition: entity.cc:68
void Activate()
activate now
Definition: simlib.h:408
continuous block connection (transparent reference) wrapper for pointer to objects of aContiBlock der...
Definition: simlib.h:895
static void Destroy()
Definition: zdelay.cc:61
static container_t * container
Definition: zdelay.cc:43
static void UnRegister(ZDelayTimer *p)
Definition: zdelay.cc:50
static void Register(ZDelayTimer *p)
Definition: zdelay.cc:45
static void InitAll()
Definition: zdelay.cc:68
static void Initialize()
Definition: zdelay.cc:56
std::list< ZDelayTimer * > container_t
Definition: zdelay.cc:42
container_t::iterator iterator
Definition: zdelay.cc:95
std::set< ZDelay * > container_t
Definition: zdelay.cc:91
ZDelayContainer * c
Definition: zdelay.h:35
void Behavior() override
behavior description
Definition: zdelay.cc:159
void Register(ZDelay *)
Definition: zdelay.cc:172
void UnRegister(ZDelay *)
Definition: zdelay.cc:181
ZDelayTimer(const ZDelayTimer &)
virtual void SampleIn()
Definition: zdelay.cc:254
virtual void SampleOut()
Definition: zdelay.cc:260
double old_value
Definition: zdelay.h:66
virtual double Value() override
get block output value this method should be defined in classes derived from aContiBlock
Definition: zdelay.cc:270
ZDelayTimer * clock
Definition: zdelay.h:59
ZDelay(const ZDelay &)
virtual void Init()
Definition: zdelay.cc:241
double new_value
Definition: zdelay.h:65
double initval
Definition: zdelay.h:68
double input_value
Definition: zdelay.h:58
static ZDelayTimer * default_clock
Definition: zdelay.h:69
base for continuous blocks with single input and algebraic loop check
Definition: simlib.h:940
double InputValue()
Definition: simlib.h:944
Internal header file for SIMLIB/C++.
#define Dprintf(f)
Definition: internal.h:100
#define SIMLIB_internal_error()
Definition: internal.h:167
#define INSTALL_HOOK(name, function)
Definition: internal.h:255
Implementation of class CalendarList interface is static - using global functions in SQS namespace.
Definition: algloop.cc:32
const double & Time
model time (is NOT the block)
Definition: run.cc:48
SIMLIB_IMPLEMENTATION
Definition: algloop.cc:34
Main SIMLIB/C++ interface.
unit delay block interface