aboutsummaryrefslogtreecommitdiff
path: root/src/ecs/networked.moon
blob: 6673a7d1060c0318829f306e7df9ef2a99bea0a4 (plain)
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
Component = require("ecs.component")
world = require("world")
log = require("log")

network_log = {}

class NetworkedComponent extends Component
	@q: {}

	new: (name, properties) =>
		assert(properties.id == nil, "networked component's id needs to be nil")
		assert(properties.name == nil, "network component's name needs to be nil")
		properties.id = world.level_sync.entid
		world.level_sync.entid += 1
		nwc = @
		update = (key, value) =>
			if not world.hub
				error("Tried to update network on the client")
				return
			if not properties[key]
				error("Trying to set key not defined in properties:" .. key)
			properties[key] = value
			properties.last_update = am.eval_js("Date.now();")
			nwc.__class.q[nwc] = true
			-- Broadcast update to other peers through client
			--world.hub\broadcast("update", properties)
			--actually, we only want to update each network component *at most* once per frame.

		proxy = {}
		setmetatable(proxy, {
			__index: properties,
			__newindex: update
		})
		super(name, proxy)
		@net_properties = properties
	join: (e, cid) =>
		@@node\action("Send Updates", ()->
			@@update_dirty!
		)
		@net_properties.id = e.id
		@net_properties.name = cid
		log.info("Added networked componenet name " .. @name .. " to entity id " .. e.id, {"net","server","ecs"})
		-- Send initial create message through client
		--if world.hub -- Actually, entity creation is hard, just sync each entity individually.
			--world.hub\broadcast("create", properties)
		super(e)

	pack: () =>
		assert(@entity, "Tried to pack on a NetworkedComponent without an Entity")
		log.info("Packing data from proxy:" .. tostring(@proxy), {"net","ecs"})
		return am.to_json({
			id: @entity.id
			data: @net_properties
			time: am.current_time!
		})
	
	unpack: () ->
		assert(@entity, "Tried to unpack on a NEtworkedComponent without an Entity")

	@update_dirty: () =>
		for component, _ in pairs(@q)
			world.hub\broadcast("update", component.net_properties)
		@q = {}
	
	-- Each different kind of entity needs to have it's own create and listen network
	-- hooks, it's way too complicated and heavy to push every entity with every componenet
	-- over the network.
		
assert(NetworkedComponent.q, "No queue found!")

NetworkedComponent