Skip to content

Instantly share code, notes, and snippets.

@glopesdev
Created October 4, 2017 09:11
Show Gist options
  • Select an option

  • Save glopesdev/13a08b8854a73124ffa98a8d32243bda to your computer and use it in GitHub Desktop.

Select an option

Save glopesdev/13a08b8854a73124ffa98a8d32243bda to your computer and use it in GitHub Desktop.
Minimalist example of a dynamically typed source in Bonsai
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);
}
}
}
@glopesdev

Copy link
Copy Markdown
Author

@jonnew I would say the Build method 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 Arduino serial port works (see here), for example, which allows you to have per-device configuration settings (i.e. for baud rates, etc).

Ultimately, Build is 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 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment