View difference between Paste ID: taHyKDKP and 2qPybHqp
SHOW: | | - or go back to the newest paste.
1
--DOCS AT http://pastebin.com/kiwbk2Ju
2
3
local classes={}
4
local objects={}
5
6
--Objects/proxies
7
8
function wOOPupdate()
9
	for i,v in pairs(objects) do
10
		for _,v2 in pairs(v[2]) do
11
			if tostring(v2)=="wOOPevent" then
12
				v2.update(v[2])
13
			end
14
		end
15
	end
16
end
17
18
local function functionToTable(tab)
19
	local mt={}
20
	mt.__call=
21
	function(a,...)
22
		local prevSelf=self
23
		self=tab
24
		local src=a.func
25
		local ret={pcall(src,...)}
26
		if not ret[1] then
27
			assert(pcall(src))
28
		end
29
		table.remove(ret,1)
30
		self=prevSelf
31
		return unpack(ret)
32
	end
33
	for i,v in pairs(tab) do
34
		if type(v)=="function" then
35
			local oldV=v
36
			tab[i]={func=oldV}
37
			setmetatable(tab[i],mt)
38
		end
39
	end
40
end
41
42
local function createProxy(o,omt)
43
	for i,v in pairs(o) do
44
		if tostring(v)=="wOOPevent" then
45-
		elseif bypassing and ind=="___bypassing" then
45+
			v.obj=o
46-
			return tab.___self
46+
			v.oldSelf=o
47
		end
48
	end
49
	local proxy=newproxy(true)
50
	local mt=getmetatable(proxy)
51
52
	for i,v in pairs(omt) do
53
		mt[i]=v
54
	end
55
	
56
	mt.__index=
57
	function(tab,ind)
58
		if not ind:find("__") then
59
			if o[ind]~=nil then
60
				return o[ind]
61
			else
62
				error("Value not found : "..ind)
63
			end
64
		else
65
			error("Private value : "..ind)
66
		end
67
	end
68
69
	mt.__newindex=
70
	function(tab,ind,val)
71
		if not ind:find("_") then
72
			if o[ind] then
73
				o[ind]=val
74
			else
75
				error("Value not found : "..ind)
76
			end
77
		else
78
			error("Read only or private value : "..ind)
79
		end
80
	end
81
	
82
	mt.__metatable=false
83
	return proxy
84
end
85
86
local function newObj(a,...)
87
	local arg={...}
88
	local o
89-
	o.___self=o
89+
90
	if arg[1]=="bypassNewFunc" then
91
		o={}
92
		class=classes[a] or {}
93
	else
94
		o=((classes[a]) and classes[a].__settings.new(...) or {})
95
		class=classes[a] or {}
96
	end
97
	local omt={}
98
	for i,v in pairs((class.__omt or (classes["base"] or {}))) do
99
		omt[i]=v
100
	end
101
	omt.__index=class
102
	setmetatable(o,omt)
103
	for i,v in pairs(class) do
104
		o[i]=(o[i] or v)
105
	end
106
	functionToTable(o)
107
	local proxy=createProxy(o,omt)
108
	table.insert(objects,{proxy,o})
109
	return proxy
110
end
111
112
--Classes
113
114
local function newClass(a, ...)
115
	arg={...}
116
	b=(type(arg[1])=="table" and arg[1] or arg[2])
117-
	b.extends=newObj(b.extends.className,"bypassNewFunc")
117+
118
	b.className=a
119
	b.name=a.."Obj"
120
	local mt=(b.__mt or {})
121
	mt.__tostring=function(a) return "Class "..a.className end
122
	mt.__call=function(a,...) local arg={...} return newObj(a.className,...) end
123
	mt.__concat=function(a,b) return tostring(a)..tostring(b) end
124
	if not b.__mt then
125
		b.__mt=mt
126
	end
127
	setmetatable(b, b.__mt)
128
	classes[a]=b
129
	for i,v in pairs(b.extends) do
130
		if not b[i] then
131
			b[i]=v
132
		end
133
	end
134
	b.extends=classes[(type(arg[2])=="table" and arg[1] or "base")]
135
	_G[a]=b
136
end
137
138
local function addClassInheritance(name, b)
139
	return function(...)
140
		newClass(name, b, arg[1])
141
	end
142
end
143
144
local function addClass(name)
145
	return function(...)
146
		local arg={...}
147
		if type(arg[1])=="table" then
148
			newClass(name,...)
149
		else
150
			return addClassInheritance(name,arg[1])
151
		end
152
	end
153
end
154
155
function class(name)
156
	return addClass(name)
157
end
158
159-
	className="base",
159+
160
161
class "base"
162
{
163-
}
163+
164
	function(arg)
165
		if self.className==arg then
166
			return true
167
		elseif self.className~="base" then
168
			if self.extends.isA(arg) then
169
				return true
170
			end
171
		else
172
			return false
173
		end
174
	end,
175
	
176
	__settings={new=function(...) return {} end},
177
	__omt={__tostring=function(a) return "Object "..a.className end,__concat=function(a,b) return tostring(a)..tostring(b) end},
178
	__mt={__tostring=function(a) return "Class "..a.className end}
179
}
180
181
class "event"
182
{
183
	__cond=function(newSelf, prevSelf) if newSelf.className=="base" then return true end end,
184
	__cb=function() end,
185
	
186
	oldSelf='',
187
	obj='',
188
	
189
	update=function(obj)
190
		if self.__cond(self.oldSelf,obj) then
191
			self.__cb(self.__cond(self.oldSelf,obj))
192
		end
193
		self.oldSelf=obj
194
	end,
195
	
196
	connect=function(func)
197
		self.__cb=func
198
		self._connected=true
199
	end,
200
	
201
	disconnect=function()
202
		self.__cb=function() end
203
		self._connected=false
204
	end,
205
	
206
	__settings=
207
	{
208
		new=
209
		function(newFunc)
210
			return({__cond=newFunc})
211
		end
212
	},
213
	__omt={__tostring=function() return 'wOOPevent' end}
214
}
215
216
wOOPupdate()