Implement generation of c header from rust interface, adapt qmlfrontend
authorunC0Rr
Tue, 15 Nov 2022 14:27:22 +0100
changeset 15893 5b3beb90e1a6
parent 15892 b3295f94e5e9
child 15894 ebc50f21e849
Implement generation of c header from rust interface, adapt qmlfrontend
qmlfrontend/engine_instance.cpp
qmlfrontend/engine_instance.h
qmlfrontend/engine_interface.h
rust/land2d/src/lib.rs
rust/lib-hedgewars-engine/Cargo.toml
rust/lib-hedgewars-engine/build.rs
rust/lib-hedgewars-engine/src/lib.rs
--- a/qmlfrontend/engine_instance.cpp	Sun Nov 13 08:45:10 2022 +0100
+++ b/qmlfrontend/engine_instance.cpp	Tue Nov 15 14:27:22 2022 +0100
@@ -6,11 +6,11 @@
 #include <QSurface>
 
 static QOpenGLContext* currentOpenglContext = nullptr;
-extern "C" void (*getProcAddress(const char* fn))() {
+extern "C" void* getProcAddress(const char* fn) {
   if (!currentOpenglContext)
     return nullptr;
   else
-    return currentOpenglContext->getProcAddress(fn);
+    return reinterpret_cast<void*>(currentOpenglContext->getProcAddress(fn));
 }
 
 EngineInstance::EngineInstance(const QString& libraryPath, const QString&dataPath, QObject* parent)
@@ -62,7 +62,9 @@
     qDebug() << "Loaded engine library with protocol version"
              << hedgewars_engine_protocol_version();
 
-    m_instance = std::unique_ptr<Engine::EngineInstance, Engine::cleanup_t*>(start_engine(dataPath.toUtf8().data()), cleanup);
+    m_instance = std::unique_ptr<Engine::EngineInstance, Engine::cleanup_t*>(
+        start_engine(reinterpret_cast<const int8_t*>(dataPath.toUtf8().data())),
+        cleanup);
   } else {
     qDebug("Engine library load failed");
   }
--- a/qmlfrontend/engine_instance.h	Sun Nov 13 08:45:10 2022 +0100
+++ b/qmlfrontend/engine_instance.h	Tue Nov 15 14:27:22 2022 +0100
@@ -4,6 +4,7 @@
 #include <QImage>
 #include <QObject>
 #include <QOpenGLContext>
+#include <memory>
 
 #include "engine_interface.h"
 #include "game_config.h"
--- a/qmlfrontend/engine_interface.h	Sun Nov 13 08:45:10 2022 +0100
+++ b/qmlfrontend/engine_interface.h	Tue Nov 15 14:27:22 2022 +0100
@@ -4,8 +4,7 @@
 #include <stddef.h>
 #include <stdint.h>
 
-#ifdef __cplusplus
-#define ENUM_CLASS enum
+#include "../rust/lib-hedgewars-engine/target/lib-hedgewars-engine.hpp"
 
 #ifndef Q_NAMESPACE
 #define Q_NAMESPACE
