@@ -7,6 +7,7 @@ local isbool = isbool
7
7
local IsValid = IsValid
8
8
local type = type
9
9
local ErrorNoHaltWithStack = ErrorNoHaltWithStack
10
+ local GProtectedCall = ProtectedCall
10
11
11
12
module ( " hook" )
12
13
@@ -76,6 +77,21 @@ function Run( name, ... )
76
77
return Call ( name , currentGM , ... )
77
78
end
78
79
80
+ --[[ ---------------------------------------------------------
81
+ Name: ProtectedRun
82
+ Args: string hookName, vararg args
83
+ Desc: Executes hooks associated with the given hook name.
84
+ Unlike hook.Run, it ensures that execution continues
85
+ even if a hook returns a value or throws an error.
86
+ -----------------------------------------------------------]]
87
+ function ProtectedRun ( name , ... )
88
+ if ( !currentGM ) then
89
+ currentGM = gmod and gmod .GetGamemode () or nil
90
+ end
91
+
92
+ return ProtectedCall ( name , currentGM , ... )
93
+ end
94
+
79
95
80
96
--[[ ---------------------------------------------------------
81
97
Name: Run
@@ -141,3 +157,60 @@ function Call( name, gm, ... )
141
157
return GamemodeFunction ( gm , ... )
142
158
143
159
end
160
+
161
+ --[[ ---------------------------------------------------------
162
+ Name: ProtectedCall
163
+ Args: string hookName, table gamemodeTable, vararg args
164
+ Desc: Executes hooks associated with the given hook name.
165
+ Unlike hook.Call, it ensures that execution continues
166
+ even if a hook returns a value or throws an error.
167
+ -----------------------------------------------------------]]
168
+ function ProtectedCall ( name , gm , ... )
169
+
170
+ --
171
+ -- Run hooks
172
+ --
173
+ local HookTable = Hooks [ name ]
174
+ if ( HookTable != nil ) then
175
+
176
+ for k , v in pairs ( HookTable ) do
177
+
178
+ if ( isstring ( k ) ) then
179
+
180
+ --
181
+ -- If it's a string, it's cool
182
+ --
183
+ GProtectedCall ( v , ... )
184
+
185
+ else
186
+
187
+ --
188
+ -- If the key isn't a string - we assume it to be an entity
189
+ -- Or panel, or something else that IsValid works on.
190
+ --
191
+ if ( IsValid ( k ) ) then
192
+ --
193
+ -- If the object is valid - pass it as the first argument (self)
194
+ --
195
+ GProtectedCall ( v , k , ... )
196
+ else
197
+ --
198
+ -- If the object has become invalid - remove it
199
+ --
200
+ HookTable [ k ] = nil
201
+ end
202
+ end
203
+
204
+ end
205
+ end
206
+
207
+ --
208
+ -- Call the gamemode function
209
+ --
210
+ if ( !gm ) then return end
211
+
212
+ local GamemodeFunction = gm [ name ]
213
+ if ( GamemodeFunction == nil ) then return end
214
+
215
+ GProtectedCall ( GamemodeFunction , gm , ... )
216
+ end
0 commit comments