Coder Social home page Coder Social logo

kerwinzxc / purescript Goto Github PK

View Code? Open in Web Editor NEW

This project forked from loongly/purescript

0.0 0.0 0.0 22.24 MB

A C# hot reload framework for Unity3D, based on Mono's MONO_AOT_MODE_INTERP mode.

License: MIT License

C# 22.81% C 75.76% C++ 1.02% Ruby 0.15% Objective-C 0.25%

purescript's Introduction

PureScript

licensePRs Welcome

一个支持Unity3D的C#热更框架,基于Mono的MONO_AOT_MODE_INTERP模式。

支持在iOS平台Assembly.Load
构建时自动绑定Unity的Il2cpp代码。
支持大部分Unity特性,包括MonoBehaviour、Coroutine。
支持配置程序集运行环境(Il2cpp/aot/interp)
支持Cocoapods自动集成
支持对"magic code"的自定义绑定实现


iOS平台

使用“Mixed Mode Execution” 兼顾性能(aot)和灵活性(interpreter)

Windows平台

使用Jit模式运行,可以导出Il2cpp工程,添加ScriptEngine项目断点调试。

Android平台

请使用Unity的Mono运行时,可以直接调用Assembly.Load,同使用PureScript是等效的,工程结构无需修改。


使用

  1. Clone本工程,拷贝DemoProject/Assets/Plugins/PureScript目录。
  2. 修改 PureScriptBuilder.cs及ScriptEngine/Tools/config.json中的路径配置。
  3. config.json中配置运行在interpreter模式的dll(否则以aot运行),以及运行在Il2cpp运行时内的dll(一般用作Adapter)。

iOS平台

iOS平台需要安装CocoapodsNinja 。并在项目的podfile内添加PureScript引用。 例: */iOS/Podfile-example
导出xcode工程,然后

    pod install  

Windows平台

Windows平台仅用来调试,目前未添加自动集成,在构建项目后,需编译 ScriptEngine/ScriptEngine.vcxproj,替换原来Plugins目录下的的ScriptEngine.dll。
手动调试步骤:

  1. 设置传入ScriptEngine.Setup接口的reloadDir路径为 */ScriptEngine/Managed
  2. Unity导出VS工程。
  3. 需要删除Unity导出目录下的Managed目录例如($(ExportPath)/DemoProject/Managed),否则Mono会默认从此处加载dll,Il2cpp并不会使用此目录,但是每次构建都会导出。
  4. 在导出的解决方案中添加ScriptEngine.vcxproj,并在主项目中添加ScriptEngine项目的依赖(方便调试)。
  5. 修改ScriptEngine.vcxproj中的输出目录为 $(ExportPath)/build/bin/DemoProject_Data/Plugins/,即替换原本的ScriptEngine.dll。
  6. 运行项目

例子

以下两段代码是等效的,详细参考DemoProject/*/MonoEntry.cs。

ScriptEngine.Setup(reloadDir, "TestEntry.dll");

// equal to:

Assembly assembly = Assembly.Load("TestEntry.dll");
Type type = assembly.GetType("MonoEntry");
MethodInfo mi = type.GetMethod("Main");
var res = mi.Invoke(null, null)

注意 需要热更新的程序集如果是Unity自动生成的工程,会自动引用一堆的无用dll,比如UntiyEditor*.dll,和一堆根本不会用到的System*.dll ,因为安装包内并没有带上这些,加载会失败。这时需要手动删掉这些用不到的引用。或者再建一个工程,手动管理引用,后面也可以考虑做自动化工具,strip掉没用的引用。


实现

PureScript 封装了Mono运行时,c/csharp代码生成器,pod项目自动集成,实现了两种绑定方式。两种方式均在构建时自动生成绑定代码,调用方几乎无感知,具体参考DemoProject。 两种绑定均支持调用和回调。

  • Internal call 绑定: 由c/cpp实现,直接使用Unity的dll,同时把Unity的Internal call绑定到UnityEngine实现,几乎没有性能损失,调用方无需修改。
    例:ScriptEngine/generated/icall_binding_gen.c。
    如果碰到“Unity magic”代码自动绑定有问题,可以实现自己的绑定。
    例:ScriptEngine/custom/icall_binding.c。
    或者在CSharp层用Adapter绑定。

  • Adapter绑定: 由纯CSharp实现,分别在Mono端和Il2cpp端生成绑定代码,具有更好的兼容和灵活性。Mono运行时内的dll调用Il2cpp内的dll时用到,在config.json中配置需要运行在Il2cpp内又需要在Mono内调用的dll,构建时自动生成绑定代码,在aot执行,调用时自动替换到绑定代码,调用方无需修改。 例:DemoProject/*/AdapterTest

  1. 绑定分两部分,构建时会自动生成Adapter.gen.dll(Il2cpp内执行)和Adapter.wrapper.dll(Mono内执行),生成代码参考:ScriptEngine/Adapter/glue/*.cs。
  2. 运行时ScriptEngine.Setup会将需要绑定的接口生成代理对象,然后序列化到非托管内存中,同时将内存指针报错到ScriptEngine中,参考:ScriptEngine.c。
  3. Mono运行时启动后,执行Main函数时会首先从ScriptEngine读取内存指针,然后反序列化为代理,供Wrapper调用。
  4. Mono运行时内,调用被Adapter绑定过的程序集时会自动指向Adapter.wrapper.dll内的Wrapper实现。
    注:代理的序列化与反序列化参考
Marshal.GetFunctionPointerForDelegate
Marshal.GetDelegateForFunctionPointer

自动绑定过程

  • 构建Unity项目时PureScriptBuilder.cs内注册了回调,并通过hook的方式分别在StripAssemblies前/后添加了绑定调用,此处是要再Il2cpp前将已经Strip的Assemblies拷贝出一份,并且进行Adapter绑定的代码生成。
  • 第一次绑定调用是做Adapter绑定的代码生成,生产物是Adapter.gen.dll和Adapter.wrapper.dll,这步需要在Strip前,否则会触发Il2cpp构建错误。
  • 第二次绑定调用是在Strip后,此次绑定会将已经Strip的Assemblies拷贝出一份。
    然后进行icall绑定,生产物是ScriptEngine/generated/.c
    如果是iOS平台,会进行aot构建,首先生成build.ninja,然后通过ninja生成ScriptEngine/aot/
    .a

正式项目请将Mono库(mono*.dll/mono*.a) 替换为自己编译的。

如果大家对这个方案有兴趣再补充详细文档,同时欢迎提交PR或者Star。

有问题请联系 [email protected]

purescript's People

Contributors

loongly avatar quicklyslow avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.