@irsdk-node/native 4.0.2 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +46 -46
  2. package/binding.gyp +28 -19
  3. package/dist/INativeSDK.d.ts +28 -0
  4. package/dist/INativeSDK.js +2 -0
  5. package/dist/MockSdk.d.ts +43 -0
  6. package/dist/MockSdk.js +70 -0
  7. package/dist/mock-data/loader.d.ts +3 -0
  8. package/dist/mock-data/loader.js +41 -0
  9. package/dist/mock-data/session.json +4305 -0
  10. package/dist/mock-data/telemetry.json +4986 -0
  11. package/{src/index.d.ts → index.d.ts} +5 -35
  12. package/index.js +36 -0
  13. package/lib/irsdk_client.cpp +495 -495
  14. package/lib/irsdk_client.h +139 -139
  15. package/lib/irsdk_defines.h +528 -528
  16. package/{src → lib}/irsdk_node.cc +404 -375
  17. package/{src → lib}/irsdk_node.h +49 -50
  18. package/lib/irsdk_node_mocked.cc +226 -0
  19. package/lib/irsdk_utils.cpp +377 -377
  20. package/lib/yaml_parser.cpp +176 -176
  21. package/lib/yaml_parser.h +34 -34
  22. package/package.json +37 -29
  23. package/prebuilds/darwin-arm64/@irsdk-node+native.node +0 -0
  24. package/prebuilds/linux-x64/@irsdk-node+native.node +0 -0
  25. package/prebuilds/win32-x64/@irsdk-node+native.node +0 -0
  26. package/build/Debug/irsdk_node.exp +0 -0
  27. package/build/Debug/irsdk_node.lib +0 -0
  28. package/build/Debug/irsdk_node.node +0 -0
  29. package/build/Debug/irsdk_node.pdb +0 -0
  30. package/build/Debug/obj/irsdk_node/irsdk_node.node.recipe +0 -11
  31. package/build/Debug/obj/irsdk_node/irsdk_node.tlog/CL.command.1.tlog +0 -0
  32. package/build/Debug/obj/irsdk_node/irsdk_node.tlog/CL.read.1.tlog +0 -0
  33. package/build/Debug/obj/irsdk_node/irsdk_node.tlog/CL.write.1.tlog +0 -0
  34. package/build/Debug/obj/irsdk_node/irsdk_node.tlog/Cl.items.tlog +0 -4
  35. package/build/Debug/obj/irsdk_node/irsdk_node.tlog/irsdk_node.lastbuildstate +0 -2
  36. package/build/Debug/obj/irsdk_node/irsdk_node.tlog/link.command.1.tlog +0 -0
  37. package/build/Debug/obj/irsdk_node/irsdk_node.tlog/link.read.1.tlog +0 -0
  38. package/build/Debug/obj/irsdk_node/irsdk_node.tlog/link.secondary.1.tlog +0 -3
  39. package/build/Debug/obj/irsdk_node/irsdk_node.tlog/link.write.1.tlog +0 -0
  40. package/build/Debug/obj/irsdk_node/lib/irsdk_utils.obj +0 -0
  41. package/build/Debug/obj/irsdk_node/lib/yaml_parser.obj +0 -0
  42. package/build/Debug/obj/irsdk_node/src/irsdk_node.obj +0 -0
  43. package/build/Debug/obj/irsdk_node/vcpkg.applocal.log +0 -1
  44. package/build/Debug/obj/irsdk_node/win_delay_load_hook.obj +0 -0
  45. package/build/Release/irsdk_node.exp +0 -0
  46. package/build/Release/irsdk_node.iobj +0 -0
  47. package/build/Release/irsdk_node.ipdb +0 -0
  48. package/build/Release/irsdk_node.lib +0 -0
  49. package/build/Release/irsdk_node.node +0 -0
  50. package/build/Release/irsdk_node.pdb +0 -0
  51. package/build/Release/obj/irsdk_node/irsdk_node.node.recipe +0 -11
  52. package/build/Release/obj/irsdk_node/irsdk_node.tlog/CL.command.1.tlog +0 -0
  53. package/build/Release/obj/irsdk_node/irsdk_node.tlog/CL.read.1.tlog +0 -0
  54. package/build/Release/obj/irsdk_node/irsdk_node.tlog/CL.write.1.tlog +0 -0
  55. package/build/Release/obj/irsdk_node/irsdk_node.tlog/Cl.items.tlog +0 -4
  56. package/build/Release/obj/irsdk_node/irsdk_node.tlog/irsdk_node.lastbuildstate +0 -2
  57. package/build/Release/obj/irsdk_node/irsdk_node.tlog/link.command.1.tlog +0 -0
  58. package/build/Release/obj/irsdk_node/irsdk_node.tlog/link.read.1.tlog +0 -0
  59. package/build/Release/obj/irsdk_node/irsdk_node.tlog/link.secondary.1.tlog +0 -5
  60. package/build/Release/obj/irsdk_node/irsdk_node.tlog/link.write.1.tlog +0 -0
  61. package/build/Release/obj/irsdk_node/lib/irsdk_utils.obj +0 -0
  62. package/build/Release/obj/irsdk_node/lib/yaml_parser.obj +0 -0
  63. package/build/Release/obj/irsdk_node/src/irsdk_node.obj +0 -0
  64. package/build/Release/obj/irsdk_node/vcpkg.applocal.log +0 -1
  65. package/build/Release/obj/irsdk_node/win_delay_load_hook.obj +0 -0
  66. package/build/binding.sln +0 -19
  67. package/build/config.gypi +0 -426
  68. package/build/irsdk_node.vcxproj +0 -157
  69. package/build/irsdk_node.vcxproj.filters +0 -73
  70. package/dist/index.d.ts +0 -1
  71. package/dist/index.js +0 -13
  72. package/src/index.js +0 -11
