1
+ using Bonsai . Expressions ;
2
+ using System . Linq . Expressions ;
3
+ using System . Collections . Generic ;
4
+ using System . Reactive . Linq ;
5
+ using System ;
6
+ using System . Reflection ;
7
+ using System . Linq ;
8
+ using Python . Runtime ;
9
+
10
+ namespace Bonsai . Scripting . Python
11
+ {
12
+ public class PythonInterpreterLock : WorkflowExpressionBuilder
13
+ {
14
+ static readonly Range < int > argumentRange = Range . Create ( lowerBound : 1 , upperBound : 1 ) ;
15
+
16
+ public PythonInterpreterLock ( )
17
+ : this ( new ExpressionBuilderGraph ( ) )
18
+ {
19
+ }
20
+
21
+ public PythonInterpreterLock ( ExpressionBuilderGraph workflow )
22
+ : base ( workflow )
23
+ {
24
+ }
25
+
26
+ public override Range < int > ArgumentRange => argumentRange ;
27
+
28
+ public override Expression Build ( IEnumerable < Expression > arguments )
29
+ {
30
+ // var source = arguments.Single();
31
+ // var sourceType = source.Type.GetGenericArguments()[0]; // Get TSource from IObservable<TSource>
32
+ // var factoryParameter = Expression.Parameter(typeof(IObservable<>).MakeGenericType(sourceType));
33
+ Console . WriteLine ( $ "here1 args: { arguments } ") ;
34
+ var source = arguments . FirstOrDefault ( ) ;
35
+ if ( source == null )
36
+ {
37
+ throw new InvalidOperationException ( "There must be at least one input." ) ;
38
+ }
39
+ var sourceType = source . Type . GetGenericArguments ( ) [ 0 ] ; // Get TSource from IObservable<TSource>
40
+ Console . WriteLine ( $ "here2 sourceType: { source . Type } ") ;
41
+ // var factoryParameter = Expression.Parameter(source.Type);
42
+ var factoryParameter = Expression . Parameter ( typeof ( IObservable < > ) . MakeGenericType ( sourceType ) , "factoryParam" ) ;
43
+ Console . WriteLine ( $ "here3 factoryParam: { factoryParameter } ") ;
44
+ return BuildWorkflow ( arguments , factoryParameter , selectorBody =>
45
+ {
46
+ Console . WriteLine ( $ "here4 selectorBody: { selectorBody } ") ;
47
+ var selector = Expression . Lambda ( selectorBody , factoryParameter ) ;
48
+ Console . WriteLine ( $ "here5 selector: { selector } ") ;
49
+ var resultType = selectorBody . Type . GetGenericArguments ( ) [ 0 ] ;
50
+ Console . WriteLine ( $ "here6 resultType: { resultType } ") ;
51
+ // var processMethod = typeof(PythonInterpreterLock).GetMethod(nameof(Process)).MakeGenericMethod(sourceType, resultType);
52
+ // Console.WriteLine($"here7 processMethod: {processMethod}");
53
+ // return Expression.Call(processMethod, source, selector);
54
+ return Expression . Call ( GetType ( ) , nameof ( Process ) , new Type [ ] { sourceType , resultType } , source , selector ) ;
55
+ } ) ;
56
+ }
57
+
58
+ static IObservable < TResult > Process < TSource , TResult > ( IObservable < TSource > source , Func < IObservable < TSource > , IObservable < TResult > > selector )
59
+ {
60
+ Console . WriteLine ( "process" ) ;
61
+ return Observable . Defer ( ( ) =>
62
+ {
63
+ using ( Py . GIL ( ) )
64
+ {
65
+ return selector ( source ) ;
66
+ }
67
+ } ) ;
68
+ }
69
+ }
70
+ }
0 commit comments