-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathirsdk.go
144 lines (126 loc) · 2.97 KB
/
irsdk.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package irsdk
import (
"fmt"
"gopkg.in/yaml.v2"
"io/ioutil"
"log"
"strings"
"time"
"github.com/hidez8891/shm"
"github.com/quimcalpe/iracing-sdk/lib/winevents"
)
// IRSDK is the main SDK object clients must use
type IRSDK struct {
r reader
h *header
session Session
s []string
tVars *TelemetryVars
lastValidData int64
}
func (sdk *IRSDK) WaitForData(timeout time.Duration) bool {
if !sdk.IsConnected() {
initIRSDK(sdk)
}
if winevents.WaitForSingleObject(timeout) {
return readVariableValues(sdk)
}
return false
}
func (sdk *IRSDK) GetVar(name string) (variable, error) {
if !sessionStatusOK(sdk.h.status) {
return variable{}, fmt.Errorf("Session is not active")
}
sdk.tVars.mux.Lock()
if v, ok := sdk.tVars.vars[name]; ok {
sdk.tVars.mux.Unlock()
return v, nil
}
sdk.tVars.mux.Unlock()
return variable{}, fmt.Errorf("Telemetry variable %q not found", name)
}
func (sdk *IRSDK) GetSession() Session {
return sdk.session
}
func (sdk *IRSDK) GetLastVersion() int {
if !sessionStatusOK(sdk.h.status) {
return -1
}
sdk.tVars.mux.Lock()
last := sdk.tVars.lastVersion
sdk.tVars.mux.Unlock()
return last
}
func (sdk *IRSDK) GetSessionData(path string) (string, error) {
if !sessionStatusOK(sdk.h.status) {
return "", fmt.Errorf("Session not connected")
}
return getSessionDataPath(sdk.s, path)
}
func (sdk *IRSDK) IsConnected() bool {
if sdk.h != nil {
if sessionStatusOK(sdk.h.status) && (sdk.lastValidData+connTimeout > time.Now().Unix()) {
return true
}
}
return false
}
// ExportTo exports current memory data to a file
func (sdk *IRSDK) ExportIbtTo(fileName string) {
rbuf := make([]byte, fileMapSize)
_, err := sdk.r.ReadAt(rbuf, 0)
if err != nil {
log.Fatal(err)
}
ioutil.WriteFile(fileName, rbuf, 0644)
}
// ExportTo exports current session yaml data to a file
func (sdk *IRSDK) ExportSessionTo(fileName string) {
y := strings.Join(sdk.s, "\n")
ioutil.WriteFile(fileName, []byte(y), 0644)
}
func (sdk *IRSDK) BroadcastMsg(msg Msg) {
if msg.P2 == nil {
msg.P2 = 0
}
winevents.BroadcastMsg(broadcastMsgName, msg.Cmd, msg.P1, msg.P2, msg.P3)
}
// Close clean up sdk resources
func (sdk *IRSDK) Close() {
sdk.r.Close()
}
// Init creates a SDK instance to operate with
func Init(r reader) IRSDK {
if r == nil {
var err error
r, err = shm.Open(fileMapName, fileMapSize)
if err != nil {
log.Fatal(err)
}
}
sdk := IRSDK{r: r, lastValidData: 0}
winevents.OpenEvent(dataValidEventName)
initIRSDK(&sdk)
return sdk
}
func initIRSDK(sdk *IRSDK) {
h := readHeader(sdk.r)
sdk.h = &h
sdk.s = nil
if sdk.tVars != nil {
sdk.tVars.vars = nil
}
if sessionStatusOK(h.status) {
sRaw := readSessionData(sdk.r, &h)
err := yaml.Unmarshal([]byte(sRaw), &sdk.session)
if err != nil {
log.Fatal(err)
}
sdk.s = strings.Split(sRaw, "\n")
sdk.tVars = readVariableHeaders(sdk.r, &h)
readVariableValues(sdk)
}
}
func sessionStatusOK(status int) bool {
return (status & stConnected) > 0
}