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

distrib.C

Go to the documentation of this file.
00001 #include "disp/action.H"
00002 #include "distrib.H"
00003 #include "geom/world.H" 
00004 #include "geom/gl_view.H"
00005 #include "geom/texturegl.H"
00006 #include "std/config.H"
00007 
00008 using namespace mlib;
00009 
00010 /*****************************************************************
00011  * Globals
00012  *****************************************************************/
00013 
00014 hashvar<int>   net_read_in_progress("NET_READ_IN_PROGRESS", 0, 0, 0);
00015 
00016 // Gloval used to let NETcontext objects know who broadcasted object...
00017 NetStream*     broadcaster = 0;
00018 
00019 static bool debug = Config::get_var_bool("DEBUG_DISTRIB",false);
00020 
00021 /*****************************************************************
00022  * Function items for networking
00023  *****************************************************************/
00024 // 
00025 // These are commands that can be sent over the net or read from a file
00026 //
00027 
00028 /*************************************
00029  * JOTdone
00030  *************************************/
00031 class JOTdone : public FUNC_ITEM 
00032 {
00033  public:
00034    JOTdone() :FUNC_ITEM("DONE") { }
00035    virtual STDdstream &format(STDdstream &ds) const 
00036    { 
00037       if (ds.ascii())
00038       {
00039          return ds << NETflush;
00040       }
00041       else
00042       {
00043          return DATA_ITEM::format(ds) << NETflush; 
00044       }
00045    }
00046    virtual void        put(TAGformat  &)   const { }
00047    virtual void        get(TAGformat  &)         { }
00048 };
00049 
00050 /*************************************
00051  * JOTclip_info
00052  *************************************/
00053 class JOTclip_info : public FUNC_ITEM 
00054 {
00055 public:
00056   JOTclip_info() : FUNC_ITEM("CLIP_INFO") {}
00057   virtual void  put(TAGformat &d) const 
00058   { 
00059      VIEW *v = VIEW::peek();
00060      *d << (int) v->is_clipping() << v->clip_plane();
00061   }
00062   virtual void  get (TAGformat &d) 
00063   {
00064     int clipping; Wplane cplane;
00065     *d >> clipping >> cplane;
00066      VIEW *v = VIEW::peek();
00067      v->set_clip_plane(cplane);
00068      v->set_is_clipping(clipping==1);
00069   }
00070 };
00071 
00072 /*************************************
00073  * JOTrender_mode
00074  *************************************/
00075 class JOTrender_mode : public FUNC_ITEM 
00076 {
00077  public:
00078    JOTrender_mode() : FUNC_ITEM("RENDER_MODE") { }
00079    virtual void  put(TAGformat &d) const 
00080    { 
00081       *d << VIEW::peek()->rendering();
00082       err_adv(debug, 
00083          "JOTrender_mode::put() - Pushing rendering mode: '%s'", 
00084             **VIEW::peek()->rendering());
00085    }
00086    virtual void  get (TAGformat &d) 
00087    {
00088       str_ptr mode;
00089       *d >> mode;
00090       VIEW::peek()->set_rendering(mode);
00091       err_adv(debug, 
00092          "JOTrender_mode::put() - Setting rendering mode from network to: '%s'", 
00093             **mode);
00094    }
00095 };
00096 
00097 /*************************************
00098  * JOTupdate_geom
00099  *************************************/
00100 class JOTupdate_geom : public FUNC_ITEM 
00101 {
00102  protected:
00103    GELptr _g;
00104  public: 
00105    JOTupdate_geom(CGELptr &g):FUNC_ITEM("UPDATE_GEOM"), _g(g)  { }
00106    virtual void       put(TAGformat  &d)   const { *d << _g; _g->format(*d);}
00107    virtual void       get(TAGformat  &d)         
00108    { 
00109       *d >> _g;
00110       if (_g) 
00111       {
00112          str_ptr str; 
00113          *d >> str; // skip over unneeded class name
00114          _g->decode(*d);
00115       }
00116    }
00117 };
00118 
00119 /*************************************
00120  * JOTsend_geom
00121  *************************************/
00122 class JOTsend_geom : public FUNC_ITEM 
00123 {
00124  protected:
00125    GELptr _g;
00126  public: 
00127    JOTsend_geom(CGELptr &g):FUNC_ITEM("SEND_GEOM"), _g(g)  { }
00128    virtual STDdstream &format(STDdstream &ds) const 
00129    { 
00130      _g->format(ds);
00131      GELdistobs::notify_distrib_obs(ds,_g);
00132      return ds;
00133    }
00134    virtual STDdstream &decode(STDdstream &ds)   
00135    { 
00136       err_msg("JOTsend_geom::decode() - *ERROR* Should not be here!!");
00137       return ds;
00138    }
00139    virtual void       put(TAGformat  &)      const { }
00140    virtual void       get(TAGformat  &)            { }
00141 };
00142 
00143 
00144 /*************************************
00145  * JOThash
00146  *************************************/
00147 class JOThash : public FUNC_ITEM 
00148 {
00149  protected:
00150    GELptr    _g;
00151    hashdist *_h;
00152  public:
00153    JOThash(CGELptr &g, hashdist *h) : FUNC_ITEM("HASH"), _g(g), _h(h) {}
00154    virtual void  put(TAGformat &d) const {_h->notify_distrib(*d,_g); }
00155    virtual void  get(TAGformat &d)       { DATA_ITEM::Decode(*d); }
00156 };
00157 
00158 /*************************************
00159  * JOTtexture
00160  *************************************/
00161 class JOTtexture : public FUNC_ITEM 
00162 {
00163  protected:
00164    GEOMptr    _g;
00165  public:
00166    JOTtexture(CGEOMptr &g) : FUNC_ITEM("TEXTURE"), _g(g) {}
00167    virtual void  put(TAGformat &d) const 
00168    {
00169       *d << _g << (int)_g->has_texture();
00170       if (_g->has_texture())  // bogus!! (put_texture should *always* send _has_texture)
00171          _g->put_texture(d);
00172    }
00173    virtual void  get(TAGformat &d)       
00174    {
00175       int      has_texture;
00176       *d >> _g >> has_texture;
00177       if (_g && GEOM::isa(_g)) 
00178       {
00179          GEOMptr geom((GEOM *)&* _g);
00180          if (has_texture)  // bogus!! (_has_texture shouldn't be 'implicit' in get/put_texture)
00181             geom->get_texture(d);
00182          else
00183             geom->unset_texture();
00184          TEXTUREobs::notify_texture_obs(geom);
00185       }
00186    }
00187 };
00188 
00189 /*************************************
00190  * JOTxform
00191  *************************************/
00192 // Will xform a GEOM
00193 class JOTxform : public FUNC_ITEM 
00194 {
00195  protected:
00196    GEOMptr _g;
00197  public:
00198    JOTxform(CGEOMptr &g) : FUNC_ITEM("XFORM"), _g(g){}
00199    virtual void  put(TAGformat &d) const { *d<< _g << _g->xform();}
00200    virtual void  get (TAGformat &d) 
00201    {
00202       Wtransf xform;
00203       *d >> _g >> xform;
00204       if (_g && GEOM::isa(_g)) 
00205       {
00206          GEOMptr geom((GEOM *)&* _g);
00207          geom->set_xform(xform);
00208          XFORMobs::notify_xform_obs(geom, XFORMobs::NET);
00209       }
00210    }
00211 };
00212 
00213 
00214 /*************************************
00215  * JOTcam
00216  *************************************/
00217 // Network command for camera location
00218 class JOTcam : public FUNC_ITEM {
00219  protected:
00220    CAMdataptr _cam;
00221    DISTRIB   *_d;
00222  public:
00223    JOTcam(CCAMdataptr &cam, DISTRIB *d = 0):FUNC_ITEM("CHNG_CAM"), _cam(cam), _d(d) { }
00224    virtual void  put(TAGformat &d)      const { *d << _cam; }
00225    virtual void  get(TAGformat &d)
00226    {
00227       CAMdataptr cam(VIEWS[0]->cam()->data());
00228       *d >> cam;
00229       _d->set_cam_loaded();
00230    }
00231 };
00232 
00233 /*************************************
00234  * JOTwin
00235  *************************************/
00236 // Network command for window things (width,height)
00237 // XXX - Added so we can load window size from files,
00238 // but not presently observed for distribution...
00239 class JOTwin : public FUNC_ITEM 
00240 {
00241  protected:
00242    WINSYS*  _win;
00243  public:
00244    JOTwin(WINSYS* win):FUNC_ITEM("CHNG_WIN"), _win(win) { }
00245    virtual void  put(TAGformat &d)      const   { assert(_win); *_win >> *d; }
00246    virtual void  get(TAGformat &d)              { *(VIEWS[0]->win()) << *d; }
00247 };
00248 
00249 /*************************************
00250  * JOTview
00251  *************************************/
00252 // Network command for view things (bkg, lights, anim)
00253 // XXX - Added so we can load from files,
00254 // but not presently observed for distribution...
00255 class JOTview : public FUNC_ITEM {
00256  public: 
00257    JOTview(CVIEWptr &v) : FUNC_ITEM("CHNG_VIEW"), _v(v) {}
00258 
00259    virtual void put(TAGformat  &d) const { _v->format(*d);}
00260    virtual void get(TAGformat  &d) {
00261       str_ptr str;
00262       *d >> str;
00263       VIEWS[0]->decode(*d);
00264    }
00265 
00266  protected:
00267    VIEWptr _v;
00268 };
00269 
00270 /*************************************
00271  * JOTcreate
00272  *************************************/
00273 // Network command for creating a new object
00274 class JOTcreate : public FUNC_ITEM {
00275  protected:
00276    GELptr  _g;
00277  public:
00278    JOTcreate(CGELptr &g) : FUNC_ITEM("CREATE"), _g(g) { }
00279    virtual void  put(TAGformat &d) const              { *d << _g->name(); }
00280    virtual void  get(TAGformat &d)
00281    {
00282       str_ptr name;
00283       *d >> name;
00284       GELlist gels(1);
00285       int i;
00286       // Get all GEL's with name
00287       for (i = 0; i < EXIST.num(); i++)
00288       {
00289          if (name == EXIST[i]->name()) gels += EXIST[i];
00290       }
00291       if (gels.empty()) 
00292       {
00293          _g = GELptr();
00294       }
00295       else 
00296       {
00297          // Destroy all but last GEL with name
00298          for (i = 0; i < gels.num()-1; i++) 
00299          {
00300             err_msg("JOTcreate::get() - Destroying a GEL named: '%s'", **name);
00301 
00302             WORLD::destroy(gels[i]);
00303          }
00304          // Create last GEL with name
00305          _g = gels[gels.num() -1];
00306       }
00307       if (_g) 
00308       {
00309             // Don't want to get in a loop by resending this JOTcreate,
00310             // so we just turn off networking of this object temporarily
00311             // Note that if we suspended all display observers then this
00312             // object wouldn't appear locally
00313             // XXX - assumes no nested net reads
00314    
00315             // XXX - Hack to make sure we aren't reading from a file, if we
00316             // don't do this, distributing after reading from a file looks
00317             // like a loop to be avoided
00318             // XXX - assume that our STDdstream is a NetStream
00319             NetStream *ns = (NetStream *) &*d;
00320             if (ns->port() > 0)
00321                net_read_in_progress.set(_g, 1);
00322             WORLD::create(_g);
00323             net_read_in_progress.del(_g);
00324       } 
00325       else 
00326       {
00327          err_msg("JOTcreate::get() - Couldn't create: '%s'", **name);
00328       }
00329    }
00330 };
00331 
00332 /*************************************
00333  * JOTio
00334  *************************************/
00335 // Network command issued at start of file IO
00336 // XXX - Added to assist issues with loading/saving streams to/from files 
00337 // but likely not well behaved in distributed networked settings...
00338 class JOTio : public FUNC_ITEM {
00339    public: 
00340      JOTio(IOManager *io):FUNC_ITEM("CHNG_IO"), _io(io)  { }
00341       virtual void       put(TAGformat  &d)   const { _io->format(*d);}
00342       virtual void       get(TAGformat  &d)   { str_ptr str; *d >> str; IOManager::instance()->decode(*d); }
00343    protected:
00344       IOManager *_io;
00345 };
00346 
00347 
00348 /*************************************
00349  * JOTgrab
00350  *************************************/
00351 // grab/release an object - for object contention
00352 // this works differently than most funcs because it expects that 
00353 // different things will happen on different clients when messages are
00354 // decoded -- thus global networking is maintained on except to for 
00355 // not repeating a network broadcast of the decoded message.  
00356 //   Most other network operations expect the same result to occur
00357 // on each machine and thus can globally turn off networking when 
00358 // they are decoding.
00359 class JOTgrab: public FUNC_ITEM 
00360 {
00361  protected:
00362    GELptr    _g; 
00363    int       _grab;
00364  public:
00365    static GELptr   _save;  // allow networking of everything but 
00366                            // a repeat of this object's grab operation
00367    JOTgrab(CGELptr &g, int grab) : FUNC_ITEM("GRAB"), _g(g), _grab(grab) {}
00368    virtual void  put(TAGformat &d) const { *d << _g << _grab; }
00369    virtual void  get (TAGformat &d) 
00370    {
00371       *d >> _g >> _grab;
00372       if (_g) 
00373       {
00374          _save = _g;
00375          // enable networking
00376          DISTRIB::get_distrib()->set_processing_gate(false);
00377          if (_grab)  
00378             GRABBED.grab(_g);
00379          else 
00380             GRABBED.release(_g);
00381          _save = 0;
00382          // disable networking
00383          DISTRIB::get_distrib()->set_processing_gate(true);
00384       }
00385    }
00386 };
00387 GELptr JOTgrab::_save = 0;
00388 
00389 
00390 /*************************************
00391  * JOTcolor
00392  *************************************/
00393 // Change a GEOM's color
00394 class JOTcolor: public FUNC_ITEM 
00395 {
00396  protected:
00397    GEOMptr _g;
00398  public:
00399    JOTcolor(CGEOMptr &g) : FUNC_ITEM("COLOR"), _g(g) {}
00400    virtual void  put(TAGformat &d) const { *d << _g << _g->color();}
00401    virtual void  get (TAGformat &d)      
00402    { 
00403       COLOR    col;
00404       *d >> _g >> col;
00405       if (_g) _g->set_color(col); 
00406    }
00407 };
00408 
00409 /*************************************
00410  * JOTdisplay
00411  *************************************/
00412 // Display/undisplay an object
00413 class JOTdisplay : public FUNC_ITEM 
00414 {
00415  protected:
00416    int    _disp;
00417    GELptr _g;
00418  public:
00419    JOTdisplay(CGELptr &g, int display = 1) : FUNC_ITEM("DISPLAY"), _disp(display), _g(g) {}
00420    virtual void  put(TAGformat &d) const { *d << _g << _disp; }
00421    virtual void  get (TAGformat &d)      
00422    { 
00423       *d >> _g >> _disp;
00424       if (_g) 
00425       {
00426          if (_disp) WORLD::display  (_g);
00427          else WORLD::undisplay(_g);
00428       } 
00429    }
00430 };
00431 
00432 /*************************************
00433  * JOTdestroy
00434  *************************************/
00435 // Destroy an object
00436 class JOTdestroy : public FUNC_ITEM 
00437 {
00438  protected:
00439    GELptr _g;
00440  public:
00441    JOTdestroy(CGELptr &g) : FUNC_ITEM("DESTROY"),_g(g) {}
00442    virtual void  put(TAGformat &d) const { *d<<_g; }
00443    virtual void  get (TAGformat &d)      
00444    { 
00445       *d>>_g; 
00446       if(_g) 
00447       {
00448          WORLD::destroy(_g);
00449       }
00450       else  
00451       {
00452          err_msg("JOTdestroy::get() - Couldn't find GEL to destroy");
00453       }
00454    }
00455 
00456 };
00457 
00458 /*************************************
00459  * JOTtransp
00460  *************************************/
00461 // Change an object's transparency
00462 class JOTtransp : public FUNC_ITEM 
00463 {
00464  protected:
00465    GEOMptr _g;
00466  public:
00467    JOTtransp(CGEOMptr &g) : FUNC_ITEM("TRANSP"), _g(g) {}
00468    virtual void  put(TAGformat &d) const 
00469    { 
00470       *d << _g << _g->has_transp() << _g->transp(); 
00471    }
00472    virtual void  get (TAGformat &d)       
00473    { 
00474       str_ptr nm;
00475       int     has_transp;
00476       double  transp;
00477       *d >> _g >> has_transp >> transp;
00478       if (_g) 
00479       {
00480          _g->set_transp(transp);
00481          if (!has_transp) _g->unset_transp();
00482       }
00483    }
00484 };
00485 
00486 /*************************************
00487  * JOTscript
00488  *************************************/
00489 class JOTscript : public FUNC_ITEM {
00490  public: 
00491    JOTscript() : FUNC_ITEM("CHNG_SCRIPT") {}
00492 
00493    virtual void put(TAGformat& d) const { ACTION::write_script(*d); }
00494    virtual void get(TAGformat  &d) {
00495       // XXX - not sure yet how to do this!
00496    }
00497 
00498  protected:
00499 };
00500 
00501 /*****************************************************************
00502  * DISTRIB
00503  *****************************************************************/
00504 
00505 /////////////////////////////////////////////////////////////////
00506 // Statics 
00507 /////////////////////////////////////////////////////////////////
00508 
00509 DISTRIB*       DISTRIB::_d = 0;
00510 
00511 /////////////////////////////////////////////////////////////////
00512 // Methods
00513 /////////////////////////////////////////////////////////////////
00514 
00515 
00516 /////////////////////////////////////
00517 // Constructor
00518 /////////////////////////////////////
00519 DISTRIB::DISTRIB(FD_MANAGER *manager):
00520    Network(manager), 
00521       _cam_loaded(false), 
00522       _processing_gate(1)
00523 {
00524    // Creating the following objects is done for the side effect
00525    // (in FUNC_ITEM constructor) of adding them to the DECODER
00526    // hash table:
00527    new JOTupdate_geom(GELptr());
00528    new JOTsend_geom(GELptr());
00529    new JOTclip_info();
00530    new JOTrender_mode();
00531    new JOThash     (GELptr(), 0);
00532    new JOTxform    (GEOMptr());
00533    new JOTcreate   (GELptr());
00534    new JOTcam      (CAMdataptr(), this);
00535    new JOTwin      (0);
00536    new JOTio       (0);
00537    new JOTview     (VIEWptr());
00538    new JOTgrab     (GELptr(), 0);
00539    new JOTcolor    (GEOMptr());
00540    new JOTdisplay  (GELptr());
00541    new JOTdestroy  (GELptr());
00542    new JOTtransp   (GEOMptr());
00543    new JOTtexture  (GEOMptr());
00544    new JOTscript   ();
00545 
00546    xform_obs();
00547    grab_obs();
00548    disp_obs();
00549    color_obs();
00550    exist_obs();
00551    geom_obs();
00552    transp_obs();
00553    save_obs();
00554    load_obs();
00555    hash_obs();
00556    texture_obs();
00557    jot_var_obs();
00558 
00559    if (Config::get_var_bool("DISTRIB_CAMERA",false,true))
00560       VIEW::peek()->cam()->data()->add_cb(this);
00561 
00562 }
00563 
00564 /////////////////////////////////////
00565 // interpret()
00566 /////////////////////////////////////
00567 //
00568 // Decodes input stream until JOTdone() is received
00569 //
00570 int
00571 DISTRIB::interpret(
00572    NETenum    code, 
00573    NetStream *sender
00574    )
00575 {
00576    int ret = 0;
00577    switch (code) 
00578    {
00579       case NETcontext: 
00580       {
00581          static int print_errs = (Config::get_var_bool("PRINT_ERRS",false,true) != 0);
00582          broadcaster = sender;
00583          do 
00584          {
00585             DATA_ITEM *di = DATA_ITEM::Decode(*sender);
00586             // Should print error w/ problem class name if we can't decode
00587             // (How to get class name nicely?)
00588             if (di) 
00589             {
00590                err_adv((print_errs>0), 
00591                   "DISTRIB::interpret() - Decoded: '%s'", **di->class_name());
00592                if (di->class_name() == JOTdone().class_name())  break;
00593             }
00594             //XXX - Try something new -- bail on failure and return failure code...
00595             else
00596             {
00597                err_msg("DISTRIB::interpret() - Could not decode input. Aborting.");
00598                ret = 1;
00599                break;
00600             }
00601             if (sender->STDdstream::ascii())
00602             {
00603                sender->peekahead(); // forces an eof() if done
00604             }
00605          } while (!sender->eof());
00606          broadcaster = 0;
00607      }
00608      brcase NETswap_ack: // only master wall receives NETswap_ack's
00609      {
00610         // Used to be CAVE related stuff here...
00611      }
00612      brcase NETadd_connection : 
00613      { 
00614      
00615      }
00616      brdefault: 
00617      {
00618          ret = 1;
00619          err_msg(
00620             "DISTRIB::interpret() - Code: '%d' from '%s' is not NETcontext",
00621                int(code), **sender->print_name()); 
00622      }
00623    }
00624    return ret;
00625 }
00626 
00627 /////////////////////////////////////
00628 // load()
00629 /////////////////////////////////////
00630 //
00631 // Load data from a NetStream
00632 //
00633 // Return true if failed, false if successful
00634 bool
00635 DISTRIB::load(NetStream &cli)
00636 {
00637 
00638    static int print_errs = (Config::get_var_bool("PRINT_ERRS",false,true) != 0);
00639 
00640    DRAWN.flush();
00641    DRAWN.buffer();
00642 
00643    cli.add_network(this);
00644    bool retval = false;
00645 
00646    err_adv((print_errs>0), 
00647       "DISTRIB::load() - About to check stream...");
00648 
00649    // just start interpreting the stream ...
00650    if (cli.istr()) 
00651    { 
00652       err_adv((print_errs>0), 
00653          "DISTRIB::load() - About to interpret...");
00654       retval = !!interpret(NETcontext, &cli);
00655    } 
00656    // otherwise, read the data, then interpret
00657    else if (cli.read_stuff()) 
00658    {           
00659       err_msg("DISTRIB::load() - Bad netstream.");
00660       retval = true;
00661    }
00662 
00663    DRAWN.flush();
00664    return retval;
00665 }
00666 
00667 /////////////////////////////////////
00668 // load_stream()
00669 /////////////////////////////////////
00670 LOADobs::load_status_t
00671 DISTRIB::load_stream(
00672    NetStream &s,
00673    bool       from_file,
00674    bool       full_scene)
00675 {
00676    bool ret;
00677 
00678    LOADobs::load_status_t result;
00679 
00680    str_ptr header;
00681 
00682    if (s.attached())
00683    {
00684       //Netstream has valid handle or stream...
00685       if (s.STDdstream::ascii())
00686       {
00687          err_adv(debug, "DISTRIB::load_stream() - Loading ASCII stream...");
00688 
00689          //Should begin with a '#jot' header...
00690          s >> header;
00691 
00692          if (header == "#jot") 
00693          {
00694             err_mesg(ERR_LEV_SPAM, "DISTRIB::load_stream() - Founder expected header: '%s'", **header);
00695             err_mesg(ERR_LEV_SPAM, "DISTRIB::load_stream() - Attempting conventional load...");
00696             ret = load(s);
00697             if (!ret)
00698             {
00699                result = LOADobs::LOAD_ERROR_NONE;
00700                err_adv(debug, "DISTRIB::load_stream() - ...load successful!");
00701             }
00702             else
00703             {
00704                result = LOADobs::LOAD_ERROR_JOT;
00705                err_msg("DISTRIB::load_stream() - *LOAD FAILED*");
00706             }
00707          }
00708          else
00709          {
00710             if (!from_file)
00711             {
00712                err_msg("DISTRIB::load_stream() - *LOAD FAILED* Not '#jot' header: '%s'", **header);
00713                result = LOADobs::LOAD_ERROR_READ;
00714             }
00715             else
00716             {
00717                err_msg("DISTRIB::load_stream() - Not '#jot' header: '%s'", **header);
00718                err_msg("DISTRIB::load_stream() - Attempting to use auxillary LOADERs...");
00719 
00720                ret = LOADER::load(s.name());
00721 
00722                if (!ret) 
00723                {
00724                   err_adv(debug, "DISTRIB::load_stream() - Auxillary LOADERs failed!!!");
00725                   err_msg("DISTRIB::load_stream() - *LOAD FAILED*");
00726                   result = LOADobs::LOAD_ERROR_READ;
00727                }
00728                else
00729                {
00730                   err_msg("DISTRIB::load_stream() - Auxillary LOADERs succeeded.");
00731                   err_adv(debug, "DISTRIB::load_stream() - ...load successful!");
00732                   result = LOADobs::LOAD_ERROR_AUX;
00733                }
00734             }
00735          }
00736       }
00737       else
00738       {
00739          err_adv(debug, "DISTRIB::load_stream() - Loading Non-ASCII stream...");
00740 
00741          err_mesg(ERR_LEV_SPAM, "DISTRIB::load_stream() - Attempting conventional load...");
00742 
00743          ret = load(s);
00744 
00745          if (!ret)
00746          {
00747             err_adv(debug, "DISTRIB::load_stream() - ...load successful!");
00748             result = LOADobs::LOAD_ERROR_NONE;
00749          }
00750          else
00751          {
00752             if (!from_file)
00753             {
00754                err_msg("DISTRIB::load_stream() - *LOAD FAILED*");
00755                result = LOADobs::LOAD_ERROR_READ;
00756             }
00757             else
00758             {
00759                err_msg("DISTRIB::load_stream() - Conventional load failed!");
00760                err_msg("DISTRIB::load_stream() - Attempting to use auxillary LOADERs...");
00761 
00762                ret = LOADER::load(s.name());
00763 
00764                if (!ret) 
00765                {
00766                   err_adv(debug, "DISTRIB::load_stream() - Auxillary LOADERs failed!!!");
00767                   err_msg("DISTRIB::load_stream() - *LOAD FAILED*");
00768                   result = LOADobs::LOAD_ERROR_READ;
00769                }
00770                else
00771                {
00772                   err_msg("DISTRIB::load_stream() - Auxillary LOADERs succeeded");
00773                   err_adv(debug, "DISTRIB::load_stream() - ...load successful!");
00774                   result = LOADobs::LOAD_ERROR_AUX;
00775                }
00776             }         
00777          }
00778       }
00779    }
00780    else
00781    {
00782       err_msg("DISTRIB::load_stream() - **LOAD FAILED** No valid stream or handle!!");
00783       result = LOADobs::LOAD_ERROR_STREAM;
00784    }
00785 
00786    return result;
00787 }
00788 
00789 
00790 /////////////////////////////////////
00791 // notify_load()
00792 /////////////////////////////////////
00793 void      
00794 DISTRIB::notify_load(
00795    NetStream     &s,
00796    load_status_t &status,
00797    bool           from_file,
00798    bool           full_scene
00799    )
00800 {
00801    if (status == LOADobs::LOAD_ERROR_NONE)
00802    {
00803       status = load_stream(s, from_file,full_scene);
00804    }
00805    else
00806    {
00807       err_adv(debug, "DISTRIB::notify_load() - Load procedure already in error state. Aborting...");      
00808    }
00809 }
00810 
00811 /////////////////////////////////////
00812 // notify_save()
00813 /////////////////////////////////////
00814 void      
00815 DISTRIB::notify_save(
00816    NetStream     &s,
00817    save_status_t &status,
00818    bool           to_file,
00819    bool           full_scene
00820    )
00821 {
00822    if (status == SAVEobs::SAVE_ERROR_NONE)
00823    {
00824       status = save_stream(s, to_file, full_scene);
00825    }
00826    else
00827    {
00828       err_adv(debug, "DISTRIB::notify_save() - Save procedure already in error state. Aborting...");      
00829    }
00830 }
00831 
00832 /////////////////////////////////////
00833 // save_stream()
00834 /////////////////////////////////////
00835 SAVEobs::save_status_t
00836 DISTRIB::save_stream(
00837    NetStream   &s, 
00838    bool         to_file,
00839    bool         full_scene
00840    )
00841 {
00842    bool ret;
00843 
00844    SAVEobs::save_status_t result;
00845 
00846    if (s.attached())
00847    {
00848       //Netstream has valid handle or stream...
00849       if (s.STDdstream::ascii())
00850       {
00851          err_adv(debug, "DISTRIB::save_stream() - Saving ASCII stream...");
00852 
00853          ret = save(s, to_file, full_scene);
00854 
00855          if (ret)
00856          {
00857             result = SAVEobs::SAVE_ERROR_NONE;
00858             err_adv(debug, "DISTRIB::save_stream() - ...save succeeded.");
00859          }
00860          else
00861          {
00862             result = SAVEobs::SAVE_ERROR_WRITE;
00863             err_msg("DISTRIB::save_stream() - **SAVE FAILED**");
00864          }
00865       }
00866       else
00867       {
00868          err_adv(debug, "DISTRIB::save_stream() - Saving Non-ASCII stream...");
00869 
00870          ret = save(s, to_file, full_scene);
00871 
00872          if (ret)
00873          {
00874             result = SAVEobs::SAVE_ERROR_NONE;
00875             err_adv(debug, "DISTRIB::save_stream() - ...save succeeded.");
00876          }
00877          else
00878          {
00879             result = SAVEobs::SAVE_ERROR_WRITE;
00880             err_msg("DISTRIB::save_stream() - **SAVE FAILED**");
00881          }
00882       }
00883    }
00884    else
00885    {
00886       err_msg("DISTRIB::save_stream() - **SAVE FAILED** No valid stream or handle!!");
00887       result = SAVEobs::SAVE_ERROR_STREAM;
00888    }
00889    
00890    return result;
00891 }
00892 
00893 /////////////////////////////////////
00894 // save()
00895 /////////////////////////////////////
00896 //
00897 // Save data to a NetStream
00898 //
00899 bool
00900 DISTRIB::save(
00901    NetStream& s, 
00902    bool       to_file,
00903    bool       full_scene
00904    )
00905 {
00906    int i;
00907 
00908    // Figure out what to save...
00909 
00910    // Get a list of all GEOMs
00911    GEOMlist geoms;
00912    for (i = 0; i < EXIST.num(); i++) {
00913       GEOM* geom = GEOM::upcast(EXIST[i]);
00914       if (geom) {
00915          geoms += geom;
00916       } 
00917    }
00918 
00919    // Get list of undisplayed objects
00920    // If no object depends on an undisplayed object, then
00921    // we don't save it to a file
00922    CGELlist &drawn = DRAWN;
00923    GELlist   undisplayed, filter;
00924    for (i = geoms.num() - 1; i >= 0; i--) {
00925       if (NETWORK.get(geoms[i]) &&    // object is networked
00926           !NO_SAVE.get(geoms[i]) &&   // object is savable
00927           !drawn.contains(geoms[i])) { // object isn't drawn
00928          if (!to_file || should_save(geoms[i])) {
00929             // if we're not writing to a file or someone depends on this obj...
00930             // Save out this object, but make sure it is undisplayed as well
00931             undisplayed += geoms[i];
00932          } else {
00933             // Don't save out this object
00934             filter += geoms[i];
00935             err_msg("DISTRIB::save() - Filtered out: '%s' (Net'd='%s' Save='%s' IDX='%d')", 
00936                **geoms[i]->name(), ((NETWORK.get(geoms[i]))?("Yes"):("No")), 
00937                   ((NO_SAVE.get(geoms[i]))?("No"):("Yes")), drawn.get_index(geoms[i]));
00938          }
00939       }
00940    }
00941 
00942    // Now save things...
00943 
00944    s.block(STD_FALSE);  // Make sure we are non-blocking
00945 
00946    if (!s.STDdstream::ascii())
00947    {
00948       s << NETcontext;  // only send the context to network connections
00949    }
00950    else 
00951    {
00952       s << "#jot\n";
00953    }
00954 
00955    //Bail out early if the IO already failed...
00956    if (s.fail())
00957    {
00958       return false;
00959    }
00960 
00961    if (full_scene)
00962    {
00963       if (to_file)
00964       {
00965          s << JOTio(IOManager::instance());
00966       }
00967 
00968       // GEOMS
00969       for (i = geoms.num() - 1; i >= 0 ; i--) {
00970          if (NETWORK.get(geoms[i]) && !NO_SAVE.get(geoms[i]) && !filter.contains(geoms[i])) {
00971             err_mesg(ERR_LEV_SPAM, "DISTRIB::save() - Writing GEOM '%s'..." ,**geoms[i]->name());
00972             s << JOTsend_geom(geoms[i]) << JOTcreate(geoms[i]); 
00973             err_mesg(ERR_LEV_SPAM, "DISTRIB::save() - ...finished writing GEOM.");
00974          } 
00975       }
00976 
00977       // Undisplays
00978       for (i = 0; i < undisplayed.num(); i++) {
00979          s << JOTdisplay(undisplayed[i], 0);
00980       }
00981 
00982       // Other stuff
00983       if (to_file) {
00984          s << JOTcam(VIEW::peek()->cam()->data());
00985          s << JOTwin(VIEW::peek()->win());
00986          s << JOTview(VIEW::peek());
00987          s << JOTscript();
00988       }
00989    } else {
00990       assert(to_file);
00991 
00992       // GEOMS
00993       for (i = geoms.num() - 1; i >= 0 ; i--) {
00994          if (NETWORK.get(geoms[i]) && !NO_SAVE.get(geoms[i]) && filter.get_index(geoms[i]) == BAD_IND) {
00995             err_mesg(ERR_LEV_SPAM, "DISTRIB::save() - Writing GEOM Update'%s'..." ,**geoms[i]->name());
00996             s << JOTupdate_geom(geoms[i]); 
00997             err_mesg(ERR_LEV_SPAM, "DISTRIB::save() - ...finished writing GEOM Update.");
00998          } 
00999       }
01000 
01001       s << JOTcam(VIEW::peek()->cam()->data());
01002    }
01003 
01004    s << JOTdone();
01005 
01006    return !s.fail();
01007 }
01008 
01009 /////////////////////////////////////
01010 // add_client()
01011 /////////////////////////////////////
01012 void  
01013 DISTRIB::add_client(NetStream *cli)  
01014 {
01015    // only save the scene to the new client if not running in the Cave
01016    // (because that's the way it was first implemented, but seems to be
01017    // wrong) or if using the Cave AND we're the front wall.
01018    //
01019    // Everything to do with CAVE support has been removed...
01020       save(*cli, false, true);
01021 }
01022 
01023 /////////////////////////////////////
01024 // remove_stream()
01025 /////////////////////////////////////
01026 void
01027 DISTRIB::remove_stream(NetStream  *s)
01028 {
01029    // call base class's method 1st
01030    Network::remove_stream(s);
01031 
01032 }
01033 
01034 /////////////////////////////////////
01035 // should_save()
01036 /////////////////////////////////////
01037 //
01038 // g is an undisplayed object - does anything that will be saved out depend
01039 // on this object?
01040 //
01041 bool
01042 DISTRIB::should_save(CGEOMptr &g)
01043 {
01044    return false;
01045 }
01046 
01047 /////////////////////////////////////
01048 // notify_exist()
01049 /////////////////////////////////////
01050 void      
01051 DISTRIB::notify_exist(
01052    CGELptr &g,
01053    int      f
01054    )
01055 {
01056    // If a network read is in progress for this object, skip
01057    if (net_read_in_progress.get(g)) return;
01058 
01059    if (f)  {
01060       if (NETWORK.get(g)) {
01061          DATA_ITEM::add_decoder(g->name(), (DATA_ITEM *)&*g, 0);
01062          if (!(GEOM::isa(g) && NO_SAVE.get(g)))
01063             *this << NETcontext<< JOTsend_geom(g) << JOTcreate(g) << JOTdone();
01064       }
01065    }
01066    if (!f) {
01067       if (!processing() && NETWORK.get(g))
01068          *this << NETcontext << JOTdestroy(g)  << JOTdone();
01069    }
01070 }
01071 
01072 
01073 /////////////////////////////////////
01074 // notify_color()
01075 /////////////////////////////////////
01076 void      
01077 DISTRIB::notify_color(
01078    CGEOMptr &g,
01079    APPEAR   *
01080    )
01081 {
01082    if (NETWORK.get(g) && !processing())
01083       *this << NETcontext << JOTcolor(g) << JOTdone();
01084 }
01085 
01086 /////////////////////////////////////
01087 // notify_transp()
01088 /////////////////////////////////////
01089 void      
01090 DISTRIB::notify_transp(
01091    CGEOMptr &g
01092    )
01093 {
01094    if (NETWORK.get(g) && !processing())
01095        *this << NETcontext << JOTtransp(g) << JOTdone();
01096 }
01097 
01098 /////////////////////////////////////
01099 // notify_geom()
01100 /////////////////////////////////////
01101 void      
01102 DISTRIB::notify_geom(
01103    CGEOMptr &g
01104    )
01105 {
01106    if (NETWORK.get(g) && !processing()){
01107       ; // what do we distribute here?
01108    }
01109 }
01110 
01111 /////////////////////////////////////
01112 // notify()
01113 /////////////////////////////////////
01114 void
01115 DISTRIB::notify(
01116    CCAMdataptr  &data
01117    )
01118 {
01119    // broadcast new camera position
01120    if (!processing())
01121       *this << NETcontext << JOTcam(data) << JOTdone();
01122 }
01123 
01124 /////////////////////////////////////
01125 // notify_jot_var()
01126 /////////////////////////////////////
01127 void
01128 DISTRIB::notify_jot_var(
01129    DATA_ITEM *item
01130    )
01131 {
01132    if (!processing())
01133       (*this) << NETcontext << *item << JOTdone();
01134 }
01135 
01136 /////////////////////////////////////
01137 // notify_hash()
01138 /////////////////////////////////////
01139 void
01140 DISTRIB::notify_hash(
01141    CGELptr  &g,
01142    hashdist *h
01143    )
01144 {
01145    if (NETWORK.get(g) && !processing())
01146       *this << NETcontext << JOThash(g, h) << JOTdone();
01147 }
01148 
01149 /////////////////////////////////////
01150 // notify_texture()
01151 /////////////////////////////////////
01152 void
01153 DISTRIB::notify_texture(
01154    CGEOMptr &g
01155    )
01156 {
01157    if (NETWORK.get(g) && !processing())
01158       *this << NETcontext << JOTtexture(g) << JOTdone();
01159 }
01160 
01161 /////////////////////////////////////
01162 // notify_xform()
01163 /////////////////////////////////////
01164 void
01165 DISTRIB::notify_xform(
01166    CGEOMptr &g,
01167    STATE     state
01168    )
01169 {
01170 
01171   if (NETWORK.get(g) && !processing()){
01172     if (state == XFORMobs::PRIMARY || state == XFORMobs::DROP)
01173       *this << NETcontext << JOTxform(g) << JOTdone();
01174     else if(state== XFORMobs::START||state==XFORMobs::END){
01175        //*this << NETcontext << JOTxform_to_undo(g,state) << JOTdone();
01176     }
01177   }
01178 }
01179 
01180 /////////////////////////////////////
01181 // notify()
01182 /////////////////////////////////////
01183 void      
01184 DISTRIB::notify(
01185    CGELptr &g,
01186    int      flag
01187    )
01188 {
01189    // If a network read is in progress for this object, skip
01190    if (net_read_in_progress.get(g)) return;
01191 
01192    int i;
01193    if (flag) {
01194       for (i = 0; i < VIEWS.num(); i++)
01195          VIEWS[i]->display(g);
01196       if (!processing() && NETWORK.get(g))
01197          *this << NETcontext << JOTdisplay(g)  << JOTdone();
01198    } else {
01199       for (i = 0; i < VIEWS.num(); i++)
01200          VIEWS[i]->undisplay(g);
01201       if (!processing() && NETWORK.get(g))
01202          *this << NETcontext << JOTdisplay(g,0)<< JOTdone();
01203    }
01204 }
01205 
01206 /////////////////////////////////////
01207 // notify_grab()
01208 /////////////////////////////////////
01209 void      
01210 DISTRIB::notify_grab(
01211    CGELptr &g,
01212    int      flag
01213    )
01214 {
01215    if (!processing() && NETWORK.get(g) && JOTgrab::_save != g)
01216       *this << NETcontext << JOTgrab(g,flag) << JOTdone();
01217 }
01218 
01219 
01220 
01221 
01222 /*****************************************************************
01223  * XXX - Old DLL functions...
01224  *****************************************************************/
01225 
01226 /////////////////////////////////////
01227 // distrib()
01228 /////////////////////////////////////
01229 extern "C"
01230 void
01231 distrib()
01232 {
01233    DISTRIB *net = DISTRIB::get_distrib();
01234    
01235    if (!net) 
01236    {
01237       err_mesg(ERR_LEV_SPAM, "DISTRIB.C::distrib() - Instantiating DISTRIB...");
01238       net = new DISTRIB(FD_MANAGER::mgr());
01239       DISTRIB::set_distrib(net);
01240    } 
01241 }
01242 
01243 /////////////////////////////////////
01244 // distrib_startnet()
01245 /////////////////////////////////////
01246 extern "C"
01247 void
01248 distrib_startnet(
01249    int  port
01250    )
01251 {
01252    distrib();   // make sure a DISTRIB object exists
01253 
01254    DISTRIB *net = DISTRIB::get_distrib();
01255 
01256    err_msg("DISTRIB.C::distrib_startnet() - Starting a networked environment...");
01257 
01258    net->start(port);
01259 }
01260 
01261 /////////////////////////////////////
01262 // distrib_client()
01263 /////////////////////////////////////
01264 extern "C"
01265 void
01266 distrib_client(
01267    FD_MANAGER *,
01268    char       *host,
01269    int         port
01270    )
01271 {
01272    distrib();   // make sure a DISTRIB object exists
01273 
01274    err_msg("DISTRIB.C::distrib_client() - Attaching to networked environment...");
01275 
01276    DISTRIB *net = DISTRIB::get_distrib();
01277 
01278    int MAXTRY = Config::get_var_int("MAX_TRY", 200, true);
01279 
01280    for(int i=0;i<MAXTRY;i++) 
01281    {
01282       net->start(host, port);
01283       
01284       if (net->num_streams() != 0) break;
01285 
01286       err_msg("DISTRIB.C::distrib_client() - Trying to connect...");
01287 #ifdef WIN32
01288       Sleep(1);
01289 #else
01290       sleep(1);
01291 #endif
01292    }
01293 
01294    if (net->num_streams() == 0)
01295       err_msg("DISTRIB.C::distrib_client() - ...giving up.");
01296    else
01297       err_msg("DISTRIB.C::distrib_client() - ...connected!!");
01298 }
01299 
01300 /////////////////////////////////////
01301 // distrib_cam()
01302 /////////////////////////////////////
01303 extern "C"
01304 void
01305 distrib_cam(STDdstream *ds, CCAMdataptr &data)
01306 {
01307    *ds << JOTcam(data);
01308 }
01309 
01310 /////////////////////////////////////
01311 // distrib_view()
01312 /////////////////////////////////////
01313 extern "C"
01314 void
01315 distrib_view(STDdstream *ds, CVIEWptr &v)
01316 {
01317    *ds << JOTview(v);
01318 }
01319 
01320 /////////////////////////////////////
01321 // distrib_win()
01322 /////////////////////////////////////
01323 extern "C"
01324 void
01325 distrib_win(STDdstream *ds, WINSYS *data)
01326 {
01327    *ds << JOTwin(data);
01328 }
01329 
01330 
01331 /////////////////////////////////////
01332 // distrib_done()
01333 /////////////////////////////////////
01334 extern "C"
01335 void
01336 distrib_done(STDdstream *ds)
01337 {
01338    *ds << JOTdone();
01339 }
01340 
01341 /////////////////////////////////////
01342 // distrib_send_geom()
01343 /////////////////////////////////////
01344 extern "C"
01345 void
01346 distrib_send_geom(CGEOMptr &obj)
01347 {
01348    if (DISTRIB::get_distrib()) 
01349    {
01350       *DISTRIB::get_distrib() << NETcontext << JOTupdate_geom(obj) << JOTdone();
01351    }
01352 }
01353 
01354 /////////////////////////////////////
01355 // distrib_render_mode()
01356 /////////////////////////////////////
01357 extern "C"
01358 void
01359 distrib_render_mode()
01360 {
01361    if (DISTRIB::get_distrib()) 
01362    {
01363       *DISTRIB::get_distrib() << NETcontext << JOTrender_mode() << JOTdone();
01364    }
01365 }
01366 
01367 /////////////////////////////////////
01368 // distrib_clip_info()
01369 /////////////////////////////////////
01370 extern "C"
01371 void
01372 distrib_clip_info()
01373 {
01374    if (DISTRIB::get_distrib()) 
01375    {
01376       *DISTRIB::get_distrib() << NETcontext << JOTclip_info() << JOTdone();
01377    }
01378 }
01379 
01380 /////////////////////////////////////
01381 // distrib_display_geom()
01382 /////////////////////////////////////
01383 extern "C"
01384 void
01385 distrib_display_geom( CGELptr &gel, int display_flag)
01386 {
01387    if (DISTRIB::get_distrib())
01388    {
01389       *DISTRIB::get_distrib() << NETcontext << JOTdisplay(gel, display_flag) << JOTdone();
01390    }
01391 }

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