00001
00054 #ifndef _GRIDLABD_H
00055 #define _GRIDLABD_H
00056
00057 #ifdef HAVE_CONFIG_H
00058 #include "config.h"
00059 #endif
00060
00061 #ifdef WIN32
00062 #define HAVE_LIBCPPUNIT
00063 #endif
00064
00065 #ifdef __cplusplus
00066 #ifndef CDECL
00067 #define CDECL extern "C"
00068 #endif
00069 #else
00070 #define CDECL
00071 #endif
00072
00073 #ifdef WIN32
00074 #ifndef EXPORT
00075 #define EXPORT CDECL __declspec(dllexport)
00076 #endif
00077 #else
00078 #define EXPORT CDECL
00079 #endif
00080
00081 #include "schedule.h"
00082 #include "object.h"
00083 #include "find.h"
00084 #include "random.h"
00085
00086 #ifdef DLMAIN
00087 #define EXTERN
00088 #define INIT(X) =(X)
00089 #else
00090 #ifdef __cplusplus
00091 #define EXTERN
00092 #else
00093 #define EXTERN extern
00094 #endif
00095 #define INIT(X)
00096 #endif
00097 CDECL EXPORT EXTERN CALLBACKS *callback INIT(NULL);
00098 #undef INIT
00099 #undef EXTERN
00100
00101 #ifndef MODULENAME
00102 #define MODULENAME(obj) (obj->oclass->module->name)
00103 #endif
00104
00105
00106
00107
00136 #define PUBLISH_STRUCT(C,T,N) {struct C _t;if (gl_publish_variable(C##_class,PT_##T,#N,(char*)&_t.N-(char*)&_t,NULL)<1) return NULL;}
00137
00139 #define PUBLISH_CLASS(C,T,N) {class C _t;if (gl_publish_variable(C##_class,PT_##T,#N,(char*)&_t.N-(char*)&_t,NULL)<1) return NULL;}
00140
00142 #define PUBLISH_CLASSX(C,T,N,V) {class C _t;if (gl_publish_variable(C##_class,PT_##T,V,(char*)&_t.N-(char*)&_t,NULL)<1) return NULL;}
00143
00146
00150 #define PUBLISH_DELEGATED(C,T,N) {class C _t;if (gl_publish_variable(C##_class,PT_delegated,T,#N,(char*)&_t.N-(char*)&_t,NULL)<1) return NULL;}
00151
00154
00155
00158
00161 #define PADDR(X) ((char*)&(this->X)-(char*)this)
00162
00163
00164
00165
00205 #define GL_TRY { EXCEPTIONHANDLER *_handler = (*callback->exception.create_exception_handler)(); if (_handler==NULL) (*callback->output_error)("%s(%d): module exception handler creation failed",__FILE__,__LINE__); else if (setjmp(_handler->buf)==0) {
00206
00207
00208
00209
00215 #define GL_THROW (*callback->exception.throw_exception)
00216
00223 #define GL_CATCH(Msg) } else {Msg = (*callback->exception.exception_msg)();
00224
00226 #define GL_ENDCATCH } (*callback->exception.delete_exception_handler)(_handler);}
00227
00229
00230
00231
00241 #define gl_verbose (*callback->output_verbose)
00242
00246 #define gl_output (*callback->output_message)
00247
00251 #define gl_warning (*callback->output_warning)
00252
00256 #define gl_error (*callback->output_error)
00257
00258 #ifdef _DEBUG
00259
00262 #define gl_debug (*callback->output_debug)
00263 #else
00264 #define gl_debug
00265 #endif
00266
00270 #define gl_testmsg (*callback->output_test)
00271
00273
00274
00275
00287 #define gl_malloc (*callback->malloc)
00288
00290
00291
00292
00304 #define set_callback(CT) (callback=(CT))
00305
00309 #define gl_get_module_var (*callback->get_module_var)
00310
00314 #define gl_findfile (*callback->file.find_file)
00315
00316 #define gl_find_module (*callback->module_find)
00317
00318 #define gl_find_property (*callback->find_property)
00319
00324 #ifdef __cplusplus
00325 inline int gl_module_depends(char *name,
00326 unsigned char major=0,
00327 unsigned char minor=0,
00328 unsigned short build=0)
00329 {
00330 return (*callback->depends)(name,major,minor,build);
00331 }
00332 #else
00333 #define gl_module_depends (*callback->depends)
00334 #endif
00335
00336
00339
00340
00341
00353 #define gl_register_class (*callback->register_class)
00354
00356
00357
00358
00369 #define gl_create_object (*callback->create.single)
00370
00374 #define gl_create_array (*callback->create.array)
00375
00379 #define gl_create_foreign (*callback->create.foreign)
00380
00387 #ifdef __cplusplus
00388 inline bool gl_object_isa(OBJECT *obj,
00389 char *type,
00390 char *modname=NULL)
00391 { bool rv = (*callback->object_isa)(obj,type)!=0;
00392 bool mv = modname ? obj->oclass->module == (*callback->module_find)(modname) : true;
00393 return (rv && mv);}
00394 #else
00395 #define gl_object_isa (*callback->object_isa)
00396 #endif
00397
00401 #define gl_publish_variable (*callback->define_map)
00402
00406 #ifdef __cplusplus
00407 inline FUNCTION *gl_publish_function(CLASS *oclass,
00408 FUNCTIONNAME functionname,
00409 FUNCTIONADDR call)
00410 { return (*callback->function.define)(oclass, functionname, call);}
00411 inline FUNCTIONADDR gl_get_function(OBJECT *obj, char *name)
00412 { return obj?(*callback->function.get)(obj->oclass->name,name):NULL;}
00413 #else
00414 #define gl_publish_function (*callback->function.define)
00415 #define gl_get_function (*callback->function.get)
00416 #endif
00417
00424 #ifdef __cplusplus
00425 inline int gl_set_dependent(OBJECT *obj,
00426 OBJECT *dep)
00427 { return (*callback->set_dependent)(obj,dep);}
00428 #else
00429 #define gl_set_dependent (*callback->set_dependent)
00430 #endif
00431
00440 #ifdef __cplusplus
00441 inline int gl_set_parent(OBJECT *obj,
00442 OBJECT *parent)
00443 { return (*callback->set_parent)(obj,parent);}
00444 #else
00445 #define gl_set_parent (*callback->set_parent)
00446 #endif
00447
00456 #ifdef __cplusplus
00457 inline int gl_set_rank(OBJECT *obj,
00458 int rank)
00459 { return (*callback->set_rank)(obj,rank);}
00460 #else
00461 #define gl_set_rank (*callback->set_rank)
00462 #endif
00463
00466
00467
00468
00480 #define gl_register_type (*callback->register_type)
00481
00485 #define gl_publish_delegate (*callback->define_type)
00486
00490 #ifdef __cplusplus
00491 inline PROPERTY *gl_get_property(OBJECT *obj,
00492 PROPERTYNAME name)
00493 { return (*callback->properties.get_property)(obj,name); }
00494 #else
00495 #define gl_get_property (*callback->properties.get_property)
00496 #endif
00497
00501 #ifdef __cplusplus
00502 inline int gl_get_value(OBJECT *obj,
00503 void *addr,
00504 char *value,
00505 int size,
00506 PROPERTY *prop=NULL)
00507 { return (*callback->properties.get_value_by_addr)(obj,addr,value,size,prop);}
00508 #else
00509 #define gl_get_value (*callback->properties.get_value_by_addr)
00510 #endif
00511 #define gl_set_value_by_type (*callback->properties.set_value_by_type)
00512
00516 #ifdef __cplusplus
00517 inline int gl_set_value(OBJECT *obj,
00518 void *addr,
00519 char *value,
00520 PROPERTY *prop)
00521 { return (*callback->properties.set_value_by_addr)(obj,addr,value,prop);}
00522 #else
00523 #define gl_set_value (*callback->properties.set_value_by_addr)
00524 #endif
00525
00526 #ifdef __cplusplus
00527
00530 template <class T> inline int gl_set_value(OBJECT *obj,
00531 PROPERTY *prop,
00532 T &value)
00533 {
00534
00535 char buffer[256];
00536 T *ptr = (T *)((char *)(obj + 1) + (int64)(prop->addr));
00537
00538 if (ptr==NULL)
00539 GL_THROW("property %s not found in object %s", prop->name, gl_name(obj, buffer, 255));
00540 if(obj->oclass->notify){
00541 if(obj->oclass->notify(obj,NM_PREUPDATE,prop) == 0){
00542 gl_error("preupdate notify failure on %s in %s", prop->name, obj->name ? obj->name : "an unnamed object");
00543 }
00544 }
00545 *ptr = value;
00546 if(obj->oclass->notify){
00547 if(obj->oclass->notify(obj,NM_POSTUPDATE,prop) == 0){
00548 gl_error("postupdate notify failure on %s in %s", prop->name, obj->name ? obj->name : "an unnamed object");
00549 }
00550 }
00551 return 1;
00552 }
00553 #endif
00554
00558 #define gl_get_reference (*callback->properties.get_reference)
00559
00563 #ifdef __cplusplus
00564 inline int gl_get_value_by_name(OBJECT *obj,
00565 PROPERTYNAME name,
00566 char *value,
00567 int size)
00568 { return (*callback->properties.get_value_by_name)(obj,name,value,size);}
00569 #else
00570 #define gl_get_value_by_name (*callback->properties.get_value_by_name)
00571 #endif
00572
00573 #ifdef __cplusplus
00574 inline char *gl_getvalue(OBJECT *obj,
00575 PROPERTYNAME name)
00576 {
00577 static char buffer[1024];
00578 memset(buffer,0,sizeof(buffer));
00579 return gl_get_value_by_name(obj,name,buffer,sizeof(buffer))>=0 ? buffer : NULL;
00580 }
00581 #endif
00582
00586 #define gl_set_value_by_name (*callback->properties.set_value_by_name)
00587
00591 #define gl_get_unit (*callback->properties.get_unit)
00592
00596 #define gl_convert (*callback->unit_convert)
00597
00601 #define gl_convert_ex (*callback->unit_convert_ex)
00602
00603 #define gl_find_unit (*callback->unit_find)
00604
00605 #define gl_get_object (*callback->get_object)
00606
00607 #define gl_name_object (*callback->name_object)
00608
00609 #define gl_get_object_count (*callback->object_count)
00610
00611 #define gl_get_object_prop (*callback->objvar.object_var)
00612
00616 #define gl_get_complex (*callback->objvar.complex_var)
00617
00618 #define gl_get_complex_by_name (*callback->objvarname.complex_var)
00619
00620 #define gl_get_enum (*callback->objvar.enum_var)
00621
00622 #define gl_get_enum_by_name (*callback->objvarname.enum_var)
00623
00624 #define gl_get_int16 (*callback->objvar.int16_var)
00625
00626 #define gl_get_int16_by_name (*callback->objvarname.int16_var)
00627
00628 #define gl_get_int32_by_name (*callback->objvarname.int32_var)
00629
00630 #define gl_get_int32 (*callback->objvar.int32_var)
00631
00632 #define gl_get_int64_by_name (*callback->objvarname.int64_var)
00633
00634 #define gl_get_int64 (*callback->objvar.int64_var)
00635
00636 #define gl_get_double_by_name (*callback->objvarname.double_var)
00637
00638 #define gl_get_double (*callback->objvar.double_var)
00639
00640 #define gl_get_string_by_name (*callback->objvarname.string_var)
00641
00642 #define gl_get_string (*callback->objvar.string_var)
00643
00644 #define gl_get_addr (*callback->properties.get_addr)
00645
00648
00649
00650
00660 #define gl_find_objects (*callback->find.objects)
00661
00665 #define gl_find_next (*callback->find.next)
00666
00670 #define gl_findlist_copy (*callback->find.copy)
00671 #define gl_findlist_add (*callback->find.add)
00672 #define gl_findlist_del (*callback->find.del)
00673 #define gl_findlist_clear (*callback->find.clear)
00674
00677 #define gl_free (*callback->free)
00678
00682 #define gl_create_aggregate (*callback->create_aggregate)
00683
00687 #define gl_run_aggregate (*callback->run_aggregate)
00688
00690
00691
00692
00704 #define gl_randomtype (*callback->random.type)
00705
00709 #define gl_randomvalue (*callback->random.value)
00710
00714 #define gl_pseudorandomvalue (*callback->random.pseudo)
00715
00719 #define gl_random_uniform (*callback->random.uniform)
00720
00724 #define gl_random_normal (*callback->random.normal)
00725
00729 #define gl_random_lognormal (*callback->random.lognormal)
00730
00734 #define gl_random_bernoulli (*callback->random.bernoulli)
00735
00739 #define gl_random_pareto (*callback->random.pareto)
00740
00744 #define gl_random_sampled (*callback->random.sampled)
00745
00749 #define gl_random_exponential (*callback->random.exponential)
00750 #define gl_random_triangle (*callback->random.triangle)
00751 #define gl_random_gamma (*callback->random.gamma)
00752 #define gl_random_beta (*callback->random.beta)
00753 #define gl_random_weibull (*callback->random.weibull)
00754 #define gl_random_rayleigh (*callback->random.rayleigh)
00755
00757
00758
00759
00764 #define gl_globalclock (*(callback->global_clock))
00765
00769 #define gl_parsetime (*callback->time.convert_to_timestamp)
00770
00771 #define gl_printtime (*callback->time.convert_from_timestamp)
00772
00776 #define gl_mktime (*callback->time.mkdatetime)
00777
00781 #define gl_strtime (*callback->time.strdatetime)
00782
00786 #define gl_todays (*callback->time.timestamp_to_days)
00787
00791 #define gl_tohours (*callback->time.timestamp_to_hours)
00792
00796 #define gl_tominutes (*callback->time.timestamp_to_minutes)
00797
00801 #define gl_toseconds (*callback->time.timestamp_to_seconds)
00802
00806 #define gl_localtime (*callback->time.local_datetime)
00807
00808 #ifdef __cplusplus
00809 inline int gl_getweekday(TIMESTAMP t)
00810 {
00811 DATETIME dt;
00812 gl_localtime(t, &dt);
00813 return dt.weekday;
00814 }
00815 inline int gl_gethour(TIMESTAMP t)
00816 {
00817 DATETIME dt;
00818 gl_localtime(t, &dt);
00819 return dt.hour;
00820 }
00821 #endif
00822
00823
00824
00825
00833 #define gl_global_create (*callback->global.create)
00834
00838 #define gl_global_setvar (*callback->global.setvar)
00839
00843 #define gl_global_getvar (*callback->global.getvar)
00844
00848 #define gl_global_find (*callback->global.find)
00849
00851 #define gl_get_oflags (*callback->get_oflags)
00852
00853 #ifdef __cplusplus
00854
00858 inline double clip(double x,
00859 double a,
00860 double b)
00861 {
00862 if (x<a) return a;
00863 else if (x>b) return b;
00864 else return x;
00865 }
00866
00870 inline char bitof(unsigned int64 x,
00871 bool use_throw=false)
00872 {
00873 char n=0;
00874 if (x==0)
00875 {
00876 if (use_throw)
00877 throw "bitof empty bit pattern";
00878 return -0x7f;
00879 }
00880 while ((x&1)==0)
00881 {
00882 x>>=1;
00883 n++;
00884 }
00885 if (x!=0)
00886 {
00887 if (use_throw)
00888 throw "bitof found more than one bit";
00889 else
00890 return -n;
00891 }
00892 return n;
00893 }
00894 inline char* gl_name(OBJECT *my, char *buffer, size_t size)
00895 {
00896 char temp[256];
00897 if(my == NULL || buffer == NULL) return NULL;
00898 if (my->name==NULL)
00899 sprintf(temp,"%s:%d", my->oclass->name, my->id);
00900 else
00901 sprintf(temp,"%s", my->name);
00902 if(size < strlen(temp))
00903 return NULL;
00904 strcpy(buffer, temp);
00905 return buffer;
00906 }
00907
00908 inline SCHEDULE *gl_schedule_find(char *name)
00909 {
00910 return callback->schedule.find(name);
00911 }
00912
00913 inline SCHEDULE *gl_schedule_create(char *name, char *definition)
00914 {
00915 return callback->schedule.create(name,definition);
00916 }
00917
00918 inline SCHEDULEINDEX gl_schedule_index(SCHEDULE *sch, TIMESTAMP ts)
00919 {
00920 return callback->schedule.index(sch,ts);
00921 }
00922
00923 inline double gl_schedule_value(SCHEDULE *sch, SCHEDULEINDEX index)
00924 {
00925 return callback->schedule.value(sch,index);
00926 }
00927
00928 inline long gl_schedule_dtnext(SCHEDULE *sch, SCHEDULEINDEX index)
00929 {
00930 return callback->schedule.dtnext(sch,index);
00931 }
00932
00933 inline int gl_enduse_create(enduse *e)
00934 {
00935 return callback->enduse.create(e);
00936 }
00937
00938 inline TIMESTAMP gl_enduse_sync(enduse *e, TIMESTAMP t1)
00939 {
00940 return callback->enduse.sync(e,PC_BOTTOMUP,t1);
00941 }
00942
00943 inline loadshape *gl_loadshape_create(SCHEDULE *s)
00944 {
00945 loadshape *ls = (loadshape*)malloc(sizeof(loadshape));
00946 memset(ls,0,sizeof(loadshape));
00947 if (0 == callback->loadshape.create(ls)){
00948 return NULL;
00949 }
00950 ls->schedule = s;
00951 return ls;
00952 }
00953
00954 inline double gl_get_loadshape_value(loadshape *shape)
00955 {
00956 if (shape)
00957 return shape->load;
00958 else
00959 return 0;
00960 }
00961
00962 inline char *gl_strftime(DATETIME *dt, char *buffer, int size) { return callback->time.strdatetime(dt,buffer,size)?buffer:NULL;};
00963 inline char *gl_strftime(TIMESTAMP ts)
00964 {
00965 static char buffer[64];
00966 strcpy(buffer,"(invalid time)");
00967 DATETIME dt;
00968 if(gl_localtime(ts,&dt)){
00969 gl_strftime(&dt,buffer,sizeof(buffer));
00970 }
00971 return buffer;
00972 }
00973 #endif //__cplusplus
00974
00975
00977
00978
00979
00987 #define gl_lerp (*callback->interpolate.linear)
00988
00993 #define gl_qerp (*callback->interpolate.quadratic)
00994
00998 #endif