View difference between Paste ID: GQSS5vx9 and jpKfiEgm
SHOW: | | - or go back to the newest paste.
1
--[[
2
ARC: AR Client
3
Uses Plethora overlay glasses and modems to display 3D signage transmitted from local "beacons"
4
]]
5
6
local m = peripheral.find "modem"
7
local mods = peripheral.wrap "back"
8
9
if not m then error "Modem required." end
10
if not mods then error "Is this even on a neural interface?" end
11
if not mods.canvas3d then error "Overlay glasses required." end
12
13
local canv = mods.canvas3d()
14
15
local object_channel = 666
16
17
m.open(object_channel)
18
19
local x, y, z
20
21
-- convert position to string for use as table key
22
local function serialize_position(p)
23
	return string.format("%f,%f,%f", p[1], p[2], p[3])
24
end
25
26
-- Generate a string representation of a table, for easy comparison. Not really hashing, I guess.
27
local function hash_table(x)
28
	if type(x) == "table" then
29
		local out = ""
30
		for k, v in pairs(x) do
31
			if type(k) ~= "string" or not k:match "^_" then -- ignore keys beginning with _
32
				out = out .. hash_table(k) .. ":" .. hash_table(v) .. ";"
33
			end
34
		end
35
		return out
36
	else
37
		return tostring(x)
38
	end
39
end
40
41
-- honestly not that elegant, but it works
42
-- TODO: do this more efficiently/nicely somehow?
43
local function tables_match(x, y)
44
	return hash_table(x) == hash_table(y)
45
end
46
47
local objects = {}
48
local timers = {}
49
50
local function redraw(object)
51
	local frame = object._frame
52
	frame.clear()
53
end
54
55
local function process_object(object)
56
	local pos = serialize_position(object.position)
57
	if objects[pos] then
58
		if not tables_match(object, objects[pos]) then
59
			print("redrawing", pos)
60
			objects[pos] = object
61
			redraw(objects[pos])
62
		end
63
		local t = os.startTimer(20)
64
		timers[t] = pos
65
	else
66
		print("new object at", pos)
67
		if x then
68
			local frame = 
69
		else
70
			print("GPS error, cannot create object")
71
		end
72
	end
73
end
74
75
local function main_loop()
76
	while true do
77
		local event, timer, channel, reply_channel, message, distance = os.pullEvent()
78
		if event == "modem_message" and channel == object_channel and distance and type(message) == "table" then -- ensure message is from this dimension and otherwise valid
79
			for _, object in pairs(msg) do
80
				local ok, err = pcall(process_object, object)
81
				if not ok then printError(err) end
82
			end
83
		elseif event == "timer" then
84
			local objpos = timers[timer]
85
			if objpos then
86
				local obj = objects[objpos]
87
				if obj then
88
					print(objpos, "timed out")
89
					obj._frame.remove()
90
					objects[objpos] = nil
91
				end
92
			end
93
		end
94
	end
95
end
96
97
-- Request location every second
98
local function GPS_loop()
99
	while true do
100
		x, y, z = gps.locate()
101
		sleep(1)
102
	end
103
end
104
105
parallel.waitForAll(GPS_loop, main_loop)