00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00025
00026 #ifndef RemoteField_H
00027 #define RemoteField_H
00028
00029
00030 #include "H3DNetworkingUtils/Config.h"
00031 #include <H3D/X3DChildNode.h>
00032 #include <H3D/SFBool.h>
00033 #include <H3D/SFInt32.h>
00034 #include <H3D/SFString.h>
00035 #include <H3D/SFTime.h>
00036 #include <H3D/TraverseInfo.h>
00037 #include <H3D/SFFloat.h>
00038 #include <H3DUtil/AutoRef.h>
00039 #include <H3DUtil/H3DBasicTypes.h>
00040 #include <iostream>
00041 #include <iomanip>
00042 #include <H3D/PeriodicUpdate.h>
00043 #include <H3D/Scene.h>
00044 #include <HAPI/HAPIForceEffect.h>
00045
00046 namespace H3DNetworkingUtils {
00047
00053
00054
00055 class RemoteConnection;
00056
00057 class H3D_NETWORKING_UTILS_DLL_SPEC RemoteField : public H3D::X3DChildNode {
00058
00059 public:
00060 struct H3D_NETWORKING_UTILS_DLL_SPEC Enabled : public H3D::SFBool {
00061 virtual void setValue(bool const & val, int id = 0) {
00062 l.lock(); H3D::SFBool::setValue(val, id); l.unlock();}
00063
00064 virtual void update() {
00065 l.lock(); H3D::SFBool::update(); l.unlock();}
00066
00067 const bool & getValue(int id = 0) {
00068 l.lock(); g = H3D::SFBool::getValue(id); l.unlock(); return g;
00069 }
00070 H3D::MutexLock l;
00071 bool g;
00072 };
00073
00074 RemoteField(H3D::Inst<H3D::SFInt32> _id = 0,
00075 H3D::Inst<H3D::SFFloat> _printPeriod = 0,
00076 H3D::Inst<H3D::SFBool> _sendOnceOnConnect = 0,
00077 H3D::Inst<Enabled> _enabled = 0,
00078 H3D::Inst<H3D::SFBool> _bufferReceivedVals = 0,
00079 H3D::Inst<H3D::SFString> _bufferStrategy = 0,
00080 H3D::Inst<H3D::SFTime> _remoteTimestamp = 0,
00081 H3D::Inst<H3D::SFBool> _timestamps = 0,
00082 H3D::Inst<H3D::SFBool> _isHapticField = 0 );
00083
00084 static H3D::H3DNodeDatabase database;
00085
00086 virtual void initialize();
00087
00088 virtual void traverseSG(H3D::TraverseInfo & ti);
00089
00090 virtual void readField();
00091
00092
00093 virtual void writeField() = 0;
00094
00095
00096
00097
00098
00099
00104 auto_ptr< H3D::SFInt32 > fieldId;
00105
00110 auto_ptr< H3D::SFFloat > printPeriod;
00111
00117 auto_ptr< H3D::SFBool > sendOnceOnConnect;
00118
00123 auto_ptr< Enabled > enabled;
00124
00130 auto_ptr< H3D::SFBool > bufferReceivedVals;
00131
00150 auto_ptr< H3D::SFString> bufferStrategy;
00151
00156 auto_ptr< H3D::SFTime > remoteTimestamp;
00157
00162 auto_ptr< H3D::SFBool > timestamps;
00163
00170 auto_ptr< H3D::SFBool > isHapticField;
00171
00175 RemoteConnection * conP;
00176
00178 bool isConnected() const;
00179
00180 virtual void setSendOnChange(bool val) = 0;
00181
00185 virtual void readValue() = 0;
00186
00187 virtual string defaultXMLContainerField() {return "remoteFields";}
00188
00189 protected:
00190 int readInt32();
00191
00192
00193 void writeInt32(const int & val);
00194
00195
00196 bool readBool();
00197
00198
00199 void writeBool(const bool & val);
00200
00201
00202 std::string readString();
00203
00204
00205 void writeString(const std::string & val);
00206
00207
00208 void sendPacket();
00209
00210
00211 virtual void checkForChange() = 0;
00212
00213
00214
00215
00216
00217 bool receivedData() const {return received_data;}
00218
00219
00220
00221 class H3D_NETWORKING_UTILS_DLL_SPEC StatsPrinter : public H3D::PeriodicUpdate< H3D::SFTime > {
00222 public:
00223
00224 StatsPrinter():
00225 counter( 0 ),
00226 latencies( new std::vector< H3D::H3DTime > ) {
00227 start = H3D::Scene::time->getValue();
00228 }
00229
00230 virtual void increment();
00231
00232 virtual void update();
00233
00234 std::string msg;
00235 RemoteField *remote_fld;
00236 std::vector< H3D::H3DTime > *latencies;
00237
00238 private:
00239 H3D::H3DTime start;
00240 int counter;
00241 };
00242 friend class StatsPrinter;
00243
00244
00245
00246 auto_ptr< StatsPrinter > stats_printer;
00247
00248 struct DummyForce : public HAPI::HAPIForceEffect {
00249 DummyForce(RemoteField * fld) : remote_fieldP(fld) {}
00250 HAPI::HAPIForceEffect::EffectOutput virtual calculateForces( const HAPI::HAPIForceEffect::EffectInput &input ) {
00251
00252 try {
00253 remote_fieldP->checkForChange();
00254 } catch (...) {
00255 }
00256 return HAPI::HAPIForceEffect::EffectOutput(H3D::Vec3f(0.0f,0.0f,0.0f));
00257 }
00258 H3D::AutoRef<RemoteField> remote_fieldP;
00259 };
00260
00261
00262 private:
00263 bool collecting_stats;
00264 bool received_data;
00265 };
00266
00267 }
00268
00269 #endif
00270