radimitrov / CSharpShellApp

77 stars 18 forks source link

Some suggestions to C# Shell #381

Open IampointZy opened 3 weeks ago

IampointZy commented 3 weeks ago

Version: C# Shell 3.1.2.7

References browser Doesn't highlight property info correctly

image The last character of property name was highlighted by blue, but it would be white.

Hide compiler generated status machines are shown in references browser

image This is the same assembly but browsed in ILSpy image By the way, I think C# shell can add a function to decompile assemblies with package ICSharpCore.Decompiler

Add library support

Reason: Most developers of Survivalcraft community are using C# Shell to develop mod, but survivalcraft-api project is upgraded to .NET 8, and C# Shell 2.6 can't reference assemblies of survivalcraft-api. So they're still using old survivalcraft-api project because C# Shell greater than 3.0 will added ConsoleLibrary.dll to project reference and it can't be removed, when survivalcraft-api load a mod assembly, Assembly.Load(byte[]) will raise exception about missing dependencies.

Support Android.Opengl.GLSurfaceVIew

This following code won't raise exception.

var view = new GLSurfaceView(NativeUi.Context);

It works correctly, but you must set a renderer for this view, or you can't see any thing.

// You have to create a view inherit from GLSurfaceView
public class MySurfaceView : GLSurfaceView, GLSurfaceView.IRenderer
{
    // Constructor and some interface implementation...
}

var view = new MySurfaceView(NativeUi.Context);
view.SetRenderer(view);

But when I run this code, it fails. I guess it's because Xamarin.Android compiler will generate a piece of Java code and fill it into classes.dex, but C# shell doesn't. So I think C# shell can add a class like this, and add some EventHandler such as Draw, OnCreate

IampointZy commented 3 weeks ago

And last one, I found that font won't change even though I've import a font. image

radimitrov commented 3 weeks ago

The type information highlighting and editor font issues were fixed at some point. Version 3.1.2.7 is 8 months old. I will add an option in the project settings to exclude ConsoleLibrary. Compiler generated state machines should be filtered out. I will check why they aren't.

I haven't delved into GLSurfaceView before. Would simply implementing that interface and exposing it via events make it decently usable?

radimitrov commented 3 weeks ago

I will also almost certainly be adding an IL decompiler. Just need to verify there is now enough app size leeway for such a sizable DLL

IampointZy commented 3 weeks ago

Normally, GLSurfaceView doesn't provide any method to draw, so you need to set a renderer for a surface view. This is the document of GLSurfaceView.IRenderer : https://learn.microsoft.com/en-us/dotnet/api/android.opengl.glsurfaceview.irenderer?view=net-android-34.0

public interface GLSurfaceView.IRenderer : Android.Runtime.IJavaObject, IDisposable, Java.Interop.IJavaPeerable

By seeing this definition, we can find that it's about java interop, it means that when you create a class implements GLSurfaceView.IRenderer, the Xamarin.Android compiler will generate a java class, but C# Shell haven't support this yet. On the other hand, it's too troublesome to implement these method: image So a simple way is to create a class like this:

public class MySurfaceView : GLSurfaceView, GLSurfaceView.IRenderer
{
    public MySurfaceView(Context? context) : base(context)
    {
    }

    public void OnDrawFrame(IGL10? gl)
    {
        // ...
    }

    public void OnSurfaceChanged(IGL10? gl, int width, int height)
    {
        // ...
    }

    public void OnSurfaceCreated(IGL10? gl, Javax.Microedition.Khronos.Egl.EGLConfig? config)
    {
        // ...
    }
}

But when I runned this code, C# Shell raised an exception. Code:

MySurfaceView view = new(NativeUi.Context);
view.SetRenderer((GLSurfaceView.IRenderer)view);
var lay = new NativeUiLib.LinearLayout();
lay.AddView(view);
lay.Show();

Output:

System.NotSupportedException: Cannot create instance of type 'GLTest.MySurfaceView': no Java peer type found.
   at Java.Interop.JniPeerMembers.JniInstanceMethods..ctor(Type declaringType)
   at Java.Interop.JniPeerMembers.JniInstanceMethods.GetConstructorsForType(Type declaringType)
   at Java.Interop.JniPeerMembers.JniInstanceMethods.StartCreateInstance(String constructorSignature, Type declaringType, JniArgumentValue* parameters)
   at Android.Opengl.GLSurfaceView..ctor(Context context)
   at GLTest.MySurfaceView..ctor(Context context)
   at GLTest.Program.Main()
   at System.Reflection.MethodInvoker.InterpretedInvoke(Object obj, Span`1 args, BindingFlags invokeAttr)

This is because C# Shell doesn't generate any java class for MySurfaceView, by compiling the same code in Visual Studio and decompiling classes.dex in apk, we can see these java code: image

So adding a new view inherit from GLSurfaceView implements GLSurfaceView.IRenderer and create these events can make OpenGL avalible on C# Shell.

radimitrov commented 3 weeks ago

Implemented it last night in NativeUi.OpenGl nameapace. I didn't have time to test, but it should work.

radimitrov commented 2 weeks ago

ConsoleLibrary.dll can now be dereferenced from the "References" menu.

I was thinking of also adding an "Export Windows assembly menu option" however it feels like cluttering the UI. I'm just going to basically add post assembly export "Recompile for Windows" option in the build output. Less efficient, but it isn't a general use case.