summaryrefslogtreecommitdiff
path: root/src/ecs.moon
blob: 182f09d8b33ada896faa23e60210336b3390a926 (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
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
entities = {}

-- Bace component class of the ECS
class Component
	depends: {}
	new: (name, properties) =>
		@name = name
		@properties = properties or {}
	join: (e) =>
		@
	leave: (e) =>
		@

-- Base entity of our ECS
class Entity
	id: 1
	new: (id, components) => -- [id], [components]
		id_cur = #entities
		while id == nil
			id_cur += 1
			if entities[id_cur] == nil
				id = id_cur
		assert(entities[id] == nil, "Attempted to create entity with the same id as one that already exists: " .. tostring(id))
		entities[id] = @
		@id = id
		-- Bookkeeping for O(1) access for componenets
		@c_by_type = {}

		--Entity is responsible for the component -> entity link
		@components = components or {}
		for name, component in pairs(@components)
			component.entity = @
			@c_by_type[component.__class] = @c_by_type[component.__class] or {}
			@c_by_type[component.__class][name] = component
		for name, component in pairs(@components)
			component\join(@)
	add: (cid, component) =>
		component.entity = @
		component\join(@)
		if cid == nil
			cid = #@components
			while @components[cid]
				cid += 1
		assert(@components[cid] == nil, "Already had a component with id" .. tostring(cid))
		@components[cid] = component
		@c_by_type[component.__class][cid] = component
		@
	remove: (cid) =>
		component = @components[cid]
		component.entity = nil
		component\leave(@)
		component
		@components[cid] = nil
		@c_by_type[component.__class][cid] = nil
	get: (cid) =>
		@components[cid]

class NetworkedComponent extends Component
	pack: () =>
		assert(@entity, "Tried to pack on a NetworkedComponent without an Entity")
		return am.to_json({
			id: @entity.id
			data: @properties
			time: am.current_time!
		})

class PredictedComponent extends Component
	new: (name, properties, netc_name, calculate) =>
		super(name, properties)
		@netc_name = netc_name
		@calculate = calculate
	join: (entity) =>
		@net = @entity\get(@netc_name)
	forward: () =>
		for property, calculation in pairs(@calculate)
			@properties[property] = calculation(@)

-- componnt moved to world.moon
--class GraphicsComponent extends Component
--	new: (name, properties) =>
--		print("Got name", name, "and properties", properties)
--		assert(properties and properties.node , "Failed to find node for graphics component")
--		super(name, properties)
--	static: () =>
--		@@static
--	node: () =>
--		@properties.node

class PhysicsComponent extends Component
	new: (name, properties) =>
		assert(properties and properties.shape, "Failed to find a shape for physics component")
		super(name, properties)

class ScriptComponent extends Component
	new: (name, properties) =>
		assert(properties and properties.script, "Failed to find script name for script component")
		super(name, properties)

{
	Component: Component
	Entity: Entity
	NetworkedComponent: NetworkedComponent
	PredictedComponent: PredictedComponent
	GraphicsComponent: GraphicsComponent
	PhysicsComponent: PhysicsComponent
	ScriptComponent: ScriptComponent
}