Skip to content

Commit 956a8b7

Browse files
committed
clrcore: also allow using attributes for RegisterScript
1 parent 2e2bb1e commit 956a8b7

File tree

2 files changed

+179
-163
lines changed

2 files changed

+179
-163
lines changed

code/client/clrcore/BaseScript.cs

+176
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Linq.Expressions;
5+
using System.Reflection;
46
using System.Security;
57
using System.Text;
68
using System.Threading.Tasks;
@@ -188,6 +190,180 @@ public static void UnregisterScript(BaseScript script)
188190
{
189191
InternalManager.RemoveScript(script);
190192
}
193+
194+
private bool m_initialized = false;
195+
196+
internal void InitializeOnAdd()
197+
{
198+
if (m_initialized)
199+
{
200+
return;
201+
}
202+
203+
m_initialized = true;
204+
205+
var allMethods = this.GetType().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
206+
207+
IEnumerable<MethodInfo> GetMethods(Type t)
208+
{
209+
return allMethods.Where(m => m.GetCustomAttributes(t, false).Length > 0);
210+
}
211+
212+
// register all Tick decorators
213+
try
214+
{
215+
foreach (var method in GetMethods(typeof(TickAttribute)))
216+
{
217+
Debug.WriteLine("Registering Tick for attributed method {0}", method.Name);
218+
219+
if (method.IsStatic)
220+
this.RegisterTick((Func<Task>)Delegate.CreateDelegate(typeof(Func<Task>), method));
221+
else
222+
this.RegisterTick((Func<Task>)Delegate.CreateDelegate(typeof(Func<Task>), this, method.Name));
223+
}
224+
}
225+
catch (Exception e)
226+
{
227+
Debug.WriteLine("Registering Tick failed: {0}", e.ToString());
228+
}
229+
230+
// register all EventHandler decorators
231+
try
232+
{
233+
foreach (var method in GetMethods(typeof(EventHandlerAttribute)))
234+
{
235+
var parameters = method.GetParameters().Select(p => p.ParameterType).ToArray();
236+
var actionType = Expression.GetDelegateType(parameters.Concat(new[] { typeof(void) }).ToArray());
237+
var attribute = method.GetCustomAttribute<EventHandlerAttribute>();
238+
239+
Debug.WriteLine("Registering EventHandler {2} for attributed method {0}, with parameters {1}", method.Name, string.Join(", ", parameters.Select(p => p.GetType().ToString())), attribute.Name);
240+
241+
if (method.IsStatic)
242+
this.RegisterEventHandler(attribute.Name, Delegate.CreateDelegate(actionType, method));
243+
else
244+
this.RegisterEventHandler(attribute.Name, Delegate.CreateDelegate(actionType, this, method.Name));
245+
}
246+
}
247+
catch (Exception e)
248+
{
249+
Debug.WriteLine("Registering EventHandler failed: {0}", e.ToString());
250+
}
251+
252+
// register all commands
253+
try
254+
{
255+
foreach (var method in GetMethods(typeof(CommandAttribute)))
256+
{
257+
var attribute = method.GetCustomAttribute<CommandAttribute>();
258+
var parameters = method.GetParameters();
259+
260+
Debug.WriteLine("Registering command {0}", attribute.Command);
261+
262+
// no params, trigger only
263+
if (parameters.Length == 0)
264+
{
265+
if (method.IsStatic)
266+
{
267+
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
268+
{
269+
method.Invoke(null, null);
270+
}), attribute.Restricted);
271+
}
272+
else
273+
{
274+
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
275+
{
276+
method.Invoke(this, null);
277+
}), attribute.Restricted);
278+
}
279+
}
280+
// Player
281+
else if (parameters.Any(p => p.ParameterType == typeof(Player)) && parameters.Length == 1)
282+
{
283+
#if IS_FXSERVER
284+
if (method.IsStatic)
285+
{
286+
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
287+
{
288+
method.Invoke(null, new object[] { new Player(source.ToString()) });
289+
}), attribute.Restricted);
290+
}
291+
else
292+
{
293+
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
294+
{
295+
method.Invoke(this, new object[] { new Player(source.ToString()) });
296+
}), attribute.Restricted);
297+
}
298+
#else
299+
Debug.WriteLine("Client commands with parameter type Player not supported");
300+
#endif
301+
}
302+
// string[]
303+
else if (parameters.Length == 1)
304+
{
305+
if (method.IsStatic)
306+
{
307+
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
308+
{
309+
method.Invoke(null, new object[] { args.Select(a => (string)a).ToArray() });
310+
}), attribute.Restricted);
311+
}
312+
else
313+
{
314+
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
315+
{
316+
method.Invoke(this, new object[] { args.Select(a => (string)a).ToArray() });
317+
}), attribute.Restricted);
318+
}
319+
}
320+
// Player, string[]
321+
else if (parameters.Any(p => p.ParameterType == typeof(Player)) && parameters.Length == 2)
322+
{
323+
#if IS_FXSERVER
324+
if (method.IsStatic)
325+
{
326+
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
327+
{
328+
method.Invoke(null, new object[] { new Player(source.ToString()), args.Select(a => (string)a).ToArray() });
329+
}), attribute.Restricted);
330+
}
331+
else
332+
{
333+
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
334+
{
335+
method.Invoke(this, new object[] { new Player(source.ToString()), args.Select(a => (string)a).ToArray() });
336+
}), attribute.Restricted);
337+
}
338+
#else
339+
Debug.WriteLine("Client commands with parameter type Player not supported");
340+
#endif
341+
}
342+
// legacy --> int, List<object>, string
343+
else
344+
{
345+
if (method.IsStatic)
346+
{
347+
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
348+
{
349+
method.Invoke(null, new object[] { source, args, rawCommand });
350+
}), attribute.Restricted);
351+
}
352+
else
353+
{
354+
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
355+
{
356+
method.Invoke(this, new object[] { source, args, rawCommand });
357+
}), attribute.Restricted);
358+
}
359+
}
360+
}
361+
}
362+
catch (Exception e)
363+
{
364+
Debug.WriteLine("Registering command failed: {0}", e.ToString());
365+
}
366+
}
191367
}
192368

