Created
October 4, 2017 09:11
-
-
Save glopesdev/13a08b8854a73124ffa98a8d32243bda to your computer and use it in GitHub Desktop.
Minimalist example of a dynamically typed source in Bonsai
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Bonsai.Expressions; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Linq.Expressions; | |
| using System.Reactive.Linq; | |
| using System.Text; | |
| using System.Threading.Tasks; | |
| namespace Bonsai.Dynamic | |
| { | |
| public enum DynamicDevice | |
| { | |
| String, | |
| Int32, | |
| Double | |
| } | |
| [WorkflowElementCategory(ElementCategory.Source)] | |
| public class DynamicSource : ZeroArgumentExpressionBuilder | |
| { | |
| public DynamicDevice Device { get; set; } | |
| public override Expression Build(IEnumerable<Expression> arguments) | |
| { | |
| switch (Device) | |
| { | |
| case DynamicDevice.String: | |
| return Expression.Call(typeof(DynamicSource), "GenerateString", null); | |
| case DynamicDevice.Int32: | |
| return Expression.Call(typeof(DynamicSource), "GenerateInt32", null); | |
| case DynamicDevice.Double: | |
| return Expression.Call(typeof(DynamicSource), "GenerateDouble", null); | |
| default: | |
| throw new InvalidOperationException("Unsupported source"); | |
| } | |
| } | |
| static IObservable<string> GenerateString() | |
| { | |
| return Observable.Return("hello"); | |
| } | |
| static IObservable<int> GenerateInt32() | |
| { | |
| return Observable.Return(42); | |
| } | |
| static IObservable<double> GenerateDouble() | |
| { | |
| return Observable.Return(Math.PI); | |
| } | |
| } | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@jonnew I would say the
Buildmethod can probably do this handshaking. It can be as complicated as you want. Also, the output can be a list, or sequence, of devices. I can also extend the example to do the discovery and handshaking of devices within a drop-down dialog that is shown on the property pages, so the user can pick which device(s) should be activated.Sometimes I also setup hardware manager classes that can be accessed more globally and take care of discovering/configuring connected devices. This is the way the
Arduinoserial port works (see here), for example, which allows you to have per-device configuration settings (i.e. for baud rates, etc).Ultimately,
Buildis just the entry point, but you can exploit it to setup your own complicated infrastructure that controls the runtime code generation in detail. In fact, I often find myself doing this for exactly the same reasons you pointed out 😄