Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

unity3d mvvmcross porting thread #215

Closed
yuewah opened this Issue · 32 comments

4 participants

@yuewah

PropertyInfo.GetValue() in iOS device would raise AOT error, not all codes has fixed by replacing with PropertyInfo.GetGetMethod().Invoke()

@slodge
Owner

Thanks

can i get a repro of this? Eg what were you binding and what version of xamarin.ios were you using?

I've seen this before - a year ago - but have been assured by xamarin that they fixed it - so if it's broken then we should let them know

thanks again

stuart

@yuewah

Actually, I am not using xarmarin to deploy iOS build, I am using Unity3d ( a game engine using mono c# ), I am trying to port mvvmcross to it. In the meantime, the UISlider, TextLabel and Button event binding are working on Android, Window and Mac but not iOS because of AOT error, then I fixed by changing PropertyInfo.GetValue() -> PropertyInfo.GetGetMethod().Invoke(), if xamarin already fixed, then I think it is the unity3d issue.

@yuewah yuewah closed this
@slodge
Owner

I may have mis-remembered the bug

this is what i remember - http://monotouch.2284126.n4.nabble.com/Attempting-to-JIT-compile-method-what-am-I-doing-wrong-td4492920.html - so different

i am happy to help with the unity port :)

i think unity will not support pcls but we can try to help make the code unity friendly

i have a free unity license, but no real experience

stuart

@slodge slodge reopened this
@yuewah

It would be great that you are interested on unity3d port. As built-in GUI Library in unity3d is very old fashion and poor in performance on mobile device, so I don't recommend to support it. Most of the unity3d developers now use 3rd party GUI Library called NGUI http://www.tasharen.com/?page_id=140 ( it has a free edition ). NGUI is what I am trying to support now. However, unity3d announced that they will release a newly designed GUI officially in near future.

@slodge
Owner

I did look into the idea of supporting Unity late last year - saw there were already a couple of Mvvm frameworks around - one of them was based on top of NGUI I think (but was $).

I think my main problem - the main reason I stopped looking - was lack of 'use case'. All mvvmcross development has been born out of real projects where I've needed the end products - and I really didn't have somewhere to start for Unity - I didn't have an app.

Very happy to help you out if you have an app or a need. Which branch are you building off of? v3? How are you converting the PCLs to the Unity library projects? Is there anything you need? Happy to change things like GetGetMethod() if needed - will just need to test here on other platforms.

Stuart

@yuewah

I am built using v3. As I don't have a visual studio professional, I only use visual studio express which cannot reference several project file in a solution. So, I just copy the necessary source folders and files to Unity, i.e.

MvvmCross-3/Cirrious/Cirrious.MvvmCross
MvvmCross-3/Cirrious/Cirrious.MvvmCross.Binding
MvvmCross-3/Cirrious/Cirrious.MvvmCross.Binding.Touch
MvvmCross-3/Cirrious/Cirrious.MvvmCross.Touch
MvvmCross-3/CrossCore/Cirrious.CrossCore
MvvmCross-3/CrossCore/Cirrious.CrossCore.Touch
MvvmCross-3/PortableSupport/System.Windows

and then replace the .Touch related code to support NGUI in Unity.

@slodge
Owner

Impressive!

Definitely automate that folder/file copy if you can - as the source tree in MvvmCross keeps growing and we will want to be able to recreate the Unity projects too.

Let me know if there are things you need.

Stuart

@yuewah

Basically, the main different of Unity to other native app development is how to create object instance that can be rendered on screen. It must be instantiated with unity api from file system. Therefore, in mvvmcross, CreateView(MvxViewModelRequest request) is not working i.e. "var view = Activator.CreateInstance(viewType) as IMvxNguiView;", also it cannot have any constructors.

So, I would like know what the presentationBundle and ChangePresentation(MvxPresentationHint hint) used for ?

@yuewah

by the way, I think this issue is going to out of the track, can you create a new issue to start with unity port ?

@slodge
Owner

presentationBundle is there for showviewmodel to provide a hint about the presentation - eg 'please clear backstack and present'. Since 99% of code doesn't use it, you can probably ignore it.

ChangePresentation is a new method - designed so view models can request ui actions - eg 'please close a dialog' or 'please go back' or.... - eg a AddNewCustomerViewModel might want to tell the ui to 'go back' after a successful save.

@yuewah

I would like to use presentationBundle to pass the file name needed to load the unity view

@slodge
Owner

doesn't sound like that would make the code very portable,

Can't you guess the filename from the viewmodel name - that's pretty much what the WindowsPhone code does

@yuewah

not only for the unity port, how can I show view model that load different view in runtime?

@slodge
Owner

how can I show view model that load different view

I don't understand what you are asking. I need some sample pseudo code for what you are trying to do.

@yuewah

Customer1View is binded to CustomerViewModel
Customer2View is binded to CustomerViewModel

ShowViewModel< CustomerViewModel >( Customer1View )
or ShowViewModel< CustomerViewModel >( Customer2View )

@slodge
Owner

Why are they both bound to the same viewmodel?

FooView should be bound to FooViewModel
BarView should be bound to BarViewModel

@yuewah

The logic (ViewModel) is the same, but the layout (View) is different.

@slodge
Owner

Please provide more detail - this is issues, not chat and the communication will work much better with more detail.

My opinion is:

  • A ViewModel is a 'Model for a View'.
  • If you have two views, then you should have two viewmodels.
  • If there is no data difference, then these two viewmodels can easily share all their code through inheritance.

If you really think you need something here, then maybe please provide a real example instead of Customer1 and Customer2 (Foo and Bar).

Stuart

@yuewah

In unity project, the View declaration file (.prefab) is put under a folder called Resources, then it is instantiated by its file path.

e.g.

Scripts/ViewModel/Customer/CustomerViewModel.cs
Scripts/ViewModel/Sales/SalesViewModel.cs
Scripts/View/Customer/CustomerView.cs
Scripts/View/Sales/SalesView.cs

Resources/View/Customer/CustomerView.prefab
Resources/View/Sales/SalesView.prefab

.prefab = .xaml

CustomerView.cs is linked to CustomerView.prefab
SalesView.cs is linked to SalesView.prefab

By ViewModelType Name, how can I get the ViewType Name?

@slodge
Owner

The Setup.cs process creates a lookup table of ViewModel type to View type - take a look at

https://github.com/slodge/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross/Platform/MvxSetup.cs#L254

e.g. step through it in a Windows8 app to see what it does.

This table is then used in the ViewsContainer to look up View from ViewModel

@yuewah

In 3D Game, there is 2D Camera mainly for UI and 3D Camera for game objects ( e.g. Character, Enemy etc ), since the navigation of viewmodel is very different, can I use two different presenters for each camera ? or any design can solve my problem ?

@slodge
Owner

As I asked on #217 'please provide much more info if you can'

  • I don't understand what you are trying to do with Mvvm.
  • I don't understand how you understand 'presenters' - I suspect you mean something different to what I mean when I say 'presenter'..
  • I don't understand what your viewmodels are in your 2D and 3D cameras.

One thing that may help is this monogame-mvvmcross question from @AlphaPage - http://stackoverflow.com/questions/13201174/insert-a-monogame-view-inside-mvvmcross-monodroid-activity

Please provide as much info as you can, and I will try to help - maybe you can try to provide a simple set of viewmodels which need to be shown in both 2D and 3D?

However, if you can only provide 2 lines at a time, then I may not be able to help - sorry.

@yuewah

Sorry for misleading question.

I am working on a 3D city building game using unity3d. The UI has a Build Button, when you click it, a Building List Panel is pop up, you can choose one of the building. The selected building appear on the 3D map and you can drag the position of the building around the map. Finally, you can build many buildings on the map.

In the unity3d game engine, you can create many cameras. each camera only render gameobject lay on that Layer. Therefore, the UI is in the layer called "UILayer", and the 3D building is in the layer called "MapLayer". Since the my presenter that work for the UI is using a modified version of MvxModalNavSupportTouchViewPresenter, its logic is suitable to a 2D UI, but not the 3D Map.

@slodge
Owner

a Building List Panel is pop up, you can choose one of the building. The selected building appear on the 3D map and you can drag the position of the building around the map. Finally, you can build many buildings on the map.

So which of these things has a ViewModel behind it?

And which of these things need to be shown through the ShowViewModel/Presenter option?

Normally, when I have a list of things, then they are just child ViewModels - e.g. I did this demo for showing players on a football pitch - https://github.com/slodge/MvvmCross-Players

So I don't think you will be using the presenter for this...

However... if you really do want to mix and match 2D and 3D and you want to use presenters, then I still think you can only have one presenter

If you want to write a custom presenter which puts some views/viewmodels in 2d and some views/viewmodels in 3d, then you can do it - this is no difference really to a custom presenter which puts some views/viewmodels in modal and some views/viewmodels in tabs and some views/viewmodels in splitviews - it's just C# so you can use an if to choose where to put things?

Why would you need multiple presenters?

@yuewah

PropertyInfo.GetValue() in iOS device would raise AOT error , Could you change to PropertyInfo.GetGetMethod().Invoke()

e.g.
value = propertyInfo.GetValue(host, null);
value = propertyInfo.GetGetMethod().Invoke(host, null);

@slodge
Owner

Is there a class and line number where you would like this changed?

Have you got a repo case for it so I or someone could test?

I'm also assuming this is unity only as I'm pretty sure I don't have any issues with GetValue in monotouch - although we have previously seen issues invoking events

@yuewah

Actually, some of your original code are already using " propertyInfo.GetGetMethod().Invoke(... "
MvvmCross\Cirrious\Cirrious.MvvmCross\Views\MvxViewExtensionMethods.cs(77)
MvvmCross\Cirrious\Cirrious.MvvmCross.Binding\Bindings\Target\MvxPropertyInfoTargetBinding.cs(65)

why don't you make it consistent through out the codebase ?

@slodge
Owner

Is there a class and line number where you would like this changed?

Have you got a repo case for it so I or someone could test?

@SeeD-Seifer

Hi yuewah,

Could you please provide the simplest test project.
If you could reproduce the issue without MvvmCross, it would be excellent!

This code works in Unity3D 3.5.6 (iOS-Pro) with turned on stripping:

    public class MyClass<T>
    {
        public T Value { get; set; }
    }

    void Test()
    {
        var c = new MyClass<int>();
        //c.Value = 10;
        var p = c.GetType().GetProperty ("Value");
        var v = p.GetValue (c, null);
        Debug.Log (v);
    }

As you can see GetValue works even for generic class. So we need to understand the actual core of the issue.

@yuewah

I just tried your code example in Unity3D.
In the PlayerSettings, the Api Compatibility Level is set to .Net 2.0 Subset in default, there is no problem. If set to .Net 2.0, it will raise AOT error in iOS device.

@et-nowis

MvxStringToTypeParser
Unity's Mono does not have Guid.TryParse()
Below is my workaround code:

    public class GuidParser : ValueParser
    {
        protected override bool TryParse(string input, out object result)
        {
            Guid value = new Guid();
            bool toReturn = false;
            try
            {
                value = new Guid(input);
                toReturn = true;
            }
            catch (Exception) { }
            result = value;
            return toReturn;
        }
    }
@slodge
Owner

Is there any update on getting your port into a publicly visible repo?

  • Sending very short snippets like this is very hard to work with.
  • And there's no point in MvvmCross making changes which Mono doesn't need if all we are doing is helping to build a private repo for a private company.

Thanks

Stuart

@slodge slodge closed this in 1d4774a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.