-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlStepper.lua
210 lines (195 loc) · 6.07 KB
/
lStepper.lua
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
-- Module lSteppper
-- Allows Lua programs to run and control multiple Lua scripts in parallel
local lstep_lib = require("LuaStepper")
local type = type
local setfenv = setfenv
local loadstring = loadstring
local load = load
local pairs = pairs
local tostring = tostring
local string = string
local package = package
local ver = "1.16.06.17" -- Should correspond to the version of the C module
-- Create the module table here
local M = {}
package.loaded[...] = M
if setenv then
setfenv(1,M) -- Lua 5.1
else
_ENV = M -- Lua 5.2
end
-- Creaate the module table ends
-- Add the normal functions
addTask = lstep_lib.addTask
runLoop = lstep_lib.runLoop
taskStatus = lstep_lib.taskStatus
getNumOfTasks = lstep_lib.getNumOfTasks
closeTask = lstep_lib.closeTask
suspendTask = lstep_lib.suspendTask
resumeTask = lstep_lib.resumeTask
_VERSION = lstep_lib._VERSION
if _VERSION ~= ver then
package.loaded[...] = "LuaStepper module version not correct. Lua Version: "..ver.." C library version: ".._VERSION
return nil
end
runCode = lstep_lib.runCode
registerCallBack = lstep_lib.registerCallBack
getTaskData = function(index,key)
local ret,msg = lstep_lib.getTaskData(index,key)
if not ret then
return nil,msg
end
if msg == 'TABLE' then
-- Convert the string to a table and return that
local sf = {}
local f,msg
if setfenv and loadstring then
f,msg = loadstring(ret)
if not f then
return nil,msg
end
setfenv(f,sf)
else
f,msg = load(ret,nil,nil,sf)
if not f then
return nil,msg
end
end
f()
return sf.t0
end
return ret
end
-- Creates lua code for a table which when executed will create a table t0 which would be the same as the originally passed table
-- Handles the following types for keys and values:
-- Keys: Number, String, Table
-- Values: Number, String, Table, Boolean
-- It also handles recursive and interlinked tables to recreate them back
local function tableToString(t)
if type(t) ~= 'table' then return nil, 'Expected table parameter' end
local rL = {cL = 1} -- Table to track recursion into nested tables (cL = current recursion level)
rL[rL.cL] = {}
local tabIndex = {} -- Table to store a list of tables indexed into a string and their variable name
local latestTab = 0
local result = {}
do
rL[rL.cL]._f,rL[rL.cL]._s,rL[rL.cL]._var = pairs(t)
result[#result + 1] = 't0={}' -- t0 would be the main table
--rL[rL.cL].str = 't0={}'
rL[rL.cL].t = t
rL[rL.cL].tabIndex = 0
tabIndex[t] = rL[rL.cL].tabIndex
while true do
local key
local k,v = rL[rL.cL]._f(rL[rL.cL]._s,rL[rL.cL]._var)
rL[rL.cL]._var = k
if not k and rL.cL == 1 then
break
elseif not k then
-- go up in recursion level
--rL[rL.cL-1].str = rL[rL.cL-1].str..'\\n'..rL[rL.cL].str
rL.cL = rL.cL - 1
if rL[rL.cL].vNotDone then
key = 't'..rL[rL.cL].tabIndex..'[t'..tostring(rL[rL.cL+1].tabIndex)..']'
--rL[rL.cL].str = rL[rL.cL].str..'\\n'..key..'='
result[#result + 1] = "\n"..key.."="
v = rL[rL.cL].vNotDone
end
rL[rL.cL+1] = nil
else
-- Handle the key and value here
if type(k) == 'number' then
key = 't'..rL[rL.cL].tabIndex..'['..tostring(k)..']'
--rL[rL.cL].str = rL[rL.cL].str..'\\n'..key..'='
result[#result + 1] = "\n"..key.."="
elseif type(k) == 'string' then
key = 't'..rL[rL.cL].tabIndex..'.'..tostring(k)
--rL[rL.cL].str = rL[rL.cL].str..'\\n'..key..'='
result[#result + 1] = "\n"..key.."="
else
-- Table key
-- Check if the table already exists
if tabIndex[k] then
key = 't'..rL[rL.cL].tabIndex..'[t'..tabIndex[k]..']'
--rL[rL.cL].str = rL[rL.cL].str..'\\n'..key..'='
result[#result + 1] = "\n"..key.."="
else
-- Go deeper to stringify this table
latestTab = latestTab + 1
--rL[rL.cL].str = rL[rL.cL].str..'\\nt'..tostring(latestTab)..'={}'
result[#result + 1] = "\nt"..tostring(latestTab).."={}"
rL[rL.cL].vNotDone = v
rL.cL = rL.cL + 1
rL[rL.cL] = {}
rL[rL.cL]._f,rL[rL.cL]._s,rL[rL.cL]._var = pairs(k)
rL[rL.cL].tabIndex = latestTab
rL[rL.cL].t = k
--rL[rL.cL].str = ''
tabIndex[k] = rL[rL.cL].tabIndex
end -- if tabIndex[k] then ends
end -- if type(k)ends
end -- if not k and rL.cL == 1 then ends
if key then
rL[rL.cL].vNotDone = nil
if type(v) == 'table' then
-- Check if this table is already indexed
if tabIndex[v] then
--rL[rL.cL].str = rL[rL.cL].str..'t'..tabIndex[v]
result[#result + 1] = 't'..tabIndex[v]
else
-- Go deeper in recursion
latestTab = latestTab + 1
--rL[rL.cL].str = rL[rL.cL].str..'{}'
--rL[rL.cL].str = rL[rL.cL].str..'\\nt'..tostring(latestTab)..'='..key
result[#result + 1] = "{}\nt"..tostring(latestTab)..'='..key -- New table
rL.cL = rL.cL + 1
rL[rL.cL] = {}
rL[rL.cL]._f,rL[rL.cL]._s,rL[rL.cL]._var = pairs(v)
rL[rL.cL].tabIndex = latestTab
rL[rL.cL].t = v
--rL[rL.cL].str = ''
tabIndex[v] = rL[rL.cL].tabIndex
end
elseif type(v) == 'number' then
--rL[rL.cL].str = rL[rL.cL].str..tostring(v)
result[#result + 1] = tostring(v)
elseif type(v) == 'boolean' then
--rL[rL.cL].str = rL[rL.cL].str..tostring(v)
result[#result + 1] = tostring(v)
else
--rL[rL.cL].str = rL[rL.cL].str..string.format('%q',tostring(v))
result[#result + 1] = string.format('%q',tostring(v))
end -- if type(v) == "table" then ends
end -- if key then ends
end -- while true ends here
end -- do ends
--return rL[rL.cL].str
return table.concat(result)
end
setTaskData = function(index,tab)
if not type(tab) == 'table' then
return nil, '2nd argument expected to be a table'
end
local setTabs = {}
local setVals = {}
for k,v in pairs(tab) do
if type(v) == 'table' then
setTabs[k] = v
else
setVals[k] = v
end
end
-- Now set the simple Data first
local ret,msg = lstep_lib.setTaskData(index,setVals)
if not ret then
return nil,msg
end
-- Now set the tables
for k,v in pairs(setTabs) do
ret,msg = lstep_lib.setTaskTable(index,k,tableToString(v))
if not ret then
return nil,msg
end
end
return true
end