menu_bookDocumentation
CodeGenerator: Compile-Time Method and Property Wrapping via Attributes
The [CodeGenerator] attribute in s&box lets you create custom attributes that wrap methods and properties at compile time. This is the mechanism behind [Sync] properties and [Rpc.Broadcast] — you can use it to build your own systems.
Wrapping Methods
Create an attribute that intercepts method calls:
CSHARP
[AttributeUsage( AttributeTargets.Method )]
[CodeGenerator( CodeGeneratorFlags.WrapMethod | CodeGeneratorFlags.Instance, "OnMethodInvoked" )]
public class MyRPC : Attribute { }
public class MyObject
{
[MyRPC]
public void SendMessage( string message )
{
Log.Info( message );
}
internal void OnMethodInvoked( WrappedMethod m, params object[] args )
{
// Do something before/instead of the original call
// e.g., send over network
m.Resume(); // Call the original method
}
}Wrapping Properties (Get/Set)
Intercept property reads and writes:
CSHARP
[AttributeUsage( AttributeTargets.Property )]
[CodeGenerator( CodeGeneratorFlags.WrapPropertySet | CodeGeneratorFlags.Instance, "OnWrapSet" )]
[CodeGenerator( CodeGeneratorFlags.WrapPropertyGet | CodeGeneratorFlags.Instance, "OnWrapGet" )]
public class NetVar : Attribute { }
public class MyObject
{
[NetVar] public string Name { get; set; }
internal void OnWrapSet<T>( WrappedPropertySet<T> p )
{
// Custom logic before setting
p.Setter( p.Value ); // Call original setter
}
internal T OnWrapGet<T>( WrappedPropertyGet<T> p )
{
// Return custom value or original
return p.Value;
}
}CodeGeneratorFlags
| Flag | Effect |
|---|---|
| WrapMethod | Intercept method calls |
| WrapPropertySet | Intercept property setter |
| WrapPropertyGet | Intercept property getter |
| Instance | Apply to instance members |
| Static | Apply to static members (callback must also be static) |
Callback Resolution
- Instance callbacks: method name only (e.g., "OnMethodInvoked")
- Static callbacks: fully qualified (e.g., "MyStaticClass.OnMethodInvoked")
- Callbacks can use generics to handle different parameter/return types
- WrappedMethod.Resume() calls the original method
- WrappedMethod<T>.Resume() calls and returns the original value
Was this helpful?