00001 #include "geom/distrib.H"
00002 #include "std/config.H"
00003 #include "gel_filt.H"
00004 #include "ray.H"
00005 #include "jot_vars.H"
00006
00007 using namespace mlib;
00008
00009 #define MAKE_HASHVAR(NAME, TYPE, VAL) hashvar<TYPE> NAME(#NAME, VAL, 0)
00010
00011 GrabVar GRABBED;
00012 MAKE_HASHVAR (NETWORK, int, 0);
00013 MAKE_NET_HASHVAR(NO_COLOR_MOD, int, 0);
00014 MAKE_NET_HASHVAR(NO_XFORM_MOD, int, 0);
00015 MAKE_NET_HASHVAR(NO_DISP_MOD, int, 0);
00016 MAKE_NET_HASHVAR(NO_SCALE_MOD, int, 0);
00017 MAKE_NET_HASHVAR(NO_COPY, int, 0);
00018 MAKE_NET_HASHVAR(NO_EXTNETWORK, int, 0);
00019 MAKE_NET_HASHVAR(PICKABLE, int, 1);
00020 MAKE_NET_HASHVAR(NO_SAVE, int, 0);
00021 MAKE_NET_HASHVAR(NO_CONSTRAINT_MOD, int, 0);
00022 MAKE_NET_HASHVAR(CONSTRAINT_VECTOR, Wvec, Wvec(0,1,0));
00023 MAKE_NET_HASHVAR(CONSTRAINT_POINT, Wpt, Wpt (0,0,0));
00024
00025 Cstr_ptr GEL::_name("work'er");
00026 TAGlist *GEL::_gel_tags = 0;
00027
00028
00029
00030
00031
00032 GELdistobs_list *GELdistobs::_dist_obs = 0;
00033 EXISTobs_list *EXISTobs::_exist_obs = 0;
00034 DUPobs_list *DUPobs::_dup_obs = 0;
00035 GRABobs_list *GRABobs::_grab_obs = 0;
00036 SAVEobs_list *SAVEobs::_save_obs = 0;
00037 SAVEobs_list *SAVEobs::_presave_obs = 0;
00038 SAVEobs_list *SAVEobs::_postsave_obs= 0;
00039 LOADobs_list *LOADobs::_load_obs = 0;
00040 LOADobs_list *LOADobs::_preload_obs = 0;
00041 LOADobs_list *LOADobs::_postload_obs= 0;
00042 HASHobs_list *HASHobs::_hash_obs_list=0;
00043 JOTvar_obs_list *JOTvar_obs::_jot_var_obs_list = 0;
00044
00045
00046 GEL::GEL():DATA_ITEM(1)
00047 {
00048
00049 REFlock lock(this);
00050 if (EXIST.allocated())
00051 EXIST.add(this);
00052 }
00053
00054 GEL::GEL(CGELptr &oldg)
00055 {
00056
00057 REFlock lock(this);
00058 if (EXIST.allocated())
00059 EXIST.add(this);
00060 DUPobs::notify_dup_obs(oldg, this);
00061 }
00062
00063 GEL::~GEL()
00064 {
00065 static bool debug =
00066 Config::get_var_bool("JOT_REPORT_GEL_DESTRUCTOR",false,true);
00067 if (debug)
00068 cerr << "~GEL" << endl;
00069 }
00070
00071 RAYhit &
00072 GEL::intersect(
00073 RAYhit &r,
00074 CWtransf &,
00075 int
00076 ) const
00077 {
00078 return r;
00079 }
00080
00081 RAYnear &
00082 GEL::nearest (
00083 RAYnear &r,
00084 CWtransf &
00085 ) const
00086 {
00087 return r;
00088 }
00089
00090 STDdstream &
00091 operator>>(STDdstream &ds, GELptr &p)
00092 {
00093 DATA_ITEM *d = DATA_ITEM::Decode(ds);
00094 if (d && GEL::isa(d))
00095 p = (GEL *)d;
00096 else {
00097 cerr << "operator >> Couldn't find GEL in stream" << endl;
00098 p = 0;
00099 }
00100
00101 return ds;
00102 }
00103
00104 STDdstream &
00105 operator<<(STDdstream &d, const GEL *p)
00106 {
00107 return d << p->name();
00108 }
00109
00110 static const bool debug = Config::get_var_bool("DEBUG_SCHEDULER",false);
00111
00112 int
00113 SCHEDULER::tick(void)
00114 {
00115
00116
00117
00118 _ticking = 1;
00119 for (int i=_scheduled.num()-1; i>=0; i--) {
00120 if (!_unscheduled.contains(_scheduled[i])) {
00121 if (_scheduled[i]->tick() == -1) {
00122 unschedule(_scheduled[i]);
00123 }
00124 }
00125 }
00126 _ticking = 0;
00127
00128 while (!_unscheduled.empty()) {
00129 unschedule(_unscheduled.pop());
00130 }
00131
00132 return _scheduled.empty() ? -1 : 1;
00133 }
00134
00135 bool
00136 SCHEDULER::is_scheduled(CFRAMEobsptr& o) const
00137 {
00138 return get_index(o) >= 0;
00139 }
00140
00141 int
00142 SCHEDULER::get_index(CFRAMEobsptr& o) const
00143 {
00144
00145
00146
00147
00148
00149
00150 return _scheduled.get_index(o);
00151 }
00152
00153 void
00154 SCHEDULER::schedule(CFRAMEobsptr &o)
00155 {
00156 if (_unscheduled.contains(o)) {
00157 if (debug) {
00158 cerr << "SCHEDULER::schedule: object " << o
00159 << " was in unscheduled list" << endl;
00160 }
00161 _unscheduled -= o;
00162 }
00163 if (is_scheduled(o)) {
00164 if (debug) {
00165 cerr << "SCHEDULER::schedule: object " << o
00166 << " was already scheduled " << endl;
00167 }
00168 } else {
00169
00170 _scheduled += o;
00171 if (debug) {
00172 cerr << "SCHEDULER::schedule: scheduled object " << o << endl;
00173 }
00174 }
00175 if (debug) {
00176 cerr << "scheduled list: " << endl
00177 << _scheduled << endl;
00178 }
00179 }
00180
00181 void
00182 SCHEDULER::unschedule(CFRAMEobsptr &o)
00183 {
00184
00185 if (!is_scheduled(o))
00186 return;
00187
00188
00189
00190 if (_ticking) {
00191 _unscheduled.add_uniquely(o);
00192 return;
00193 }
00194
00195
00196 int idx = get_index(o);
00197 assert(idx >= 0);
00198
00199 ((FRAMEobsptr&)o)->setIndex(-1);
00200 _scheduled.remove(idx);
00201 if (_scheduled.valid_index(idx))
00202 _scheduled[idx]->setIndex(idx);
00203 }
00204
00205
00206 GELlist
00207 GELlist::filter(GELFILT& f) const
00208 {
00209 GELlist ret;
00210 for (int i=0; i<_num; i++)
00211 if (f.accept(_array[i]))
00212 ret += _array[i];
00213 return ret;
00214 }
00215
00216
00217
00218 DrawnList DRAWN;
00219
00220 void
00221 DrawnList::add(
00222 CGELptr &g
00223 )
00224 {
00225 if (g) {
00226 if (buffering())
00227 _dispq += DispOp(g, true);
00228 else {
00229 GELlist::add_uniquely(g);
00230 DISPobs::notify_disp_obs(g, 1);
00231 }
00232 }
00233 }
00234
00235 void
00236 DrawnList::rem(
00237 CGELptr &g
00238 )
00239 {
00240 if (g) {
00241 if (buffering())
00242 _dispq += DispOp(g, 0);
00243 else {
00244 GELlist::rem(g);
00245 DISPobs::notify_disp_obs(g, 0);
00246 }
00247 }
00248 }
00249
00250 GELptr
00251 DrawnList::lookup(
00252 Cstr_ptr &s
00253 ) const
00254 {
00255 for (int i = 0; i < num(); i++)
00256 if (s == (*this)[i]->name())
00257 return (*this)[i];
00258 return GELptr();
00259 }
00260
00261 void
00262 DrawnList::flush()
00263 {
00264 _buffering = 0;
00265 int i;
00266 for (i = 0; i < _dispq.num(); i++) {
00267 if (_dispq[i]._op) add(_dispq[i]._gel);
00268 else rem(_dispq[i]._gel);
00269 }
00270 _dispq.clear();
00271 }
00272
00273
00274
00275 ExistList EXIST;
00276
00277 void
00278 ExistList::add(
00279 CGELptr &g
00280 )
00281 {
00282 if (g)
00283 GELlist::add_uniquely(g);
00284 }
00285
00286 void
00287 ExistList::rem(
00288 CGELptr &g
00289 )
00290 {
00291 if (g)
00292 GELlist::rem(g);
00293 }
00294
00295 GELptr
00296 ExistList::lookup(
00297 Cstr_ptr &s
00298 ) const
00299 {
00300 for (int i = 0; i < num(); i++)
00301 if (s == (*this)[i]->name())
00302 return (*this)[i];
00303 return GELptr();
00304 }
00305
00306
00307
00308
00309 str_ptr
00310 ExistList::unique_dupname(
00311 Cstr_ptr &buff
00312 ) const
00313 {
00314 static char nbuff[255];
00315 int count = 0;
00316
00317 sprintf(nbuff, "C%d_%s", count++, **buff);
00318
00319 while (lookup(nbuff))
00320 sprintf(nbuff, "C%d_%s", count++, **buff);
00321
00322 return nbuff;
00323 }
00324
00325
00326
00327
00328 str_ptr
00329 ExistList::unique_name(
00330 Cstr_ptr &pref
00331 ) const
00332 {
00333 static char nbuff[255];
00334 static char buff [255];
00335 int count = 1;
00336 gethostname(buff, 255);
00337
00338 sprintf(nbuff, "%s_%d(%s)", **pref, count++, buff);
00339
00340 while (lookup(nbuff))
00341 sprintf(nbuff, "%s_%d(%s)", **pref, count++, buff);
00342
00343 return nbuff;
00344 }
00345
00346
00347
00348 DISPobs_list DISPobs::_all_disp(32);
00349 HASH DISPobs::_hash_disp(32);
00350 int DISPobs::_suspend_disp = 0;
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 void
00361 DISPobs::notify_disp_obs(
00362 CGELptr &g,
00363 int disp
00364 )
00365 {
00366 if (_suspend_disp || WORLD::is_over())
00367 return;
00368 int i;
00369
00370 for (i = 0; i < _all_disp.num(); i++)
00371 _all_disp[i]->notify(g, disp);
00372
00373
00374 CDISPobs_list obj_obs = disp_obs_list((GEL *)&*g);
00375 for (i = 0; i < obj_obs.num(); i++)
00376 obj_obs[i]->notify(g, disp);
00377 }
00378
00379
00380 void
00381 SAVEobs::notify_save_obs(
00382 NetStream &s,
00383 save_status_t &status,
00384 bool to_file,
00385 bool full_scene)
00386 {
00387 int i;
00388 distrib();
00389 status = SAVE_ERROR_NONE;
00390 for (i=0; i<presaveobs_list()->num(); i++)
00391 (*_presave_obs)[i]->notify_presave(s, status, to_file, full_scene);
00392 for (i=0; i<saveobs_list()->num(); i++)
00393 (*_save_obs)[i]->notify_save(s, status, to_file, full_scene);
00394 for (i=0; i<postsaveobs_list()->num(); i++)
00395 (*_postsave_obs)[i]->notify_postsave(s, status, to_file, full_scene);
00396 }
00397
00398 void
00399 LOADobs::notify_load_obs(
00400 NetStream &s,
00401 load_status_t &status,
00402 bool to_file,
00403 bool full_scene )
00404 {
00405 int i;
00406 distrib();
00407 status = LOAD_ERROR_NONE;
00408 for (i=0; i<preloadobs_list()->num(); i++)
00409 (*_preload_obs)[i]->notify_preload(s, status, to_file, full_scene);
00410 for (i=0; i<loadobs_list()->num(); i++)
00411 (*_load_obs)[i]->notify_load(s, status, to_file, full_scene);
00412 for (i=0; i<postloadobs_list()->num(); i++)
00413 (*_postload_obs)[i]->notify_postload(s, status, to_file, full_scene);
00414 }