2
0
Эх сурвалжийг харах

Reasonably functioning generated stuff

Lucien Greathouse 6 сар өмнө
parent
commit
30fbec5217

+ 0 - 8
JoltC/Enums.h

@@ -162,14 +162,6 @@ ENSURE_ENUM_EQ(JPC_CONSTRAINT_SUB_TYPE_USER2, JPH::EConstraintSubType::User2)
 ENSURE_ENUM_EQ(JPC_CONSTRAINT_SUB_TYPE_USER3, JPH::EConstraintSubType::User3)
 ENSURE_ENUM_EQ(JPC_CONSTRAINT_SUB_TYPE_USER4, JPH::EConstraintSubType::User4)
 
-typedef enum JPC_ConstraintSpace: uint32_t {
-	JPC_CONSTRAINT_SPACE_LOCAL_TO_BODY_COM,
-	JPC_CONSTRAINT_SPACE_WORLD_SPACE,
-} JPC_ConstraintSpace;
-
-ENSURE_ENUM_EQ(JPC_CONSTRAINT_SPACE_LOCAL_TO_BODY_COM, JPH::EConstraintSpace::LocalToBodyCOM)
-ENSURE_ENUM_EQ(JPC_CONSTRAINT_SPACE_WORLD_SPACE, JPH::EConstraintSpace::WorldSpace)
-
 typedef enum JPC_MotionType: uint8_t {
 	JPC_MOTION_TYPE_STATIC,
 	JPC_MOTION_TYPE_KINEMATIC,

+ 0 - 18
JoltC/Functions.h

@@ -566,24 +566,6 @@ JPC_API void JPC_Constraint_delete(JPC_Constraint* self);
 ////////////////////////////////////////////////////////////////////////////////
 // FixedConstraintSettings
 
-typedef struct JPC_FixedConstraintSettings {
-	JPC_ConstraintSettings ConstraintSettings;
-
-	// TwoBodyConstraintSettings: no extra members
-
-	// FixedConstraintSettings
-	JPC_ConstraintSpace Space;
-	bool AutoDetectPoint;
-
-	JPC_RVec3 Point1;
-	JPC_Vec3 AxisX1;
-	JPC_Vec3 AxisY1;
-
-	JPC_RVec3 Point2;
-	JPC_Vec3 AxisX2;
-	JPC_Vec3 AxisY2;
-} JPC_FixedConstraintSettings;
-
 JPC_API void JPC_FixedConstraintSettings_default(JPC_FixedConstraintSettings* settings);
 JPC_API JPC_Constraint* JPC_FixedConstraintSettings_Create(
 	const JPC_FixedConstraintSettings* self,

+ 20 - 0
JoltC/Generated.h

@@ -1,6 +1,12 @@
 #pragma once
 // Generated by JoltC-generate
 
+typedef uint32_t JPC_ConstraintSpace;
+const JPC_ConstraintSpace JPC_CONSTRAINT_SPACE_LOCAL_TO_BODY_COM = 0;
+ENSURE_ENUM_EQ(JPC_CONSTRAINT_SPACE_LOCAL_TO_BODY_COM, JPH::EConstraintSpace::LocalToBodyCOM)
+const JPC_ConstraintSpace JPC_CONSTRAINT_SPACE_WORLD_SPACE = 1;
+ENSURE_ENUM_EQ(JPC_CONSTRAINT_SPACE_WORLD_SPACE, JPH::EConstraintSpace::WorldSpace)
+
 typedef struct JPC_ConstraintSettings {
 	bool Enabled;
 	uint32_t ConstraintPriority;
@@ -12,3 +18,17 @@ typedef struct JPC_ConstraintSettings {
 
 JPC_API void JPC_ConstraintSettings_default(JPC_ConstraintSettings* value);
 
+typedef struct JPC_FixedConstraintSettings {
+	JPC_ConstraintSettings ConstraintSettings;
+	JPC_ConstraintSpace Space;
+	bool AutoDetectPoint;
+	JPC_RVec3 Point1;
+	JPC_Vec3 AxisX1;
+	JPC_Vec3 AxisY1;
+	JPC_RVec3 Point2;
+	JPC_Vec3 AxisX2;
+	JPC_Vec3 AxisY2;
+} JPC_FixedConstraintSettings;
+
+JPC_API void JPC_FixedConstraintSettings_default(JPC_FixedConstraintSettings* value);
+

+ 29 - 0
JoltCImpl/Generated.h

@@ -23,3 +23,32 @@ JPC_API void JPC_ConstraintSettings_default(JPC_ConstraintSettings* value) {
 	JPC_ConstraintSettings_to_jpc(value, &defaultValue);
 }
 
+JPC_IMPL void JPC_FixedConstraintSettings_to_jpc(JPC_FixedConstraintSettings* outJpc, const JPH::FixedConstraintSettings* inJph) {
+	JPC_ConstraintSettings_to_jpc(&outJpc->ConstraintSettings, &*inJph);
+	outJpc->Space = static_cast<JPC_ConstraintSpace>(inJph->mSpace);
+	outJpc->AutoDetectPoint = inJph->mAutoDetectPoint;
+	outJpc->Point1 = to_jpc(inJph->mPoint1);
+	outJpc->AxisX1 = to_jpc(inJph->mAxisX1);
+	outJpc->AxisY1 = to_jpc(inJph->mAxisY1);
+	outJpc->Point2 = to_jpc(inJph->mPoint2);
+	outJpc->AxisX2 = to_jpc(inJph->mAxisX2);
+	outJpc->AxisY2 = to_jpc(inJph->mAxisY2);
+}
+
+JPC_IMPL void JPC_FixedConstraintSettings_to_jph(const JPC_FixedConstraintSettings* inJpc, JPH::FixedConstraintSettings* outJph) {
+	JPC_ConstraintSettings_to_jph(&inJpc->ConstraintSettings, &*outJph);
+	outJph->mSpace = static_cast<JPH::EConstraintSpace>(inJpc->Space);
+	outJph->mAutoDetectPoint = inJpc->AutoDetectPoint;
+	outJph->mPoint1 = to_jph(inJpc->Point1);
+	outJph->mAxisX1 = to_jph(inJpc->AxisX1);
+	outJph->mAxisY1 = to_jph(inJpc->AxisY1);
+	outJph->mPoint2 = to_jph(inJpc->Point2);
+	outJph->mAxisX2 = to_jph(inJpc->AxisX2);
+	outJph->mAxisY2 = to_jph(inJpc->AxisY2);
+}
+
+JPC_API void JPC_FixedConstraintSettings_default(JPC_FixedConstraintSettings* value) {
+	JPH::FixedConstraintSettings defaultValue{};
+	JPC_FixedConstraintSettings_to_jpc(value, &defaultValue);
+}
+

+ 2 - 39
JoltCImpl/JoltC.cpp

@@ -33,8 +33,6 @@
 
 #define JPC_IMPL static
 
-#include <JoltCImpl/Generated.h>
-
 #define OPAQUE_WRAPPER(c_type, cpp_type) \
 	static c_type* to_jpc(cpp_type *in) { return reinterpret_cast<c_type*>(in); } \
 	static const c_type* to_jpc(const cpp_type *in) { return reinterpret_cast<const c_type*>(in); } \
@@ -278,6 +276,8 @@ JPC_IMPL JPH::ShapeCastSettings JPC_ShapeCastSettings_to_jph(JPC_ShapeCastSettin
 	return out;
 }
 
+#include <JoltCImpl/Generated.h>
+
 JPC_API void JPC_RegisterDefaultAllocator() {
 	JPH::RegisterDefaultAllocator();
 }
@@ -752,43 +752,6 @@ JPC_API void JPC_Constraint_delete(JPC_Constraint* self) {
 ////////////////////////////////////////////////////////////////////////////////
 // FixedConstraintSettings
 
-JPC_IMPL void JPC_FixedConstraintSettings_to_jpc(
-	JPC_FixedConstraintSettings* outJpc,
-	const JPH::FixedConstraintSettings* inJph)
-{
-	JPC_ConstraintSettings_to_jpc(&outJpc->ConstraintSettings, inJph);
-
-	outJpc->Space = static_cast<JPC_ConstraintSpace>(inJph->mSpace);
-	outJpc->AutoDetectPoint = inJph->mAutoDetectPoint;
-	outJpc->Point1 = to_jpc(inJph->mPoint1);
-	outJpc->AxisX1 = to_jpc(inJph->mAxisX1);
-	outJpc->AxisY1 = to_jpc(inJph->mAxisY1);
-	outJpc->Point2 = to_jpc(inJph->mPoint2);
-	outJpc->AxisX2 = to_jpc(inJph->mAxisX2);
-	outJpc->AxisY2 = to_jpc(inJph->mAxisY2);
-}
-
-JPC_IMPL void JPC_FixedConstraintSettings_to_jph(
-	const JPC_FixedConstraintSettings* inJpc,
-	JPH::FixedConstraintSettings* outJph)
-{
-	JPC_ConstraintSettings_to_jph(&inJpc->ConstraintSettings, outJph);
-
-	outJph->mSpace = static_cast<JPH::EConstraintSpace>(inJpc->Space);
-	outJph->mAutoDetectPoint = inJpc->AutoDetectPoint;
-	outJph->mPoint1 = to_jph(inJpc->Point1);
-	outJph->mAxisX1 = to_jph(inJpc->AxisX1);
-	outJph->mAxisY1 = to_jph(inJpc->AxisY1);
-	outJph->mPoint2 = to_jph(inJpc->Point2);
-	outJph->mAxisX2 = to_jph(inJpc->AxisX2);
-	outJph->mAxisY2 = to_jph(inJpc->AxisY2);
-}
-
-JPC_API void JPC_FixedConstraintSettings_default(JPC_FixedConstraintSettings* settings) {
-	JPH::FixedConstraintSettings defaultSettings{};
-	JPC_FixedConstraintSettings_to_jpc(settings, &defaultSettings);
-}
-
 JPC_API JPC_Constraint* JPC_FixedConstraintSettings_Create(
 	const JPC_FixedConstraintSettings* self,
 	JPC_Body* inBody1,

+ 137 - 8
generate/src/emit.rs

@@ -1,11 +1,77 @@
 use std::fmt::Write;
 
+fn is_builtin_type(ty: &str) -> bool {
+    crate::BUILTIN_TYPES.contains(&ty)
+}
+
+fn is_generated_type(ty: &str) -> bool {
+    crate::structs().iter().any(|s| s.jpc_name == ty)
+}
+
+#[expect(unused)]
+fn get_struct(ty: &str) -> Option<&'static MirrorStruct> {
+    crate::structs().iter().find(|s| s.jpc_name == ty)
+}
+
+fn get_enum(ty: &str) -> Option<&'static MirrorEnum> {
+    crate::enums().iter().find(|e| e.jpc_name == ty)
+}
+
+fn is_enum(ty: &str) -> bool {
+    crate::enums().iter().any(|e| e.jpc_name == ty)
+}
+
+fn jph_to_jpc(
+    out: &mut impl Write,
+    jpc_ty: &str,
+    in_place: &str,
+    out_place: &str,
+) -> anyhow::Result<()> {
+    if is_builtin_type(jpc_ty) {
+        writeln!(out, "\t{out_place} = {in_place};")?;
+    } else if is_generated_type(jpc_ty) {
+        writeln!(out, "\t{jpc_ty}_to_jpc(&{out_place}, &{in_place});")?;
+    } else if is_enum(jpc_ty) {
+        writeln!(out, "\t{out_place} = static_cast<{jpc_ty}>({in_place});")?;
+    } else {
+        writeln!(out, "\t{out_place} = to_jpc({in_place});")?;
+    }
+
+    Ok(())
+}
+
+fn jpc_to_jph(
+    out: &mut impl Write,
+    jpc_ty: &str,
+    in_place: &str,
+    out_place: &str,
+) -> anyhow::Result<()> {
+    if is_builtin_type(jpc_ty) {
+        writeln!(out, "\t{out_place} = {in_place};")?;
+    } else if is_generated_type(jpc_ty) {
+        writeln!(out, "\t{jpc_ty}_to_jph(&{in_place}, &{out_place});")?;
+    } else if let Some(e) = get_enum(jpc_ty) {
+        let jph_ty = e.jph_name;
+        writeln!(out, "\t{out_place} = static_cast<{jph_ty}>({in_place});")?;
+    } else {
+        writeln!(out, "\t{out_place} = to_jph({in_place});")?;
+    }
+
+    Ok(())
+}
+
 pub struct MirrorStruct {
     pub jph_name: &'static str,
     pub jpc_name: &'static str,
     pub fields: &'static [StructField],
 }
 
+pub struct StructField {
+    pub ty: &'static str,
+    pub name: &'static str,
+    pub is_superclass: bool,
+}
+
 impl MirrorStruct {
     pub fn emit_header(&self, out: &mut impl Write) -> anyhow::Result<()> {
         self.header_definition(out)?;
@@ -26,7 +92,7 @@ impl MirrorStruct {
         let jpc_name = self.jpc_name;
 
         writeln!(out, "typedef struct {jpc_name} {{")?;
-        for StructField { ty, name } in self.fields {
+        for StructField { ty, name, .. } in self.fields {
             writeln!(out, "\t{ty} {name};")?;
         }
         writeln!(out, "}} {jpc_name};")?;
@@ -49,8 +115,22 @@ impl MirrorStruct {
             out,
             "JPC_IMPL void {jpc_name}_to_jpc({jpc_name}* outJpc, const {jph_name}* inJph) {{"
         )?;
-        for StructField { ty, name } in self.fields {
-            writeln!(out, "\toutJpc->{name} = inJph->m{name};")?;
+        for StructField {
+            ty,
+            name,
+            is_superclass,
+        } in self.fields
+        {
+            if *is_superclass {
+                jph_to_jpc(out, ty, "*inJph", &format!("outJpc->{name}"))?;
+            } else {
+                jph_to_jpc(
+                    out,
+                    ty,
+                    &format!("inJph->m{name}"),
+                    &format!("outJpc->{name}"),
+                )?;
+            }
         }
         writeln!(out, "}}")?;
         writeln!(out)?;
@@ -59,8 +139,22 @@ impl MirrorStruct {
             out,
             "JPC_IMPL void {jpc_name}_to_jph(const {jpc_name}* inJpc, {jph_name}* outJph) {{"
         )?;
-        for StructField { ty, name } in self.fields {
-            writeln!(out, "\toutJph->m{name} = inJpc->{name};")?;
+        for StructField {
+            ty,
+            name,
+            is_superclass,
+        } in self.fields
+        {
+            if *is_superclass {
+                jpc_to_jph(out, ty, &format!("inJpc->{name}"), "*outJph")?;
+            } else {
+                jpc_to_jph(
+                    out,
+                    ty,
+                    &format!("inJpc->{name}"),
+                    &format!("outJph->m{name}"),
+                )?;
+            }
         }
         writeln!(out, "}}")?;
         writeln!(out)?;
@@ -75,7 +169,42 @@ impl MirrorStruct {
     }
 }
 
-pub struct StructField {
-    pub ty: &'static str,
-    pub name: &'static str,
+pub struct MirrorEnum {
+    pub jpc_name: &'static str,
+    pub jph_name: &'static str,
+    pub repr: &'static str,
+    pub members: Vec<EnumMember>,
+}
+
+pub struct EnumMember {
+    pub jpc_name: String,
+    pub jph_name: String,
+    pub value: &'static str,
+}
+
+impl MirrorEnum {
+    pub fn emit_header(&self, out: &mut impl Write) -> anyhow::Result<()> {
+        let Self {
+            jpc_name,
+            members,
+            repr,
+            ..
+        } = self;
+
+        writeln!(out, "typedef {repr} {jpc_name};")?;
+        for member in members {
+            let EnumMember {
+                jph_name: jph_member,
+                jpc_name: jpc_member,
+                value,
+                ..
+            } = member;
+
+            writeln!(out, "const {jpc_name} {jpc_member} = {value};")?;
+            writeln!(out, "ENSURE_ENUM_EQ({jpc_member}, {jph_member})")?;
+        }
+        writeln!(out)?;
+
+        Ok(())
+    }
 }

+ 79 - 9
generate/src/macros.rs

@@ -1,7 +1,28 @@
+macro_rules! builtin_types {
+    (
+        $($builtin:ident)*
+    ) => {
+        [$(stringify!($builtin),)*]
+    }
+}
+
+#[cps::cps]
+macro_rules! include_builtin_types {
+    () =>
+    let $($body:tt)* = cps::include!("input/BuiltinTypes.inc") in
+    {
+        builtin_types!($($body)*)
+    }
+}
+
 macro_rules! mirrored_structs {
     (
         $(struct $struct_name:ident {
-            $($field_ty:ident $field_name:ident;)*
+            $(
+                $([[$field_attr:tt]])*
+                $field_ty:ident
+                $field_name:ident;
+            )*
         };)*
     ) => {
         [$(
@@ -9,21 +30,70 @@ macro_rules! mirrored_structs {
                 jph_name: concat!("JPH::", stringify!($struct_name)),
                 jpc_name: concat!("JPC_", stringify!($struct_name)),
                 fields: &[$(
-                    StructField {
-                        ty: stringify!($field_ty),
-                        name: stringify!($field_name),
+                    mirrored_struct_field!($([[$field_attr]])* $field_ty $field_name),
+                )*],
+            },
+        )*]
+    };
+}
+
+macro_rules! mirrored_struct_field {
+    ($field_ty:ident $field_name:ident) => {
+        StructField {
+            ty: stringify!($field_ty),
+            name: stringify!($field_name),
+            is_superclass: false,
+        }
+    };
+
+    ([[superclass]] $field_ty:ident $field_name:ident) => {
+        StructField {
+            ty: stringify!($field_ty),
+            name: stringify!($field_name),
+            is_superclass: true,
+        }
+    };
+}
+
+#[cps::cps]
+macro_rules! include_mirrored_structs {
+    () =>
+    let $($body:tt)* = cps::include!("input/MirroredStructs.h") in
+    {
+        mirrored_structs!($($body)*)
+    }
+}
+
+macro_rules! mirrored_enums {
+    (
+        $(enum $enum_name:ident : $repr:ident {
+            $($member_name:ident = $member_value:expr,)*
+        };)*
+    ) => {
+        vec![$(
+            MirrorEnum {
+                jph_name: concat!("JPH::E", stringify!($enum_name)),
+                jpc_name: concat!("JPC_", stringify!($enum_name)),
+                repr: stringify!($repr),
+                members: vec![$(
+                    EnumMember {
+                        jph_name: format!("JPH::E{}::{}", stringify!($enum_name), stringify!($member_name)),
+                        jpc_name: format!("JPC_{}_{}",
+                            heck::AsShoutySnakeCase(stringify!($enum_name)),
+                            heck::AsShoutySnakeCase(stringify!($member_name))),
+                        value: stringify!($member_value),
                     },
-                )*]
+                )*],
             }
         )*]
     }
 }
 
 #[cps::cps]
-macro_rules! include_mirrored_structs {
-    ($source:literal) =>
-    let $($body:tt)* = cps::include!($source) in
+macro_rules! include_mirrored_enums {
+    () =>
+    let $($body:tt)* = cps::include!("input/Enums.h") in
     {
-        mirrored_structs!($($body)*)
+        mirrored_enums!($($body)*)
     }
 }

+ 21 - 4
generate/src/main.rs

@@ -4,10 +4,23 @@ mod emit;
 mod macros;
 
 use std::fmt::Write;
+use std::sync::OnceLock;
 
-use self::emit::{MirrorStruct, StructField};
+use self::emit::{EnumMember, MirrorEnum, MirrorStruct, StructField};
 
-static STRUCTS: &[MirrorStruct] = &include_mirrored_structs!("input/ReflectedStructs.h");
+pub static BUILTIN_TYPES: &[&str] = &include_builtin_types!();
+
+pub fn structs() -> &'static [MirrorStruct] {
+    static STRUCTS: &[MirrorStruct] = &include_mirrored_structs!();
+
+    STRUCTS
+}
+
+pub fn enums() -> &'static [MirrorEnum] {
+    static ENUMS: OnceLock<Vec<MirrorEnum>> = OnceLock::new();
+
+    ENUMS.get_or_init(|| include_mirrored_enums!())
+}
 
 fn main() {
     if let Err(err) = generate() {
@@ -22,7 +35,11 @@ fn generate() -> anyhow::Result<()> {
     writeln!(header, "// Generated by JoltC-generate")?;
     writeln!(header)?;
 
-    for struc in STRUCTS {
+    for e in enums() {
+        e.emit_header(&mut header)?;
+    }
+
+    for struc in structs() {
         struc.emit_header(&mut header)?;
     }
 
@@ -31,7 +48,7 @@ fn generate() -> anyhow::Result<()> {
     writeln!(cpp, "// Generated by JoltC-generate")?;
     writeln!(cpp)?;
 
-    for struc in STRUCTS {
+    for struc in structs() {
         struc.emit_impl(&mut cpp)?;
     }
 

+ 8 - 0
input/BuiltinTypes.inc

@@ -0,0 +1,8 @@
+bool
+int
+uint
+uint16_t
+uint32_t
+uint64_t
+float
+double

+ 4 - 0
input/Enums.h

@@ -0,0 +1,4 @@
+enum ConstraintSpace: uint32_t {
+	LocalToBodyCOM = 0,
+	WorldSpace = 1,
+};

+ 18 - 0
input/MirroredStructs.h

@@ -8,4 +8,22 @@ struct ConstraintSettings {
 	uint NumPositionStepsOverride;
 	float DrawConstraintSize;
 	uint64_t UserData;
+};
+
+struct FixedConstraintSettings {
+	[[superclass]] JPC_ConstraintSettings ConstraintSettings;
+
+	// TwoBodyConstraintSettings: no extra members
+
+	// FixedConstraintSettings
+	JPC_ConstraintSpace Space;
+	bool AutoDetectPoint;
+
+	JPC_RVec3 Point1;
+	JPC_Vec3 AxisX1;
+	JPC_Vec3 AxisY1;
+
+	JPC_RVec3 Point2;
+	JPC_Vec3 AxisX2;
+	JPC_Vec3 AxisY2;
 };