-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathObjectVariable
More file actions
132 lines (108 loc) · 3.06 KB
/
ObjectVariable
File metadata and controls
132 lines (108 loc) · 3.06 KB
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
local TableUtil = require(script.Parent.Parent:WaitForChild("TableUtil"))
local function clone(value)
if typeof(value) == "table" then
return TableUtil.clone(value)
else
return value
end
end
local ObjectVariable = {}
ObjectVariable.__index = ObjectVariable
setmetatable(ObjectVariable, {
__call = function(cls, ...)
return cls.new(...)
end
})
function ObjectVariable.new(name, value, instance)
local self = setmetatable({}, ObjectVariable)
local val = value
pcall(function()
if instance and instance[name] then
instance[name] = value
val = name
else
instance = nil
end
end)
local callbacks = {}
local propertyTable = {}
local function _Update(dontCallOnUpdate, newValue, oldValue, key)
if not dontCallOnUpdate then
for _,callback in pairs(callbacks) do
callback(newValue, oldValue, key)
end
end
end
function self:OnUpdate(func)
table.insert(callbacks, func)
end
function self:_Get()
if instance then
return instance[val]
else
return val
end
end
function self:_Set(newVal, _dontCallOnUpdate)
local oldValue = val
if instance then
oldValue = instance[val]
instance[val] = newVal
_Update(_dontCallOnUpdate, instance[val], oldValue, name)
else
val = newVal
_Update(_dontCallOnUpdate, val, oldValue, name)
end
end
function self:Update(updateFunc, _dontCallOnUpdate)
local oldValue = self:_Get()
val = updateFunc(oldValue)
_Update(_dontCallOnUpdate, val, oldValue, name)
end
self.__index = function(_, key)
if propertyTable[key] then
if pcall(function() return(typeof(val) == "table" or typeof(val) == "Instance") and val[key] and val[key] ~= propertyTable[key] end) then
val[key] = propertyTable[key]:_Get()
end
return propertyTable[key]
elseif val[key] then
propertyTable[key] = ObjectVariable.new(key, val[key])
return propertyTable[key]
end
end
self.__newindex = function(_, key, newVal)
if propertyTable[key] then
local oldValue = propertyTable[key]
_Update(false, newVal, oldValue, key)
propertyTable[key]:_Set(newVal)
else
if typeof(val) == "Instance" then
local succ,oldVal = pcall(function() return val[key] end)
propertyTable[key] = ObjectVariable.new(key, newVal, val)
if succ then
_Update(false, newVal, oldVal, key)
else
_Update(false, newVal, nil, key)
end
else
propertyTable[key] = ObjectVariable.new(key, newVal)
_Update(false, newVal, nil, key)
end
end
end
self.__call = function(_, ...)
assert(typeof(val) == "function", ("Cannot call "))
return val(...)
end
self.__tostring = function()
return tostring(val)
end
self = setmetatable(self, self)
if typeof(val) == "table" then
for key,v in pairs(val) do
propertyTable[key] = ObjectVariable.new(key, v)
end
end
return self
end
return ObjectVariable