Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/vrpn/vrpnClient.cxx

Go to the documentation of this file.
00001 // Filename: vrpnClient.cxx
00002 // Created by:  jason (04Aug00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "vrpnClient.h"
00020 #include "vrpnTracker.h"
00021 #include "vrpnTrackerDevice.h"
00022 #include "vrpnButton.h"
00023 #include "vrpnButtonDevice.h"
00024 #include "vrpnAnalog.h"
00025 #include "vrpnAnalogDevice.h"
00026 #include "vrpnDial.h"
00027 #include "vrpnDialDevice.h"
00028 #include "config_vrpn.h"
00029 
00030 #include "dcast.h"
00031 #include "string_utils.h"
00032 #include "indent.h"
00033 
00034 TypeHandle VrpnClient::_type_handle;
00035 
00036 ////////////////////////////////////////////////////////////////////
00037 //     Function: VrpnClient::Constructor
00038 //       Access: Public
00039 //  Description:
00040 ////////////////////////////////////////////////////////////////////
00041 VrpnClient::
00042 VrpnClient(const string &server_name) :
00043   _server_name(server_name)
00044 {
00045   if (vrpn_cat.is_debug()) {
00046     vrpn_cat.debug()
00047       << "Attempting to connect to VRPN server " << _server_name
00048       << "\n";
00049   }
00050   _connection = vrpn_get_connection_by_name(_server_name.c_str());
00051   nassertv(_connection != (vrpn_Connection *)NULL);
00052 
00053   if (!is_valid()) {
00054     vrpn_cat.warning()
00055       << "Unable to establish connection to VRPN server " << _server_name
00056       << "\n";
00057   }
00058 }
00059 
00060 ////////////////////////////////////////////////////////////////////
00061 //     Function: VrpnClient::Constructor
00062 //       Access: Public
00063 //  Description:
00064 ////////////////////////////////////////////////////////////////////
00065 VrpnClient::
00066 ~VrpnClient() {
00067   delete _connection;
00068 }
00069 
00070 ////////////////////////////////////////////////////////////////////
00071 //     Function: VrpnClient::write
00072 //       Access: Public
00073 //  Description: Writes a list of the active devices that the
00074 //               VrpnClient is currently polling each frame.
00075 ////////////////////////////////////////////////////////////////////
00076 void VrpnClient::
00077 write(ostream &out, int indent_level) const {
00078   indent(out, indent_level)
00079     << "VrpnClient, server " << _server_name << "\n";
00080 
00081   if (!is_valid()) {
00082     indent(out, indent_level + 2)
00083       << "(error)\n";
00084   } else if (!is_connected()) {
00085     indent(out, indent_level + 2)
00086       << "(no connection)\n";
00087   }
00088 
00089   if (!_trackers.empty()) {
00090     indent(out, indent_level + 2)
00091       << _trackers.size() << " trackers:\n";
00092     Trackers::const_iterator ti;
00093     for (ti = _trackers.begin(); ti != _trackers.end(); ++ti) {
00094       VrpnTracker *vrpn_tracker = (*ti).second;
00095       vrpn_tracker->write(out, indent_level + 4);
00096     }
00097   }
00098 
00099   if (!_buttons.empty()) {
00100     indent(out, indent_level + 2)
00101       << _buttons.size() << " buttons:\n";
00102     Buttons::const_iterator bi;
00103     for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
00104       VrpnButton *vrpn_button = (*bi).second;
00105       vrpn_button->write(out, indent_level + 4);
00106     }
00107   }
00108 
00109   if (!_analogs.empty()) {
00110     indent(out, indent_level + 2)
00111       << _analogs.size() << " analogs:\n";
00112     Analogs::const_iterator ai;
00113     for (ai = _analogs.begin(); ai != _analogs.end(); ++ai) {
00114       VrpnAnalog *vrpn_analog = (*ai).second;
00115       vrpn_analog->write(out, indent_level + 4);
00116     }
00117   }
00118 
00119   if (!_dials.empty()) {
00120     indent(out, indent_level + 2)
00121       << _dials.size() << " dials:\n";
00122     Dials::const_iterator di;
00123     for (di = _dials.begin(); di != _dials.end(); ++di) {
00124       VrpnDial *vrpn_dial = (*di).second;
00125       vrpn_dial->write(out, indent_level + 4);
00126     }
00127   }
00128 }
00129 
00130 ////////////////////////////////////////////////////////////////////
00131 //     Function: VrpnClient::make_device
00132 //       Access: Protected, Virtual
00133 //  Description: Creates and returns a new ClientDevice of the
00134 //               appropriate type, according to the requested
00135 //               device_type and device_name.  Returns NULL if a
00136 //               matching device cannot be found.
00137 //
00138 //               This is guaranteed not to be called twice for a given
00139 //               device_type/device_name combination (unless
00140 //               disconnect_device() has already been called for the
00141 //               same device_type/device_name).
00142 ////////////////////////////////////////////////////////////////////
00143 PT(ClientDevice) VrpnClient::
00144 make_device(TypeHandle device_type, const string &device_name) {
00145   if (device_type == ClientTrackerDevice::get_class_type()) {
00146     return make_tracker_device(device_name);
00147 
00148   } else if (device_type == ClientButtonDevice::get_class_type()) {
00149     return make_button_device(device_name);
00150 
00151   } else if (device_type == ClientAnalogDevice::get_class_type()) {
00152     return make_analog_device(device_name);
00153 
00154   } else if (device_type == ClientDialDevice::get_class_type()) {
00155     return make_dial_device(device_name);
00156 
00157   } else {
00158     return NULL;
00159   }
00160 }
00161 
00162 ////////////////////////////////////////////////////////////////////
00163 //     Function: VrpnClient::disconnect_device
00164 //       Access: Protected, Virtual
00165 //  Description: Removes the device, which is presumably about to
00166 //               destruct, from the list of connected devices, and
00167 //               frees any data required to support it.  This device
00168 //               will no longer receive automatic updates with each
00169 //               poll.
00170 //
00171 //               The return value is true if the device was
00172 //               disconnected, or false if it was unknown (e.g. it was
00173 //               disconnected previously).
00174 ////////////////////////////////////////////////////////////////////
00175 bool VrpnClient::
00176 disconnect_device(TypeHandle device_type, const string &device_name,
00177                   ClientDevice *device) {
00178   if (vrpn_cat.is_debug()) {
00179     vrpn_cat.debug()
00180       << "Disconnecting device " << *device << "\n";
00181   }
00182 
00183   if (ClientBase::disconnect_device(device_type, device_name, device)) {
00184     if (device->is_of_type(VrpnTrackerDevice::get_class_type())) {
00185       disconnect_tracker_device(DCAST(VrpnTrackerDevice, device));
00186 
00187     } else if (device->is_of_type(VrpnButtonDevice::get_class_type())) {
00188       disconnect_button_device(DCAST(VrpnButtonDevice, device));
00189 
00190     } else if (device->is_of_type(VrpnAnalogDevice::get_class_type())) {
00191       disconnect_analog_device(DCAST(VrpnAnalogDevice, device));
00192 
00193     } else if (device->is_of_type(VrpnDialDevice::get_class_type())) {
00194       disconnect_dial_device(DCAST(VrpnDialDevice, device));
00195 
00196     }
00197     return true;
00198   }
00199 
00200   return false;
00201 }
00202 
00203 ////////////////////////////////////////////////////////////////////
00204 //     Function: VrpnClient::do_poll
00205 //       Access: Protected, Virtual
00206 //  Description: Implements the polling and updating of connected
00207 //               devices, if the ClientBase requires this.  This may
00208 //               be called in a sub-thread if
00209 //               fork_asynchronous_thread() was called; otherwise, it
00210 //               will be called once per frame.
00211 ////////////////////////////////////////////////////////////////////
00212 void VrpnClient::
00213 do_poll() {
00214   ClientBase::do_poll();
00215 
00216   if (vrpn_cat.is_spam()) {
00217     vrpn_cat.spam()
00218       << "VrpnClient " << _server_name << " polling "
00219       << _trackers.size() + _buttons.size() + _analogs.size() + _dials.size()
00220       << " devices.\n";
00221   }
00222 
00223   Trackers::iterator ti;
00224   for (ti = _trackers.begin(); ti != _trackers.end(); ++ti) {
00225     VrpnTracker *vrpn_tracker = (*ti).second;
00226     vrpn_tracker->poll();
00227   }
00228 
00229   Buttons::iterator bi;
00230   for (bi = _buttons.begin(); bi != _buttons.end(); ++bi) {
00231     VrpnButton *vrpn_button = (*bi).second;
00232     vrpn_button->poll();
00233   }
00234 
00235   Analogs::iterator ai;
00236   for (ai = _analogs.begin(); ai != _analogs.end(); ++ai) {
00237     VrpnAnalog *vrpn_analog = (*ai).second;
00238     vrpn_analog->poll();
00239   }
00240 
00241   Dials::iterator di;
00242   for (di = _dials.begin(); di != _dials.end(); ++di) {
00243     VrpnDial *vrpn_dial = (*di).second;
00244     vrpn_dial->poll();
00245   }
00246 }
00247 
00248 ////////////////////////////////////////////////////////////////////
00249 //     Function: VrpnClient::make_tracker_device
00250 //       Access: Private
00251 //  Description: Creates a new tracker device.  The device_name is
00252 //               parsed for sensor and data_type information.
00253 //
00254 //               The device_name may be one of the following:
00255 //
00256 //                    tracker_name
00257 //                    tracker_name:N
00258 //                    tracker_name:N[pva]
00259 //
00260 //               Where N is an integer sensor number, and [pva] is one
00261 //               of the lowercase letters p, v, or a.
00262 //
00263 //               In the first form, the device connects to the
00264 //               indicated tracker, and reports position information
00265 //               on sensor number 0.
00266 //
00267 //               In the second form, the device connects to the
00268 //               indicated tracker, and reports position information
00269 //               on the indicated sensor number.
00270 //
00271 //               In the third form, the device connects to the
00272 //               indicated tracker, and reports either position,
00273 //               velocity, or acceleration information on the
00274 //               indicated sensor number.
00275 ////////////////////////////////////////////////////////////////////
00276 PT(ClientDevice) VrpnClient::
00277 make_tracker_device(const string &device_name) {
00278   if (vrpn_cat.is_debug()) {
00279     vrpn_cat.debug()
00280       << "Making tracker device for " << device_name << "\n";
00281   }
00282 
00283   string tracker_name = device_name;
00284   int sensor = 0;
00285   VrpnTrackerDevice::DataType data_type = VrpnTrackerDevice::DT_position;
00286 
00287   size_t colon = device_name.rfind(':');
00288   if (colon != string::npos && colon + 1 < device_name.length()) {
00289     size_t begin = colon + 1;
00290     size_t end = device_name.length();
00291     VrpnTrackerDevice::DataType maybe_data_type = data_type;
00292 
00293     switch (device_name[end - 1]) {
00294     case 'p':
00295       maybe_data_type = VrpnTrackerDevice::DT_position;
00296       end--;
00297       break;
00298 
00299     case 'v':
00300       maybe_data_type = VrpnTrackerDevice::DT_velocity;
00301       end--;
00302       break;
00303 
00304     case 'a':
00305       maybe_data_type = VrpnTrackerDevice::DT_acceleration;
00306       end--;
00307       break;
00308     }
00309     int maybe_sensor;
00310     if (string_to_int(device_name.substr(begin, end - begin), maybe_sensor)) {
00311       // It seems to be a legitimate integer!
00312       sensor = maybe_sensor;
00313       data_type = maybe_data_type;
00314       tracker_name = device_name.substr(0, colon);
00315     }
00316   }
00317 
00318   VrpnTracker *tracker = get_tracker(tracker_name);
00319 
00320   VrpnTrackerDevice *device =
00321     new VrpnTrackerDevice(this, device_name, sensor, data_type, tracker);
00322 
00323   if (vrpn_cat.is_debug()) {
00324     vrpn_cat.debug()
00325       << "Creating " << *device << "\n";
00326   }
00327 
00328   tracker->mark(device);
00329   return device;
00330 }
00331 
00332 ////////////////////////////////////////////////////////////////////
00333 //     Function: VrpnClient::make_button_device
00334 //       Access: Private
00335 //  Description: Creates a new button device.  The device_name is sent
00336 //               verbatim to the VRPN library.
00337 ////////////////////////////////////////////////////////////////////
00338 PT(ClientDevice) VrpnClient::
00339 make_button_device(const string &device_name) {
00340   if (vrpn_cat.is_debug()) {
00341     vrpn_cat.debug()
00342       << "Making button device for " << device_name << "\n";
00343   }
00344 
00345   VrpnButton *button = get_button(device_name);
00346 
00347   VrpnButtonDevice *device =
00348     new VrpnButtonDevice(this, device_name, button);
00349 
00350   if (vrpn_cat.is_debug()) {
00351     vrpn_cat.debug()
00352       << "Creating " << *device << "\n";
00353   }
00354 
00355   button->mark(device);
00356   return device;
00357 }
00358 
00359 ////////////////////////////////////////////////////////////////////
00360 //     Function: VrpnClient::make_analog_device
00361 //       Access: Private
00362 //  Description: Creates a new analog device.  The device_name is sent
00363 //               verbatim to the VRPN library.
00364 ////////////////////////////////////////////////////////////////////
00365 PT(ClientDevice) VrpnClient::
00366 make_analog_device(const string &device_name) {
00367   if (vrpn_cat.is_debug()) {
00368     vrpn_cat.debug()
00369       << "Making analog device for " << device_name << "\n";
00370   }
00371 
00372   VrpnAnalog *analog = get_analog(device_name);
00373 
00374   VrpnAnalogDevice *device =
00375     new VrpnAnalogDevice(this, device_name, analog);
00376 
00377   if (vrpn_cat.is_debug()) {
00378     vrpn_cat.debug()
00379       << "Creating " << *device << "\n";
00380   }
00381 
00382   analog->mark(device);
00383   return device;
00384 }
00385 
00386 ////////////////////////////////////////////////////////////////////
00387 //     Function: VrpnClient::make_dial_device
00388 //       Access: Private
00389 //  Description: Creates a new dial device.  The device_name is sent
00390 //               verbatim to the VRPN library.
00391 ////////////////////////////////////////////////////////////////////
00392 PT(ClientDevice) VrpnClient::
00393 make_dial_device(const string &device_name) {
00394   if (vrpn_cat.is_debug()) {
00395     vrpn_cat.debug()
00396       << "Making dial device for " << device_name << "\n";
00397   }
00398 
00399   VrpnDial *dial = get_dial(device_name);
00400 
00401   VrpnDialDevice *device =
00402     new VrpnDialDevice(this, device_name, dial);
00403 
00404   if (vrpn_cat.is_debug()) {
00405     vrpn_cat.debug()
00406       << "Creating " << *device << "\n";
00407   }
00408 
00409   dial->mark(device);
00410   return device;
00411 }
00412 
00413 ////////////////////////////////////////////////////////////////////
00414 //     Function: VrpnClient::disconnect_tracker_device
00415 //       Access: Private
00416 //  Description: Removes the tracker device from the list of things to
00417 //               be updated.
00418 ////////////////////////////////////////////////////////////////////
00419 void VrpnClient::
00420 disconnect_tracker_device(VrpnTrackerDevice *device) {
00421   VrpnTracker *vrpn_tracker = device->get_vrpn_tracker();
00422   vrpn_tracker->unmark(device);
00423   if (vrpn_tracker->is_empty()) {
00424     free_tracker(vrpn_tracker);
00425   }
00426 }
00427 
00428 ////////////////////////////////////////////////////////////////////
00429 //     Function: VrpnClient::disconnect_button_device
00430 //       Access: Private
00431 //  Description: Removes the button device from the list of things to
00432 //               be updated.
00433 ////////////////////////////////////////////////////////////////////
00434 void VrpnClient::
00435 disconnect_button_device(VrpnButtonDevice *device) {
00436   VrpnButton *vrpn_button = device->get_vrpn_button();
00437   vrpn_button->unmark(device);
00438   if (vrpn_button->is_empty()) {
00439     free_button(vrpn_button);
00440   }
00441 }
00442 
00443 ////////////////////////////////////////////////////////////////////
00444 //     Function: VrpnClient::disconnect_analog_device
00445 //       Access: Private
00446 //  Description: Removes the analog device from the list of things to
00447 //               be updated.
00448 ////////////////////////////////////////////////////////////////////
00449 void VrpnClient::
00450 disconnect_analog_device(VrpnAnalogDevice *device) {
00451   VrpnAnalog *vrpn_analog = device->get_vrpn_analog();
00452   vrpn_analog->unmark(device);
00453   if (vrpn_analog->is_empty()) {
00454     free_analog(vrpn_analog);
00455   }
00456 }
00457 
00458 ////////////////////////////////////////////////////////////////////
00459 //     Function: VrpnClient::disconnect_dial_device
00460 //       Access: Private
00461 //  Description: Removes the dial device from the list of things to
00462 //               be updated.
00463 ////////////////////////////////////////////////////////////////////
00464 void VrpnClient::
00465 disconnect_dial_device(VrpnDialDevice *device) {
00466   VrpnDial *vrpn_dial = device->get_vrpn_dial();
00467   vrpn_dial->unmark(device);
00468   if (vrpn_dial->is_empty()) {
00469     free_dial(vrpn_dial);
00470   }
00471 }
00472 
00473 ////////////////////////////////////////////////////////////////////
00474 //     Function: VrpnClient::get_tracker
00475 //       Access: Private
00476 //  Description: Finds a VrpnTracker of the indicated name, and
00477 //               returns it if one already exists, or creates a new
00478 //               one if it does not.
00479 ////////////////////////////////////////////////////////////////////
00480 VrpnTracker *VrpnClient::
00481 get_tracker(const string &tracker_name) {
00482   Trackers::iterator ti;
00483   ti = _trackers.find(tracker_name);
00484 
00485   if (ti != _trackers.end()) {
00486     return (*ti).second;
00487   }
00488 
00489   VrpnTracker *vrpn_tracker = new VrpnTracker(tracker_name, _connection);
00490   _trackers.insert(Trackers::value_type(tracker_name, vrpn_tracker));
00491 
00492   if (vrpn_cat.is_debug()) {
00493     vrpn_cat.debug()
00494       << "Creating tracker " << *vrpn_tracker << "\n";
00495   }
00496 
00497   return vrpn_tracker;
00498 }
00499 
00500 ////////////////////////////////////////////////////////////////////
00501 //     Function: VrpnClient::free_tracker
00502 //       Access: Private
00503 //  Description: Removes and deletes the indicated VrpnTracker, which
00504 //               is no longer referenced by any VrpnTrackerDevices.
00505 ////////////////////////////////////////////////////////////////////
00506 void VrpnClient::
00507 free_tracker(VrpnTracker *vrpn_tracker) {
00508   nassertv(vrpn_tracker->is_empty());
00509 
00510   if (vrpn_cat.is_debug()) {
00511     vrpn_cat.debug()
00512       << "Deleting tracker " << *vrpn_tracker << "\n";
00513   }
00514 
00515   Trackers::iterator ti;
00516   ti = _trackers.find(vrpn_tracker->get_tracker_name());
00517   nassertv(ti != _trackers.end());
00518   nassertv((*ti).second == vrpn_tracker);
00519 
00520   _trackers.erase(ti);
00521   delete vrpn_tracker;
00522 }
00523 
00524 ////////////////////////////////////////////////////////////////////
00525 //     Function: VrpnClient::get_button
00526 //       Access: Private
00527 //  Description: Finds a VrpnButton of the indicated name, and
00528 //               returns it if one already exists, or creates a new
00529 //               one if it does not.
00530 ////////////////////////////////////////////////////////////////////
00531 VrpnButton *VrpnClient::
00532 get_button(const string &button_name) {
00533   Buttons::iterator bi;
00534   bi = _buttons.find(button_name);
00535 
00536   if (bi != _buttons.end()) {
00537     return (*bi).second;
00538   }
00539 
00540   VrpnButton *vrpn_button = new VrpnButton(button_name, _connection);
00541   _buttons.insert(Buttons::value_type(button_name, vrpn_button));
00542 
00543   if (vrpn_cat.is_debug()) {
00544     vrpn_cat.debug()
00545       << "Creating button " << *vrpn_button << "\n";
00546   }
00547 
00548   return vrpn_button;
00549 }
00550 
00551 ////////////////////////////////////////////////////////////////////
00552 //     Function: VrpnClient::free_button
00553 //       Access: Private
00554 //  Description: Removes and deletes the indicated VrpnButton, which
00555 //               is no longer referenced by any VrpnButtonDevices.
00556 ////////////////////////////////////////////////////////////////////
00557 void VrpnClient::
00558 free_button(VrpnButton *vrpn_button) {
00559   nassertv(vrpn_button->is_empty());
00560 
00561   if (vrpn_cat.is_debug()) {
00562     vrpn_cat.debug()
00563       << "Deleting button " << *vrpn_button << "\n";
00564   }
00565 
00566   Buttons::iterator bi;
00567   bi = _buttons.find(vrpn_button->get_button_name());
00568   nassertv(bi != _buttons.end());
00569   nassertv((*bi).second == vrpn_button);
00570 
00571   _buttons.erase(bi);
00572   delete vrpn_button;
00573 }
00574 
00575 ////////////////////////////////////////////////////////////////////
00576 //     Function: VrpnClient::get_analog
00577 //       Access: Private
00578 //  Description: Finds a VrpnAnalog of the indicated name, and
00579 //               returns it if one already exists, or creates a new
00580 //               one if it does not.
00581 ////////////////////////////////////////////////////////////////////
00582 VrpnAnalog *VrpnClient::
00583 get_analog(const string &analog_name) {
00584   Analogs::iterator ai;
00585   ai = _analogs.find(analog_name);
00586 
00587   if (ai != _analogs.end()) {
00588     return (*ai).second;
00589   }
00590 
00591   VrpnAnalog *vrpn_analog = new VrpnAnalog(analog_name, _connection);
00592   _analogs.insert(Analogs::value_type(analog_name, vrpn_analog));
00593 
00594   if (vrpn_cat.is_debug()) {
00595     vrpn_cat.debug()
00596       << "Creating analog " << *vrpn_analog << "\n";
00597   }
00598 
00599   return vrpn_analog;
00600 }
00601 
00602 ////////////////////////////////////////////////////////////////////
00603 //     Function: VrpnClient::free_analog
00604 //       Access: Private
00605 //  Description: Removes and deletes the indicated VrpnAnalog, which
00606 //               is no longer referenced by any VrpnAnalogDevices.
00607 ////////////////////////////////////////////////////////////////////
00608 void VrpnClient::
00609 free_analog(VrpnAnalog *vrpn_analog) {
00610   nassertv(vrpn_analog->is_empty());
00611 
00612   if (vrpn_cat.is_debug()) {
00613     vrpn_cat.debug()
00614       << "Deleting analog " << *vrpn_analog << "\n";
00615   }
00616 
00617   Analogs::iterator ai;
00618   ai = _analogs.find(vrpn_analog->get_analog_name());
00619   nassertv(ai != _analogs.end());
00620   nassertv((*ai).second == vrpn_analog);
00621 
00622   _analogs.erase(ai);
00623   delete vrpn_analog;
00624 }
00625 
00626 ////////////////////////////////////////////////////////////////////
00627 //     Function: VrpnClient::get_dial
00628 //       Access: Private
00629 //  Description: Finds a VrpnDial of the indicated name, and
00630 //               returns it if one already exists, or creates a new
00631 //               one if it does not.
00632 ////////////////////////////////////////////////////////////////////
00633 VrpnDial *VrpnClient::
00634 get_dial(const string &dial_name) {
00635   Dials::iterator di;
00636   di = _dials.find(dial_name);
00637 
00638   if (di != _dials.end()) {
00639     return (*di).second;
00640   }
00641 
00642   VrpnDial *vrpn_dial = new VrpnDial(dial_name, _connection);
00643   _dials.insert(Dials::value_type(dial_name, vrpn_dial));
00644 
00645   if (vrpn_cat.is_debug()) {
00646     vrpn_cat.debug()
00647       << "Creating dial " << *vrpn_dial << "\n";
00648   }
00649 
00650   return vrpn_dial;
00651 }
00652 
00653 ////////////////////////////////////////////////////////////////////
00654 //     Function: VrpnClient::free_dial
00655 //       Access: Private
00656 //  Description: Removes and deletes the indicated VrpnDial, which
00657 //               is no longer referenced by any VrpnDialDevices.
00658 ////////////////////////////////////////////////////////////////////
00659 void VrpnClient::
00660 free_dial(VrpnDial *vrpn_dial) {
00661   nassertv(vrpn_dial->is_empty());
00662 
00663   if (vrpn_cat.is_debug()) {
00664     vrpn_cat.debug()
00665       << "Deleting dial " << *vrpn_dial << "\n";
00666   }
00667 
00668   Dials::iterator di;
00669   di = _dials.find(vrpn_dial->get_dial_name());
00670   nassertv(di != _dials.end());
00671   nassertv((*di).second == vrpn_dial);
00672 
00673   _dials.erase(di);
00674   delete vrpn_dial;
00675 }
00676 
00677 
00678 #if 0
00679 
00680 #include <datagram.h>
00681 #include <datagramIterator.h>
00682 
00683 typedef struct {
00684   string device_name;
00685   void *self;
00686 } VrpnClientInfo;
00687 
00688 
00689 ////////////////////////////////////////////////////////////////////
00690 //     Function: VrpnClient::add_remote_tracker
00691 //       Access: Public, Virtual
00692 //  Description: Creates a new vrpn remote tracker object and registers
00693 //               a callback with it.
00694 ////////////////////////////////////////////////////////////////////
00695 bool VrpnClient::
00696 add_remote_tracker(const string &tracker, int sensor) {
00697 
00698   vrpn_Tracker_Remote *vrpn_tracker = new vrpn_Tracker_Remote(tracker.c_str(), _connection);
00699   if (vrpn_tracker == (vrpn_Tracker_Remote *)NULL) {
00700     return false;
00701   }
00702 
00703   //Now package up the information that needs to be passed to the
00704   //callback function to allow it to determine for which tracker we
00705   //are receiving information for
00706   VrpnClientInfo *data = new VrpnClientInfo;
00707   data->device_name = tracker;
00708   data->self = this;
00709 
00710   vrpn_tracker->register_change_handler((void*)data, st_tracker_position);
00711   vrpn_tracker->register_change_handler((void*)data, st_tracker_velocity);
00712   vrpn_tracker->register_change_handler((void*)data, st_tracker_acceleration);
00713 
00714   _vrpn_trackers[tracker] = vrpn_tracker;
00715   _trackers.push_back(tracker);
00716   _sensors[tracker].push_back(sensor);
00717 
00718   return true;
00719 }
00720 
00721 ////////////////////////////////////////////////////////////////////
00722 //     Function: VrpnClient::add_remote_analog
00723 //       Access: Public, Virtual
00724 //  Description: Creates a new vrpn remote analog object and registers
00725 //               a callback with it.
00726 ////////////////////////////////////////////////////////////////////
00727 bool VrpnClient::
00728 add_remote_analog(const string &analog) {
00729 
00730   vrpn_Analog_Remote *vrpn_analog = new vrpn_Analog_Remote(analog.c_str(), _connection);
00731   if (vrpn_analog == (vrpn_Analog_Remote *)NULL) {
00732     return false;
00733   }
00734 
00735   //Now package up the information that needs to be passed to the
00736   //callback function to allow it to determine for which analog we
00737   //are receiving information for
00738   VrpnClientInfo *data = new VrpnClientInfo;
00739   data->device_name = analog;
00740   data->self = this;
00741 
00742   vrpn_analog->register_change_handler((void*)data, st_analog);
00743 
00744   _vrpn_analogs[analog] = vrpn_analog;
00745   _analogs.push_back(analog);
00746 
00747   return true;
00748 }
00749 
00750 ////////////////////////////////////////////////////////////////////
00751 //     Function: VrpnClient::add_remote_button
00752 //       Access: Public, Virtual
00753 //  Description: Creates a new vrpn remote button object and registers
00754 //               a callback with it.
00755 ////////////////////////////////////////////////////////////////////
00756 bool VrpnClient::
00757 add_remote_button(const string &button) {
00758 
00759   vrpn_Button_Remote *vrpn_button = new vrpn_Button_Remote(button.c_str(), _connection);
00760   if (vrpn_button == (vrpn_Button_Remote *)NULL) {
00761     return false;
00762   }
00763 
00764   //Now package up the information that needs to be passed to the
00765   //callback function to allow it to determine for which button we
00766   //are receiving information for
00767   VrpnClientInfo *data = new VrpnClientInfo;
00768   data->device_name = button;
00769   data->self = this;
00770 
00771   vrpn_button->register_change_handler((void*)data, st_button);
00772 
00773   _vrpn_buttons[button] = vrpn_button;
00774   _buttons.push_back(button);
00775 
00776   return true;
00777 }
00778 
00779 ////////////////////////////////////////////////////////////////////
00780 //     Function: VrpnClient::add_remote_dial
00781 //       Access: Public, Virtual
00782 //  Description: Creates a new vrpn remote dial object and registers
00783 //               a callback with it.
00784 ////////////////////////////////////////////////////////////////////
00785 bool VrpnClient::
00786 add_remote_dial(const string &dial) {
00787 
00788   vrpn_Dial_Remote *vrpn_dial = new vrpn_Dial_Remote(dial.c_str(), _connection);
00789   if (vrpn_dial == (vrpn_Dial_Remote *)NULL) {
00790     return false;
00791   }
00792 
00793   //Now package up the information that needs to be passed to the
00794   //callback function to allow it to determine for which dial we
00795   //are receiving information for
00796   VrpnClientInfo *data = new VrpnClientInfo;
00797   data->device_name = dial;
00798   data->self = this;
00799 
00800   vrpn_dial->register_change_handler((void*)data, st_dial);
00801 
00802   _vrpn_dials[dial] = vrpn_dial;
00803   _dials.push_back(dial);
00804 
00805   return true;
00806 }
00807 
00808 ////////////////////////////////////////////////////////////////////
00809 //     Function: VrpnClient::max_analog_channels
00810 //       Access: Public, Virtual
00811 //  Description: Max number of analog channels
00812 ////////////////////////////////////////////////////////////////////
00813 int VrpnClient::
00814 max_analog_channels() {
00815   return vrpn_CHANNEL_MAX;
00816 }
00817 
00818 ////////////////////////////////////////////////////////////////////
00819 //     Function: VrpnClient::poll_trackers
00820 //       Access: Public, Virtual
00821 //  Description: Calls mainloop for the registered tracker object
00822 //         Note: In a non-threaded case, this may need to come up with
00823 //               some kind of cacheing scheme so we don't call mainloop
00824 //               multiple times when a user is just asking for the data
00825 //               of multiple sensors on 1 tracker (as that is the interface
00826 //               supported).  This is a non-trivial problem as it is
00827 //               difficult to know when we should and shouldn't cache.
00828 ////////////////////////////////////////////////////////////////////
00829 void VrpnClient::
00830 poll_tracker(const string &tracker) {
00831   _vrpn_trackers[tracker]->mainloop();
00832 }
00833 
00834 ////////////////////////////////////////////////////////////////////
00835 //     Function: VrpnClient::poll_analog
00836 //       Access: Public, Virtual
00837 //  Description: Calls mainloop for the registered analog object
00838 ////////////////////////////////////////////////////////////////////
00839 void VrpnClient::
00840 poll_analog(const string &analog) {
00841   _vrpn_analogs[analog]->mainloop();
00842 }
00843 
00844 ////////////////////////////////////////////////////////////////////
00845 //     Function: VrpnClient::poll_button
00846 //       Access: Public, Virtual
00847 //  Description: Calls mainloop for the registered button object
00848 ////////////////////////////////////////////////////////////////////
00849 void VrpnClient::
00850 poll_button(const string &button) {
00851   _vrpn_buttons[button]->mainloop();
00852 }
00853 
00854 ////////////////////////////////////////////////////////////////////
00855 //     Function: VrpnClient::poll_dial
00856 //       Access: Public, Virtual
00857 //  Description: Calls mainloop for the registered dial object
00858 ////////////////////////////////////////////////////////////////////
00859 void VrpnClient::
00860 poll_dial(const string &dial) {
00861   _vrpn_dials[dial]->mainloop();
00862 }
00863 
00864 ////////////////////////////////////////////////////////////////////
00865 //     Function: VrpnClient::st_tracker_position
00866 //       Access: Private, Static
00867 //  Description: Callback function that merely passes the data down
00868 //               to the appropriate non-static function
00869 ////////////////////////////////////////////////////////////////////
00870 void VrpnClient::
00871 st_tracker_position(void *userdata, const vrpn_TRACKERCB info) {
00872   VrpnClientInfo *data = (VrpnClientInfo *)userdata;
00873   ((VrpnClient *)data->self)->tracker_position(data->device_name, info);
00874 }
00875 
00876 ////////////////////////////////////////////////////////////////////
00877 //     Function: VrpnClient::st_tracker_velocity
00878 //       Access: Private, Static
00879 //  Description: Callback function that merely passes the data down
00880 //               to the appropriate non-static function
00881 ////////////////////////////////////////////////////////////////////
00882 void VrpnClient::
00883 st_tracker_velocity(void *userdata, const vrpn_TRACKERVELCB info) {
00884   VrpnClientInfo *data = (VrpnClientInfo *)userdata;
00885   ((VrpnClient *)data->self)->tracker_velocity(data->device_name, info);
00886 }
00887 ////////////////////////////////////////////////////////////////////
00888 //     Function: VrpnClient::st_tracker_acceleration
00889 //       Access: Private, Static
00890 //  Description: Callback function that merely passes the data down
00891 //               to the appropriate non-static function
00892 ////////////////////////////////////////////////////////////////////
00893 void VrpnClient::
00894 st_tracker_acceleration(void *userdata, const vrpn_TRACKERACCCB info) {
00895   VrpnClientInfo *data = (VrpnClientInfo *)userdata;
00896   ((VrpnClient *)data->self)->tracker_acceleration(data->device_name, info);
00897 }
00898 
00899 ////////////////////////////////////////////////////////////////////
00900 //     Function: VrpnClient::st_analog
00901 //       Access: Private, Static
00902 //  Description: Callback function that merely passes the data down
00903 //               to the appropriate non-static function
00904 ////////////////////////////////////////////////////////////////////
00905 void VrpnClient::
00906 st_analog(void *userdata, const vrpn_ANALOGCB info) {
00907   VrpnClientInfo *data = (VrpnClientInfo *)userdata;
00908   ((VrpnClient *)data->self)->analog(data->device_name, info);
00909 }
00910 
00911 ////////////////////////////////////////////////////////////////////
00912 //     Function: VrpnClient::st_button
00913 //       Access: Private, Static
00914 //  Description: Callback function that merely passes the data down
00915 //               to the appropriate non-static function
00916 ////////////////////////////////////////////////////////////////////
00917 void VrpnClient::
00918 st_button(void *userdata, const vrpn_BUTTONCB info) {
00919   VrpnClientInfo *data = (VrpnClientInfo *)userdata;
00920   ((VrpnClient *)data->self)->button(data->device_name, info);
00921 }
00922 
00923 ////////////////////////////////////////////////////////////////////
00924 //     Function: VrpnClient::st_dial
00925 //       Access: Private, Static
00926 //  Description: Callback function that merely passes the data down
00927 //               to the appropriate non-static function
00928 ////////////////////////////////////////////////////////////////////
00929 void VrpnClient::
00930 st_dial(void *userdata, const vrpn_DIALCB info) {
00931   VrpnClientInfo *data = (VrpnClientInfo *)userdata;
00932   ((VrpnClient *)data->self)->dial(data->device_name, info);
00933 }
00934 
00935 #endif

Generated on Fri May 2 00:44:35 2003 for Panda by doxygen1.3