Giter VIP home page Giter VIP logo

loxodon-framework's Introduction

Loxodon Framework(Unity-MVVM)

license release openupm npm

(中文版)

MVVM and Databinding for Unity3d(C# & XLua & ILRuntime)

Developed by Clark

Requires Unity 2018.4 or higher.

LoxodonFramework is a lightweight MVVM (Model-View-ViewModel) framework specifically crafted for Unity3D. It includes data binding and various useful components. The framework's performance is meticulously optimized, avoiding value type boxing and unboxing, minimizing garbage collection overhead. It utilizes dynamic delegates/static code weaving techniques to ensure comparable performance between data binding and direct invocation, zero garbage collection during UI view updates, and more. Additionally, it has been validated in projects, demonstrating superior performance, stability, and reliability with a clear, extensible architecture. We hope it can contribute to making your game development faster and more effortless.

For tutorials,examples and support,please see the project.You can also discuss the project in the Unity Forums.

The plugin is compatible with MacOSX,Windows,Linux,UWP,WebGL,IOS and Android,and provides all the source code of the project.

If you like this framework or think it is useful, please write a review on AssetStore or give me a STAR or FORK it on Github, thank you!

Tested in Unity 3D on the following platforms:
PC/Mac/Linux
IOS
Android
UWP(window10)
WebGL

Installation

For detailed installation steps, please refer to the installation documentation.

English manual

Key Features:

  • MVVM Framework;
  • Multiple platforms;
  • Higher Extensibility;
  • async&await (C#&Lua)
  • try&catch&finally for lua
  • XLua support(You can make your game in lua.);
  • Asynchronous result and asynchronous task are supported;
  • Scheduled Executor and Multi-threading;
  • Messaging system support;
  • Preferences can be encrypted;
  • Localization support;
  • Code weaving
  • Databinding support:
    • Avoiding boxing and unboxing of value types;
    • Optimizing performance through dynamic delegates/static code weaving techniques, avoiding the use of reflection;
    • Minimizing garbage collection, avoiding memory allocations during string concatenation, and numeric-to-string conversions;
    • Data binding performance is comparable to direct invocation;
    • Zero garbage collection during UI view updates;
    • Field binding;
    • Property binding;
    • Dictionary,list and array binding;
    • Event binding;
    • Unity3d's EventBase binding;
    • Static property and field binding;
    • Method binding;
    • Command binding;
    • ObservableProperty,ObservableDictionary and ObservableList binding;
    • Expression binding;

Notes

  • .Net2.0 and .Net2.0 Subset,please use version 1.9.x.
  • LoxodonFramework 2.0 supports .Net4.x and .Net Standard2.0
  • LoxodonFramework 2.0 supports Mono and IL2CPP

Plugins

  • Loxodon Framework OSA

    This plugin is designed to optimize Optimized ScrollView Adapter, specifically adding data binding capabilities to ListView and GridView.

    Note: This plugin depends on Optimized ScrollView Adapter. Please ensure you have installed Optimized ScrollView Adapter before using this plugin.

  • Loxodon Framework TextFormatting

    This is a text formatting plugin modified based on the official C# library. By extending the AppendFormat function of StringBuilder, it aims to avoid garbage collection (GC) when concatenating strings or converting numbers to strings. This optimization is particularly beneficial in scenarios with high-performance requirements.

    Furthermore, the plugin extends Unity's Unity GUI (UGUI) by introducing two new text controls: TemplateText and FormattableText. These controls support the data binding features of MVVM, allowing the binding of ViewModel or value-type objects to the controls. This approach eliminates the need for boxing and unboxing of value-type objects, thus maximizing the optimization of garbage collection (GC).

    It's worth noting that using the controls TemplateTextMeshPro or FormattableTextMeshProUGUI from Loxodon.Framework.TextMeshPro can further reduce garbage collection (GC), achieving a completely GC-free update of the game view.

  • Loxodon Framework TextMeshPro

    This plugin primarily serves to enhance AlertDialog and Toast views by providing TextMeshPro support, replacing UnityEngine.UI.Text with TextMeshProUGUI for optimized UI views.

    Additionally, the plugin depends on the Loxodon.Framework.TextFormatting plugin, further optimizing garbage collection. By utilizing FormattableTextMeshProUGUI and TemplateTextMeshProUGUI controls, updating UI views results in absolutely no garbage collection (GC), achieving a fully GC-free view update.

  • Loxodon Framework Data

    This plugin supports exporting data from Excel files to Json files, Lua files, or LiteDB databases. Additionally, it enables converting data to C# objects using Json.Net. It is recommended to use LiteDB for storing configuration data, as it is a lightweight NoSQL embedded database that supports ORM functionality, BSON format, and data indexing, making it highly convenient to use.

  • Loxodon Framework Fody

    This is a plugin for static code weaving, comprising multiple sub-plugins. It supports static weaving for objects, including the addition of the ToString function, integration of the PropertyChanged event, incorporation of the BindingProxy class, and more. This not only optimizes performance but also enhances development efficiency.

  • Loxodon Framework UIToolkit

    This plugin integrates UIToolkit into the Loxodon.Framework, introducing the UIToolkitWindow class. It supports data binding and allows for a mix of UIToolkit and UGUI.

  • Loxodon Framework ILRuntime

  • Loxodon Framework Localization For CSV

    It supports localization files in csv format, requires Unity2018.4 or higher.

  • Loxodon Framework XLua

    It supports making games with lua scripts.

  • Loxodon Framework Bundle

    Loxodon Framework Bundle is an AssetBundle manager.It provides a functionality that can automatically manage/load an AssetBundle and its dependencies from local or remote location.Asset Dependency Management including BundleManifest that keep track of every AssetBundle and all of their dependencies. An AssetBundle Simulation Mode which allows for iterative testing of AssetBundles in a the Unity editor without ever building an AssetBundle.

    The asset redundancy analyzer can help you find the redundant assets included in the AssetsBundles.Create a fingerprint for the asset by collecting the characteristic data of the asset. Find out the redundant assets in all AssetBundles by fingerprint comparison.it only supports the AssetBundle of Unity 5.6 or higher.

  • Loxodon Framework NLog

    This plug-in integrates NLog into Loxodon.Framework. It is recommended to use this plug-in instead of the Log4Net plug-in. It allocates less heap memory during the log printing process.

  • Loxodon Framework Log4Net

    This is a log plugin.It helps you to use Log4Net in the Unity3d.

  • Loxodon Framework Obfuscation

    The plugin is a data type memory obfuscation tool that supports ObfuscatedByte, ObfuscatedShort, ObfuscatedInt, ObfuscatedLong, ObfuscatedFloat, and ObfuscatedDouble types. Its purpose is to prevent memory modification of game values by memory editors. The plugin supports all arithmetic operators for numerical types and can automatically convert between them and their standard counterparts (byte, short, int, long, float, double).

    During the obfuscation of Float and Double types, the plugin converts them to int and long types for bitwise AND and OR operations to ensure that precision is not lost. Unsafe code is used for type conversion to balance conversion performance. The plugin aims to provide a comprehensive solution for protecting game values against memory modification, allowing for seamless integration with different numerical types and maintaining performance through careful type conversion.

    Example:

      ObfuscatedInt  length = 200;
      ObfuscatedFloat scale = 20.5f;
      int offset = 30;
      
      float value = (length * scale) + offset;
    
  • Loxodon Framework Addressable

  • Loxodon Framework Connection

    This is a network connection component, implemented using TcpClient, supports IPV6 and IPV4, automatically recognizes the current network when connecting with a domain name, and preferentially connects to the IPV4 network.

  • DotNetty for Unity

    DotNetty is a port of Netty, asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.

    This version is modified based on DotNetty's 0.7.5 version and is a customized version for the Unity development platform. It includes the removal of certain dependency libraries, bug fixes, performance optimizations, and enhancements to cater to game development on the Unity platform. Additionally, it has undergone testing under IL2CPP for compatibility and reliability.

  • LiteDB

    LiteDB is a small, fast and lightweight NoSQL embedded database.

Quick Start

Create a view and view model of the progress bar.

public class ProgressBarViewModel : ViewModelBase
{
    private string tip;
    private bool enabled;
    private float value;
    public ProgressBarViewModel()
    {
    }

    public string Tip
    {
        get { return this.tip; }
        set { this.Set<string>(ref this.tip, value, nameof(Tip)); }
    }

    public bool Enabled
    {
        get { return this.enabled; }
        set { this.Set<bool>(ref this.enabled, value, nameof(Enabled)); }
    }

    public float Value
    {
        get { return this.value; }
        set { this.Set<float>(ref this.value, value, nameof(Value)); }
    }
}

public class ProgressBarView : UIView
{
    public GameObject progressBar;
    public Text progressTip;
    public Text progressText;
    public Slider progressSlider;

    protected override void Awake()
    {
        var bindingSet = this.CreateBindingSet<ProgressBar, ProgressBarViewModel>();

        bindingSet.Bind(this.progressBar).For(v => v.activeSelf).To(vm => vm.Enabled).OneWay();
        bindingSet.Bind(this.progressTip).For(v => v.text).To(vm => vm.Tip).OneWay();
        bindingSet.Bind(this.progressText).For(v => v.text)
            .ToExpression(vm => string.Format("{0:0.00}%", vm.Value * 100)).OneWay();
        bindingSet.Bind(this.progressSlider).For(v => v.value).To(vm => vm.Value).OneWay();

        bindingSet.Build();
    }
}


IEnumerator Unzip(ProgressBarViewModel progressBar)
{
    progressBar.Tip = "Unziping";
    progressBar.Enabled = true;//Display the progress bar

    for(int i=0;i<30;i++)
    {            
        //TODO:Add unzip code here.

        progressBar.Value = (i/(float)30);            
        yield return null;
    }

    progressBar.Enabled = false;//Hide the progress bar
    progressBar.Tip = "";        
}

Tutorials and Examples

Introduction

  • Window View

  • Localization

  • Databinding

  • Variable Example

  • ListView Binding

Contact Us

Email: [email protected]
Website: https://vovgou.github.io/loxodon-framework/
QQ Group: 622321589 15034148

loxodon-framework's People

Contributors

mingzhi1 avatar vovgou avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

loxodon-framework's Issues

示例代码在u3d 2018上报错

调用堆栈:
NotSupportedException: Expressions of type System.Delegate are not supported.
Loxodon.Framework.Binding.Paths.PathParser.Parse (System.Linq.Expressions.Expression expression, Loxodon.Framework.Binding.Paths.Path path) (at Assets/LoxodonFramework/Scripts/Framework/Binding/Paths/PathParser.cs:134)
Loxodon.Framework.Binding.Paths.PathParser.Parse (System.Linq.Expressions.LambdaExpression expression) (at Assets/LoxodonFramework/Scripts/Framework/Binding/Paths/PathParser.cs:40)
Loxodon.Framework.Binding.Builder.BindingBuilder2[TTarget,TSource].To (System.Linq.Expressions.Expression1[TDelegate] path) (at Assets/LoxodonFramework/Scripts/Framework/Binding/Builder/BindingBuilder.cs:105)
Loxodon.Framework.Tutorials.DatabindingForAsyncLoadingSpriteExample.Start () (at Assets/LoxodonFramework/Tutorials/Scripts/DatabindingForAsyncLoadingSpriteExample.cs:53)

image

Inquiry

Hello! Does Loxodon provide a patcher template for mobile? I am asking this because I have very little knowledge in coding and I rely only on templates and kits for my game. 😔

Related to enter play mode settings

Check "Enter Play Mode Settings" with no Reload domain will result error. Is there any setting necessary to be adjusted?
This is the doc from Unity, Configurable Enter Play Mode.
The errors I receive are

ArgumentException: An item with the same key has already been added.

DuplicateRegisterServiceException: Duplicate key IBinder
Loxodon.Framework.Services.ServiceContainer.Register[T]

I guess it is the use of static variable causing such errors? I am just wonering if there is a way to work with Loxodon framework as nowadays, turning on Enter Player Mode Settings speed up the development.

Binding enum failed

Issue

BindingSet.Bind().For(v=>v.enumType).To(vm=>vm.enumType) got error.

How to reproduce

Step 1: Declare a public enum type, and a public enum property, for both view and view model class. Property in view model needs to follow the Set<> function inherited from ViewModelBase class.
Step 2: In View class, create a bindingSet, and bind the view's enum property onto viewModel's enum property.
Step 3: In controller class, set data context.
Step 4: Run the game

Reasons

In Binding.cs, the enum type was cast as Int32.

【功能需求】DataBinding:加入数据更新事件监听

现在的DataBinding,只能绑定某个变量,到某个数据上;

然而,有些时候,ViewModel的副作用可能难以通过简单的View层变量更新体现,而需要更多复杂的处理

因此,我希望BindingSet加入回调绑定的功能,样例写法如下:

void OnVarChanged(int val);
Bind(OnVarChanged).To(vm->x);

Besides:响应式数据这块,是否有可能参考Vue/React的写法,实现useEffect这样复杂的监听Hook?

切换IOS平台编译报错

系统:macOS Mojave 10.14.4
描述:在Unity 2019.1及2018.4上切换IOS平台有编译错误
Assets/LoxodonFramework/Scripts/Framework/Binding/Reflection/ProxyFieldInfo.cs(134,33): error CS0103: The name 'Expression' does not exist in the current context

Assets/LoxodonFramework/Scripts/Framework/Binding/Reflection/ProxyFieldInfo.cs(135,32): error CS0103: The name 'Expression' does not exist in the current context

Assets/LoxodonFramework/Scripts/Framework/Binding/Reflection/ProxyFieldInfo.cs(136,32): error CS0103: The name 'Expression' does not exist in the current context

Assets/LoxodonFramework/Scripts/Framework/Binding/Reflection/ProxyFieldInfo.cs(137,33): error CS0103: The name 'Expression' does not exist in the current context

Assets/LoxodonFramework/Scripts/Framework/Binding/Reflection/ProxyFieldInfo.cs(138,30): error CS0103: The name 'Expression' does not exist in the current context
错误原因应该是 ENABLE_IL2CPP 没生效 手动配置ENABLE_IL2CPP后编译正常
运行Databinding Tutorials示例 后出现错误
2019-08-16 11:38:22.420 [ERROR] Binding - An exception occurs when the target property is updated.Please check the binding "Text{binding text Expression:vm => Window (Loxodon.Framework.Tutorials.DatabindingExample).localization.GetFormattedText("databinding.tutorials.description", new [] {vm.Account.Username, vm.Username}) Mode:OneWay }" in the view "DatabindingExample[Window]".exception: System.NotSupportedException: Expressions of type System.Object[] are not supported.
  at Loxodon.Framework.Binding.Expressions.ExpressionVisitor.Visit (System.Linq.Expressions.Expression expr) [0x00179] in /Users/xxxxx/Documents/workspace_unity/loxodon-framework/Assets/LoxodonFramework/Scripts/Framework/Binding/Expressions/ExpressionVisitor.cs:110 
  at Loxodon.Framework.Binding.Expressions.EvaluatingVisitor.<InvokeMethod>b__7_0 (System.Linq.Expressions.Expression a) [0x00000] in /Users/xxxxx/Documents/workspace_unity/loxodon-framework/Assets/LoxodonFramework/Scripts/Framework/Binding/Expressions/EvaluatingVisitor.cs:891 
  at System.Linq.Enumerable+SelectIListIterator`2[TSource,TResult].ToArray () [0x00034] in <1b13ba6391c74847bbc3eddc86df7eee>:0 
  at System.Linq.Enumerable.ToArray[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x0001f] in <1b13ba6391c74847bbc3eddc86df7eee>:0 
  at Loxodon.Framework.Binding.Expressions.EvaluatingVisitor.InvokeMethod (System.Func`2[T,TResult] invoke, System.Collections.Generic.IEnumerable`1[T] arguments) [0x00001] in /Users/xxxxx/Documents/workspace_unity/loxodon-framework/Assets/LoxodonFramework/Scripts/Framework/Binding/Expressions/EvaluatingVisitor.cs:891 
  at Loxodon.Framework.Binding.Expressions.EvaluatingVisitor.VisitMethodCall (System.Linq.Expressions.MethodCallExpression expr) [0x0009f] in /Users/xxxxx/Documents/workspace_unity/loxodon-framework/Assets/LoxodonFramework/Scripts/Framework/Binding/Expressions/EvaluatingVisitor.cs:951 
  at Loxodon.Framework.Binding.Expressions.ExpressionVisitor.Visit (System.Linq.Expressions.Expression expr) [0x000fe] in /Users/xxxxx/Documents/workspace_unity/loxodon-framework/Assets/LoxodonFramework/Scripts/Framework/Binding/Expressions/ExpressionVisitor.cs:77 
  at Loxodon.Framework.Binding.Expressions.EvaluatingVisitor.Evaluate (System.Linq.Expressions.LambdaExpression expr, Loxodon.Framework.Binding.Expressions.Scope scope, System.Object[] args) [0x0005c] in /Users/xxxxx/Documents/workspace_unity/loxodon-framework/Assets/LoxodonFramework/Scripts/Framework/Binding/Expressions/EvaluatingVisitor.cs:996 
  at Loxodon.Framework.Binding.Expressions.EvaluatingVisitor+<>c__DisplayClass13_0.<VisitLambda>b__0 (System.Object[] args) [0x00000] in /Users/xxxxx/Documents/workspace_unity/loxodon-framework/Assets/LoxodonFramework/Scripts/Framework/Binding/Expressions/EvaluatingVisitor.cs:971 
  at Loxodon.Framework.Binding.Proxy.Sources.Expressions.ExpressionSourceProxy.GetValue () [0x0000f] in /Users/xxxxx/Documents/workspace_unity/loxodon-framework/Assets/LoxodonFramework/Scripts/Framework/Binding/Proxy/Sources/Expressions/ExpressionSourceProxy.cs:59 
  at Loxodon.Framework.Binding.Proxy.Sources.Expressions.ExpressionSourceProxy.GetValue[TValue] () [0x00001] in /Users/xxxxx/Documents/workspace_unity/loxodon-framework/Assets/LoxodonFramework/Scripts/Framework/Binding/Proxy/Sources/Expressions/ExpressionSourceProxy.cs:69 
  at Loxodon.Framework.Binding.Binding.<UpdateTargetFromSource>b__25_0 () [0x001c5] in /Users/xxxxx/Documents/workspace_unity/loxodon-framework/Assets/LoxodonFramework/Scripts/Framework/Binding/Binding.cs:302 
UnityEngine.Debug:LogError(Object)
Loxodon.Log.LogImpl:Error(Object) (at Assets/LoxodonFramework/Scripts/Log/DefaultLogFactory.cs:160)
Loxodon.Log.LogImpl:ErrorFormat(String, Object[]) (at Assets/LoxodonFramework/Scripts/Log/DefaultLogFactory.cs:174)
Loxodon.Framework.Binding.Binding:<UpdateTargetFromSource>b__25_0() (at Assets/LoxodonFramework/Scripts/Framework/Binding/Binding.cs:379)
Loxodon.Framework.Execution.Executors:RunOnMainThread(Action, Boolean) (at Assets/LoxodonFramework/Scripts/Framework/Execution/Executors.cs:164)
Loxodon.Framework.Binding.Binding:UpdateTargetFromSource() (at Assets/LoxodonFramework/Scripts/Framework/Binding/Binding.cs:209)
Loxodon.Framework.Binding.Binding:UpdateDataOnBind() (at Assets/LoxodonFramework/Scripts/Framework/Binding/Binding.cs:126)
Loxodon.Framework.Binding.Binding:.ctor(IBindingContext, Object, Object, BindingDescription, ISourceProxyFactory, ITargetProxyFactory) (at Assets/LoxodonFramework/Scripts/Framework/Binding/Binding.cs:76)
Loxodon.Framework.Binding.BindingFactory:Create(IBindingContext, Object, Object, BindingDescription) (at Assets/LoxodonFramework/Scripts/Framework/Binding/BindingFactory.cs:56)
Loxodon.Framework.Binding.Binders.StandardBinder:Bind(IBindingContext, Object, Object, BindingDescription) (at Assets/LoxodonFramework/Scripts/Framework/Binding/Binders/StandardBinder.cs:42)
Loxodon.Framework.Binding.Contexts.BindingContext:Add(Object, BindingDescription, Object) (at Assets/LoxodonFramework/Scripts/Framework/Binding/Contexts/BindingContext.cs:181)
Loxodon.Framework.Binding.Builder.BindingBuilderBase:Build() (at Assets/LoxodonFramework/Scripts/Framework/Binding/Builder/BindingBuilderBase.cs:218)
Loxodon.Framework.Binding.Builder.BindingSetBase:Build() (at Assets/LoxodonFramework/Scripts/Framework/Binding/Builder/BindingSet.cs:50)
Loxodon.Framework.Tutorials.DatabindingExample:Start() (at Assets/LoxodonFramework/Tutorials/Scripts/DatabindingExample.cs:230)Assets/LoxodonFramework/Scripts/Framework/Binding/Reflection/ProxyFieldInfo.cs(138,30): error CS0103: The name 'Expression' does not exist in the current context

InteractionTargetProxy的Target被意外释放

TargetProxyBase中的target是一个WeakReference,target是LuaTable的时候,有时会意外变成null。业务那边是将一个View中异步的InteractionAction和VM中异步的InteractionRequest做绑定

bindingSet:Bind(self):For("gameAlertAsyncInteractionAction"):To("testAsyncInteractionRequest")
function M:TestInteractionRequest()
    self.testCommand.Enabled = false
    Executors.RunLuaOnCoroutineNoReturn(async(function()
        local notification = GameAlertNotification("未知事件", "事件类型未知", "确定")
        await(self.testAsyncInteractionRequest:Raise(notification))
        self.testCommand.Enabled = true
        log.debug(notification.DialogResult)
    end))
end

image
image

请大神帮忙看看问题~感谢

[Feature] Split the framework further

Thanks to provide such a wonderful package for making mvvm work flawlessly in Unity. After adjusting the current project, I find out that the use of Microsoft.Extension.Logging for logging and Message Pipe for message publishing/subscribing will be more suitable. I am just wondering if the core part of the framework can be further split so that the logging, messaging etc. could be extracted. Or providing a way to replace them with other solution maybe?

log4 插件导入会报错

log4 插件包安装后报错

Library\PackageCache\[email protected]\Runtime\Log\Log4Net\Log4NetLogImpl.cs(7,25): error CS0433: The type 'ILog' exists in both 'log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a' and 'log4net, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'

一系列

删掉插件包Plugins里面的log4net.dll才不报错

trampolines compile how-to?

Hi, I own your bundle product on unity asset store. I am trying to find out more info about AOT Trampolines on iOS. I found this link below:
https://www.mono-project.com/docs/advanced/runtime/docs/trampolines/

  • however I do not know the specifics of how it relates to your project or how to use this feature. Where do I paste your AOT Compilation Option?
    xcode? xamarin?

Can I paste only one option or all?
i.e. are they referring to standard, PLT, delegate?

I believe I understand what they do. It is the only way to use runtime code on iOS - as the iOS platform doesn't support JIT. I assume this lets us use xlua on iOS. My limited understanding is that on AOT we get a token for the type/ptl/delegate we are accessing so we can call the method from xlua in a more static and likely secure way?

Mainly just a hello world for iOS and AOT using these trampolines and where to put those compilation options and what each does, is all we would need.

Thank you for your time reading this.
also mentioned on unity forums, not sure which would get your eyes first :-)
https://forum.unity.com/threads/loxodon-framework-mvvm.545335/#post-4849013

AB中的资源在内存中会有多个副本的问题

在资源中,有一个字库文件zyt.ttf,该字库文件独立打包为一个AssetBundle,且此AB是能被其他AssetBundle中所引用到。但在运行时,经编辑器的Profiler分析,此字库文件在内存中会有多个副本的存在。所有资源文件未经预加载且未常驻内存。

請問關於數據綁定,如何注入委託函數

「而且在数据绑定部分进行了性能优化,在支持JIT的平台上使用的是委托的方式绑定,在不支持JIT的平台,默认使用的是反射,但是可以通过注入委托函数的方式来优化」

我在文件中有閱讀看可以針對要綁定的 unity 物件注入委託函數
那麼請問 vm 的部分是否有可能呢

[Fody]当项目中有其他包引用了Mono.Cecil相关的库文件会报错

当项目中有Package引用Mono.Cecil相关的库,会导致库文件冲突。

例如引用这个库com.unity.runtime-scene-serialization

我对Fody中引用的Mono.Cecil是否有做什么特殊的定制不太清楚。
目前我采用的办法是把Fody和PropertyChanged.Fody单独做成Package,然后把
Mono.Cecil
Mono.Cecil.Pdb
Mono.Cecil.Rocks
这三个文件的文件名改变成
Fody.Mono.Cecil
Fody.Mono.Cecil.Pdb
Fody.Mono.Cecil.Rocks
然后重新设置相关引用,这样可以解决问题。

Snipaste_2022-09-09_11-41-31

我这个改动对项目结构改动有点大,我不确定提交一个pr是否合适。

同时,个人也觉得引用的第三方库最好是做成package标注版本,这样也方便使用者比对版本,升级之类的。

Any reason to implement IServiceBundle or extend AbstractServiceBundle?

This is not a feature request. I just would like to know how your architecture approaches my problem.

I have some components attached to a GameObject prefab that I would like to use as services. While I know that I can use Resources.Load to load and instantiate the prefab synchronously, I want to use LoadAsync and then make the Start method of the service bundle async instead to that I can emphasize that it is a relatively heavy operation.

Because of this, I cannot make my service bundle class conform to IServiceBundle. But since I did not see any methods that would take the interface as a parameter, I am not even sure if I lose any functionality if I don't extend the interface. Is IServiceBundle used just for conventional/ceremonial purpose to remind implementors to follow Start/Stop procedures?

Thank you so much!

Service container doesn't register generics properly

Steps to reproduce:

  1. Create a generic service Service<T>
  2. Register Service<Type1>
  3. Register Service<Type2>

Result: DuplicateRegisterServiceException is thrown.

Expected: All works fine.

Here is a source of the problem: https://github.com/vovgou/loxodon-framework/blob/master/Loxodon.Framework/Assets/LoxodonFramework/Runtime/Framework/Services/ServiceContainer.cs#L72

namespace Loxodon.Framework.Services
{
    public class ServiceContainer : IServiceContainer, IDisposable
    {
        private Dictionary<string, IFactory> services = new Dictionary<string, IFactory>();

        public virtual object Resolve(Type type)
        {
            return this.Resolve<object>(type.Name);
        }

        public virtual T Resolve<T>()
        {
            return this.Resolve<T>(typeof(T).Name);
        }

...

        public virtual void Register<T>(T target)
        {
            this.Register<T>(typeof(T).Name, target);
        }

typeof(T).Name for Service<Type1> Service<Type2> will return same string: Service'1.

My suggestion is to use typeof(T).ToString() then we get something like: Service'1[Type1] and Service'1[Type2]. If you ok with that - I can prepare a PR.

Databinding Examples

sample scene: loxodon-framework\Loxodon.Framework\Assets\Samples\Loxodon Framework\2.0.0\Tutorials\Databinding Tutorials.unity

DatabindingExamples.cs line 225:
bindingSet.Bind(this.usernameEdit).For(v => v.text, v => v.onEndEdit).To(vm => vm.Username).TwoWay();

我认为应该把TwoWay改成OneWayToSource, username inputfield应该是由外部输入决定vm的username,反过来没有意义

What is the reason of catching all exceptions in `Subject<>.Publish`

Hi @vovgou

I am wondering what is the reason of trapping all exceptions here:

MVVM is heavily relaying on messaging system and it is sometime hard to debug issues due to that trap. I might prepare a PR with adding a conditional compilation flag which enables the rethrow. Something like:

{
catch(Exception)
{
#if DEBUG_MESSAGING
    throw;
#endif
}

What do you think?

WindowManager

WindowManager.Clear()
不能将当前容器下面的所有Window销毁
public virtual void Clear()
{
for (int i = this.windows.Count; i > 0; i--)
{
### this.windows[0].Dismiss(true);### issue
}
this.windows.Clear();
}

Encryption

Does this provide assetbundle encryption ?And what is the difference of this framework from the one on unity store? It seems they are different versions.

Edit: Sorry I was referring to the Bundle Maker. Well, my question for thr bundle is, can it create encryption where my asset cant be opened by ripping?

Lua用ToExpression方法进行Bind问题

lua执行ToExpression方法时,会传入LuaFunction

 public LuaBindingBuilder ToExpression(LuaFunction expression, params string[] paths)
        {
            if (this.description.Source != null)
                throw new BindingException("You cannot set the source path of a Fluent binding more than once");

            this.description.Source = new LuaExpressionSourceDescription()
            {
                Expression = expression,
                Paths = paths
            };

            return this;
        }

当我执行 SetDataContext时,LuaExpressionSourceProxy会执行Dispose(),将func释放

 protected override void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    if (this.inners != null && this.inners.Count > 0)
                    {
                        foreach (ISourceProxy proxy in this.inners)
                        {
                            if (proxy is INotifiable)
                                ((INotifiable)proxy).ValueChanged -= OnValueChanged;
                            proxy.Dispose();
                        }
                        this.inners.Clear();
                    }

                    if (func != null)
                    {
                        func.Dispose();
                        func = null;
                    }
                }
                disposed = true;
                base.Dispose(disposing);
            }
        }

导致下次执行func报错。

Android IL2CPP Weak References error

Hello!

I have following issue: I bind a very simple view with one button:

dataContext = new MainMenuViewModel(commandDelay);
this.SetDataContext(dataContext);

/* databinding */
BindingSet<MainMenuViewController, MainMenuViewModel> bindingSet = this.CreateBindingSet<MainMenuViewController, MainMenuViewModel>();
bindingSet.Bind(this.runButton).For(v => v.onClick).To(vm => vm.OnRun).OneWay();

bindingSet.Build();

OnRun in this case is a simple public void method in the MainMenuViewModel. It works just fine in the editor but when I compile it to android I get following error:

2020-07-12 22:25:45.695 [ERROR] BindingSetBase - Loxodon.Framework.Binding.BindingException: An exception occurred while building the data binding for {binding onClick Path:OnRun Mode:OneWay }. ---> System.NotSupportedException: /Applications/Unity/2019.3.0f5/Unity.app/Contents/il2cpp/libil2cpp/gc/GCHandle.cpp(183) : Unsupported internal call for IL2CPP:GCHandle::NewWeakref - "IL2CPP does not support resurrection for weak references. Pass the trackResurrection with a value of false."
  at System.Runtime.InteropServices.GCHandle.Alloc (System.Object value, System.Runtime.InteropServices.GCHandleType type) [0x00000] in <00000000000000000000000000000000>:0 
  at System.WeakReference.AllocateHandle (System.Object target) [0x00000] in <00000000000000000000000000000000>:0 
  at Loxodon.Framework.Binding.AbstractBinding..ctor (Loxodon.Framework.Binding.Contexts.IBindingContext bindingContext, System.Object dataContext, System.Object target) [0x00000] in <00000000000000000000000000000000>:0 
  at Loxodon.Framework.Binding.Binding..ctor (Loxodon.Framework.Binding.Contexts.IBindingContext bindingContext, System.Object source, System.Object target, Loxodon.Framework.Binding.BindingDescription bindingDescription, Loxodon.Framework.Binding.Proxy.Sources.ISourceProxyFactory sourceProxyFactory, Loxodon.Framework.Binding.Proxy.Targets.ITargetProxyFactory targetProxyFactory) [0x00000] in <00000000000000000000000000000000>:0 
  at Loxodon.Framework.Binding.BindingFactory.Create (Loxodon.Framework.Binding.Contexts.IBindingContext bindingContext, System.Object source, System.Object target, Loxodon.Framework.Binding.BindingDescription bindingDescription) [0x00000] in <00000000000000000000000000000000>:0 
  at Loxodon.Framework.Binding.Contexts.BindingContext.Add (System.Object target, Loxodon.Framework.Binding.BindingDescription description, System.Object key) [0x00000] in <00000000000000000000000000000000>:0 
  at Loxodon.Framework.Binding.Builder.BindingBuilderBase.Build () [0x00000] in <00000000000000000000000000000000>:0 
  at Loxodon.Framework.Binding.Builder.BindingSetBase.Build () [0x00000] in <00000000000000000000000000000000>:0 
  at IslandRunner.UI.MainMenuViewController.<Start>b__3_0 () [0x00000] in <00000000000000000000000000000000>:0 
  at System.Action.Invoke () [0x00000] in <00000000000000000000000000000000>:0 
  at Run+<_RunAfter>d__9.MoveNext () [0x00000] in <00000000000000000000000000000000>:0 
  at UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) [0x00000] in <00000000000000000000000000000000>:0 
   --- End of inner exception stack trace ---
  at Loxodon.Framework.Binding.Builder.BindingBuilderBase.Build () [0x00000] in <00000000000000000000000000000000>:0 
  at Loxodon.Framework.Binding.Builder.BindingSetBase.Build () [0x00000] in <00000000000000000000000000000000>:0 
  at IslandRunner.UI.MainMenuViewController.<Start>b__3_0 () [0x00000] in <00000000000000000000000000000000>:0 
  at System.Action.Invoke () [0x00000] in <00000000000000000000000000000000>:0 
  at Run+<_RunAfter>d__9.MoveNext () [0x00000] in <00000000000000000000000000000000>:0 
  at UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) [0x00000] in <00000000000000000000000000000000>:0 
Loxodon.Framework.Binding.Builder.BindingSetBase:Build()
IslandRunner.UI.MainMenuViewController:<Start>b__3_0()
System.Action:Invoke()
<_RunAfter>d__9:MoveNext()
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

It must have been because of the newest update. I've used this case before without problems in older versions but I cannot recall which one was it.

Lua View 的数据绑定失败问题

local DatabindingViewModel = class("DatabindingViewModel",ObservableObject)
function DatabindingViewModel:ctor(t)
	DatabindingViewModel.base(self).ctor(self,t)
	self.ViewModelName = "DatabindingViewModel"
end

function M:start()
	self.viewName = "DefaultViewName"
	
	self:BindingContext().DataContext = DatabindingViewModel()
	
	--进行数据绑定
	local bindingSet = self:CreateBindingSet();
	-- 下面这行绑定会报错。
	bindingSet:Bind():For("viewName"):To("ViewModelName"):OneWay()
	bindingSet:Build()
end
2020-08-07 15:35:47.330 [ERROR] BindingSetBase - Loxodon.Framework.Binding.Proxy.ProxyException: Unable to bind the "{binding viewName Path:ViewModelName Mode:OneWay }".An exception occurred while creating a proxy for the "viewName" property of class "LuaBehaviour". ---> System.MissingMemberException: Member 'Loxodon.Framework.Views.LuaBehaviour.viewName' not found.
  at Loxodon.Framework.Binding.Proxy.Targets.TargetProxyFactory.TryCreateProxy (System.Object target, Loxodon.Framework.Binding.BindingDescription description, Loxodon.Framework.Binding.Proxy.Targets.ITargetProxy& proxy) [0x00058] in C:\Projects\loxodon-framework-2.0.1-master\Loxodon.Framework - MVVM\Assets\LoxodonFramework\Runtime\Framework\Binding\Proxy\Targets\TargetProxyFactory.cs:71 
  at Loxodon.Framework.Binding.Proxy.Targets.TargetProxyFactory.CreateProxy (System.Object target, Loxodon.Framework.Binding.BindingDescription description) [0x00004] in C:\Projects\loxodon-framework-2.0.1-master\Loxodon.Framework - MVVM\Assets\LoxodonFramework\Runtime\Framework\Binding\Proxy\Targets\TargetProxyFactory.cs:42 
   --- End of inner exception stack trace ---
  at Loxodon.Framework.Binding.Builder.BindingBuilderBase.Build () [0x0003f] in C:\Projects\loxodon-framework-2.0.1-master\Loxodon.Framework - MVVM\Assets\LoxodonFramework\Runtime\Framework\Binding\Builder\BindingBuilderBase.cs:222 
  at Loxodon.Framework.Binding.Builder.BindingSetBase.Build () [0x0001a] in C:\Projects\loxodon-framework-2.0.1-master\Loxodon.Framework - MVVM\Assets\LoxodonFramework\Runtime\Framework\Binding\Builder\BindingSet.cs:50 

在lua代码中调用IUIViewLocator的LoadWindowAsync异步加载函数报错

lua代码如下:

require("framework.System")

local WindowContainer = CS.Loxodon.Framework.Views.WindowContainer
local Context = CS.Loxodon.Framework.Contexts.Context

function launch()
    print("lua launching...")
    local context = Context.GetApplicationContext()
    local locator = context:GetService("AddressableUIViewLocator")
    local winContainer = WindowContainer.Create("MAIN")
    locator:LoadWindowAsync(winContainer, "HotUpdate/Startup/Startup"):OnPostExecute(
        function(window)
            window:Create()
            local transition = window:Show()
            transition:OnStateChanged(
                function(w, state)
                    print("Window:" .. w.Name .. " State:" .. state:ToString())
                end
            )
            transition:OnFinish(
                function()
                    print("OnFinished")
                end
            )
        end
    )
end

我写了一个新的IUIViewLocator接口实现——AddressableUIViewLocator,用于Addressable资源的加载,所以需要使用异步方式。
错误提示说参数无效:

LuaException: invalid arguments to LoadWindowAsync
stack traceback:
	[C]: in method 'LoadWindowAsync'
	[string "chunk"]:35: in function 'launch'
	[string "chunk"]:54: in main chunk
XLua.LuaEnv.ThrowExceptionFromError (System.Int32 oldTop) (at Assets/XLua/Src/LuaEnv.cs:443)
XLua.LuaEnv.DoString (System.Byte[] chunk, System.String chunkName, XLua.LuaTable env) (at Assets/XLua/Src/LuaEnv.cs:276)
XLua.LuaEnv.DoString (System.String chunk, System.String chunkName, XLua.LuaTable env) (at Assets/XLua/Src/LuaEnv.cs:290)

请教一下,应该如何调用才能争取的呢?

Async & Await Tutorials Error

Unity 2020.3.4f1
When I run Assets/Samples/Loxodon Framework XLua/2.0.0/Examples/Async & Await Tutorials.unity
I get this error.
Why is it happening and how should I fix it?

InvalidCastException: This type must add to CSharpCallLua: Loxodon.Framework.Asynchronous.ILuaTask
XLua.DelegateBridge.Func[T1,TResult] (T1 p1) (at Assets/XLua/Src/GenericDelegateBridge.cs:157)
Loxodon.Framework.Views.LuaBehaviour+d__15.MoveNext () (at Assets/LoxodonFramework/XLua/Runtime/Framework/Views/LuaBehaviour.cs:116)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.b__6_0 (System.Object state) (at <695d1cc93cca45069c528c15c9fdd749>:0)
UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () (at /Users/bokken/buildslave/unity/build/Runtime/Export/Scripting/UnitySynchronizationContext.cs:153)
UnityEngine.UnitySynchronizationContext:ExecuteTasks() (at /Users/bokken/buildslave/unity/build/Runtime/Export/Scripting/UnitySynchronizationContext.cs:107)

订阅消息会导致VM无法被回收

原因:
Subject里对Action的引用是强引用

 public class Subject<T> : SubjectBase
    {
        private readonly object _lock = new object();
        private readonly List<Action<T>> actions = new List<Action<T>>();

       // 略
}

Loxodon.Framework.Prefs.DefaultEncryptor带参数的构造函数中key和iv没有赋值啊???

public DefaultEncryptor(byte[] key, byte[] iv)
{
    if (iv == null)
        this.iv = DEFAULT_IV;

    if (key == null)
        this.key = DEFAULT_KEY;

    CheckIV(this.iv);
    CheckKey(this.key);
    // ...
}

应改为

public DefaultEncryptor(byte[] key, byte[] iv)
{
    if (iv == null)
        this.iv = DEFAULT_IV;
    else
        this.iv = iv;

    if (key == null)
        this.key = DEFAULT_KEY;
    else
        this.key = key;

    CheckIV(this.iv);
    CheckKey(this.key);
    // ...
}

ProxyType.cs的IsParameterMatch存在问题

原代码:

        protected bool IsParameterMatch(IProxyMethodInfo proxyMethodInfo, Type[] parameterTypes)
        {
            ParameterInfo[] parameters = proxyMethodInfo.Parameters;
            if ((parameters == null || parameters.Length == 0) && (parameterTypes == null || parameterTypes.Length == 0))
                return true;

            if (parameters != null && parameterTypes != null && parameters.Length == parameters.Length)
            {
                for (int i = 0; i < parameters.Length; i++)
                {
                    if (!parameters[i].Equals(parameterTypes[i]))
                        return false;
                }
                return true;
            }
            return false;
        }

这里parameters[i]类型和parameterTypes类型不同,Equals会永远不等,所以这里一直会往list里面添加,在运行了1个小时后变得非常巨大.同时上面parameters.Length == parameters.Length应该也是笔误了
修正后:

        protected bool IsParameterMatch(IProxyMethodInfo proxyMethodInfo, Type[] parameterTypes)
        {
            ParameterInfo[] parameters = proxyMethodInfo.Parameters;
            if ((parameters == null || parameters.Length == 0) && (parameterTypes == null || parameterTypes.Length == 0))
                return true;

            if (parameters != null && parameterTypes != null && parameters.Length == parameterTypes.Length)
            {
                for (int i = 0; i < parameters.Length; i++)
                {
                    if (parameters[i].ParameterType != parameterTypes[i])
                        return false;
                }
                return true;
            }
            return false;
        }

Documentation needed here

Hi, @cocowolf !
Framework is good and i really enjoy using it on production projects!)
But when i presented this framework as main part of new projects - it was hard to explain how to use it... Can you write documentation for it here (on github i mean), please?)

在FormattableTextMeshProUGUI & TemplateTextMeshProUGUI中Text.text会被自身的OnEnable设置为初始值

源代码:

        protected override void OnEnable()
        {
            base.OnEnable();
            Initialize();
        }

        public override void SetAllDirty()
        {
            base.SetAllDirty();
            Initialize();
        }

        protected virtual void Initialize()
        {
            SetText(BUFFER.Clear().Append(m_Template));//格式化为默认值
        }

重现步骤:

  1. 将任意Template or Formattable绑定数据模型
  2. 在Text激活状态下更新数据
  3. 将Text的状态关闭并再次激活
  4. 此时Text.text会被Initialize设置为Text.Format

lua里面的Launcher案例运行不起来

local window = locator:LoadWindow(winContainer, "LuaUI/Startup/Startup")
window:Create() --创建窗口

create()方法报错
stack traceback:
[C]: in method 'Create'
[string "Launcher(Launcher)"]:51: in function <[string "Launcher(Launcher)"]:34>
XLua.LuaEnv.ThrowExceptionFromError (System.Int32 oldTop) (at Assets/XLua/Src/LuaEnv.cs:441)

请问是什么情况?

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.