193369
class DummyAsyncResult : IAsyncResult

code/client/clrcore/InternalManager.cs

+3-163
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ internal static void AddScript(BaseScript script)
6161
{
6262
if (!ms_definedScripts.Contains(script))
6363
{
64+
script.InitializeOnAdd();
65+
6466
ms_definedScripts.Add(script);
6567
}
6668
}
@@ -104,169 +106,7 @@ private static Assembly CreateAssemblyInternal(string assemblyFile, byte[] assem
104106

105107
Debug.WriteLine("Instantiated instance of script {0}.", type.FullName);
106108

107-
var allMethods = derivedScript.GetType().GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
108-
109-
IEnumerable<MethodInfo> GetMethods(Type t)
110-
{
111-
return allMethods.Where(m => m.GetCustomAttributes(t, false).Length > 0);
112-
}
113-
114-
// register all Tick decorators
115-
try
116-
{
117-
foreach (var method in GetMethods(typeof(TickAttribute)))
118-
{
119-
Debug.WriteLine("Registering Tick for attributed method {0}", method.Name);
120-
121-
if (method.IsStatic)
122-
derivedScript.RegisterTick((Func<Task>)Delegate.CreateDelegate(typeof(Func<Task>), method));
123-
else
124-
derivedScript.RegisterTick((Func<Task>)Delegate.CreateDelegate(typeof(Func<Task>), derivedScript, method.Name));
125-
}
126-
}
127-
catch (Exception e)
128-
{
129-
Debug.WriteLine("Registering Tick failed: {0}", e.ToString());
130-
}
131-
132-
// register all EventHandler decorators
133-
try
134-
{
135-
foreach (var method in GetMethods(typeof(EventHandlerAttribute)))
136-
{
137-
var parameters = method.GetParameters().Select(p => p.ParameterType).ToArray();
138-
var actionType = Expression.GetDelegateType(parameters.Concat(new[] { typeof(void) }).ToArray());
139-
var attribute = method.GetCustomAttribute<EventHandlerAttribute>();
140-
141-
Debug.WriteLine("Registering EventHandler {2} for attributed method {0}, with parameters {1}", method.Name, String.Join(", ", parameters.Select(p => p.GetType().ToString())), attribute.Name);
142-
143-
if (method.IsStatic)
144-
derivedScript.RegisterEventHandler(attribute.Name, Delegate.CreateDelegate(actionType, method));
145-
else
146-
derivedScript.RegisterEventHandler(attribute.Name, Delegate.CreateDelegate(actionType, derivedScript, method.Name));
147-
}
148-
}
149-
catch (Exception e)
150-
{
151-
Debug.WriteLine("Registering EventHandler failed: {0}", e.ToString());
152-
}
153-
154-
// register all commands
155-
try
156-
{
157-
foreach (var method in GetMethods(typeof(CommandAttribute)))
158-
{
159-
var attribute = method.GetCustomAttribute<CommandAttribute>();
160-
var parameters = method.GetParameters();
161-
162-
Debug.WriteLine("Registering command {0}", attribute.Command);
163-
164-
// no params, trigger only
165-
if (parameters.Length == 0)
166-
{
167-
if (method.IsStatic)
168-
{
169-
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
170-
{
171-
method.Invoke(null, null);
172-
}), attribute.Restricted);
173-
}
174-
else
175-
{
176-
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
177-
{
178-
method.Invoke(derivedScript, null);
179-
}), attribute.Restricted);
180-
}
181-
}
182-
// Player
183-
else if (parameters.Any(p => p.ParameterType == typeof(Player)) && parameters.Length == 1)
184-
{
185-
#if IS_FXSERVER
186-
if (method.IsStatic)
187-
{
188-
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
189-
{
190-
method.Invoke(null, new object[] { new Player(source.ToString()) });
191-
}), attribute.Restricted);
192-
}
193-
else
194-
{
195-
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
196-
{
197-
method.Invoke(derivedScript, new object[] { new Player(source.ToString()) });
198-
}), attribute.Restricted);
199-
}
200-
#else
201-
Debug.WriteLine("Client commands with parameter type Player not supported");
202-
#endif
203-
}
204-
// string[]
205-
else if (parameters.Length == 1)
206-
{
207-
if (method.IsStatic)
208-
{
209-
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
210-
{
211-
method.Invoke(null, new object[] { args.Select(a => (string)a).ToArray() });
212-
}), attribute.Restricted);
213-
}
214-
else
215-
{
216-
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
217-
{
218-
method.Invoke(derivedScript, new object[] { args.Select(a => (string)a).ToArray() });
219-
}), attribute.Restricted);
220-
}
221-
}
222-
// Player, string[]
223-
else if (parameters.Any(p => p.ParameterType == typeof(Player)) && parameters.Length == 2)
224-
{
225-
#if IS_FXSERVER
226-
if (method.IsStatic)
227-
{
228-
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
229-
{
230-
method.Invoke(null, new object[] { new Player(source.ToString()), args.Select(a => (string)a).ToArray() });
231-
}), attribute.Restricted);
232-
}
233-
else
234-
{
235-
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
236-
{
237-
method.Invoke(derivedScript, new object[] { new Player(source.ToString()), args.Select(a => (string)a).ToArray() });
238-
}), attribute.Restricted);
239-
}
240-
#else
241-
Debug.WriteLine("Client commands with parameter type Player not supported");
242-
#endif
243-
}
244-
// legacy --> int, List<object>, string
245-
else
246-
{
247-
if (method.IsStatic)
248-
{
249-
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
250-
{
251-
method.Invoke(null, new object[] { source, args, rawCommand });
252-
}), attribute.Restricted);
253-
}
254-
else
255-
{
256-
Native.API.RegisterCommand(attribute.Command, new Action<int, List<object>, string>((source, args, rawCommand) =>
257-
{
258-
method.Invoke(derivedScript, new object[] { source, args, rawCommand });
259-
}), attribute.Restricted);
260-
}
261-
}
262-
}
263-
}
264-
catch (Exception e)
265-
{
266-
Debug.WriteLine("Registering command failed: {0}", e.ToString());
267-
}
268-
269-
ms_definedScripts.Add(derivedScript);
109+
AddScript(derivedScript);
270110
}
271111
catch (Exception e)
272112
{

0 commit comments

Comments
 (0)