Panda3D

vrpnClient.cxx

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