public static ISignalPreProcessor Create(ISignalPreProcessor previous, PreProcessorType type = PreProcessorType.Endless) { if (previous != null) { Points = previous.Points; } switch (type) { case PreProcessorType.ByFrame: return(new PreProcessor((context, xpoints, rawSignal) => { var last = context.Steps + 1; var m = rawSignal.X % (last); var next = Points.Count + 1 <= last ? Points.Count + 1 : 0; var index = next == m + 1 ? m : next; if (index == 0) { Points = new List <RPoint> (); } Points.Add(new RPoint(index, rawSignal.Y)); //Scale return Points.Select(x => { var step = (float)((x.X) * context.Step); return XPointFty.New(step, x.Y); } ).ToArray(); }, Points)); case PreProcessorType.Endless: return(new ContinuousPreProcessor(Points)); } throw new ArgumentException("unkwon Preprocessor Type"); }
protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); base.OnCreate(savedInstanceState); SetContentView(Resource.Layout.Main); _surface = FindViewById <Xurface> (Resource.Id.surfaceView1); ActivityState = new ActivityState(); ActivityState.Scale = 10; ActivityState.SamplingRate = 200; ActivityState.SignalRate = 200; Func <float> getSignal = () => { var halfHeight = ActivityState.Height / 2; var r = _random.Next(-halfHeight, halfHeight); return(halfHeight + r); }; var signalSource = Observable.Interval(TimeSpan.FromMilliseconds(ActivityState.SignalRate)) .Select(x => getSignal()); var timer = Observable.Interval(TimeSpan.FromMilliseconds(ActivityState.SamplingRate)) .Select(x => (int)x); var signalSources = timer // Setup , dimensions .Do(x => ActivityState.SetDimensions(_surface.Width, _surface.Height)) //Merge Signal and TimeLine .Zip(signalSource, (x, y) => XPointFty.New(x, y)); //IEnumerable<XPoint> points = new List<XPoint> (); _signalPreProcessor = PreProcessorFty.Create(_signalPreProcessor, PreProcessorType); subscribe = () => { //points = new List<XPoint>(); if (_subscription != null) { _subscription.Dispose(); } _subscription = signalSources .TakeWhile(x => ActivityState.State == States.Running) //Arrange .Select(rawSignal => { return(_signalPreProcessor.Arrange(ActivityState, rawSignal).ToArray()); }) .Subscribe(xpoints => { var canvasActions = new List <Action <Canvas> >(); //Before Signal canvasActions.AddRange(CanvasActions .Where(plugin => plugin.IsEnabled && plugin.Order == CanvasActionOrder.BeforeSignal) .Select(plugin => plugin.GetAction(xpoints, ActivityState))); // Highlander principle : Only One canvasActions.Add(SignalRenders.FirstOrDefault(x => x.IsEnabled).GetAction(xpoints, ActivityState)); //After Signal canvasActions.AddRange(CanvasActions .Where(plugin => plugin.IsEnabled && plugin.Order == CanvasActionOrder.AfterSignal) .Select(plugin => plugin.GetAction(xpoints, ActivityState))); using (var _canvas = new Canvas()){ _surface.Drawit(_canvas, canvasActions.ToArray()); } RunOnUiThread(_surface.Invalidate); }, /*onCompleted*/ subscribe); }; Action Unsubscribe = () => { if (_subscription != null) { _subscription.Dispose(); } }; ActivityState .Changed .Where(p => p.Name == "State") .Subscribe(p => { var state = p.Value as States?; switch (state) { case States.Running: subscribe(); break; case States.Stopped: Unsubscribe(); break; } }); }
XPoint Expand(ActivityState context, XPoint rawSignal) { return(XPointFty.New(rawSignal.X * context.Step, rawSignal.Y)); }