Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

gel.C

Go to the documentation of this file.
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 // Static constructors can be the spawn of satan.
00029 // We don't know when someone will reference distobs_list or existobs_list,
00030 // so we have to protect by making the class allocate these objects as
00031 // soon as they are referenced (during static initialization).
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   // XXX -- we hate this, potential memory leak
00049   REFlock lock(this);
00050   if (EXIST.allocated())
00051     EXIST.add(this); 
00052 }
00053 
00054 GEL::GEL(CGELptr &oldg)
00055 {
00056    // XXX -- we hate this, potential memory leak
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    // This deals with the possibility that inside of a tick, one or
00116    // more objects may be unscheduled.  Thus, we can't remove them
00117    // from the list until the end of the tick.
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    // XXX - 
00145    //
00146    //   The stored index value is incorrect because SCHEDULER
00147    //   code has bugs that don't keep the value up to date...
00148    //
00149    //   Use the "slow" way of accessing the index instead:
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       // not currently scheduled, so schedule it:
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    // do nothing if nothing to do:
00185    if (!is_scheduled(o))
00186       return;
00187 
00188    // If we're ticking, we can't remove it.  
00189    // We put it in the list, to be removed later.
00190    if (_ticking) {
00191       _unscheduled.add_uniquely(o);
00192       return;
00193    }
00194 
00195    // do it:
00196    int idx = get_index(o);
00197    assert(idx >= 0);
00198    // setIndex() must be done here in case the remove() call destroys o
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 // ---------------- Define the DrawnLists's functions 
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); // Displayed
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); // Undisplay
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 // ---------------- Define the ExistList's functions 
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 // Gets a unique name for a duplicate of an object
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 // Gets a unique name for an object
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 /* ---- DISPobs routines----- */
00347 
00348 DISPobs_list DISPobs::_all_disp(32);
00349 HASH         DISPobs::_hash_disp(32);
00350 int          DISPobs::_suspend_disp = 0;
00351 
00352 /* -------------------------------------------------------------
00353  *
00354  * DISPobs
00355  *
00356  *   This class provides callbacks when an object's displayed or
00357  * undisplayed.
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    // Notify observers who want to know about all undisplays
00370    for (i = 0; i < _all_disp.num(); i++)
00371       _all_disp[i]->notify(g, disp);
00372 
00373    // Notify observers who want to know about undisplays of this object
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 }

Generated on Mon Sep 18 11:39:29 2006 for jot by  doxygen 1.4.4