00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "OVR_LatencyTestImpl.h"
00017
00018 namespace OVR {
00019
00020
00021
00022
00023 enum {
00024 LatencyTester_VendorId = Oculus_VendorId,
00025 LatencyTester_ProductId = 0x0101,
00026 };
00027
00028
00029 static UInt16 DecodeUInt16(const UByte* buffer)
00030 {
00031 return (UInt16(buffer[1]) << 8) | UInt16(buffer[0]);
00032 }
00033
00034
00035
00036
00037
00038
00039
00040 static void UnpackSamples(const UByte* buffer, UByte* r, UByte* g, UByte* b)
00041 {
00042 *r = buffer[0];
00043 *g = buffer[1];
00044 *b = buffer[2];
00045 }
00046
00047
00048 enum LatencyTestMessageType
00049 {
00050 LatencyTestMessage_None = 0,
00051 LatencyTestMessage_Samples = 1,
00052 LatencyTestMessage_ColorDetected = 2,
00053 LatencyTestMessage_TestStarted = 3,
00054 LatencyTestMessage_Button = 4,
00055 LatencyTestMessage_Unknown = 0x100,
00056 LatencyTestMessage_SizeError = 0x101,
00057 };
00058
00059 struct LatencyTestSample
00060 {
00061 UByte Value[3];
00062 };
00063
00064 struct LatencyTestSamples
00065 {
00066 UByte SampleCount;
00067 UInt16 Timestamp;
00068
00069 LatencyTestSample Samples[20];
00070
00071 LatencyTestMessageType Decode(const UByte* buffer, int size)
00072 {
00073 if (size < 64)
00074 {
00075 return LatencyTestMessage_SizeError;
00076 }
00077
00078 SampleCount = buffer[1];
00079 Timestamp = DecodeUInt16(buffer + 2);
00080
00081 for (UByte i = 0; i < SampleCount; i++)
00082 {
00083 UnpackSamples(buffer + 4 + (3 * i), &Samples[i].Value[0], &Samples[i].Value[1], &Samples[i].Value[2]);
00084 }
00085
00086 return LatencyTestMessage_Samples;
00087 }
00088 };
00089
00090 struct LatencyTestSamplesMessage
00091 {
00092 LatencyTestMessageType Type;
00093 LatencyTestSamples Samples;
00094 };
00095
00096 bool DecodeLatencyTestSamplesMessage(LatencyTestSamplesMessage* message, UByte* buffer, int size)
00097 {
00098 memset(message, 0, sizeof(LatencyTestSamplesMessage));
00099
00100 if (size < 64)
00101 {
00102 message->Type = LatencyTestMessage_SizeError;
00103 return false;
00104 }
00105
00106 switch (buffer[0])
00107 {
00108 case LatencyTestMessage_Samples:
00109 message->Type = message->Samples.Decode(buffer, size);
00110 break;
00111
00112 default:
00113 message->Type = LatencyTestMessage_Unknown;
00114 break;
00115 }
00116
00117 return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
00118 }
00119
00120 struct LatencyTestColorDetected
00121 {
00122 UInt16 CommandID;
00123 UInt16 Timestamp;
00124 UInt16 Elapsed;
00125 UByte TriggerValue[3];
00126 UByte TargetValue[3];
00127
00128 LatencyTestMessageType Decode(const UByte* buffer, int size)
00129 {
00130 if (size < 13)
00131 return LatencyTestMessage_SizeError;
00132
00133 CommandID = DecodeUInt16(buffer + 1);
00134 Timestamp = DecodeUInt16(buffer + 3);
00135 Elapsed = DecodeUInt16(buffer + 5);
00136 memcpy(TriggerValue, buffer + 7, 3);
00137 memcpy(TargetValue, buffer + 10, 3);
00138
00139 return LatencyTestMessage_ColorDetected;
00140 }
00141 };
00142
00143 struct LatencyTestColorDetectedMessage
00144 {
00145 LatencyTestMessageType Type;
00146 LatencyTestColorDetected ColorDetected;
00147 };
00148
00149 bool DecodeLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage* message, UByte* buffer, int size)
00150 {
00151 memset(message, 0, sizeof(LatencyTestColorDetectedMessage));
00152
00153 if (size < 13)
00154 {
00155 message->Type = LatencyTestMessage_SizeError;
00156 return false;
00157 }
00158
00159 switch (buffer[0])
00160 {
00161 case LatencyTestMessage_ColorDetected:
00162 message->Type = message->ColorDetected.Decode(buffer, size);
00163 break;
00164
00165 default:
00166 message->Type = LatencyTestMessage_Unknown;
00167 break;
00168 }
00169
00170 return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
00171 }
00172
00173 struct LatencyTestStarted
00174 {
00175 UInt16 CommandID;
00176 UInt16 Timestamp;
00177 UByte TargetValue[3];
00178
00179 LatencyTestMessageType Decode(const UByte* buffer, int size)
00180 {
00181 if (size < 8)
00182 return LatencyTestMessage_SizeError;
00183
00184 CommandID = DecodeUInt16(buffer + 1);
00185 Timestamp = DecodeUInt16(buffer + 3);
00186 memcpy(TargetValue, buffer + 5, 3);
00187
00188 return LatencyTestMessage_TestStarted;
00189 }
00190 };
00191
00192 struct LatencyTestStartedMessage
00193 {
00194 LatencyTestMessageType Type;
00195 LatencyTestStarted TestStarted;
00196 };
00197
00198 bool DecodeLatencyTestStartedMessage(LatencyTestStartedMessage* message, UByte* buffer, int size)
00199 {
00200 memset(message, 0, sizeof(LatencyTestStartedMessage));
00201
00202 if (size < 8)
00203 {
00204 message->Type = LatencyTestMessage_SizeError;
00205 return false;
00206 }
00207
00208 switch (buffer[0])
00209 {
00210 case LatencyTestMessage_TestStarted:
00211 message->Type = message->TestStarted.Decode(buffer, size);
00212 break;
00213
00214 default:
00215 message->Type = LatencyTestMessage_Unknown;
00216 break;
00217 }
00218
00219 return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
00220 }
00221
00222 struct LatencyTestButton
00223 {
00224 UInt16 CommandID;
00225 UInt16 Timestamp;
00226
00227 LatencyTestMessageType Decode(const UByte* buffer, int size)
00228 {
00229 if (size < 5)
00230 return LatencyTestMessage_SizeError;
00231
00232 CommandID = DecodeUInt16(buffer + 1);
00233 Timestamp = DecodeUInt16(buffer + 3);
00234
00235 return LatencyTestMessage_Button;
00236 }
00237 };
00238
00239 struct LatencyTestButtonMessage
00240 {
00241 LatencyTestMessageType Type;
00242 LatencyTestButton Button;
00243 };
00244
00245 bool DecodeLatencyTestButtonMessage(LatencyTestButtonMessage* message, UByte* buffer, int size)
00246 {
00247 memset(message, 0, sizeof(LatencyTestButtonMessage));
00248
00249 if (size < 5)
00250 {
00251 message->Type = LatencyTestMessage_SizeError;
00252 return false;
00253 }
00254
00255 switch (buffer[0])
00256 {
00257 case LatencyTestMessage_Button:
00258 message->Type = message->Button.Decode(buffer, size);
00259 break;
00260
00261 default:
00262 message->Type = LatencyTestMessage_Unknown;
00263 break;
00264 }
00265
00266 return (message->Type < LatencyTestMessage_Unknown) && (message->Type != LatencyTestMessage_None);
00267 }
00268
00269 struct LatencyTestConfigurationImpl
00270 {
00271 enum { PacketSize = 5 };
00272 UByte Buffer[PacketSize];
00273
00274 OVR::LatencyTestConfiguration Configuration;
00275
00276 LatencyTestConfigurationImpl(const OVR::LatencyTestConfiguration& configuration)
00277 : Configuration(configuration)
00278 {
00279 Pack();
00280 }
00281
00282 void Pack()
00283 {
00284 Buffer[0] = 5;
00285 Buffer[1] = UByte(Configuration.SendSamples);
00286 Buffer[2] = Configuration.Threshold.R;
00287 Buffer[3] = Configuration.Threshold.G;
00288 Buffer[4] = Configuration.Threshold.B;
00289 }
00290
00291 void Unpack()
00292 {
00293 Configuration.SendSamples = Buffer[1] != 0 ? true : false;
00294 Configuration.Threshold.R = Buffer[2];
00295 Configuration.Threshold.G = Buffer[3];
00296 Configuration.Threshold.B = Buffer[4];
00297 }
00298 };
00299
00300 struct LatencyTestCalibrateImpl
00301 {
00302 enum { PacketSize = 4 };
00303 UByte Buffer[PacketSize];
00304
00305 Color CalibrationColor;
00306
00307 LatencyTestCalibrateImpl(const Color& calibrationColor)
00308 : CalibrationColor(calibrationColor)
00309 {
00310 Pack();
00311 }
00312
00313 void Pack()
00314 {
00315 Buffer[0] = 7;
00316 Buffer[1] = CalibrationColor.R;
00317 Buffer[2] = CalibrationColor.G;
00318 Buffer[3] = CalibrationColor.B;
00319 }
00320
00321 void Unpack()
00322 {
00323 CalibrationColor.R = Buffer[1];
00324 CalibrationColor.G = Buffer[2];
00325 CalibrationColor.B = Buffer[3];
00326 }
00327 };
00328
00329 struct LatencyTestStartTestImpl
00330 {
00331 enum { PacketSize = 6 };
00332 UByte Buffer[PacketSize];
00333
00334 Color TargetColor;
00335
00336 LatencyTestStartTestImpl(const Color& targetColor)
00337 : TargetColor(targetColor)
00338 {
00339 Pack();
00340 }
00341
00342 void Pack()
00343 {
00344 UInt16 commandID = 1;
00345
00346 Buffer[0] = 8;
00347 Buffer[1] = UByte(commandID & 0xFF);
00348 Buffer[2] = UByte(commandID >> 8);
00349 Buffer[3] = TargetColor.R;
00350 Buffer[4] = TargetColor.G;
00351 Buffer[5] = TargetColor.B;
00352 }
00353
00354 void Unpack()
00355 {
00356
00357 TargetColor.R = Buffer[3];
00358 TargetColor.G = Buffer[4];
00359 TargetColor.B = Buffer[5];
00360 }
00361 };
00362
00363 struct LatencyTestDisplayImpl
00364 {
00365 enum { PacketSize = 6 };
00366 UByte Buffer[PacketSize];
00367
00368 OVR::LatencyTestDisplay Display;
00369
00370 LatencyTestDisplayImpl(const OVR::LatencyTestDisplay& display)
00371 : Display(display)
00372 {
00373 Pack();
00374 }
00375
00376 void Pack()
00377 {
00378 Buffer[0] = 9;
00379 Buffer[1] = Display.Mode;
00380 Buffer[2] = UByte(Display.Value & 0xFF);
00381 Buffer[3] = UByte((Display.Value >> 8) & 0xFF);
00382 Buffer[4] = UByte((Display.Value >> 16) & 0xFF);
00383 Buffer[5] = UByte((Display.Value >> 24) & 0xFF);
00384 }
00385
00386 void Unpack()
00387 {
00388 Display.Mode = Buffer[1];
00389 Display.Value = UInt32(Buffer[2]) |
00390 (UInt32(Buffer[3]) << 8) |
00391 (UInt32(Buffer[4]) << 16) |
00392 (UInt32(Buffer[5]) << 24);
00393 }
00394 };
00395
00396
00397
00398
00399 LatencyTestDeviceFactory LatencyTestDeviceFactory::Instance;
00400
00401 void LatencyTestDeviceFactory::EnumerateDevices(EnumerateVisitor& visitor)
00402 {
00403
00404 class LatencyTestEnumerator : public HIDEnumerateVisitor
00405 {
00406
00407 void operator = (const LatencyTestEnumerator&) { }
00408
00409 DeviceFactory* pFactory;
00410 EnumerateVisitor& ExternalVisitor;
00411 public:
00412 LatencyTestEnumerator(DeviceFactory* factory, EnumerateVisitor& externalVisitor)
00413 : pFactory(factory), ExternalVisitor(externalVisitor) { }
00414
00415 virtual bool MatchVendorProduct(UInt16 vendorId, UInt16 productId)
00416 {
00417 return pFactory->MatchVendorProduct(vendorId, productId);
00418 }
00419
00420 virtual void Visit(HIDDevice& device, const HIDDeviceDesc& desc)
00421 {
00422 OVR_UNUSED(device);
00423
00424 LatencyTestDeviceCreateDesc createDesc(pFactory, desc);
00425 ExternalVisitor.Visit(createDesc);
00426 }
00427 };
00428
00429 LatencyTestEnumerator latencyTestEnumerator(this, visitor);
00430 GetManagerImpl()->GetHIDDeviceManager()->Enumerate(&latencyTestEnumerator);
00431 }
00432
00433 bool LatencyTestDeviceFactory::MatchVendorProduct(UInt16 vendorId, UInt16 productId) const
00434 {
00435 return ((vendorId == LatencyTester_VendorId) && (productId == LatencyTester_ProductId));
00436 }
00437
00438 bool LatencyTestDeviceFactory::DetectHIDDevice(DeviceManager* pdevMgr,
00439 const HIDDeviceDesc& desc)
00440 {
00441 if (MatchVendorProduct(desc.VendorId, desc.ProductId))
00442 {
00443 LatencyTestDeviceCreateDesc createDesc(this, desc);
00444 return pdevMgr->AddDevice_NeedsLock(createDesc).GetPtr() != NULL;
00445 }
00446 return false;
00447 }
00448
00449
00450
00451
00452 DeviceBase* LatencyTestDeviceCreateDesc::NewDeviceInstance()
00453 {
00454 return new LatencyTestDeviceImpl(this);
00455 }
00456
00457 bool LatencyTestDeviceCreateDesc::GetDeviceInfo(DeviceInfo* info) const
00458 {
00459 if ((info->InfoClassType != Device_LatencyTester) &&
00460 (info->InfoClassType != Device_None))
00461 return false;
00462
00463 OVR_strcpy(info->ProductName, DeviceInfo::MaxNameLength, HIDDesc.Product.ToCStr());
00464 OVR_strcpy(info->Manufacturer, DeviceInfo::MaxNameLength, HIDDesc.Manufacturer.ToCStr());
00465 info->Type = Device_LatencyTester;
00466 info->Version = 0;
00467
00468 if (info->InfoClassType == Device_LatencyTester)
00469 {
00470 SensorInfo* sinfo = (SensorInfo*)info;
00471 sinfo->VendorId = HIDDesc.VendorId;
00472 sinfo->ProductId = HIDDesc.ProductId;
00473 OVR_strcpy(sinfo->SerialNumber, sizeof(sinfo->SerialNumber),HIDDesc.SerialNumber.ToCStr());
00474 }
00475 return true;
00476 }
00477
00478
00479
00480
00481 LatencyTestDeviceImpl::LatencyTestDeviceImpl(LatencyTestDeviceCreateDesc* createDesc)
00482 : OVR::HIDDeviceImpl<OVR::LatencyTestDevice>(createDesc, 0)
00483 {
00484 }
00485
00486 LatencyTestDeviceImpl::~LatencyTestDeviceImpl()
00487 {
00488
00489 OVR_ASSERT(!pCreateDesc->pDevice);
00490 }
00491
00492
00493 bool LatencyTestDeviceImpl::Initialize(DeviceBase* parent)
00494 {
00495 if (HIDDeviceImpl<OVR::LatencyTestDevice>::Initialize(parent))
00496 {
00497 LogText("OVR::LatencyTestDevice initialized.\n");
00498 return true;
00499 }
00500
00501 return false;
00502 }
00503
00504 void LatencyTestDeviceImpl::Shutdown()
00505 {
00506 HIDDeviceImpl<OVR::LatencyTestDevice>::Shutdown();
00507
00508 LogText("OVR::LatencyTestDevice - Closed '%s'\n", getHIDDesc()->Path.ToCStr());
00509 }
00510
00511 void LatencyTestDeviceImpl::OnInputReport(UByte* pData, UInt32 length)
00512 {
00513
00514 bool processed = false;
00515 if (!processed)
00516 {
00517 LatencyTestSamplesMessage message;
00518 if (DecodeLatencyTestSamplesMessage(&message, pData, length))
00519 {
00520 processed = true;
00521 onLatencyTestSamplesMessage(&message);
00522 }
00523 }
00524
00525 if (!processed)
00526 {
00527 LatencyTestColorDetectedMessage message;
00528 if (DecodeLatencyTestColorDetectedMessage(&message, pData, length))
00529 {
00530 processed = true;
00531 onLatencyTestColorDetectedMessage(&message);
00532 }
00533 }
00534
00535 if (!processed)
00536 {
00537 LatencyTestStartedMessage message;
00538 if (DecodeLatencyTestStartedMessage(&message, pData, length))
00539 {
00540 processed = true;
00541 onLatencyTestStartedMessage(&message);
00542 }
00543 }
00544
00545 if (!processed)
00546 {
00547 LatencyTestButtonMessage message;
00548 if (DecodeLatencyTestButtonMessage(&message, pData, length))
00549 {
00550 processed = true;
00551 onLatencyTestButtonMessage(&message);
00552 }
00553 }
00554 }
00555
00556 bool LatencyTestDeviceImpl::SetConfiguration(const OVR::LatencyTestConfiguration& configuration, bool waitFlag)
00557 {
00558 bool result = false;
00559 ThreadCommandQueue* queue = GetManagerImpl()->GetThreadQueue();
00560
00561 if (GetManagerImpl()->GetThreadId() != OVR::GetCurrentThreadId())
00562 {
00563 if (!waitFlag)
00564 {
00565 return queue->PushCall(this, &LatencyTestDeviceImpl::setConfiguration, configuration);
00566 }
00567
00568 if (!queue->PushCallAndWaitResult( this,
00569 &LatencyTestDeviceImpl::setConfiguration,
00570 &result,
00571 configuration))
00572 {
00573 return false;
00574 }
00575 }
00576 else
00577 return setConfiguration(configuration);
00578
00579 return result;
00580 }
00581
00582 bool LatencyTestDeviceImpl::setConfiguration(const OVR::LatencyTestConfiguration& configuration)
00583 {
00584 LatencyTestConfigurationImpl ltc(configuration);
00585 return GetInternalDevice()->SetFeatureReport(ltc.Buffer, LatencyTestConfigurationImpl::PacketSize);
00586 }
00587
00588 bool LatencyTestDeviceImpl::GetConfiguration(OVR::LatencyTestConfiguration* configuration)
00589 {
00590 bool result = false;
00591
00592 ThreadCommandQueue* pQueue = this->GetManagerImpl()->GetThreadQueue();
00593 if (!pQueue->PushCallAndWaitResult(this, &LatencyTestDeviceImpl::getConfiguration, &result, configuration))
00594 return false;
00595
00596 return result;
00597 }
00598
00599 bool LatencyTestDeviceImpl::getConfiguration(OVR::LatencyTestConfiguration* configuration)
00600 {
00601 LatencyTestConfigurationImpl ltc(*configuration);
00602 if (GetInternalDevice()->GetFeatureReport(ltc.Buffer, LatencyTestConfigurationImpl::PacketSize))
00603 {
00604 ltc.Unpack();
00605 *configuration = ltc.Configuration;
00606 return true;
00607 }
00608
00609 return false;
00610 }
00611
00612 bool LatencyTestDeviceImpl::SetCalibrate(const Color& calibrationColor, bool waitFlag)
00613 {
00614 bool result = false;
00615 ThreadCommandQueue* queue = GetManagerImpl()->GetThreadQueue();
00616
00617 if (!waitFlag)
00618 {
00619 return queue->PushCall(this, &LatencyTestDeviceImpl::setCalibrate, calibrationColor);
00620 }
00621
00622 if (!queue->PushCallAndWaitResult( this,
00623 &LatencyTestDeviceImpl::setCalibrate,
00624 &result,
00625 calibrationColor))
00626 {
00627 return false;
00628 }
00629
00630 return result;
00631 }
00632
00633 bool LatencyTestDeviceImpl::setCalibrate(const Color& calibrationColor)
00634 {
00635 LatencyTestCalibrateImpl ltc(calibrationColor);
00636 return GetInternalDevice()->SetFeatureReport(ltc.Buffer, LatencyTestCalibrateImpl::PacketSize);
00637 }
00638
00639 bool LatencyTestDeviceImpl::SetStartTest(const Color& targetColor, bool waitFlag)
00640 {
00641 bool result = false;
00642 ThreadCommandQueue* queue = GetManagerImpl()->GetThreadQueue();
00643
00644 if (!waitFlag)
00645 {
00646 return queue->PushCall(this, &LatencyTestDeviceImpl::setStartTest, targetColor);
00647 }
00648
00649 if (!queue->PushCallAndWaitResult( this,
00650 &LatencyTestDeviceImpl::setStartTest,
00651 &result,
00652 targetColor))
00653 {
00654 return false;
00655 }
00656
00657 return result;
00658 }
00659
00660 bool LatencyTestDeviceImpl::setStartTest(const Color& targetColor)
00661 {
00662 LatencyTestStartTestImpl ltst(targetColor);
00663 return GetInternalDevice()->SetFeatureReport(ltst.Buffer, LatencyTestStartTestImpl::PacketSize);
00664 }
00665
00666 bool LatencyTestDeviceImpl::SetDisplay(const OVR::LatencyTestDisplay& display, bool waitFlag)
00667 {
00668 bool result = false;
00669 ThreadCommandQueue * queue = GetManagerImpl()->GetThreadQueue();
00670
00671 if (!waitFlag)
00672 {
00673 return queue->PushCall(this, &LatencyTestDeviceImpl::setDisplay, display);
00674 }
00675
00676 if (!queue->PushCallAndWaitResult( this,
00677 &LatencyTestDeviceImpl::setDisplay,
00678 &result,
00679 display))
00680 {
00681 return false;
00682 }
00683
00684 return result;
00685 }
00686
00687 bool LatencyTestDeviceImpl::setDisplay(const OVR::LatencyTestDisplay& display)
00688 {
00689 LatencyTestDisplayImpl ltd(display);
00690 return GetInternalDevice()->SetFeatureReport(ltd.Buffer, LatencyTestDisplayImpl::PacketSize);
00691 }
00692
00693 void LatencyTestDeviceImpl::onLatencyTestSamplesMessage(LatencyTestSamplesMessage* message)
00694 {
00695
00696 if (message->Type != LatencyTestMessage_Samples)
00697 return;
00698
00699 LatencyTestSamples& s = message->Samples;
00700
00701
00702 Lock::Locker scopeLock(HandlerRef.GetLock());
00703
00704 if (HandlerRef.GetHandler())
00705 {
00706 MessageLatencyTestSamples samples(this);
00707 for (UByte i = 0; i < s.SampleCount; i++)
00708 {
00709 samples.Samples.PushBack(Color(s.Samples[i].Value[0], s.Samples[i].Value[1], s.Samples[i].Value[2]));
00710 }
00711
00712 HandlerRef.GetHandler()->OnMessage(samples);
00713 }
00714 }
00715
00716 void LatencyTestDeviceImpl::onLatencyTestColorDetectedMessage(LatencyTestColorDetectedMessage* message)
00717 {
00718 if (message->Type != LatencyTestMessage_ColorDetected)
00719 return;
00720
00721 LatencyTestColorDetected& s = message->ColorDetected;
00722
00723
00724 Lock::Locker scopeLock(HandlerRef.GetLock());
00725
00726 if (HandlerRef.GetHandler())
00727 {
00728 MessageLatencyTestColorDetected detected(this);
00729 detected.Elapsed = s.Elapsed;
00730 detected.DetectedValue = Color(s.TriggerValue[0], s.TriggerValue[1], s.TriggerValue[2]);
00731 detected.TargetValue = Color(s.TargetValue[0], s.TargetValue[1], s.TargetValue[2]);
00732
00733 HandlerRef.GetHandler()->OnMessage(detected);
00734 }
00735 }
00736
00737 void LatencyTestDeviceImpl::onLatencyTestStartedMessage(LatencyTestStartedMessage* message)
00738 {
00739 if (message->Type != LatencyTestMessage_TestStarted)
00740 return;
00741
00742 LatencyTestStarted& ts = message->TestStarted;
00743
00744
00745 Lock::Locker scopeLock(HandlerRef.GetLock());
00746
00747 if (HandlerRef.GetHandler())
00748 {
00749 MessageLatencyTestStarted started(this);
00750 started.TargetValue = Color(ts.TargetValue[0], ts.TargetValue[1], ts.TargetValue[2]);
00751
00752 HandlerRef.GetHandler()->OnMessage(started);
00753 }
00754 }
00755
00756 void LatencyTestDeviceImpl::onLatencyTestButtonMessage(LatencyTestButtonMessage* message)
00757 {
00758 if (message->Type != LatencyTestMessage_Button)
00759 return;
00760
00761
00762
00763
00764 Lock::Locker scopeLock(HandlerRef.GetLock());
00765
00766 if (HandlerRef.GetHandler())
00767 {
00768 MessageLatencyTestButton button(this);
00769
00770 HandlerRef.GetHandler()->OnMessage(button);
00771 }
00772 }
00773
00774 }