Open nadako opened 1 year ago
To do that, we need to have an assembly post-processing task made with Mono.Cecil, it would iterate over types, find [Model]
classes, find [Observable]
properties in it, remove their default backing fields, add backing observables and change the get
/set
methods to use that.
We also need a MSBuild task to easily add this post-processing, and for Unity we need to hook into the CompilationPipeline.
I've played with this today and had some success, one thing that comes in mind is that we also want to expose underlying Observable
and State
objects for easy binding. In coconut.data
this is easy because the macros generates observables
fields with everything. With IL weaving this is harder, since it's a post-processing operation and we cannot add things that will be visible by the users of the model.
So far I have one idea how to implement it. Instead of the [Model]
attribute, we'll have models implementing the special Model
marker interface for which we'll have an extension method like this:
static class ModelExtensions
{
static Observable<T> GetObservable<T>(this Model model, string fieldName) {
return ((ModelInternal)model).GetObservable<T>(fieldName);
}
}
So you can then do something like data.GetObservable<string>(nameof(Data.Name)).Bind(...)
, which is not very nice (not type-safe enough), but it's something.
Internally, we'd have another special interface like ModelInternal
that actually defines per-type GetObservable<T>
method, and then we'd implement this interface when doing the weaving with a switch
or something.
If someone has better ideas how to do it, suggestions are welcome :)
So you can then do something like
data.GetObservable<string>(nameof(Data.Name)).Bind(...)
, which is not very nice (not type-safe enough), but it's something.
OK, for type-safety (and type inference!) we could also use the expression tree feature of C#, so the API would be something like var observable = GetObservable(() => player.Name)
.
I'd like to add something like coconut.data. There's no macros in C# so we'll have to do some IL weaving magic, but I'm pretty sure it would be possible to have something like:
and generate something like this from that: