MyGUI from C# / Mono

Jeko

08-02-2009 10:03:30

Hi,

On the subversion repository, it seems you're writing a Managed C++ wrapper for .NET platform. I'm working on a C# project which have to be portable (which means not MS only), so I'm using Mono. However this last doesn't support yet Managed C++, so I'd like a real C# wrapper. I made little tests yesterday with SWIG (http://www.swig.org) and ended-up quickly with a working framework (wrapping MyGUI's Gui, Widget, Window and Button only + OIS init/shutdown).

Before to go any further, I'd like to know if there is a C# wrapper for MyGUI that I missed.

Also my soft will be distributed soon, so I think I should rely only on latest stable version (2.2), do you agree?

Finally, if you're interested by a pure C# wrapper, I can certainly do it using SWIG. If you're not I'll continue to wrap only what I need and probably release a separated framework built on top of last stable version (MyGUI 2.2) or on top of SVN if you feel it's stable enough.

Regards,

Jeko

Five_stars

08-02-2009 12:33:35


Finally, if you're interested by a pure C# wrapper, I can certainly do it using SWIG. If you're not I'll continue to wrap only what I need and probably release a separated framework built on top of last stable version (MyGUI 2.2) or on top of SVN if you feel it's stable enough.

Please, write an example of wrapped widget. And we try to edit autowrapper for C#.

Jeko

08-02-2009 13:05:32

I don't really see what kind example you like. How swig works? Or what do I need to do?

Well, I just copy here a little subset of my code for Window.

Example usage from C#:

MyGUI.Window win = gui.CreateWindow("RF_Window", 3*w/4,0,w/4,h, MyGUI.ALIGN_DEFAULT, "Overlapped");
win.setMinMax(w/4,h, w/2,h);
win.setCaption("Select your race");


In the SWIG file:

// include "MyGUI_Window.h"
class Window : public Widget
{
public:
virtual void setCaption(const std::string& _caption);
void setMinMax(int _min_h, int _min_v, int _max_h, int _max_v);
};
%extend Gui {
CREATE_WIDGET(Window); // Instanciate the widget creation template as CreateWidget.
}


With this, SWIG generates the necessary C# proxy classes. In a full wrapper attempt, I'd just include MyGUI_Window.h and then resolve unwrappable stuffs (arrays, templates and function pointers). I hope I'm clear.

2- What is the autowrapper you talk about?

Jeko

Altren

08-02-2009 15:01:11

With this, SWIG generates the necessary C# proxy classes. In a full wrapper attempt, I'd just include MyGUI_Window.h and then resolve unwrappable stuffs (arrays, templates and function pointers). I hope I'm clear. Show us C# proxy class for example for Button.
2- What is the autowrapper you talk about? You can find it in svn in trunk/Managed/Wrapper folder. We use doxygen for parsing and giving us meta data. And then we use this data to generate managed proxy classes. I think it's also possible to generate C# proxy classes, but we ned to create templates for it first.

Jeko

08-02-2009 16:50:23

Ok, here is the generated code for Button:

Button.cs

/* ----------------------------------------------------------------------------
* This file was automatically generated by SWIG (http://www.swig.org).
* Version 1.3.33
*
* Do not make changes to this file unless you know what you are doing--modify
* the SWIG interface file instead.
* ----------------------------------------------------------------------------- */

namespace MyGUI {

using System;
using System.Runtime.InteropServices;

public class Button : Widget {
private HandleRef swigCPtr;

internal Button(IntPtr cPtr, bool cMemoryOwn) : base(MyGUIPINVOKE.ButtonUpcast(cPtr), cMemoryOwn) {
swigCPtr = new HandleRef(this, cPtr);
}

internal static HandleRef getCPtr(Button obj) {
return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
}

public override void Dispose() {
lock(this) {
if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) {
swigCMemOwn = false;
throw new MethodAccessException("C++ destructor does not have public access");
}
swigCPtr = new HandleRef(null, IntPtr.Zero);
GC.SuppressFinalize(this);
base.Dispose();
}
}

public override string getWidgetType() {
string ret = MyGUIPINVOKE.Button_getWidgetType(swigCPtr);
return ret;
}

public void setButtonPressed(bool _pressed) {
MyGUIPINVOKE.Button_setButtonPressed(swigCPtr, _pressed);
}

public bool getButtonPressed() {
bool ret = MyGUIPINVOKE.Button_getButtonPressed(swigCPtr);
return ret;
}

public void setImageIndex(uint _index) {
MyGUIPINVOKE.Button_setImageIndex(swigCPtr, _index);
}

public override void setEnabled(bool _enabled) {
MyGUIPINVOKE.Button_setEnabled(swigCPtr, _enabled);
}
}
}


Then within MyGUIPINVOKE.cs


...
[DllImport("libmyguinet", EntryPoint="CSharp_Button_getWidgetType")]
public static extern string Button_getWidgetType(HandleRef jarg1);

[DllImport("libmyguinet", EntryPoint="CSharp_Button_setButtonPressed")]
public static extern void Button_setButtonPressed(HandleRef jarg1, bool jarg2);

[DllImport("libmyguinet", EntryPoint="CSharp_Button_getButtonPressed")]
public static extern bool Button_getButtonPressed(HandleRef jarg1);

[DllImport("libmyguinet", EntryPoint="CSharp_Button_setImageIndex")]
public static extern void Button_setImageIndex(HandleRef jarg1, uint jarg2);

[DllImport("libmyguinet", EntryPoint="CSharp_Button_setEnabled")]
public static extern void Button_setEnabled(HandleRef jarg1, bool jarg2);
...


C++ generated code: SwigMyGUI.cpp

