00001 // Filename: clientDevice.cxx 00002 // Created by: drose (25Jan01) 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 00020 #include "clientDevice.h" 00021 #include "clientBase.h" 00022 00023 #include <indent.h> 00024 00025 TypeHandle ClientDevice::_type_handle; 00026 00027 //////////////////////////////////////////////////////////////////// 00028 // Function: ClientDevice::Constructor 00029 // Access: Protected 00030 // Description: 00031 //////////////////////////////////////////////////////////////////// 00032 ClientDevice:: 00033 ClientDevice(ClientBase *client, TypeHandle device_type, 00034 const string &device_name) : 00035 _client(client), 00036 _device_type(device_type), 00037 _device_name(device_name) 00038 { 00039 // We have to explicitly ref the client pointer, since we can't use 00040 // a PT(ClientBase) for circular include reasons. 00041 _client->ref(); 00042 _is_connected = false; 00043 } 00044 00045 //////////////////////////////////////////////////////////////////// 00046 // Function: ClientDevice::Destructor 00047 // Access: Public, Virtual 00048 // Description: We don't actually call disconnect() at the 00049 // ClientDevice level destructor, because by the time 00050 // we get here we're already partly destructed. 00051 // Instead, we should call disconnect() from each 00052 // specific kind of derived class. 00053 //////////////////////////////////////////////////////////////////// 00054 ClientDevice:: 00055 ~ClientDevice() { 00056 nassertv(!_is_connected); 00057 00058 // And now we explicitly unref the client pointer. 00059 unref_delete(_client); 00060 } 00061 00062 //////////////////////////////////////////////////////////////////// 00063 // Function: ClientDevice::disconnect 00064 // Access: Public 00065 // Description: Disconnects the ClientDevice from its ClientBase 00066 // object. The device will stop receiving 00067 // updates. 00068 // 00069 // Normally, you should not need to call this explicitly 00070 // (and it is probably a mistake to do so); it will 00071 // automatically be called when the ClientDevice object 00072 // destructs. 00073 // 00074 // The lock should *not* be held while this call is 00075 // made; it will explicitly grab the lock itself. 00076 //////////////////////////////////////////////////////////////////// 00077 void ClientDevice:: 00078 disconnect() { 00079 if (_is_connected) { 00080 lock(); 00081 bool disconnected = 00082 _client->disconnect_device(_device_type, _device_name, this); 00083 _is_connected = false; 00084 unlock(); 00085 nassertv(disconnected); 00086 } 00087 } 00088 00089 //////////////////////////////////////////////////////////////////// 00090 // Function: ClientDevice::poll 00091 // Access: Public 00092 // Description: Causes the connected ClientBase to poll all of its 00093 // clients, if necessary. This will be a no-op if the 00094 // client is running in forked mode, or if it has 00095 // already polled everything this frame. 00096 // 00097 // This should generally be called before accessing the 00098 // data in this ClientDevice to ensure that it is fresh. 00099 //////////////////////////////////////////////////////////////////// 00100 void ClientDevice:: 00101 poll() { 00102 _client->poll(); 00103 } 00104 00105 //////////////////////////////////////////////////////////////////// 00106 // Function: ClientDevice::output 00107 // Access: Public, Virtual 00108 // Description: 00109 //////////////////////////////////////////////////////////////////// 00110 void ClientDevice:: 00111 output(ostream &out) const { 00112 out << get_type() << " " << get_device_name(); 00113 } 00114 00115 //////////////////////////////////////////////////////////////////// 00116 // Function: ClientDevice::write 00117 // Access: Public, Virtual 00118 // Description: 00119 //////////////////////////////////////////////////////////////////// 00120 void ClientDevice:: 00121 write(ostream &out, int indent_level) const { 00122 indent(out, indent_level) << *this << "\n"; 00123 }