1
1
using System ;
2
2
using System . IO ;
3
+ using System . Reflection ;
3
4
using System . Reactive . Concurrency ;
4
5
using System . Reactive . Linq ;
5
6
using Python . Runtime ;
7
+ using SystemPath = System . IO . Path ;
6
8
7
9
namespace Bonsai . Scripting . Python
8
10
{
@@ -13,6 +15,7 @@ namespace Bonsai.Scripting.Python
13
15
/// </summary>
14
16
public class RuntimeManager : IDisposable
15
17
{
18
+ const char AssemblySeparator = ':' ;
16
19
readonly EventLoopScheduler runtimeScheduler ;
17
20
readonly IObserver < RuntimeManager > runtimeObserver ;
18
21
IntPtr threadState ;
@@ -40,6 +43,40 @@ internal RuntimeManager(string pythonHome, string scriptPath, IObserver<RuntimeM
40
43
disposable => disposable . Subject )
41
44
. Take ( 1 ) ;
42
45
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
+
43
80
internal static DynamicModule CreateModule ( string name = "" , string scriptPath = "" )
44
81
{
45
82
using ( Py . GIL ( ) )
@@ -49,7 +86,7 @@ internal static DynamicModule CreateModule(string name = "", string scriptPath =
49
86
{
50
87
try
51
88
{
52
- var code = File . ReadAllText ( scriptPath ) ;
89
+ var code = ReadAllText ( scriptPath ) ;
53
90
module . Exec ( code ) ;
54
91
}
55
92
catch ( Exception )
0 commit comments