SWIGEXPORT char * SWIGSTDCALL CSharp_Button_getWidgetType(void * jarg1) {
char * jresult ;
MyGUI::Button *arg1 = (MyGUI::Button *) 0 ;
std::string *result = 0 ;

arg1 = (MyGUI::Button *)jarg1;
{
std::string const &_result_ref = (arg1)->getWidgetType();
result = (std::string *) &_result_ref;
}
jresult = SWIG_csharp_string_callback(result->c_str());
return jresult;
}


SWIGEXPORT void SWIGSTDCALL CSharp_Button_setButtonPressed(void * jarg1, unsigned int jarg2) {
MyGUI::Button *arg1 = (MyGUI::Button *) 0 ;
bool arg2 ;

arg1 = (MyGUI::Button *)jarg1;
arg2 = jarg2 ? true : false;
(arg1)->setButtonPressed(arg2);
}


SWIGEXPORT unsigned int SWIGSTDCALL CSharp_Button_getButtonPressed(void * jarg1) {
unsigned int jresult ;
MyGUI::Button *arg1 = (MyGUI::Button *) 0 ;
bool result;

arg1 = (MyGUI::Button *)jarg1;
result = (bool)(arg1)->getButtonPressed();
jresult = result;
return jresult;
}


SWIGEXPORT void SWIGSTDCALL CSharp_Button_setImageIndex(void * jarg1, unsigned long jarg2) {
MyGUI::Button *arg1 = (MyGUI::Button *) 0 ;
size_t arg2 ;

arg1 = (MyGUI::Button *)jarg1;
arg2 = (size_t)jarg2;
(arg1)->setImageIndex(arg2);
}


SWIGEXPORT void SWIGSTDCALL CSharp_Button_setEnabled(void * jarg1, unsigned int jarg2) {
MyGUI::Button *arg1 = (MyGUI::Button *) 0 ;
bool arg2 ;

arg1 = (MyGUI::Button *)jarg1;
arg2 = jarg2 ? true : false;
(arg1)->setEnabled(arg2);
}

Altren

08-02-2009 17:16:20

Well, it doesn't looks hard to make C# wrapper same way as we made Managed, but we don't have time right now so we will make it approximately for a week.

Jeko

08-02-2009 17:41:48

If you like to see a class with constructors / destructor, just ask.

Thanks for quick reaction!

Jeko

KeithCu

10-02-2009 09:02:03

Supporting C# and Mono would be great for attracting developers to MyGUI, and Managed C++ is an ugly, Microsoft-only hack. Even within Microsoft it is hardly used, and looked down upon by many of the other teams! (I was a programmer there.)

Once you support C#, you can kill your MC++ wrappers as any MC++ clients can use the more portable ones...

Let people know it is out there, and they will come find you. Maybe we are just the first to ask for this :)

Of course, a pure managed implementation is ideal because it is easier to build, port, deploy, etc., but of course that is probably a lot of work for you guys. One of the things I realize is that the greatest threat to the free software movement is that Microsoft moves all of its code to C# and these modern tools and the free software community gets left behind. The free software community is already much bigger than Microsoft today, but it hasn't won yet because it is diffuse and disorganized and inefficient.

Kind regards,

-Keith

Jeko

17-02-2009 16:27:43

Hi again,

For now I'm still relying on my minimal SWIG wrapper. However, for it to analyze MyGUI headers correctly, I need to remove non-ASCII characters.

There is only 3 little changes to do, patch linked bellow.. hope you can integrate this change in the SVN.

http://jeko.free.fr/mygui/pure-ascii-headers.patch.txt

Regards,

- Jeko

my.name

18-02-2009 16:12:55

C# wrapper will be done in one week, so you just need to wait

KeithCu

18-02-2009 16:57:06

Great! We've got a very basic Swig wrapper limping along but are looking forward to being able to chuck it and Jeko will integrate your wrapper into our repo right after.

https://launchpad.net/openracing (You can see a screen shot using MyGUI with the current hack wrapper)

Thanks so much for the quick turnaround.

-Keith

KeithCu

26-02-2009 16:27:15

Hi;

Any ETA on the MyGUI wrapper? No hurry, just trying to plan our development.

BTW, someone is building a MyGUI wrapper for Python as well:
viewtopic.php?f=3&t=9245

You should work with those guys and get that as well into your base distribution!

Regards.

Altren

26-02-2009 17:39:18

Wait one week. I took more time than we expected first because we checking all methods. ETA is one week.

KeithCu

26-02-2009 20:00:10

A week is fine. Thanks for the update!

my.name

04-03-2009 00:55:58

update from svn and test

KeithCu

04-03-2009 02:19:46

Thanks for the great news and the quick feature response!! We are just now in the middle of something disruptive, but we will check it out ASAP!

Altren

04-03-2009 02:22:48

Take revision 1788 (or greater), build MyGUI.Export and then run TestApp project in Wrapper/Sharp (this is filter in solution, not folder).

KeithCu

18-03-2009 04:30:13

As of about one week ago, we now have your MyGUI.Net wrapper in our codebase! We are only using basic functionality right now, but so far, no problems at all.

Thanks very much for doing this and for the quick turnaround! This is the power of free software. Make sure you advertise this nice little piece of functionality for other C# users like us. Now that you've done the work, you should promote it. I'm sure it could bring in more customers.

BTW, we are using it with OgreDotNet. Mogre is managed C++.

Warm regards

Altren

18-03-2009 21:31:21

Looks like you misunderstood us. We created MyGUI for both: for Managed and for C# (without Mogre and managed). So you can use it with OgreDotNet.

KeithCu

19-03-2009 00:37:58

I didn't misunderstand you. I was just browsing through your source code and thought I'd make that comment.

BTW, Mogre has been abandoned. Others are trying to restart it.