ialex32x / unity-jsb

It brings Javascript runtime capability to Unity3D by integrating QuickJS.
MIT License
337 stars 43 forks source link

unity-jsb lite #52

Closed FreakTheMighty closed 2 years ago

FreakTheMighty commented 3 years ago

I've started investigating how to integrate this library into my project and have some thoughts about how we could make it easier and more modular. My ideas are pretty rough, and would require a big change to the project, so this issue is really just to start the conversation and see where it goes.

I started a branch jsb-lite here. I want to re-iterate that this is just a rough sketch, I stripped a lot out just to see what could work.

Goals

Approach

What if the project were broken up into UPM packages that depended on one another? For example, something like this.

ialex32x commented 3 years ago

Good idea👍. The mechanism of C# value operations currently used like js_push_* and js_get_* need to be replaced with a new way (by type registering at runtime, instead of partial class), and it will lead to some (acceptable) side effects on the performance. But the generated code is highly relevant to the version of Unity, it's better to generate by users.

FreakTheMighty commented 3 years ago

👏 I'm very happy to hear you like the idea!

  1. For the Values static methods, I did something a bit hacky, but also pretty simple here https://github.com/iospectar/unity-jsb/blob/feature/jsb-lite/Assets/unity-jsb/Editor/CodeGeneration/Codegen/CodeGenerator.cs#L65. The result is that _QuickJSBindings.cs contains public partial class BindingList : Values.
  2. When you say the generated code is "highly relevant to the version of Unity", is the because each build platform has its own requirements or because things change so much between Unity versions?
ialex32x commented 3 years ago

Yes, there are some API changes between different unity versions. And it may be a burden on code size if all types are exported, it's different what types used in every project.

FreakTheMighty commented 3 years ago

@ialex32x I’ve got another clarifying question. Is the unity version important to all bindings or just bindings for Unity APIs?

ialex32x commented 3 years ago

only bindings for Unity API

ialex32x commented 3 years ago

Hi @FreakTheMighty, I've committed a submission splitting the jsb source into several DLLs with asmdef, maybe it's meaningful to further works like encapsulating it as a unity package (I'll try this later).

FreakTheMighty commented 2 years ago

@ialex32x thanks for the update! I've been pretty busy with other work, so I haven't had a chance to take a look. I hope to do so in the next few weeks.

ialex32x commented 2 years ago

Alright, I'm looking forward to any further suggestion. BTW, I've submitted the first package to openupm. https://openupm.com/packages/cc.starlessnight.unity-jsb/

FreakTheMighty commented 2 years ago

@ialex32x I've finally had a chance to try this. I think things are looking really good. It has integrated much more easily into a project with assembly references. I was able to add an assembly definition to the root of the Generated folder, and then consume the bindings in another assembly.

I haven't quite gotten things to run though. I have a stripped down example for running a remote script.

    public class ScriptExecutor : MonoBehaviour
    {
        public string baseUrl;
        private ScriptRuntime _rt;
        private IFileSystem _fileSystem;
        public string entryFileName = "example_main.js";

        private void Start()
        {
            var pathResolver = new PathResolver();
            var logger = new ScriptLogger();
            var asyncManager = new DefaultAsyncManager();

            _rt = ScriptEngine.CreateRuntime();
            _fileSystem = new HttpFileSystem(logger, baseUrl);
            _rt.withStacktrace = true;
            _rt.AddModuleResolvers();
            _rt.Initialize(new ScriptRuntimeArgs
            {
                fileSystem = _fileSystem,
                pathResolver = pathResolver,
                asyncManager = asyncManager,
                logger = logger,
                byteBufferAllocator = new ByteBufferPooledAllocator(),
                binder = DefaultBinder.GetBinder(false),
            });
            _rt.EvalMain(entryFileName);
        }

When I run I get this exception

ArgumentException: Directory does not exist
Parameter name: path
System.IO.FileSystemWatcher..ctor (System.String path, System.String filter) (at <0463b2ef957545c0a51b42f372cd4fbb>:0)
(wrapper remoting-invoke-with-check) System.IO.FileSystemWatcher..ctor(string,string)
QuickJS.Unity.JSScriptFinder.Start () (at Library/PackageCache/cc.starlessnight.unity-jsb@409f9a35d0/Source/Unity/Editor/JSScriptFinder.cs:166)
QuickJS.Unity.JSScriptFinder.GetInstance () (at Library/PackageCache/cc.starlessnight.unity-jsb@409f9a35d0/Source/Unity/Editor/JSScriptFinder.cs:36)
QuickJS.Unity.EditorRuntime.OnScriptRuntimeInitializing (QuickJS.ScriptRuntime runtime) (at Library/PackageCache/cc.starlessnight.unity-jsb@409f9a35d0/Source/Unity/Editor/EditorRuntime.cs:207)
QuickJS.ScriptRuntime.Initialize (QuickJS.Utils.IFileSystem fileSystem, QuickJS.Utils.IPathResolver resolver, QuickJS.Utils.IAsyncManager asyncManager, QuickJS.Utils.IScriptLogger logger, QuickJS.IO.IByteBufferAllocator byteBufferAllocator, QuickJS.Binding.BindAction binder) (at Library/PackageCache/cc.starlessnight.unity-jsb@409f9a35d0/Source/ScriptRuntime.cs:389)
QuickJS.ScriptRuntime.Initialize (QuickJS.ScriptRuntimeArgs args) (at Library/PackageCache/cc.starlessnight.unity-jsb@409f9a35d0/Source/ScriptRuntime.cs:316)
Spectar.Scripting.ScriptExecutor.Start () (at Assets/Spectar/Scripting/ScriptExecutor.cs:28)

It seems like the editor runtime is executing . . . which for my purpose I think is uncessary. Is there a way to disable this?

FreakTheMighty commented 2 years ago

Apologies, I posted that a minute too soon. I see in the JS Bridge Prefs I can disable "Editor Scripting".