@@ -21,69 +20,35 @@
 
 namespace Engine {
 extern "C" {
-#else
-#define ENUM_CLASS enum class
-#endif
-
-typedef struct _EngineInstance EngineInstance;
-
-typedef struct {
-  uint32_t width;
-  uint32_t height;
-  uint8_t hedgehogs_number;
-  unsigned char* land;
-} PreviewInfo;
 
-typedef uint32_t hedgewars_engine_protocol_version_t();
-typedef EngineInstance* start_engine_t(const char* data_path);
-typedef void generate_preview_t(EngineInstance* engine_state,
-                                PreviewInfo* preview);
-typedef void dispose_preview_t(EngineInstance* engine_state);
-typedef void cleanup_t(EngineInstance* engine_state);
+using EngineInstance = hwengine::EngineInstance;
+using PreviewInfo = hwengine::PreviewInfo;
 
-typedef void send_ipc_t(EngineInstance* engine_state, uint8_t* buf,
-                        size_t size);
-typedef size_t read_ipc_t(EngineInstance* engine_state, uint8_t* buf,
-                          size_t size);
-
-typedef void setup_current_gl_context_t(EngineInstance* engine_state,
-                                        uint16_t width, uint16_t height,
-                                        void (*(const char*))());
-typedef void render_frame_t(EngineInstance* engine_state);
+using hedgewars_engine_protocol_version_t =
+    decltype(hwengine::hedgewars_engine_protocol_version);
 
-typedef bool advance_simulation_t(EngineInstance* engine_state, uint32_t ticks);
-
-typedef void move_camera_t(EngineInstance* engine_state, int32_t delta_x,
-                           int32_t delta_y);
-
-ENUM_CLASS SimpleEventType{
-    SwitchHedgehog, Timer, LongJump, HighJump, Accept, Deny,
-};
-
-ENUM_CLASS LongEventType{
-    ArrowUp, ArrowDown, ArrowLeft, ArrowRight, Precision, Attack,
-};
+using start_engine_t = decltype(hwengine::start_engine);
+using generate_preview_t = decltype(hwengine::generate_preview);
+using dispose_preview_t = decltype(hwengine::dispose_preview);
+using cleanup_t = decltype(hwengine::cleanup);
+using send_ipc_t = decltype(hwengine::send_ipc);
+using read_ipc_t = decltype(hwengine::read_ipc);
+using setup_current_gl_context_t = decltype(hwengine::setup_current_gl_context);
+using render_frame_t = decltype(hwengine::render_frame);
+using advance_simulation_t = decltype(hwengine::advance_simulation);
+using move_camera_t = decltype(hwengine::move_camera);
 
-ENUM_CLASS LongEventState{
-    Set,
-    Unset,
-};
+using simple_event_t = decltype(hwengine::simple_event);
+using long_event_t = decltype(hwengine::long_event);
+using positioned_event_t = decltype(hwengine::positioned_event);
 
-ENUM_CLASS PositionedEventType{
-    CursorMove,
-    CursorClick,
-};
+using SimpleEventType = hwengine::SimpleEventType;
+using LongEventType = hwengine::LongEventType;
+using LongEventState = hwengine::LongEventState;
+using PositionedEventType = hwengine::PositionedEventType;
 
-typedef void simple_event_t(EngineInstance* engine_state,
-                            SimpleEventType event_type);
-typedef void long_event_t(EngineInstance* engine_state,
-                          LongEventType event_type, LongEventState state);
-typedef void positioned_event_t(EngineInstance* engine_state,
-                                PositionedEventType event_type, int32_t x,
-                                int32_t y);
 }  // extern "C"
 
-#ifdef __cplusplus
 Q_NAMESPACE
 
 Q_ENUM_NS(SimpleEventType)
@@ -97,6 +62,5 @@
 Q_DECLARE_METATYPE(Engine::LongEventType)
 Q_DECLARE_METATYPE(Engine::LongEventState)
 Q_DECLARE_METATYPE(Engine::PositionedEventType)
-#endif
 
 #endif  // ENGINE_H
--- a/rust/land2d/src/lib.rs	Sun Nov 13 08:45:10 2022 +0100
+++ b/rust/land2d/src/lib.rs	Tue Nov 15 14:27:22 2022 +0100
@@ -140,7 +140,7 @@
             if mask.contains_y(yd as usize) {
                 stack.push((xl, xr, yd as usize, dir));
             }
-        };
+        }
 
         let start_x_l = (start_point.x - 1) as usize;
         let start_x_r = start_point.x as usize;
--- a/rust/lib-hedgewars-engine/Cargo.toml	Sun Nov 13 08:45:10 2022 +0100
+++ b/rust/lib-hedgewars-engine/Cargo.toml	Tue Nov 15 14:27:22 2022 +0100
@@ -2,7 +2,8 @@
 name = "lib-hedgewars-engine"
 version = "0.1.0"
 authors = ["Andrey Korotaev <a.korotaev@hedgewars.org>"]
-edition = "2018"
+edition = "2021"
+build = "build.rs"
 
 [dependencies]
 gl = "0.11"
@@ -23,6 +24,9 @@
 [dev-dependencies]
 proptest = "0.9.2"
 
+[build-dependencies]
+cbindgen = "0.24"
+
 [lib]
 name = "hedgewars_engine"
 crate-type = ["dylib"]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rust/lib-hedgewars-engine/build.rs	Tue Nov 15 14:27:22 2022 +0100
@@ -0,0 +1,32 @@
+extern crate cbindgen;
+
+use cbindgen::Config;
+use std::env;
+use std::path::PathBuf;
+
+fn main() {
+    let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
+
+    let package_name = env::var("CARGO_PKG_NAME").unwrap();
+    let output_file = target_dir()
+        .join(format!("{}.hpp", package_name))
+        .display()
+        .to_string();
+
+    let config = Config {
+        namespace: Some(String::from("hwengine")),
+        ..Default::default()
+    };
+
+    cbindgen::generate_with_config(&crate_dir, config)
+        .unwrap()
+        .write_to_file(&output_file);
+}
+
+fn target_dir() -> PathBuf {
+    if let Ok(target) = env::var("CARGO_TARGET_DIR") {
+        PathBuf::from(target)
+    } else {
+        PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("target")
+    }
+}
--- a/rust/lib-hedgewars-engine/src/lib.rs	Sun Nov 13 08:45:10 2022 +0100
+++ b/rust/lib-hedgewars-engine/src/lib.rs	Tue Nov 15 14:27:22 2022 +0100
@@ -113,7 +113,7 @@
 }
 
 #[no_mangle]
-pub extern "C" fn dispose_preview(engine_state: &mut EngineInstance, preview: &mut PreviewInfo) {
+pub extern "C" fn dispose_preview(engine_state: &mut EngineInstance) {
     (*engine_state).world.dispose_preview();
 }
 
@@ -142,7 +142,7 @@
     engine_state: &mut EngineInstance,
     width: u16,
     height: u16,
-    gl_loader: extern "C" fn(*const c_char) -> *const c_void,
+    gl_loader: extern "C" fn(*const c_char) -> *mut c_void,
 ) {
     gl::load_with(|name| {
         let c_name = CString::new(name).unwrap();
@@ -175,6 +175,6 @@
 #[no_mangle]
 pub extern "C" fn cleanup(engine_state: *mut EngineInstance) {
     unsafe {
-        Box::from_raw(engine_state);
+        drop(Box::from_raw(engine_state));
     }
 }