Skip to content

Commit acb2244

Browse files
authored
Merge pull request #6 from ncguilbeault/assembly-loading
Allow RuntimeManager to load scripts stored as assembly resource files
2 parents d5d1c65 + c774db3 commit acb2244

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

src/Bonsai.Scripting.Python/RuntimeManager.cs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
using System;
22
using System.IO;
3+
using System.Reflection;
34
using System.Reactive.Concurrency;
45
using System.Reactive.Linq;
56
using Python.Runtime;
7+
using SystemPath = System.IO.Path;
68

79
namespace 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

Comments
 (0)