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

Support registering godot enums and bitfields. #890

Open
lilizoey opened this issue Sep 12, 2024 · 1 comment
Open

Support registering godot enums and bitfields. #890

lilizoey opened this issue Sep 12, 2024 · 1 comment
Labels
c: register Register classes, functions and other symbols to GDScript feature Adds functionality to the library

Comments

@lilizoey
Copy link
Member

In Godot, a class can have integer constants as well as enums/bitfields. These enums and bitfields are largely just a convenient way of grouping together integer constants, since under the hood they are just integer constants and not fully-featured sum types like what rust has. From what i understand, enums and bitfields are largely the same from the perspective of ffi.

We have long had support for registering integer constants associated with a class, when this was added we also made the infrastructure needed to register enums and bitfields with a class. However it wasn't clear what syntax should be used to actually register them with the proc-macros. The most obvious syntax, something like

impl Foo {
  enum Bar { .. }
}

Does not work since enums cannot be declared in an impl block. This would be helped by inherent associated types since we could then declare a type alias in the impl block.

The main things to take into account for enums and bitfields are:

  • These enums and bitfields must be registered with a specific class
  • They can only contain integer variants

Some possible syntaxes:

#[derive(GodotClass)]
struct Foo { .. }

#[godot_enum_bikeshed_macro(Foo)]
#[repr(u8)]
enum Bar {
  ..
}
#[derive(GodotClass)]
struct Foo { .. }

#[godot_api]
impl Foo {
  #[enum(Bar)]
  const A: u8 = 10;
  #[enum(Bar)]
  const B: u8 = 10;
}

@Houtamelo made a declarative macro that emulates this:

gdscript_rust_enum! {
    GDSCRIPT: TerrainVariant; // Name of the Godot class that will contain the constants
    
    pub enum TerrainVariant {
        Water = 0, // Integer values must be provided for each variant
        Plains = 1,
    }
}
@lilizoey lilizoey added feature Adds functionality to the library c: register Register classes, functions and other symbols to GDScript labels Sep 12, 2024
@Houtamelo
Copy link
Contributor

The main problem with my declarative macro is that it doesn't actually register the enums with Godot, it creates a dummy class with a bunch of constants, so you can't use the enum as a type in GDScript.

Example, using the macro like this:

gdscript_rust_enum! {
    GDSCRIPT: TerrainVariant;
    
    pub enum TerrainVariant {
        Water = 0,
        Plains = 1,
    }
}

Allows you to, in GDScript:

var terrain: int = TerrainVariant.Plains

However, you can't use it as a type annotation:

func get_terrain() -> TerrainVariant:
    return TerrainVariant.Plains // doesn't compile, TerrainVariant is an object but we are trying to return an int

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c: register Register classes, functions and other symbols to GDScript feature Adds functionality to the library
Projects
None yet
Development

No branches or pull requests

2 participants