11using System ;
22using System . IO ;
3+ using System . Reflection ;
34using System . Reactive . Concurrency ;
45using System . Reactive . Linq ;
56using Python . Runtime ;
7+ using SystemPath = System . IO . Path ;
68
79namespace Bonsai . Scripting . Python
810{
@@ -13,6 +15,7 @@ namespace Bonsai.Scripting.Python
1315 /// </summary>
1416 public class RuntimeManager : IDisposable
1517 {
18+ const char AssemblySeparator = ':' ;
1619 readonly EventLoopScheduler runtimeScheduler ;
1720 readonly IObserver < RuntimeManager > runtimeObserver ;
1821 IntPtr threadState ;
@@ -40,6 +43,40 @@ internal RuntimeManager(string pythonHome, string scriptPath, IObserver<RuntimeM
4043 disposable => disposable . Subject )
4144 . Take ( 1 ) ;
4245
46+ static bool IsEmbeddedResourcePath ( string path )
47+ {
48+ var separatorIndex = path . IndexOf ( AssemblySeparator ) ;
49+ return separatorIndex >= 0 && ! SystemPath . IsPathRooted ( path ) ;
50+ }
51+
52+ static string ReadAllText ( string path )
53+ {
54+ if ( IsEmbeddedResourcePath ( path ) )
55+ {
56+ var nameElements = path . Split ( new [ ] { AssemblySeparator } , 2 ) ;
57+ if ( string . IsNullOrEmpty ( nameElements [ 0 ] ) )
58+ {
59+ throw new InvalidOperationException (
60+ "The embedded resource path \" " + path +
61+ "\" must be qualified with a valid assembly name." ) ;
62+ }
63+
64+ var assembly = Assembly . Load ( nameElements [ 0 ] ) ;
65+ var resourceName = string . Join ( ExpressionHelper . MemberSeparator , nameElements ) ;
66+ using var resourceStream = assembly . GetManifestResourceStream ( resourceName ) ;
67+ if ( resourceStream == null )
68+ {
69+ throw new InvalidOperationException (
70+ "The specified embedded resource \" " + nameElements [ 1 ] +
71+ "\" was not found in assembly \" " + nameElements [ 0 ] + "\" " ) ;
72+ }
73+
74+ using var reader = new StreamReader ( resourceStream ) ;
75+ return reader . ReadToEnd ( ) ;
76+ }
77+ else return File . ReadAllText ( path ) ;
78+ }
79+
4380 internal static DynamicModule CreateModule ( string name = "" , string scriptPath = "" )
4481 {
4582 using ( Py . GIL ( ) )
@@ -49,7 +86,7 @@ internal static DynamicModule CreateModule(string name = "", string scriptPath =
4986 {
5087 try
5188 {
52- var code = File . ReadAllText ( scriptPath ) ;
89+ var code = ReadAllText ( scriptPath ) ;
5390 module . Exec ( code ) ;
5491 }
5592 catch ( Exception )
0 commit comments