Now you can download a copy of these docs so you can use them offline! Download now
Dashboard.cpp
00001 /*----------------------------------------------------------------------------*/ 00002 /* Copyright (c) FIRST 2008. All Rights Reserved. */ 00003 /* Open Source Software - may be modified and shared by FRC teams. The code */ 00004 /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */ 00005 /*----------------------------------------------------------------------------*/ 00006 00007 #include "Dashboard.h" 00008 #include "DriverStation.h" 00009 #include "Synchronized.h" 00010 #include "WPIErrors.h" 00011 #include <strLib.h> 00012 00013 const INT32 Dashboard::kMaxDashboardDataSize; 00014 00020 Dashboard::Dashboard(SEM_ID statusDataSem) 00021 : m_userStatusData (NULL) 00022 , m_userStatusDataSize (0) 00023 , m_localBuffer (NULL) 00024 , m_localPrintBuffer (NULL) 00025 , m_packPtr (NULL) 00026 , m_printSemaphore (0) 00027 , m_statusDataSemaphore (statusDataSem) 00028 { 00029 m_userStatusData = new char[kMaxDashboardDataSize]; 00030 m_localBuffer = new char[kMaxDashboardDataSize]; 00031 m_localPrintBuffer = new char[kMaxDashboardDataSize * 2]; 00032 m_localPrintBuffer[0] = 0; 00033 m_packPtr = m_localBuffer; 00034 m_printSemaphore = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE); 00035 } 00036 00042 Dashboard::~Dashboard() 00043 { 00044 semDelete(m_printSemaphore); 00045 m_packPtr = NULL; 00046 delete [] m_localPrintBuffer; 00047 m_localPrintBuffer = NULL; 00048 delete [] m_localBuffer; 00049 m_localBuffer = NULL; 00050 delete [] m_userStatusData; 00051 m_userStatusData = NULL; 00052 } 00053 00058 void Dashboard::AddI8(INT8 value) 00059 { 00060 if (!ValidateAdd(sizeof(INT8))) return; 00061 memcpy(m_packPtr, (char*)&value, sizeof(value)); 00062 m_packPtr += sizeof(value); 00063 AddedElement(kI8); 00064 } 00065 00070 void Dashboard::AddI16(INT16 value) 00071 { 00072 if (!ValidateAdd(sizeof(INT16))) return; 00073 memcpy(m_packPtr, (char*)&value, sizeof(value)); 00074 m_packPtr += sizeof(value); 00075 AddedElement(kI16); 00076 } 00077 00082 void Dashboard::AddI32(INT32 value) 00083 { 00084 if (!ValidateAdd(sizeof(INT32))) return; 00085 memcpy(m_packPtr, (char*)&value, sizeof(value)); 00086 m_packPtr += sizeof(value); 00087 AddedElement(kI32); 00088 } 00089 00094 void Dashboard::AddU8(UINT8 value) 00095 { 00096 if (!ValidateAdd(sizeof(UINT8))) return; 00097 memcpy(m_packPtr, (char*)&value, sizeof(value)); 00098 m_packPtr += sizeof(value); 00099 AddedElement(kU8); 00100 } 00101 00106 void Dashboard::AddU16(UINT16 value) 00107 { 00108 if (!ValidateAdd(sizeof(UINT16))) return; 00109 memcpy(m_packPtr, (char*)&value, sizeof(value)); 00110 m_packPtr += sizeof(value); 00111 AddedElement(kU16); 00112 } 00113 00118 void Dashboard::AddU32(UINT32 value) 00119 { 00120 if (!ValidateAdd(sizeof(UINT32))) return; 00121 memcpy(m_packPtr, (char*)&value, sizeof(value)); 00122 m_packPtr += sizeof(value); 00123 AddedElement(kU32); 00124 } 00125 00130 void Dashboard::AddFloat(float value) 00131 { 00132 if (!ValidateAdd(sizeof(float))) return; 00133 memcpy(m_packPtr, (char*)&value, sizeof(value)); 00134 m_packPtr += sizeof(value); 00135 AddedElement(kFloat); 00136 } 00137 00142 void Dashboard::AddDouble(double value) 00143 { 00144 if (!ValidateAdd(sizeof(double))) return; 00145 memcpy(m_packPtr, (char*)&value, sizeof(value)); 00146 m_packPtr += sizeof(value); 00147 AddedElement(kDouble); 00148 } 00149 00154 void Dashboard::AddBoolean(bool value) 00155 { 00156 if (!ValidateAdd(sizeof(char))) return; 00157 *m_packPtr = value ? 1 : 0; 00158 m_packPtr += sizeof(char); 00159 AddedElement(kBoolean); 00160 } 00161 00166 void Dashboard::AddString(char* value) 00167 { 00168 AddString(value, strlen(value)); 00169 } 00170 00176 void Dashboard::AddString(char* value, INT32 length) 00177 { 00178 if (!ValidateAdd(length + sizeof(length))) return; 00179 memcpy(m_packPtr, (char*)&length, sizeof(length)); 00180 m_packPtr += sizeof(length); 00181 memcpy(m_packPtr, (char*)&value, length); 00182 m_packPtr += length; 00183 AddedElement(kString); 00184 } 00185 00195 void Dashboard::AddArray() 00196 { 00197 if (!ValidateAdd(sizeof(INT32))) return; 00198 m_complexTypeStack.push(kArray); 00199 m_arrayElementCount.push_back(0); 00200 m_arraySizePtr.push_back((INT32*)m_packPtr); 00201 m_packPtr += sizeof(INT32); 00202 } 00203 00210 void Dashboard::FinalizeArray() 00211 { 00212 if (m_complexTypeStack.top() != kArray) 00213 { 00214 wpi_setWPIError(MismatchedComplexTypeClose); 00215 return; 00216 } 00217 m_complexTypeStack.pop(); 00218 *(m_arraySizePtr.back()) = m_arrayElementCount.back(); 00219 m_arraySizePtr.pop_back(); 00220 if (m_arrayElementCount.back() != 0) 00221 { 00222 m_expectedArrayElementType.pop_back(); 00223 } 00224 m_arrayElementCount.pop_back(); 00225 AddedElement(kOther); 00226 } 00227 00235 void Dashboard::AddCluster() 00236 { 00237 m_complexTypeStack.push(kCluster); 00238 } 00239 00246 void Dashboard::FinalizeCluster() 00247 { 00248 if (m_complexTypeStack.top() != kCluster) 00249 { 00250 wpi_setWPIError(MismatchedComplexTypeClose); 00251 return; 00252 } 00253 m_complexTypeStack.pop(); 00254 AddedElement(kOther); 00255 } 00256 00263 void Dashboard::Printf(const char *writeFmt, ...) 00264 { 00265 va_list args; 00266 INT32 size; 00267 00268 // Check if the buffer has already been used for packing. 00269 if (m_packPtr != m_localBuffer) 00270 { 00271 wpi_setWPIError(DashboardDataCollision); 00272 return; 00273 } 00274 va_start (args, writeFmt); 00275 { 00276 Synchronized sync(m_printSemaphore); 00277 vsprintf(m_localPrintBuffer + strlen(m_localPrintBuffer), writeFmt, args); 00278 size = strlen(m_localPrintBuffer); 00279 } 00280 if (size > kMaxDashboardDataSize) 00281 { 00282 wpi_setWPIError(DashboardDataOverflow); 00283 } 00284 00285 va_end (args); 00286 } 00287 00297 INT32 Dashboard::Finalize() 00298 { 00299 if (!m_complexTypeStack.empty()) 00300 { 00301 wpi_setWPIError(MismatchedComplexTypeClose); 00302 return 0; 00303 } 00304 00305 Synchronized sync(m_statusDataSemaphore); 00306 00307 // Sequence number 00308 DriverStation::GetInstance()->IncrementUpdateNumber(); 00309 00310 // Packed Dashboard Data 00311 m_userStatusDataSize = m_packPtr - m_localBuffer; 00312 memcpy(m_userStatusData, m_localBuffer, m_userStatusDataSize); 00313 m_packPtr = m_localBuffer; 00314 00315 return m_userStatusDataSize; 00316 } 00317 00323 void Dashboard::GetStatusBuffer(char **userStatusData, INT32* userStatusDataSize) 00324 { 00325 // User printed strings 00326 if (m_localPrintBuffer[0] != 0) 00327 { 00328 // Sequence number 00329 DriverStation::GetInstance()->IncrementUpdateNumber(); 00330 00331 INT32 printSize; 00332 Synchronized syncPrint(m_printSemaphore); 00333 printSize = strlen(m_localPrintBuffer); 00334 m_userStatusDataSize = printSize; 00335 memcpy(m_userStatusData, m_localPrintBuffer, m_userStatusDataSize); 00336 m_localPrintBuffer[0] = 0; 00337 } 00338 00339 *userStatusData = m_userStatusData; 00340 *userStatusDataSize = m_userStatusDataSize; 00341 } 00342 00346 bool Dashboard::ValidateAdd(INT32 size) 00347 { 00348 if ((m_packPtr - m_localBuffer) + size > kMaxDashboardDataSize) 00349 { 00350 wpi_setWPIError(DashboardDataOverflow); 00351 return false; 00352 } 00353 // Make sure printf is not being used at the same time. 00354 if (m_localPrintBuffer[0] != 0) 00355 { 00356 wpi_setWPIError(DashboardDataCollision); 00357 return false; 00358 } 00359 return true; 00360 } 00361 00365 void Dashboard::AddedElement(Type type) 00366 { 00367 if(IsArrayRoot()) 00368 { 00369 if (m_arrayElementCount.back() == 0) 00370 { 00371 m_expectedArrayElementType.push_back(type); 00372 } 00373 else 00374 { 00375 if (type != m_expectedArrayElementType.back()) 00376 { 00377 wpi_setWPIError(InconsistentArrayValueAdded); 00378 } 00379 } 00380 m_arrayElementCount.back() = m_arrayElementCount.back() + 1; 00381 } 00382 } 00383 00387 bool Dashboard::IsArrayRoot() 00388 { 00389 return !m_complexTypeStack.empty() && m_complexTypeStack.top() == kArray; 00390 } 00391
Generated on Thu Jan 12 2012 22:35:19 for WPILibC++ by
1.7.1