@@ -1,375 +1,404 @@
1
- #include "./irsdk_node.h"
2
- #include "../lib/yaml_parser.h"
3
-
4
- /*
5
- Nan::SetPrototypeMethod(tmpl, "getSessionData", GetSessionData);
6
- Nan::SetPrototypeMethod(tmpl, "getSessionVersionNum", GetSessionVersionNum);
7
- Nan::SetPrototypeMethod(tmpl, "getTelemetryData", GetTelemetryData);
8
- Nan::SetPrototypeMethod(tmpl, "broadcast", BroadcastMessage);
9
- Nan::SetPrototypeMethod(tmpl, "__getTelemetryTypes", __GetTelemetryTypes);
10
- */
11
-
12
- // ---------------------------
13
- // Constructors
14
- // ---------------------------
15
- Napi::Object iRacingSdkNode::Init(Napi::Env env, Napi::Object exports)
16
- {
17
- Napi::Function func = DefineClass(env, "iRacingSdkNode", {
18
- // Properties
19
- InstanceAccessor<&iRacingSdkNode::GetCurrSessionDataVersion>("currDataVersion"),
20
- InstanceAccessor<&iRacingSdkNode::GetEnableLogging, &iRacingSdkNode::SetEnableLogging>("enableLogging"),
21
- // Methods
22
- //Control
23
- InstanceMethod<&iRacingSdkNode::StartSdk>("startSDK"),
24
- InstanceMethod("stopSDK", &iRacingSdkNode::StopSdk),
25
- InstanceMethod("waitForData", &iRacingSdkNode::WaitForData),
26
- InstanceMethod("broadcast", &iRacingSdkNode::BroadcastMessage),
27
- // Getters
28
- InstanceMethod("isRunning", &iRacingSdkNode::IsRunning),
29
- InstanceMethod("getSessionVersionNum", &iRacingSdkNode::GetSessionVersionNum),
30
- InstanceMethod("getSessionData", &iRacingSdkNode::GetSessionData),
31
- InstanceMethod("getTelemetryData", &iRacingSdkNode::GetTelemetryData),
32
- InstanceMethod("getTelemetryVariable", &iRacingSdkNode::GetTelemetryVar),
33
- // Helpers
34
- InstanceMethod("__getTelemetryTypes", &iRacingSdkNode::__GetTelemetryTypes)
35
- });
36
-
37
- Napi::FunctionReference* constructor = new Napi::FunctionReference();
38
- *constructor = Napi::Persistent(func);
39
- env.SetInstanceData(constructor);
40
-
41
- exports.Set("iRacingSdkNode", func);
42
- return exports;
43
- }
44
-
45
- iRacingSdkNode::iRacingSdkNode(const Napi::CallbackInfo &info)
46
- : Napi::ObjectWrap<iRacingSdkNode>(info)
47
- , _data(NULL)
48
- , _bufLineLen(0)
49
- , _sessionStatusID(0)
50
- , _lastSessionCt(-1)
51
- , _sessionData(NULL)
52
- , _loggingEnabled(false)
53
- {
54
- printf("Initializing cpp class instance...\n");
55
- }
56
-
57
- // ---------------------------
58
- // Property implementations
59
- // ---------------------------
60
- Napi::Value iRacingSdkNode::GetCurrSessionDataVersion(const Napi::CallbackInfo &info)
61
- {
62
- int ver = this->_lastSessionCt;
63
- return Napi::Number::New(info.Env(), ver);
64
- }
65
-
66
- Napi::Value iRacingSdkNode::GetEnableLogging(const Napi::CallbackInfo &info)
67
- {
68
- bool enabled = this->_loggingEnabled;
69
- return Napi::Boolean::New(info.Env(), enabled);
70
- }
71
-
72
- void iRacingSdkNode::SetEnableLogging(const Napi::CallbackInfo &info, const Napi::Value &value)
73
- {
74
- Napi::Boolean enable;
75
- if (info.Length() <= 0 || !info[0].IsBoolean()) {
76
- enable = Napi::Boolean::New(info.Env(), false);
77
- } else {
78
- enable = info[0].As<Napi::Boolean>();
79
- }
80
- printf("Setting logging enabled: %i\n", info[0]);
81
- this->_loggingEnabled = enable;
82
- }
83
-
84
- // ---------------------------
85
- // Instance implementations
86
- // ---------------------------
87
- // SDK Control
88
- Napi::Value iRacingSdkNode::StartSdk(const Napi::CallbackInfo &info)
89
- {
90
- printf("Starting SDK...\n");
91
- if (!irsdk_isConnected()) {
92
- bool result = irsdk_startup();
93
- printf("Connected at least! %i\n", result);
94
- return Napi::Boolean::New(info.Env(), result);
95
- }
96
- return Napi::Boolean::New(info.Env(), true);
97
- }
98
-
99
- Napi::Value iRacingSdkNode::StopSdk(const Napi::CallbackInfo &info)
100
- {
101
- irsdk_shutdown();
102
- return Napi::Boolean::New(info.Env(), true);
103
- }
104
-
105
- Napi::Value iRacingSdkNode::WaitForData(const Napi::CallbackInfo &info)
106
- {
107
- // Figure out the time to wait
108
- // This will default to the timeout set on the class
109
- Napi::Number timeout;
110
- if (info.Length() <= 0 || !info[0].IsNumber()) {
111
- timeout = Napi::Number::New(info.Env(), 16);
112
- } else {
113
- timeout = info[0].As<Napi::Number>();
114
- }
115
-
116
- if (!irsdk_isConnected() && !irsdk_startup()) {
117
- return Napi::Boolean::New(info.Env(), false);
118
- }
119
-
120
- // @todo: try to do this async instead
121
- const irsdk_header* header = irsdk_getHeader();
122
-
123
- // @todo: This isn't the best way of doing this. Need to improve, but this works for now
124
- if (!this->_data) {
125
- this->_data = new char[header->bufLen];
126
- }
127
-
128
- // wait for start of sesh or new data
129
- bool dataReady = irsdk_waitForDataReady(timeout, this->_data);
130
- if (dataReady && header)
131
- {
132
- if (this->_loggingEnabled) ("Session started or we have new data.\n");
133
-
134
- // New connection or data changed length
135
- if (this->_bufLineLen != header->bufLen) {
136
- if (this->_loggingEnabled) printf("Connection started / data changed length.\n");
137
-
138
- this->_bufLineLen = header->bufLen;
139
-
140
- // Increment connection
141
- this->_sessionStatusID++;
142
-
143
- // Reset info str status
144
- this->_lastSessionCt = -1;
145
- return Napi::Boolean::New(info.Env(), true);
146
- } else if (this->_data) {
147
- if (this->_loggingEnabled) printf("Data initialized and ready to process.\n");
148
- // already initialized and ready to process
149
- return Napi::Boolean::New(info.Env(), true);
150
- }
151
- }
152
- else if (!(this->_data != NULL && irsdk_isConnected()))
153
- {
154
- printf("Session ended. Cleaning up.\n");
155
- // Session ended
156
- if (this->_data) delete[] this->_data;
157
- this->_data = NULL;
158
-
159
- // Reset Info str
160
- this->_lastSessionCt = -1;
161
- }
162
- printf("Session ended or something went wrong. Not successful.\n");
163
- return Napi::Boolean::New(info.Env(), false);
164
- }
165
-
166
- Napi::Value iRacingSdkNode::BroadcastMessage(const Napi::CallbackInfo &info)
167
- {
168
- auto env = info.Env();
169
-
170
- // Determine message type
171
- if (info.Length() <= 2 || !info[0].IsNumber()) {
172
- return Napi::Boolean::New(env, false);
173
- }
174
-
175
- if (info.Length() == 4 && !info[2].IsNumber()) {
176
- return Napi::Boolean::New(env, false);
177
- }
178
-
179
- int msgEnumIndex = info[0].As<Napi::Number>();
180
- irsdk_BroadcastMsg msgType = static_cast<irsdk_BroadcastMsg>(msgEnumIndex);
181
-
182
- // Args
183
- int arg1 = info[1].As<Napi::Number>();
184
- auto arg2 = info[2].As<Napi::Number>();
185
- auto arg3 = info[3].As<Napi::Number>();
186
-
187
- // these defs are in irsdk_defines.cpp
188
- switch (msgType)
189
- {
190
- // irsdk_BroadcastMsg msg, int arg1, int arg2, int var3
191
- case irsdk_BroadcastCamSwitchPos: // @todo we need to use irsdk_padCarNum for arg1
192
- case irsdk_BroadcastCamSwitchNum:
193
- printf("BroadcastMessage(msgType: %d, arg1: %d, arg2: %d, arg3: %d)\n", msgType, arg1, arg2.Int32Value(), arg3.Int32Value());
194
- irsdk_broadcastMsg(msgType, arg1, arg2, arg3);
195
- break;
196
-
197
- // irsdk_BroadcastMsg msg, int arg1, int unused, int unused
198
- case irsdk_BroadcastReplaySearch: // arg1 == irsdk_RpySrchMode
199
- case irsdk_BroadcastReplaySetState: // arg1 == irsdk_RpyStateMode
200
- case irsdk_BroadcastCamSetState: // arg1 == irsdk_CameraState
201
- case irsdk_BroadcastTelemCommand: // arg1 == irsdk_TelemCommandMode
202
- case irsdk_BroadcastVideoCapture: // arg1 == irsdk_VideoCaptureMode
203
- printf("BroadcastMessage(msgType: %d, arg1: %d, arg2: -1, arg3: -1)\n", msgType, arg1);
204
- irsdk_broadcastMsg(msgType, arg1, -1, -1);
205
- break;
206
-
207
- // irsdk_BroadcastMsg msg, int arg1, int arg2, int unused
208
- case irsdk_BroadcastReloadTextures: // arg1 == irsdk_ReloadTexturesMode
209
- case irsdk_BroadcastChatComand: // arg1 == irsdk_ChatCommandMode
210
- case irsdk_BroadcastReplaySetPlaySpeed:
211
- printf("BroadcastMessage(msgType: %d, arg1: %d, arg2: %d, arg3: -1)\n", msgType, arg1, arg2.Int32Value());
212
- irsdk_broadcastMsg(msgType, arg1, arg2, -1);
213
- break;
214
-
215
- // irsdk_BroadcastMsg msg, int arg1, float arg2
216
- case irsdk_BroadcastPitCommand: // arg1 == irsdk_PitCommandMode
217
- case irsdk_BroadcastFFBCommand: // arg1 == irsdk_FFBCommandMode
218
- case irsdk_BroadcastReplaySearchSessionTime:
219
- case irskd_BroadcastReplaySetPlayPosition:
220
- printf("BroadcastMessage(msgType: %d, arg1: %d, arg2: %f)\n", msgType, arg1, (float)arg2.FloatValue());
221
- irsdk_broadcastMsg(msgType, arg1, (float)arg2.FloatValue());
222
- break;
223
-
224
- default:
225
- printf("Attempted to broadcast an unsupported message.");
226
- return Napi::Boolean::New(env, false);
227
- }
228
-
229
- return Napi::Boolean::New(env, true);
230
- }
231
-
232
- // SDK State Getters
233
- Napi::Value iRacingSdkNode::IsRunning(const Napi::CallbackInfo &info)
234
- {
235
- bool result = irsdk_isConnected();
236
- return Napi::Boolean::New(info.Env(), result);
237
- }
238
-
239
- Napi::Value iRacingSdkNode::GetSessionVersionNum(const Napi::CallbackInfo &info)
240
- {
241
- int sessVer = irsdk_getSessionInfoStrUpdate();
242
- return Napi::Number::New(info.Env(), sessVer);
243
- }
244
-
245
- Napi::Value iRacingSdkNode::GetSessionData(const Napi::CallbackInfo &info)
246
- {
247
- int latestUpdate = irsdk_getSessionInfoStrUpdate();
248
- if (this->_lastSessionCt != latestUpdate) {
249
- printf("Session data has been updated (prev: %d, new: %d)\n", this->_lastSessionCt, latestUpdate);
250
- this->_lastSessionCt = latestUpdate;
251
- this->_sessionData = irsdk_getSessionInfoStr();
252
- }
253
- const char *session = this->_sessionData;
254
- if (session == NULL) {
255
- return Napi::String::New(info.Env(), "");
256
- }
257
- return Napi::String::New(info.Env(), session);
258
- }
259
-
260
- Napi::Value iRacingSdkNode::GetTelemetryVar(const Napi::CallbackInfo &info)
261
- {
262
- Napi::Env env = info.Env();
263
-
264
- int varIndex;
265
- if (info.Length() <= 0) {
266
- varIndex = 0;
267
- } else if (!info[0].IsNumber()) {
268
- if (info[0].IsString()) {
269
- const char *name = info[0].As<Napi::String>().Utf8Value().c_str();
270
- return this->GetTelemetryVar(env, name);
271
- }
272
- varIndex = 0;
273
- }
274
-
275
- return this->GetTelemetryVarByIndex(env, varIndex);
276
- }
277
-
278
- Napi::Value iRacingSdkNode::GetTelemetryData(const Napi::CallbackInfo &info)
279
- {
280
- const irsdk_header* header = irsdk_getHeader();
281
- auto env = info.Env();
282
- auto telemVars = Napi::Object::New(env);
283
-
284
- int count = header->numVars;
285
- for (int i = 0; i < count; i++) {
286
- auto telemVariable = this->GetTelemetryVarByIndex(env, i);
287
- if (telemVariable.IsObject() && telemVariable.Has("name")) {
288
- telemVars.Set(telemVariable.Get("name"), telemVariable);
289
- }
290
- }
291
-
292
- return telemVars;
293
- }
294
-
295
- // Helpers
296
- Napi::Value iRacingSdkNode::__GetTelemetryTypes(const Napi::CallbackInfo &info)
297
- {
298
- auto env = info.Env();
299
- auto result = Napi::Object::New(env);
300
-
301
- const int count = irsdk_getHeader()->numVars;
302
- const irsdk_varHeader *varHeader;
303
- for (int i = 0; i < count; i++) {
304
- varHeader = irsdk_getVarHeaderEntry(i);
305
- result.Set(varHeader->name, Napi::Number::New(env, varHeader->type));
306
- }
307
-
308
- return result;
309
- }
310
-
311
-
312
- // ---------------------------
313
- // Helper functions
314
- // ---------------------------
315
- bool iRacingSdkNode::GetTelemetryBool(int entry, int index)
316
- {
317
- const irsdk_varHeader *headerVar = irsdk_getVarHeaderEntry(entry);
318
- return *(reinterpret_cast<bool const *>(_data + headerVar->offset) + index);
319
- }
320
-
321
- int iRacingSdkNode::GetTelemetryInt(int entry, int index)
322
- {
323
- // Each int is 4 bytes
324
- const irsdk_varHeader *headerVar = irsdk_getVarHeaderEntry(entry);
325
- return *(reinterpret_cast<int const *>(_data + headerVar->offset) + index * 4);
326
- }
327
-
328
- float iRacingSdkNode::GetTelemetryFloat(int entry, int index)
329
- {
330
- // Each float is 4 bytes
331
- const irsdk_varHeader *headerVar = irsdk_getVarHeaderEntry(entry);
332
- return *(reinterpret_cast<float const *>(_data + headerVar->offset) + index * 4);
333
- }
334
-
335
- double iRacingSdkNode::GetTelemetryDouble(int entry, int index)
336
- {
337
- // Each double is 8 bytes
338
- const irsdk_varHeader *headerVar = irsdk_getVarHeaderEntry(entry);
339
- return *(reinterpret_cast<double const *>(_data + headerVar->offset) + index * 8);
340
- }
341
-
342
- Napi::Object iRacingSdkNode::GetTelemetryVarByIndex(const Napi::Env env, int index)
343
- {
344
- auto headerVar = irsdk_getVarHeaderEntry(index);
345
- auto telemVar = Napi::Object::New(env);
346
-
347
- // Create entry object
348
- telemVar.Set("countAsTime", headerVar->countAsTime);
349
- telemVar.Set("length", headerVar->count);
350
- telemVar.Set("name", headerVar->name);
351
- telemVar.Set("description", headerVar->desc);
352
- telemVar.Set("unit", headerVar->unit);
353
- telemVar.Set("varType", headerVar->type);
354
-
355
- int dataSize = headerVar->count * irsdk_VarTypeBytes[headerVar->type];
356
- auto entryVal = Napi::ArrayBuffer::New(env, dataSize);
357
- memcpy(entryVal.Data(), this->_data + headerVar->offset, dataSize);
358
-
359
- telemVar.Set("value", entryVal);
360
- return telemVar;
361
- }
362
-
363
- Napi::Object iRacingSdkNode::GetTelemetryVar(const Napi::Env env, const char *varName)
364
- {
365
- int varIndex = irsdk_varNameToIndex(varName);
366
- return this->GetTelemetryVarByIndex(env, varIndex);
367
- }
368
-
369
- Napi::Object InitAll(Napi::Env env, Napi::Object exports)
370
- {
371
- iRacingSdkNode::Init(env, exports);
372
- return exports;
373
- }
374
-
375
- NODE_API_MODULE(NODE_GYP_MODULE_NAME, InitAll);
1
+ #include "./irsdk_node.h"
2
+ #include "./yaml_parser.h"
3
+ #include "./irsdk_defines.h"
4
+ #include "./irsdk_client.h"
5
+
6
+ // ---------------------------
7
+ // Constructors
8
+ // ---------------------------
9
+ Napi::Object iRacingSdkNode::Init(Napi::Env env, Napi::Object exports)
10
+ {
11
+ Napi::Function func = DefineClass(env, "iRacingSdkNode", {// Properties
12
+ InstanceAccessor<&iRacingSdkNode::GetCurrSessionDataVersion>("currDataVersion"), InstanceAccessor<&iRacingSdkNode::GetEnableLogging, &iRacingSdkNode::SetEnableLogging>("enableLogging"), InstanceAccessor<&iRacingSdkNode::GetIsMocked>("isMocked"),
13
+
14
+ // Methods
15
+ // Control
16
+ InstanceMethod<&iRacingSdkNode::StartSdk>("startSDK"), InstanceMethod("stopSDK", &iRacingSdkNode::StopSdk), InstanceMethod("waitForData", &iRacingSdkNode::WaitForData), InstanceMethod("broadcast", &iRacingSdkNode::BroadcastMessage),
17
+ // Getters
18
+ InstanceMethod("isRunning", &iRacingSdkNode::IsRunning), InstanceMethod("getSessionVersionNum", &iRacingSdkNode::GetSessionVersionNum), InstanceMethod("getSessionData", &iRacingSdkNode::GetSessionData), InstanceMethod("getTelemetryData", &iRacingSdkNode::GetTelemetryData), InstanceMethod("getTelemetryVariable", &iRacingSdkNode::GetTelemetryVar),
19
+ // Helpers
20
+ InstanceMethod("__getTelemetryTypes", &iRacingSdkNode::__GetTelemetryTypes)});
21
+
22
+ Napi::FunctionReference *constructor = new Napi::FunctionReference();
23
+ *constructor = Napi::Persistent(func);
24
+ env.SetInstanceData(constructor);
25
+
26
+ exports.Set("iRacingSdkNode", func);
27
+ return exports;
28
+ }
29
+
30
+ iRacingSdkNode::iRacingSdkNode(const Napi::CallbackInfo &info)
31
+ : Napi::ObjectWrap<iRacingSdkNode>(info), _data(NULL), _bufLineLen(0), _sessionStatusID(0), _lastSessionCt(-1), _sessionData(NULL), _loggingEnabled(false)
32
+ {
33
+ printf("Initializing iRacingSdkNode\n");
34
+ }
35
+
36
+ // ---------------------------
37
+ // Property implementations
38
+ // ---------------------------
39
+ Napi::Value iRacingSdkNode::GetCurrSessionDataVersion(const Napi::CallbackInfo &info)
40
+ {
41
+ int ver = this->_lastSessionCt;
42
+ return Napi::Number::New(info.Env(), ver);
43
+ }
44
+
45
+ Napi::Value iRacingSdkNode::GetEnableLogging(const Napi::CallbackInfo &info)
46
+ {
47
+ bool enabled = this->_loggingEnabled;
48
+ return Napi::Boolean::New(info.Env(), enabled);
49
+ }
50
+
51
+ void iRacingSdkNode::SetEnableLogging(const Napi::CallbackInfo &info, const Napi::Value &value)
52
+ {
53
+ Napi::Boolean enable;
54
+ if (info.Length() <= 0 || !info[0].IsBoolean())
55
+ {
56
+ enable = Napi::Boolean::New(info.Env(), false);
57
+ }
58
+ else
59
+ {
60
+ enable = info[0].As<Napi::Boolean>();
61
+ }
62
+ this->_loggingEnabled = enable;
63
+ if (this->_loggingEnabled)
64
+ printf("iRacingSDK Logging enabled\n");
65
+ }
66
+
67
+ Napi::Value iRacingSdkNode::GetIsMocked(const Napi::CallbackInfo &info)
68
+ {
69
+ return Napi::Boolean::New(info.Env(), false);
70
+ }
71
+
72
+ // ---------------------------
73
+ // Instance implementations
74
+ // ---------------------------
75
+ // SDK Control
76
+ Napi::Value iRacingSdkNode::StartSdk(const Napi::CallbackInfo &info)
77
+ {
78
+ if (this->_loggingEnabled)
79
+ printf("Starting SDK...\n");
80
+
81
+ if (!irsdk_isConnected())
82
+ {
83
+ bool result = irsdk_startup();
84
+ if (this->_loggingEnabled)
85
+ printf("Connected to iRacing SDK (%i)\n", result);
86
+ return Napi::Boolean::New(info.Env(), result);
87
+ }
88
+ return Napi::Boolean::New(info.Env(), true);
89
+ }
90
+
91
+ Napi::Value iRacingSdkNode::StopSdk(const Napi::CallbackInfo &info)
92
+ {
93
+ irsdk_shutdown();
94
+ return Napi::Boolean::New(info.Env(), true);
95
+ }
96
+
97
+ Napi::Value iRacingSdkNode::WaitForData(const Napi::CallbackInfo &info)
98
+ {
99
+ // Figure out the time to wait
100
+ // This will default to the timeout set on the class
101
+ Napi::Number timeout;
102
+ if (info.Length() <= 0 || !info[0].IsNumber())
103
+ {
104
+ timeout = Napi::Number::New(info.Env(), 16);
105
+ }
106
+ else
107
+ {
108
+ timeout = info[0].As<Napi::Number>();
109
+ }
110
+
111
+ if (!irsdk_isConnected() && !irsdk_startup())
112
+ {
113
+ return Napi::Boolean::New(info.Env(), false);
114
+ }
115
+
116
+ // @todo: try to do this async instead
117
+ const irsdk_header *header = irsdk_getHeader();
118
+
119
+ // @todo: This isn't the best way of doing this. Need to improve, but this works for now
120
+ if (!this->_data)
121
+ {
122
+ this->_data = new char[header->bufLen];
123
+ }
124
+
125
+ // wait for start of sesh or new data
126
+ bool dataReady = irsdk_waitForDataReady(timeout, this->_data);
127
+ if (dataReady && header)
128
+ {
129
+ if (this->_loggingEnabled)
130
+ ("Session started or we have new data.\n");
131
+
132
+ // New connection or data changed length
133
+ if (this->_bufLineLen != header->bufLen)
134
+ {
135
+ if (this->_loggingEnabled)
136
+ printf("Connection started / data changed length.\n");
137
+
138
+ this->_bufLineLen = header->bufLen;
139
+
140
+ // Increment connection
141
+ this->_sessionStatusID++;
142
+
143
+ // Reset info str status
144
+ this->_lastSessionCt = -1;
145
+ return Napi::Boolean::New(info.Env(), true);
146
+ }
147
+ else if (this->_data)
148
+ {
149
+ if (this->_loggingEnabled)
150
+ printf("Data initialized and ready to process.\n");
151
+ // already initialized and ready to process
152
+ return Napi::Boolean::New(info.Env(), true);
153
+ }
154
+ }
155
+ else if (!(this->_data != NULL && irsdk_isConnected()))
156
+ {
157
+ if (this->_loggingEnabled)
158
+ printf("Session ended. Cleaning up.\n");
159
+ // Session ended
160
+ if (this->_data)
161
+ delete[] this->_data;
162
+ this->_data = NULL;
163
+
164
+ // Reset Info str
165
+ this->_lastSessionCt = -1;
166
+ }
167
+ if (this->_loggingEnabled)
168
+ printf("Session ended or something went wrong. Not successful.\n");
169
+ return Napi::Boolean::New(info.Env(), false);
170
+ }
171
+
172
+ Napi::Value iRacingSdkNode::BroadcastMessage(const Napi::CallbackInfo &info)
173
+ {
174
+ auto env = info.Env();
175
+
176
+ // Determine message type
177
+ if (info.Length() <= 2 || !info[0].IsNumber())
178
+ {
179
+ return Napi::Boolean::New(env, false);
180
+ }
181
+
182
+ if (info.Length() == 4 && !info[2].IsNumber())
183
+ {
184
+ return Napi::Boolean::New(env, false);
185
+ }
186
+
187
+ int msgEnumIndex = info[0].As<Napi::Number>();
188
+ irsdk_BroadcastMsg msgType = static_cast<irsdk_BroadcastMsg>(msgEnumIndex);
189
+
190
+ // Args
191
+ int arg1 = info[1].As<Napi::Number>();
192
+ auto arg2 = info[2].As<Napi::Number>();
193
+ auto arg3 = info[3].As<Napi::Number>();
194
+
195
+ // these defs are in irsdk_defines.cpp
196
+ switch (msgType)
197
+ {
198
+ // irsdk_BroadcastMsg msg, int arg1, int arg2, int var3
199
+ case irsdk_BroadcastCamSwitchPos: // @todo we need to use irsdk_padCarNum for arg1
200
+ case irsdk_BroadcastCamSwitchNum:
201
+ if (this->_loggingEnabled)
202
+ printf("BroadcastMessage(msgType: %d, arg1: %d, arg2: %d, arg3: %d)\n", msgType, arg1, arg2.Int32Value(), arg3.Int32Value());
203
+ irsdk_broadcastMsg(msgType, arg1, arg2, arg3);
204
+ break;
205
+
206
+ // irsdk_BroadcastMsg msg, int arg1, int unused, int unused
207
+ case irsdk_BroadcastReplaySearch: // arg1 == irsdk_RpySrchMode
208
+ case irsdk_BroadcastReplaySetState: // arg1 == irsdk_RpyStateMode
209
+ case irsdk_BroadcastCamSetState: // arg1 == irsdk_CameraState
210
+ case irsdk_BroadcastTelemCommand: // arg1 == irsdk_TelemCommandMode
211
+ case irsdk_BroadcastVideoCapture: // arg1 == irsdk_VideoCaptureMode
212
+ if (this->_loggingEnabled)
213
+ printf("BroadcastMessage(msgType: %d, arg1: %d, arg2: -1, arg3: -1)\n", msgType, arg1);
214
+ irsdk_broadcastMsg(msgType, arg1, -1, -1);
215
+ break;
216
+
217
+ // irsdk_BroadcastMsg msg, int arg1, int arg2, int unused
218
+ case irsdk_BroadcastReloadTextures: // arg1 == irsdk_ReloadTexturesMode
219
+ case irsdk_BroadcastChatComand: // arg1 == irsdk_ChatCommandMode
220
+ case irsdk_BroadcastReplaySetPlaySpeed:
221
+ if (this->_loggingEnabled)
222
+ printf("BroadcastMessage(msgType: %d, arg1: %d, arg2: %d, arg3: -1)\n", msgType, arg1, arg2.Int32Value());
223
+ irsdk_broadcastMsg(msgType, arg1, arg2, -1);
224
+ break;
225
+
226
+ // irsdk_BroadcastMsg msg, int arg1, float arg2
227
+ case irsdk_BroadcastPitCommand: // arg1 == irsdk_PitCommandMode
228
+ case irsdk_BroadcastFFBCommand: // arg1 == irsdk_FFBCommandMode
229
+ case irsdk_BroadcastReplaySearchSessionTime:
230
+ case irskd_BroadcastReplaySetPlayPosition:
231
+ if (this->_loggingEnabled)
232
+ printf("BroadcastMessage(msgType: %d, arg1: %d, arg2: %f)\n", msgType, arg1, (float)arg2.FloatValue());
233
+ irsdk_broadcastMsg(msgType, arg1, (float)arg2.FloatValue());
234
+ break;
235
+
236
+ default:
237
+ if (this->_loggingEnabled)
238
+ printf("Attempted to broadcast an unsupported message.\n");
239
+ return Napi::Boolean::New(env, false);
240
+ }
241
+
242
+ return Napi::Boolean::New(env, true);
243
+ }
244
+
245
+ // SDK State Getters
246
+ Napi::Value iRacingSdkNode::IsRunning(const Napi::CallbackInfo &info)
247
+ {
248
+ bool result = irsdk_isConnected();
249
+ return Napi::Boolean::New(info.Env(), result);
250
+ }
251
+
252
+ Napi::Value iRacingSdkNode::GetSessionVersionNum(const Napi::CallbackInfo &info)
253
+ {
254
+ int sessVer = irsdk_getSessionInfoStrUpdate();
255
+ return Napi::Number::New(info.Env(), sessVer);
256
+ }
257
+
258
+ Napi::Value iRacingSdkNode::GetSessionData(const Napi::CallbackInfo &info)
259
+ {
260
+ int latestUpdate = irsdk_getSessionInfoStrUpdate();
261
+ if (this->_lastSessionCt != latestUpdate)
262
+ {
263
+ if (this->_loggingEnabled)
264
+ printf("Session data has been updated (prev: %d, new: %d)\n", this->_lastSessionCt, latestUpdate);
265
+ this->_lastSessionCt = latestUpdate;
266
+ this->_sessionData = irsdk_getSessionInfoStr();
267
+ }
268
+ const char *session = this->_sessionData;
269
+ if (session == NULL)
270
+ {
271
+ return Napi::String::New(info.Env(), "");
272
+ }
273
+ return Napi::String::New(info.Env(), session);
274
+ }
275
+
276
+ Napi::Value iRacingSdkNode::GetTelemetryVar(const Napi::CallbackInfo &info)
277
+ {
278
+ Napi::Env env = info.Env();
279
+
280
+ int varIndex;
281
+ if (info.Length() <= 0)
282
+ {
283
+ varIndex = 0;
284
+ }
285
+ else if (!info[0].IsNumber())
286
+ {
287
+ if (info[0].IsString())
288
+ {
289
+ const char *name = info[0].As<Napi::String>().Utf8Value().c_str();
290
+ return this->GetTelemetryVar(env, name);
291
+ }
292
+ varIndex = 0;
293
+ }
294
+
295
+ return this->GetTelemetryVarByIndex(env, varIndex);
296
+ }
297
+
298
+ Napi::Value iRacingSdkNode::GetTelemetryData(const Napi::CallbackInfo &info)
299
+ {
300
+ const irsdk_header *header = irsdk_getHeader();
301
+ auto env = info.Env();
302
+ auto telemVars = Napi::Object::New(env);
303
+
304
+ int count = header->numVars;
305
+ for (int i = 0; i < count; i++)
306
+ {
307
+ auto telemVariable = this->GetTelemetryVarByIndex(env, i);
308
+ if (telemVariable.IsObject() && telemVariable.Has("name"))
309
+ {
310
+ telemVars.Set(telemVariable.Get("name"), telemVariable);
311
+ }
312
+ }
313
+
314
+ return telemVars;
315
+ }
316
+
317
+ // Helpers
318
+ Napi::Value iRacingSdkNode::__GetTelemetryTypes(const Napi::CallbackInfo &info)
319
+ {
320
+ auto env = info.Env();
321
+ auto result = Napi::Object::New(env);
322
+
323
+ const int count = irsdk_getHeader()->numVars;
324
+ const irsdk_varHeader *varHeader;
325
+ for (int i = 0; i < count; i++)
326
+ {
327
+ varHeader = irsdk_getVarHeaderEntry(i);
328
+ result.Set(varHeader->name, Napi::Number::New(env, varHeader->type));
329
+ }
330
+
331
+ return result;
332
+ }
333
+
334
+ // ---------------------------
335
+ // Helper functions
336
+ // ---------------------------
337
+ bool iRacingSdkNode::GetTelemetryBool(int entry, int index)
338
+ {
339
+ const irsdk_varHeader *headerVar = irsdk_getVarHeaderEntry(entry);
340
+ return *(reinterpret_cast<bool const *>(_data + headerVar->offset) + index);
341
+ }
342
+
343
+ int iRacingSdkNode::GetTelemetryInt(int entry, int index)
344
+ {
345
+ // Each int is 4 bytes
346
+ const irsdk_varHeader *headerVar = irsdk_getVarHeaderEntry(entry);
347
+ return *(reinterpret_cast<int const *>(_data + headerVar->offset) + index * 4);
348
+ }
349
+
350
+ float iRacingSdkNode::GetTelemetryFloat(int entry, int index)
351
+ {
352
+ // Each float is 4 bytes
353
+ const irsdk_varHeader *headerVar = irsdk_getVarHeaderEntry(entry);
354
+ return *(reinterpret_cast<float const *>(_data + headerVar->offset) + index * 4);
355
+ }
356
+
357
+ double iRacingSdkNode::GetTelemetryDouble(int entry, int index)
358
+ {
359
+ // Each double is 8 bytes
360
+ const irsdk_varHeader *headerVar = irsdk_getVarHeaderEntry(entry);
361
+ return *(reinterpret_cast<double const *>(_data + headerVar->offset) + index * 8);
362
+ }
363
+
364
+ Napi::Object iRacingSdkNode::GetTelemetryVarByIndex(const Napi::Env env, int index)
365
+ {
366
+ auto headerVar = irsdk_getVarHeaderEntry(index);
367
+ auto telemVar = Napi::Object::New(env);
368
+
369
+ // Create entry object
370
+ telemVar.Set("countAsTime", headerVar->countAsTime);
371
+ telemVar.Set("length", headerVar->count);
372
+ telemVar.Set("name", headerVar->name);
373
+ telemVar.Set("description", headerVar->desc);
374
+ telemVar.Set("unit", headerVar->unit);
375
+ telemVar.Set("varType", headerVar->type);
376
+
377
+ int dataSize = headerVar->count * irsdk_VarTypeBytes[headerVar->type];
378
+ auto entryVal = Napi::ArrayBuffer::New(env, dataSize);
379
+ memcpy(entryVal.Data(), this->_data + headerVar->offset, dataSize);
380
+
381
+ telemVar.Set("value", entryVal);
382
+ return telemVar;
383
+ }
384
+
385
+ Napi::Object iRacingSdkNode::GetTelemetryVar(const Napi::Env env, const char *varName)
386
+ {
387
+ int varIndex = irsdk_varNameToIndex(varName);
388
+ return this->GetTelemetryVarByIndex(env, varIndex);
389
+ }
390
+
391
+ // ---------------------------
392
+ // Addon init
393
+ // TODO: This should be standardized/shared across the mocked/unmocked modules.
394
+ // ---------------------------
395
+ Napi::Object InitAll(Napi::Env env, Napi::Object exports)
396
+ {
397
+ iRacingSdkNode::Init(env, exports);
398
+
399
+ exports.Set("mockedSdk", false);
400
+
401
+ return exports;
402
+ }
403
+
404
+ NODE_API_MODULE(NODE_GYP_MODULE_NAME, InitAll);