00001
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include <errno.h>
00020 #include <ctype.h>
00021 #include "gridlabd.h"
00022 #include "object.h"
00023 #include "aggregate.h"
00024 #include "histogram.h"
00025 #include "group_recorder.h"
00026
00027 #define _TAPE_C
00028
00029 #include "tape.h"
00030 #include "file.h"
00031 #include "odbc.h"
00032
00033 #define MAP_DOUBLE(X,LO,HI) {#X,VT_DOUBLE,&X,LO,HI}
00034 #define MAP_INTEGER(X,LO,HI) {#X,VT_INTEGER,&X,LO,HI}
00035 #define MAP_STRING(X) {#X,VT_STRING,X,sizeof(X),0}
00036 #define MAP_END {NULL}
00037
00038 VARMAP varmap[] = {
00039
00040 MAP_STRING(timestamp_format),
00041 MAP_END
00042 };
00043
00044 extern CLASS *player_class;
00045 extern CLASS *shaper_class;
00046 extern CLASS *recorder_class;
00047 extern CLASS *multi_recorder_class;
00048 extern CLASS *collector_class;
00049
00050
00051 TIMESTAMP delta_mode_needed = TS_NEVER;
00052
00053 #ifdef WIN32
00054 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
00055 #define _WIN32_WINNT 0x0400
00056 #include <windows.h>
00057 #ifndef DLEXT
00058 #define DLEXT ".dll"
00059 #endif
00060 #define DLLOAD(P) LoadLibrary(P)
00061 #define DLSYM(H,S) GetProcAddress((HINSTANCE)H,S)
00062 #define snprintf _snprintf
00063 #else
00064 #include "dlfcn.h"
00065 #ifndef DLEXT
00066 #define DLEXT ".so"
00067 #else
00068 #endif
00069 #define DLLOAD(P) dlopen(P,RTLD_LAZY)
00070 #define DLSYM(H,S) dlsym(H,S)
00071 #endif
00072
00073 static TAPEFUNCS *funcs = NULL;
00074 static char1024 tape_gnuplot_path;
00075 int32 flush_interval = 0;
00076 int csv_data_only = 0;
00077 int csv_keep_clean = 0;
00078 void (*update_csv_data_only)(void)=NULL;
00079 void (*update_csv_keep_clean)(void)=NULL;
00080
00081 void set_csv_options(void)
00082 {
00083 if (csv_data_only && update_csv_data_only)
00084 (*update_csv_data_only)();
00085 if (csv_keep_clean && update_csv_keep_clean)
00086 (*update_csv_keep_clean)();
00087 }
00088
00089 typedef int (*OPENFUNC)(void *, char *, char *);
00090 typedef char *(*READFUNC)(void *, char *, unsigned int);
00091 typedef int (*WRITEFUNC)(void *, char *, char *);
00092 typedef int (*REWINDFUNC)(void *);
00093 typedef void (*CLOSEFUNC)(void *);
00094 typedef void (*VOIDCALL)(void);
00095 typedef void (*FLUSHFUNC)(void*);
00096
00097 TAPEFUNCS *get_ftable(char *mode){
00098
00099 char256 modname;
00100 TAPEFUNCS *fptr = funcs;
00101 TAPEOPS *ops = NULL;
00102 void *lib = NULL;
00103 CALLBACKS **c = NULL;
00104 char tpath[1024];
00105 while(fptr != NULL){
00106 if(strcmp(fptr->mode, mode) == 0)
00107 return fptr;
00108 fptr = fptr->next;
00109 }
00110
00111 fptr = malloc(sizeof(TAPEFUNCS));
00112 if(fptr == NULL)
00113 {
00114 gl_error("get_ftable(char *mode='%s'): out of memory", mode);
00115 return NULL;
00116 }
00117 snprintf(modname, sizeof(modname), "tape_%s" DLEXT, mode);
00118
00119 if(gl_findfile(modname, NULL, 0|4, tpath,sizeof(tpath)) == NULL){
00120 gl_error("unable to locate %s", modname);
00121 return NULL;
00122 }
00123 lib = fptr->hLib = DLLOAD(tpath);
00124 if(fptr->hLib == NULL){
00125 gl_error("tape module: unable to load DLL for %s", modname);
00126 return NULL;
00127 }
00128 c = (CALLBACKS **)DLSYM(lib, "callback");
00129 if(c)
00130 *c = callback;
00131
00132
00133 ops = fptr->collector = malloc(sizeof(TAPEOPS));
00134 memset(ops,0,sizeof(TAPEOPS));
00135 ops->open = (OPENFUNC)DLSYM(lib, "open_collector");
00136 ops->read = NULL;
00137 ops->write = (WRITEFUNC)DLSYM(lib, "write_collector");
00138 ops->rewind = NULL;
00139 ops->close = (CLOSEFUNC)DLSYM(lib, "close_collector");
00140 ops->flush = (FLUSHFUNC)DLSYM(lib, "flush_collector");
00141
00142 ops = fptr->player = malloc(sizeof(TAPEOPS));
00143 memset(ops,0,sizeof(TAPEOPS));
00144 ops->open = (OPENFUNC)DLSYM(lib, "open_player");
00145 ops->read = (READFUNC)DLSYM(lib, "read_player");
00146 ops->write = NULL;
00147 ops->rewind = (REWINDFUNC)DLSYM(lib, "rewind_player");
00148 ops->close = (CLOSEFUNC)DLSYM(lib, "close_player");
00149 ops->flush = NULL;
00150
00151 ops = fptr->recorder = malloc(sizeof(TAPEOPS));
00152 memset(ops,0,sizeof(TAPEOPS));
00153 ops->open = (OPENFUNC)DLSYM(lib, "open_recorder");
00154 ops->read = NULL;
00155 ops->write = (WRITEFUNC)DLSYM(lib, "write_recorder");
00156 ops->rewind = NULL;
00157 ops->close = (CLOSEFUNC)DLSYM(lib, "close_recorder");
00158 ops->flush = (FLUSHFUNC)DLSYM(lib, "flush_collector");
00159
00160 ops = fptr->histogram = malloc(sizeof(TAPEOPS));
00161 memset(ops,0,sizeof(TAPEOPS));
00162 ops->open = (OPENFUNC)DLSYM(lib, "open_histogram");
00163 ops->read = NULL;
00164 ops->write = (WRITEFUNC)DLSYM(lib, "write_histogram");
00165 ops->rewind = NULL;
00166 ops->close = (CLOSEFUNC)DLSYM(lib, "close_histogram");
00167 ops->flush = (FLUSHFUNC)DLSYM(lib, "flush_collector");
00168
00169 ops = fptr->shaper = malloc(sizeof(TAPEOPS));
00170 memset(ops,0,sizeof(TAPEOPS));
00171 ops->open = (OPENFUNC)DLSYM(lib, "open_shaper");
00172 ops->read = (READFUNC)DLSYM(lib, "read_shaper");
00173 ops->write = NULL;
00174 ops->rewind = (REWINDFUNC)DLSYM(lib, "rewind_shaper");
00175 ops->close = (CLOSEFUNC)DLSYM(lib, "close_shaper");
00176
00177 fptr->next = funcs;
00178 funcs = fptr;
00179
00180 update_csv_data_only = (VOIDCALL)DLSYM(lib,"set_csv_data_only");
00181 update_csv_keep_clean = (VOIDCALL)DLSYM(lib,"set_csv_keep_clean");
00182 return funcs;
00183 }
00184
00185 EXPORT CLASS *init(CALLBACKS *fntable, void *module, int argc, char *argv[])
00186 {
00187 struct recorder my;
00188 struct collector my2;
00189
00190 if (set_callback(fntable)==NULL)
00191 {
00192 errno = EINVAL;
00193 return NULL;
00194 }
00195
00196
00197 #ifdef WIN32
00198 sprintf(tape_gnuplot_path, "c:/Program Files/GnuPlot/bin/wgnuplot.exe");
00199 #else
00200 sprintf(tape_gnuplot_path,"/usr/bin/gnuplot");
00201 #endif
00202 gl_global_create("tape::gnuplot_path",PT_char1024,&tape_gnuplot_path,NULL);
00203 gl_global_create("tape::flush_interval",PT_int32,&flush_interval,NULL);
00204 gl_global_create("tape::csv_data_only",PT_int32,&csv_data_only,NULL);
00205 gl_global_create("tape::csv_keep_clean",PT_int32,&csv_keep_clean,NULL);
00206
00207
00208 gl_global_create("tape::delta_mode_needed", PT_timestamp, &delta_mode_needed,NULL);
00209
00210
00211 player_class = gl_register_class(module,"player",sizeof(struct player),PC_PRETOPDOWN);
00212 player_class->trl = TRL_PROVEN;
00213 PUBLISH_STRUCT(player,char256,property);
00214 PUBLISH_STRUCT(player,char1024,file);
00215 PUBLISH_STRUCT(player,char8,filetype);
00216 PUBLISH_STRUCT(player,char32,mode);
00217 PUBLISH_STRUCT(player,int32,loop);
00218
00219
00220 shaper_class = gl_register_class(module,"shaper",sizeof(struct shaper),PC_PRETOPDOWN);
00221 shaper_class->trl = TRL_QUALIFIED;
00222 PUBLISH_STRUCT(shaper,char1024,file);
00223 PUBLISH_STRUCT(shaper,char8,filetype);
00224 PUBLISH_STRUCT(shaper,char32,mode);
00225 PUBLISH_STRUCT(shaper,char256,group);
00226 PUBLISH_STRUCT(shaper,char256,property);
00227 PUBLISH_STRUCT(shaper,double,magnitude);
00228 PUBLISH_STRUCT(shaper,double,events);
00229
00230
00231 recorder_class = gl_register_class(module,"recorder",sizeof(struct recorder),PC_POSTTOPDOWN|PC_OBSERVER);
00232 recorder_class->trl = TRL_PROVEN;
00233 PUBLISH_STRUCT(recorder,char1024,property);
00234 PUBLISH_STRUCT(recorder,char32,trigger);
00235 PUBLISH_STRUCT(recorder,char1024,file);
00236 PUBLISH_STRUCT(recorder,char8,filetype);
00237 PUBLISH_STRUCT(recorder,char32,mode);
00238 PUBLISH_STRUCT(recorder,char1024,multifile);
00239
00240 PUBLISH_STRUCT(recorder,int32,limit);
00241 PUBLISH_STRUCT(recorder,char1024,plotcommands);
00242 PUBLISH_STRUCT(recorder,char32,xdata);
00243 PUBLISH_STRUCT(recorder,char32,columns);
00244 PUBLISH_STRUCT(recorder,int32,flush);
00245 PUBLISH_STRUCT(recorder,bool,format);
00246
00247 if(gl_publish_variable(recorder_class,
00248 PT_double, "interval[s]", ((char*)&(my.dInterval) - (char *)&my),
00249 PT_enumeration, "output", ((char*)&(my.output) - (char *)&my),
00250 PT_KEYWORD, "SCREEN", SCREEN,
00251 PT_KEYWORD, "EPS", EPS,
00252 PT_KEYWORD, "GIF", GIF,
00253 PT_KEYWORD, "JPG", JPG,
00254 PT_KEYWORD, "PDF", PDF,
00255 PT_KEYWORD, "PNG", PNG,
00256 PT_KEYWORD, "SVG", SVG,
00257 PT_enumeration, "header_units", ((char*)&(my.header_units) - (char *)&my),
00258 PT_KEYWORD, "DEFAULT", HU_DEFAULT,
00259 PT_KEYWORD, "ALL", HU_ALL,
00260 PT_KEYWORD, "NONE", HU_NONE,
00261 PT_enumeration, "line_units", ((char*)&(my.line_units) - (char *)&my),
00262 PT_KEYWORD, "DEFAULT", LU_DEFAULT,
00263 PT_KEYWORD, "ALL", LU_ALL,
00264 PT_KEYWORD, "NONE", LU_NONE,
00265 NULL) < 1)
00266 GL_THROW("Could not publish property output for recorder");
00267
00268
00269 multi_recorder_class = gl_register_class(module,"multi_recorder",sizeof(struct recorder),PC_POSTTOPDOWN|PC_OBSERVER);
00270 multi_recorder_class->trl = TRL_QUALIFIED;
00271 if(gl_publish_variable(multi_recorder_class,
00272 PT_double, "interval[s]", ((char*)&(my.dInterval) - (char *)&my),
00273 PT_char1024, "property", ((char*)&(my.property) - (char *)&my),
00274 PT_char32, "trigger", ((char*)&(my.trigger) - (char *)&my),
00275 PT_char1024, "file", ((char*)&(my.file) - (char *)&my),
00276 PT_char8, "filetype", ((char*)&(my.filetype) - (char *)&my),
00277 PT_char32, "mode", ((char*)&(my.mode) - (char *)&my),
00278 PT_char1024, "multifile", ((char*)&(my.multifile) - (char *)&my),
00279 PT_int32, "limit", ((char*)&(my.limit) - (char *)&my),
00280 PT_char1024, "plotcommands", ((char*)&(my.plotcommands) - (char *)&my),
00281 PT_char32, "xdata", ((char*)&(my.xdata) - (char *)&my),
00282 PT_char32, "columns", ((char*)&(my.columns) - (char *)&my),
00283 PT_char32, "format", ((char*)&(my.format) - (char *)&my),
00284 PT_enumeration, "output", ((char*)&(my.output) - (char *)&my),
00285 PT_KEYWORD, "SCREEN", SCREEN,
00286 PT_KEYWORD, "EPS", EPS,
00287 PT_KEYWORD, "GIF", GIF,
00288 PT_KEYWORD, "JPG", JPG,
00289 PT_KEYWORD, "PDF", PDF,
00290 PT_KEYWORD, "PNG", PNG,
00291 PT_KEYWORD, "SVG", SVG,
00292 PT_enumeration, "header_units", ((char*)&(my.header_units) - (char *)&my),
00293 PT_KEYWORD, "DEFAULT", HU_DEFAULT,
00294 PT_KEYWORD, "ALL", HU_ALL,
00295 PT_KEYWORD, "NONE", HU_NONE,
00296 PT_enumeration, "line_units", ((char*)&(my.line_units) - (char *)&my),
00297 PT_KEYWORD, "DEFAULT", LU_DEFAULT,
00298 PT_KEYWORD, "ALL", LU_ALL,
00299 PT_KEYWORD, "NONE", LU_NONE,
00300 NULL) < 1)
00301 GL_THROW("Could not publish property output for multi_recorder");
00302
00303
00304 collector_class = gl_register_class(module,"collector",sizeof(struct collector),PC_POSTTOPDOWN|PC_OBSERVER);
00305 collector_class->trl = TRL_PROVEN;
00306 PUBLISH_STRUCT(collector,char1024,property);
00307 PUBLISH_STRUCT(collector,char32,trigger);
00308 PUBLISH_STRUCT(collector,char1024,file);
00309
00310 PUBLISH_STRUCT(collector,int32,limit);
00311 PUBLISH_STRUCT(collector,char256,group);
00312 PUBLISH_STRUCT(collector,int32,flush);
00313 if(gl_publish_variable(collector_class,
00314 PT_double, "interval[s]", ((char*)&(my2.dInterval) - (char *)&my2),
00315 NULL) < 1)
00316 GL_THROW("Could not publish property output for collector");
00317
00318
00319 new_histogram(module);
00320
00321
00322 new_group_recorder(module);
00323
00324
00325 new_violation_recorder(module);
00326
00327
00328 new_metrics_collector(module);
00329
00330
00331 new_metrics_collector_writer(module);
00332
00333 #if 0
00334 new_loadshape(module);
00335 #endif // zero
00336
00337
00338
00339
00340 return player_class;
00341 }
00342
00343 EXPORT int check(void)
00344 {
00345 unsigned int errcount=0;
00346 char fpath[1024];
00347
00348 { OBJECT *obj=NULL;
00349 FINDLIST *players = gl_find_objects(FL_NEW,FT_CLASS,SAME,"tape",FT_END);
00350 while ((obj=gl_find_next(players,obj))!=NULL)
00351 {
00352 struct player *pData = OBJECTDATA(obj,struct player);
00353 if (gl_findfile(pData->file,NULL,F_OK,fpath,sizeof(fpath))==NULL)
00354 {
00355 errcount++;
00356 gl_error("player %s (id=%d) uses the file '%s', which cannot be found", obj->name?obj->name:"(unnamed)", obj->id, pData->file);
00357 }
00358 }
00359 }
00360
00361
00362 { OBJECT *obj=NULL;
00363 FINDLIST *shapers = gl_find_objects(FL_NEW,FT_CLASS,SAME,"shaper",FT_END);
00364 while ((obj=gl_find_next(shapers,obj))!=NULL)
00365 {
00366 struct shaper *pData = OBJECTDATA(obj,struct shaper);
00367 if (gl_findfile(pData->file,NULL,F_OK,fpath,sizeof(fpath))==NULL)
00368 {
00369 errcount++;
00370 gl_error("shaper %s (id=%d) uses the file '%s', which cannot be found", obj->name?obj->name:"(unnamed)", obj->id, pData->file);
00371 }
00372 }
00373 }
00374
00375 return errcount;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 double recorder_delta_clock = 0.0;
00388 DELTAOBJ_LIST *delta_tape_objects = NULL;
00389
00390
00391 int delta_add_tape_device(OBJECT *obj, DELTATAPEOBJ tape_type)
00392 {
00393 DELTAOBJ_LIST *temp_ll_item, *index_item;
00394
00395
00396 temp_ll_item = (DELTAOBJ_LIST*)gl_malloc(sizeof(DELTAOBJ_LIST));
00397
00398
00399 if (temp_ll_item == NULL)
00400 {
00401 gl_error("tape object:%d - unable to allocate space for deltamode",obj->id);
00402
00403
00404
00405
00406 return FAILED;
00407 }
00408
00409
00410 temp_ll_item->obj = obj;
00411 temp_ll_item->obj_type = tape_type;
00412 temp_ll_item->next = NULL;
00413
00414
00415 if (delta_tape_objects != NULL)
00416 {
00417
00418 index_item = delta_tape_objects;
00419
00420 while (index_item->next != NULL)
00421 {
00422 index_item = index_item->next;
00423 }
00424
00425
00426 index_item->next = temp_ll_item;
00427 }
00428 else
00429 {
00430 delta_tape_objects = temp_ll_item;
00431 }
00432
00433
00434 return SUCCESS;
00435 }
00436
00437
00438 void enable_deltamode(TIMESTAMP t)
00439 {
00440 if ((t<delta_mode_needed) && ((t-gl_globalclock)<0x7fffffff ))
00441 delta_mode_needed = t;
00442 }
00443
00444 EXPORT unsigned long deltamode_desired(int *flags)
00445 {
00446 TIMESTAMP tdiff = delta_mode_needed-gl_globalclock;
00447
00448
00449
00450 if ((delta_mode_needed!=TS_NEVER) && (tdiff<0x7fffffff) && (tdiff>=0))
00451 return (unsigned long)tdiff;
00452 else
00453 return DT_INFINITY;
00454 }
00455
00456 EXPORT unsigned long preupdate(MODULE *module, TIMESTAMP t0, unsigned int64 dt)
00457 {
00458
00459 return DT_INFINITY;
00460 }
00461
00462 EXPORT SIMULATIONMODE interupdate(MODULE *module, TIMESTAMP t0, unsigned int64 delta_time, unsigned long dt, unsigned int iteration_count_val)
00463 {
00464 DELTAOBJ_LIST *index_item;
00465 SIMULATIONMODE mode = SM_EVENT;
00466
00467
00468 double clock_val = (double)gl_globalclock + (double)delta_time/(double)DT_SECOND;
00469 char recorder_timestamp[64];
00470
00471
00472 static char global_dateformat[8]="";
00473
00474 TIMESTAMP integer_clock = (TIMESTAMP)clock_val;
00475 int microseconds = (int)((clock_val-(int)(clock_val))*1000000+0.5);
00476
00477
00478 if (iteration_count_val==0)
00479 {
00480
00481 if ((integer_clock != t0) || (microseconds != 0))
00482 {
00483 DATETIME rec_date_time;
00484 TIMESTAMP rec_integer_clock = (TIMESTAMP)recorder_delta_clock;
00485 int rec_microseconds = (int)((recorder_delta_clock-(int)(recorder_delta_clock))*1000000+0.5);
00486 if ( gl_localtime(rec_integer_clock,&rec_date_time)!=0 )
00487 {
00488 if ( global_dateformat[0]=='\0')
00489 gl_global_getvar("dateformat",global_dateformat,sizeof(global_dateformat));
00490 if ( strcmp(global_dateformat,"ISO")==0)
00491 sprintf(recorder_timestamp,"%04d-%02d-%02d %02d:%02d:%02d.%.06d %s",rec_date_time.year,rec_date_time.month,rec_date_time.day,rec_date_time.hour,rec_date_time.minute,rec_date_time.second,rec_microseconds,rec_date_time.tz);
00492 else if ( strcmp(global_dateformat,"US")==0)
00493 sprintf(recorder_timestamp,"%02d-%02d-%04d %02d:%02d:%02d.%.06d %s",rec_date_time.month,rec_date_time.day,rec_date_time.year,rec_date_time.hour,rec_date_time.minute,rec_date_time.second,rec_microseconds,rec_date_time.tz);
00494 else if ( strcmp(global_dateformat,"EURO")==0)
00495 sprintf(recorder_timestamp,"%02d-%02d-%04d %02d:%02d:%02d.%.06d %s",rec_date_time.day,rec_date_time.month,rec_date_time.year,rec_date_time.hour,rec_date_time.minute,rec_date_time.second,rec_microseconds,rec_date_time.tz);
00496 else
00497 sprintf(recorder_timestamp,"%.09f",recorder_delta_clock);
00498 }
00499 else
00500 sprintf(recorder_timestamp,"%.09f",recorder_delta_clock);
00501
00502
00503 index_item = delta_tape_objects;
00504
00505
00506 while (index_item != NULL)
00507 {
00508 if (index_item->obj_type == RECORDER)
00509 {
00510 OBJECT *obj = index_item->obj;
00511 struct recorder *my = (struct recorder *)OBJECTDATA(obj,struct recorder);
00512 char value[1024];
00513 extern int read_properties(struct recorder *my, OBJECT *obj, PROPERTY *prop, char *buffer, int size);
00514
00515
00516 if ((obj->in_svc_double <= gl_globaldeltaclock) && (obj->out_svc_double >= gl_globaldeltaclock))
00517 {
00518 if( read_properties(my, obj->parent,my->target,value,sizeof(value)) )
00519 {
00520 if ( !my->ops->write(my, recorder_timestamp, value) )
00521 {
00522 gl_error("recorder:%d: unable to write sample to file", obj->id);
00523 return SM_ERROR;
00524 }
00525 }
00526 }
00527
00528 }
00529
00530
00531
00532 index_item = index_item->next;
00533 }
00534 }
00535
00536
00537 recorder_delta_clock = clock_val;
00538 }
00539
00540
00541
00542
00543 index_item = delta_tape_objects;
00544
00545
00546 while (index_item != NULL)
00547 {
00548 if (index_item->obj_type == PLAYER)
00549 {
00550 OBJECT *obj = index_item->obj;
00551 struct player *my = (struct player *)OBJECTDATA(obj,struct player);
00552 int y=0,m=0,d=0,H=0,M=0,S=0,ms=0, n=0;
00553 char *fmt = "%d/%d/%d %d:%d:%d.%d,%*s";
00554 double t = (double)my->next.ts + (double)my->next.ns/1e9;
00555 char256 curr_value;
00556
00557
00558 if ((obj->in_svc_double <= gl_globaldeltaclock) && (obj->out_svc_double >= gl_globaldeltaclock))
00559 {
00560 strcpy(curr_value,my->next.value);
00561
00562
00563 if ( t<=clock_val )
00564 {
00565 extern TIMESTAMP player_read(OBJECT *obj);
00566
00567
00568 if (my->target == NULL)
00569 {
00570
00571
00572
00573
00574 gl_error("deltamode player: player \"%s\" has a deltamode timestep starting it - please avoid this",(obj->name ? obj->name : "(anon)"));
00575
00576
00577
00578
00579
00580
00581 return SM_ERROR;
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626 }
00627
00628
00629 while ( t<=clock_val )
00630 {
00631 gl_set_value(obj->parent,GETADDR(obj->parent,my->target),my->next.value,my->target);
00632
00633
00634 player_read(obj);
00635
00636
00637 t = (double)my->next.ts + (double)my->next.ns/1e9;
00638 }
00639 }
00640
00641
00642 if (my->next.ts != TS_NEVER)
00643 {
00644
00645 t = (double)my->next.ts + (double)my->next.ns/1e9;
00646
00647
00648
00649 if ((t>=clock_val) && (t<(clock_val+1.0)))
00650 {
00651
00652 if (my->next.ns!=0)
00653 {
00654 mode = SM_DELTA;
00655 gl_verbose("Tape object:%d - %s - requested deltamode to continue",obj->id,(obj->name ? obj->name : "Unnamed"));
00656 }
00657 }
00658 }
00659 else
00660 {
00661
00662 my->delta_track.ns = 0;
00663 my->delta_track.ts = TS_NEVER;
00664 }
00665 }
00666
00667 }
00668
00669
00670
00671 index_item = index_item->next;
00672 }
00673
00674 return mode;
00675 }
00676
00677 EXPORT STATUS postupdate(MODULE *module, TIMESTAMP t0, unsigned int64 dt)
00678 {
00679 DELTAOBJ_LIST *index_item;
00680 OBJECT *obj = NULL;
00681 struct recorder *myrec = NULL;
00682 struct player *myplayer = NULL;
00683 FUNCTIONADDR temp_fxn;
00684 char value[1024];
00685 extern int read_properties(struct recorder *my, OBJECT *obj, PROPERTY *prop, char *buffer, int size);
00686
00687
00688
00689
00690 char recorder_timestamp[64];
00691 DATETIME rec_date_time;
00692 TIMESTAMP rec_integer_clock;
00693 int rec_microseconds;
00694 bool recorder_init_items = false;
00695 char global_dateformat[8]="";
00696 int return_val;
00697
00698
00699 index_item = delta_tape_objects;
00700
00701
00702
00703 while (index_item != NULL)
00704 {
00705 if (index_item->obj_type == RECORDER)
00706 {
00707 if (recorder_init_items == false)
00708 {
00709
00710 rec_integer_clock = (TIMESTAMP)recorder_delta_clock;
00711 rec_microseconds = (int)((recorder_delta_clock-(int)(recorder_delta_clock))*1000000+0.5);
00712 if ( gl_localtime(rec_integer_clock,&rec_date_time)!=0 )
00713 {
00714 if ( global_dateformat[0]=='\0')
00715 gl_global_getvar("dateformat",global_dateformat,sizeof(global_dateformat));
00716 if ( strcmp(global_dateformat,"ISO")==0)
00717 sprintf(recorder_timestamp,"%04d-%02d-%02d %02d:%02d:%02d.%.06d %s",rec_date_time.year,rec_date_time.month,rec_date_time.day,rec_date_time.hour,rec_date_time.minute,rec_date_time.second,rec_microseconds,rec_date_time.tz);
00718 else if ( strcmp(global_dateformat,"US")==0)
00719 sprintf(recorder_timestamp,"%02d-%02d-%04d %02d:%02d:%02d.%.06d %s",rec_date_time.month,rec_date_time.day,rec_date_time.year,rec_date_time.hour,rec_date_time.minute,rec_date_time.second,rec_microseconds,rec_date_time.tz);
00720 else if ( strcmp(global_dateformat,"EURO")==0)
00721 sprintf(recorder_timestamp,"%02d-%02d-%04d %02d:%02d:%02d.%.06d %s",rec_date_time.day,rec_date_time.month,rec_date_time.year,rec_date_time.hour,rec_date_time.minute,rec_date_time.second,rec_microseconds,rec_date_time.tz);
00722 else
00723 sprintf(recorder_timestamp,"%.09f",recorder_delta_clock);
00724 }
00725 else
00726 sprintf(recorder_timestamp,"%.09f",recorder_delta_clock);
00727
00728
00729 recorder_init_items = true;
00730 }
00731
00732 obj = index_item->obj;
00733 myrec = (struct recorder *)OBJECTDATA(obj,struct recorder);
00734
00735
00736 if ((obj->in_svc_double <= gl_globaldeltaclock) && (obj->out_svc_double >= gl_globaldeltaclock))
00737 {
00738 if( read_properties(myrec, obj->parent,myrec->target,value,sizeof(value)) )
00739 {
00740 if ( !myrec->ops->write(myrec, recorder_timestamp, value) )
00741 {
00742 gl_error("recorder:%d: unable to write sample to file", obj->id);
00743 return FAILED;
00744 }
00745
00746
00747 myrec->last.ts = rec_integer_clock;
00748 myrec->last.ns = rec_microseconds;
00749
00750
00751 strcpy(myrec->last.value,value);
00752 }
00753 }
00754
00755 }
00756 else if (index_item->obj_type == GROUPRECORDER)
00757 {
00758
00759 obj = index_item->obj;
00760
00761
00762 temp_fxn = (FUNCTIONADDR)(gl_get_function(obj->oclass->name,"obj_postupdate_fxn"));
00763
00764 if (temp_fxn == NULL)
00765 {
00766 gl_error("Unable to map group_recorder postupdate function");
00767
00768
00769
00770
00771
00772
00773 return FAILED;
00774 }
00775
00776
00777 return_val = ((int (*)(OBJECT *,double))(*temp_fxn))(index_item->obj,gl_globaldeltaclock);
00778
00779
00780 if (return_val != 1)
00781 {
00782 gl_error("Failed to perform postupdate for group_recorder object");
00783
00784
00785
00786
00787
00788 return FAILED;
00789 }
00790
00791
00792 temp_fxn = NULL;
00793 }
00794
00795
00796
00797 index_item = index_item->next;
00798 }
00799
00800
00801 if (recorder_init_items == true)
00802 {
00803
00804 fflush(NULL);
00805 }
00806
00807
00808 delta_mode_needed = TS_NEVER;
00809
00810 index_item = delta_tape_objects;
00811
00812
00813 while (index_item != NULL)
00814 {
00815
00816 if (index_item->obj_type == PLAYER)
00817 {
00818 obj = index_item->obj;
00819 myplayer = (struct player *)OBJECTDATA(obj,struct player);
00820
00821
00822 if ((obj->in_svc_double <= gl_globaldeltaclock) && (obj->out_svc_double >= gl_globaldeltaclock))
00823 {
00824 if (( myplayer->next.ns!=0 ) && (myplayer->next.ts != t0))
00825 enable_deltamode(myplayer->next.ts);
00826 }
00827 }
00828
00829
00830
00831 index_item = index_item->next;
00832 }
00833
00834 return SUCCESS;
00835 }
00836
00837 int do_kill()
00838 {
00839
00840 return 0;
00841 }
00842