Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

override virtual methods #208

Open
Miqueas opened this issue Oct 22, 2022 · 8 comments
Open

override virtual methods #208

Miqueas opened this issue Oct 22, 2022 · 8 comments

Comments

@Miqueas
Copy link

Miqueas commented Oct 22, 2022

In Vala, we can override virtual methods and this helps to achieve things like this:

public class App : Adw.Application {
  public App() {
    Object(application_id: "org.app");
  }

  static int main(string[] args) {
    return new App().run(args);
  }

  protected override void activate() {
    // ...
  }

  protected override void startup() {
    base.startup();

    // ...
  }
}

In this case, this skips the step of connecting functions to signals and the app just will run without problems, is this possible in gintro?

@StefanSalewski
Copy link
Owner

Unfortunately with gintro we can not do all that what is possible in C or in Vala. (I think Rust is closest to C and Vala for GTK.)

For example, in current gintro we can not create new GObjects with new properties. And the GtkExpression is not supported in gintro or in the Python bindings. This may be generally possible with Nim GTK bindings, but it is difficult and would need some work.

When you already have learned Vala, I would recommend just to continue with Vala, as Vala was created for GTK. When you think that you need "override virtual methods" in Nim, first step would be to provide a minimal but working example in plain C for that, then we can start thinking about how it can be done in Nim. Unfortunately I am not familiar with Vala.

@Miqueas
Copy link
Author

Miqueas commented Oct 22, 2022

I see, thanks anyway, i'll try to check and see how to do that in C and provide an example

@Miqueas
Copy link
Author

Miqueas commented Oct 24, 2022

@StefanSalewski ok, I did valac -C override.vala --pkg=Adw-1 pkg=gtk4 to the example I made and basically, the override in the C side is made in the _class_init function. This is the C code generated by the Vala compiler (only the _class_init part):

static void
app_class_init (AppClass * klass,
                gpointer klass_data)
{
	app_parent_class = g_type_class_peek_parent (klass);
	((GApplicationClass *) klass)->activate = (void (*) (GApplication*)) app_real_activate;
	((GApplicationClass *) klass)->startup = (void (*) (GApplication*)) app_real_startup;
}

These two lines is where the override happens

@StefanSalewski
Copy link
Owner

I think for override virtual methods, we have to support creating and subclassing GObjects, as described in https://docs.gtk.org/gobject/tutorial.html. It would be nice to have support for that in the gintro bindings, but is in not really easy. In C a lot of complicated and nested macros like G_DECLARE_FINAL_TYPE() and many more are used, which are generally not available for language bindings. For Nim, we could try to expand the C macros into plain function calls, and then try to do the same in Nim. I was playing with that many years ago when I created the oldgtk3 bindings, and wrote the old NEd editor. It was really difficult. I have seen how GTK subclassing is used from Python, looks not too nice. For doing it in Nim, I would have to understand all the GObject and C macro stuff very well, and then think about a nice Nim API. And then create the Nim macros. I am sure that I would be not able to do all that in less than 100 hours. I am slow, so I should better assume 200 hours when doing it myself. Maybe someone can do it in 100 hours, maybe Mr Rumpf, Mr. Disruptec, Mr. Döhring? Or someone from the GTK team, Mr. Bassi, or Mr. Droege from the Rust team? You may contact that people.

You may know, that we initial intended to create a new Nim binding set based on the Rust bindings, as the Rust bindings may be the most advanced. I would be willing to donate up to 1000 Euro for that task, so with some more supporters, we had some hope to collect some 10k Euro to hire some experts. But with the current state of Nim, GTK, and gintro, I have no hope for such a project any more. I guess the actual number of users of gintro is one or two currently. And actually I looked at some Rust GTK code recently -- using GTK from Rust is really ugly.

When you really should intent to use Nim with GTK, and need low level GObject access, you may consider mixing plain C and Nim. It is possible and not so difficult, I gave an example some years ago in the gintro issue tracker, will see if I can find it. Yes, here it is: #141 When you have some basic C and Nim skills, you may be able to solve your issues.

Maybe a very different approach is, to use low level bindings. My oldgtk3 is still available. Or some people have generated low level bindings generators, like the futhark of P. Munch, or earlier tools of people who have left Nim. I think there was something like toast or nimbindgen some years ago?

Or use Vala, Rust, or Python. Or a native Nim GUI toolkit, maybe that of treeform and elcritch -- figma or fidget or somethink like that?

@Miqueas
Copy link
Author

Miqueas commented Oct 27, 2022

Makes sense, well, I just was being curious. And since you said to keep going using Vala in your first response, I'll do that. I known making bindings for GTK is a really hard thing, so there's not much I can do about this

@mildred
Copy link

mildred commented Jul 26, 2023

I am under the impression that overriding virtual methods is the only way to perform certain tasks...

I looked around and the GObject type system is described here in more detail : https://docs.gtk.org/gobject/concepts.html this is basically what is behind the macros.

@mildred
Copy link

mildred commented Jul 26, 2023

The provided link should be enough to subclass a GObject using the gobject bindings manually without using any of the C macros. Basically subclassing an object seems to go down to:

  • declare a struct for the subclass vtable linking to the parent class vtable and containing the virtual method function pointers
  • declare a struct for the subclass instance object containing the instance variables
  • declare a _get_type() function that returns a GType based on a GTypeInfo, the first time it is called, it initializes the GType.
  • when the GType is initialized, function pointers to init and finalize both the class vtable (to set the function pointers) and the object instance (to initialize instance variables) are used

With that, you should be close to ready to subclass any GObject.

@StefanSalewski
Copy link
Owner

Thanks for your comment. I think I remember your name. But you should be aware, that with comments like https://forum.nim-lang.org/t/10312#68650 you support their behaviour with had seriously damaged the whole Nim project. As you are observing the Nim project for some years already, you might know their impolite behaviour well, as discussed in https://www.reddit.com/r/nim/comments/ywxsbz/this_is_disappointing_to_read_coming_from_the_nim/. Not to mention all the personal attacks like https://forum.nim-lang.org/t/10101#66729

I think I have seen much better comments from you in the past, but I can not remember details, sorry.

For gintro, I just answered to a request of Mr. Arkan and explained why I am not any longer work on Gintro or use Nim, see #224

Your provided link is interesting, it seems to be new content, or at least a new layout. At least I can not remember having seen that page. I may read it in next winter, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants