00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026
00027 #ifndef RemoteNodeField_H
00028 #define RemoteNodeField_H
00029
00030 #include "H3DNetworkingUtils/RemoteField.h"
00031 #include <H3D/Node.h>
00032
00033 #include "H3DNetworkingUtils/RemoteConnection.h"
00034 #include "H3DNetworkingUtils/Config.h"
00035 #include <H3DUtil/Threads.h>
00036 #include <H3D/MFInt32.h>
00037 #include <H3D/SFInt32.h>
00038 #include <H3D/MFVec3f.h>
00039 #include <H3D/MFBool.h>
00040
00041
00042 namespace H3D {
00043 H3D_VALUE_EXCEPTION( int, InvalidNodeFieldFlag );
00044 }
00045
00046 namespace H3DNetworkingUtils {
00047
00074
00075 template< class TheNode, class MultiFieldType, auto_ptr<MultiFieldType> TheNode::*fld >
00076 class H3D_NETWORKING_UTILS_DLL_SPEC RemoteNodeField : public RemoteField {
00077 public:
00078 static MultiFieldType *theField( H3D::Node *node ) {
00079 return (static_cast< TheNode* >( node )->*fld).get();
00080 }
00081
00083 RemoteNodeField();
00084
00086 class H3D_NETWORKING_UTILS_DLL_SPEC SFSender : public H3D::AutoUpdate< H3D::SFInt32 > {
00087 public:
00088 virtual void update( ) {
00089 RemoteNodeField * rem_node_fieldP = static_cast<RemoteNodeField *>(getOwner());
00090 H3D::SFInt32 * f = static_cast<H3D::SFInt32 *>(event.ptr);
00091 value = f->getValue();
00092 if (rem_node_fieldP->conP->isConnected->getValue()) {
00093 rem_node_fieldP->conP->lockWriteThread();
00094 rem_node_fieldP->writeSField(value);
00095 rem_node_fieldP->sendPacket();
00096 rem_node_fieldP->conP->unlockWriteThread();
00097 }
00098 }
00099 virtual void setValue( const int & val, int id = 0 ) {
00100 RemoteNodeField * rem_node_fieldP = static_cast<RemoteNodeField *>(getOwner());
00101 H3D::SFInt32::setValue(val, id);
00102 if (rem_node_fieldP->conP->isConnected->getValue()) {
00103 rem_node_fieldP->conP->lockWriteThread();
00104 rem_node_fieldP->writeSField(val);
00105 rem_node_fieldP->sendPacket();
00106 rem_node_fieldP->conP->unlockWriteThread();
00107 }
00108 }
00109 };
00110
00112 class H3D_NETWORKING_UTILS_DLL_SPEC MFSender : public H3D::AutoUpdate< H3D::MFInt32 > {
00113 public:
00114 virtual void update() {
00115 H3D::MFInt32 * f = static_cast<H3D::MFInt32 *>(event.ptr);
00116 RemoteNodeField * rem_node_fieldP = static_cast<RemoteNodeField *>(getOwner());
00117 value = f->getValue();
00118 if (rem_node_fieldP->conP->isConnected->getValue()) {
00119 rem_node_fieldP->conP->lockWriteThread();
00120 rem_node_fieldP->writeMField(value);
00121 rem_node_fieldP->sendPacket();
00122 rem_node_fieldP->conP->unlockWriteThread();
00123 }
00124 }
00125 virtual void setValue( const std::vector<int> & val, int id = 0 ) {
00126 RemoteNodeField * rem_node_fieldP = static_cast<RemoteNodeField *>(getOwner());
00127 H3D::MFInt32::setValue(val, id);
00128 if (rem_node_fieldP->conP->isConnected->getValue()) {
00129 rem_node_fieldP->conP->lockWriteThread();
00130 rem_node_fieldP->writeMField(val);
00131 rem_node_fieldP->sendPacket();
00132 rem_node_fieldP->conP->unlockWriteThread();
00133 }
00134 }
00135 virtual void setValue( H3D::MFInt32::size_type index, const int & val, int id = 0 ) {
00136
00137
00138 }
00139 };
00140
00142 class SFSendAll : public H3D::AutoUpdate< H3D::Field > {
00143 public:
00144 virtual void update( ) {
00145 RemoteNodeField * rem_node_fieldP = static_cast<RemoteNodeField *>(getOwner());
00146
00147
00148 if (rem_node_fieldP->conP->isConnected->getValue()) {
00149 rem_node_fieldP->conP->lockWriteThread();
00150 rem_node_fieldP->writeWholeArray();
00151 rem_node_fieldP->sendPacket();
00152 rem_node_fieldP->conP->unlockWriteThread();
00153 }
00154 }
00155 };
00156
00157 typedef H3D::TypedSFNode<TheNode> SFTheNode;
00158
00159
00160
00165 auto_ptr< SFTheNode > theNode;
00166
00171 auto_ptr< SFSender > indexToBeSent;
00172
00177 auto_ptr< MFSender > indiciesToBeSent;
00178
00183 auto_ptr< SFSendAll > sendAll;
00184
00186 static H3D::H3DNodeDatabase database;
00187
00188 protected:
00190 virtual void setSendOnChange(bool val) {}
00191
00193 virtual void writeField () {writeSField(indexToBeSent->getValue());}
00194
00196 virtual void writeSField (unsigned int index);
00197
00199 virtual void writeMField (const std::vector<int> & indicies);
00200
00202 virtual void writeWholeArray ();
00203
00205 virtual void writeValue (typename MultiFieldType::value_type const & val);
00206
00208 virtual typename MultiFieldType::value_type readVal ();
00209
00211 virtual void readValue();
00212
00213 virtual void readMField();
00214
00215 virtual void readSField();
00216
00219 virtual void checkForChange();
00220
00222 static const int WHOLE_ARRAY;
00223
00225 static const int SINGLE_VALUE;
00226
00228 static const int MULTI_VALUE;
00229
00230 private:
00231 struct NodeUpdateData {
00232 std::vector<int> index;
00233 std::vector<typename MultiFieldType::value_type> val;
00234 };
00235
00236 NodeUpdateData data;
00237 bool received_whole_array;
00238 bool data_waiting;
00239
00240 H3D::MutexLock change_lock;
00241
00242 };
00243
00244 }
00245
00246 #endif