Implement external events approach to input user actions into engine.
authorunc0rr
Mon, 29 Apr 2019 23:41:25 +0200
changeset 14859 aed75d439027
parent 14858 b96ba3c1ab67
child 14860 6d95d314ae8b
Implement external events approach to input user actions into engine. Doesn't work for some obscure reason ("Error: Unknown method parameter type: LongEventType")
qmlfrontend/Page1.qml
qmlfrontend/engine_instance.cpp
qmlfrontend/engine_instance.h
qmlfrontend/engine_interface.h
qmlfrontend/main.cpp
rust/lib-hedgewars-engine/src/lib.rs
--- a/qmlfrontend/Page1.qml	Mon Apr 29 23:13:52 2019 +0200
+++ b/qmlfrontend/Page1.qml	Mon Apr 29 23:41:25 2019 +0200
@@ -2,7 +2,9 @@
 import Hedgewars.Engine 1.0
 
 Page1Form {
-  property var hwEngine
+  focus: true
+
+  property HWEngine hwEngine
 
   Component {
     id: hwEngineComponent
@@ -19,14 +21,35 @@
     hwEngine = hwEngineComponent.createObject()
   }
 
-  tickButton.onClicked: {
-    gameView.tick(100)
+  tickButton {
+    onClicked: {
+      tickButton.visible = false
+      gameView.tick(100)
+    }
+  }
+  gameButton {
+    visible: !gameView.engineInstance
+    onClicked: {
+      var engineInstance = hwEngine.runQuickGame()
+      gameView.engineInstance = engineInstance
+    }
   }
-  gameButton.onClicked: {
-    var engineInstance = hwEngine.runQuickGame()
-    gameView.engineInstance = engineInstance
+  button1 {
+    visible: !gameView.engineInstance
+    onClicked: {
+      hwEngine.getPreview()
+    }
   }
-  button1.onClicked: {
-    hwEngine.getPreview()
+
+  Keys.onPressed: {
+    if (event.key === Qt.Key_Enter)
+      gameView.engineInstance.longEvent(EngineInstance.Attack,
+                                        EngineInstance.Set)
+  }
+
+  Keys.onReleased: {
+    if (event.key === Qt.Key_Enter)
+      gameView.engineInstance.longEvent(EngineInstance.Attack,
+                                        EngineInstance.Unset)
   }
 }
--- a/qmlfrontend/engine_instance.cpp	Mon Apr 29 23:13:52 2019 +0200
+++ b/qmlfrontend/engine_instance.cpp	Mon Apr 29 23:41:25 2019 +0200
@@ -43,11 +43,19 @@
       hwlib.resolve("advance_simulation"));
   move_camera =
       reinterpret_cast<Engine::move_camera_t*>(hwlib.resolve("move_camera"));
+  simple_event =
+      reinterpret_cast<Engine::simple_event_t*>(hwlib.resolve("simple_event"));
+  long_event =
+      reinterpret_cast<Engine::long_event_t*>(hwlib.resolve("long_event"));
+  positioned_event = reinterpret_cast<Engine::positioned_event_t*>(
+      hwlib.resolve("positioned_event"));
 
   m_isValid = hedgewars_engine_protocol_version && start_engine &&
               generate_preview && dispose_preview && cleanup && send_ipc &&
               read_ipc && setup_current_gl_context && render_frame &&
-              advance_simulation && move_camera;
+              advance_simulation && move_camera && simple_event && long_event &&
+              positioned_event;
+
   emit isValidChanged(m_isValid);
 
   if (isValid()) {
@@ -79,6 +87,19 @@
   move_camera(m_instance, delta.x(), delta.y());
 }
 
+void EngineInstance::simpleEvent(SimpleEventType event_type) {
+  simple_event(m_instance, event_type);
+}
+
+void EngineInstance::longEvent(LongEventType event_type, LongEventState state) {
+  long_event(m_instance, event_type, state);
+}
+
+void EngineInstance::positionedEvent(PositionedEventType event_type, qint32 x,
+                                     qint32 y) {
+  positioned_event(m_instance, event_type, x, y);
+}
+
 void EngineInstance::renderFrame() { render_frame(m_instance); }
 
 void EngineInstance::setOpenGLContext(QOpenGLContext* context) {
--- a/qmlfrontend/engine_instance.h	Mon Apr 29 23:13:52 2019 +0200
+++ b/qmlfrontend/engine_instance.h	Mon Apr 29 23:41:25 2019 +0200
@@ -10,7 +10,17 @@
 
 class EngineInstance : public QObject {
   Q_OBJECT
+
  public:
+  using SimpleEventType = Engine::SimpleEventType;
+  Q_ENUMS(SimpleEventType)
+  using LongEventType = Engine::LongEventType;
+  Q_ENUMS(LongEventType)
+  using LongEventState = Engine::LongEventState;
+  Q_ENUMS(LongEventState)
+  using PositionedEventType = Engine::PositionedEventType;
+  Q_ENUMS(PositionedEventType)
+
   explicit EngineInstance(const QString& libraryPath,
                           QObject* parent = nullptr);
   ~EngineInstance();
@@ -30,7 +40,9 @@
  public slots:
   void advance(quint32 ticks);
   void moveCamera(const QPoint& delta);
-  void controlEvent(bool isStart, int type);
+  void simpleEvent(SimpleEventType event_type);
+  void longEvent(LongEventType event_type, LongEventState state);
+  void positionedEvent(PositionedEventType event_type, qint32 x, qint32 y);
 
  private:
   Engine::EngineInstance* m_instance;
@@ -47,7 +59,15 @@
   Engine::render_frame_t* render_frame;
   Engine::advance_simulation_t* advance_simulation;
   Engine::move_camera_t* move_camera;
+  Engine::simple_event_t* simple_event;
+  Engine::long_event_t* long_event;
+  Engine::positioned_event_t* positioned_event;
   bool m_isValid;
 };
 
+Q_DECLARE_METATYPE(EngineInstance::SimpleEventType)
+Q_DECLARE_METATYPE(EngineInstance::LongEventType)
+Q_DECLARE_METATYPE(EngineInstance::LongEventState)
+Q_DECLARE_METATYPE(EngineInstance::PositionedEventType)
+
 #endif  // ENGINEINSTANCE_H
--- a/qmlfrontend/engine_interface.h	Mon Apr 29 23:13:52 2019 +0200
+++ b/qmlfrontend/engine_interface.h	Mon Apr 29 23:41:25 2019 +0200
@@ -5,8 +5,11 @@
 #include <stdint.h>
 
 #ifdef __cplusplus
+#define ENUM_CLASS enum
 namespace Engine {
 extern "C" {
+#else
+#define ENUM_CLASS enum
 #endif
 
 typedef struct _EngineInstance EngineInstance;
@@ -40,6 +43,31 @@
 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,
+};
+
+ENUM_CLASS LongEventState{
+    Set,
+    Unset,
+};
+
+ENUM_CLASS PositionedEventType{
+    CursorMove,
+    CursorClick,
+};
+
+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);
 #ifdef __cplusplus
 }
 };
--- a/qmlfrontend/main.cpp	Mon Apr 29 23:13:52 2019 +0200
+++ b/qmlfrontend/main.cpp	Mon Apr 29 23:41:25 2019 +0200
@@ -8,8 +8,6 @@
 #include "hwengine.h"
 #include "preview_acceptor.h"
 
-namespace Engine {};  // namespace Engine
-
 static QObject* previewacceptor_singletontype_provider(
     QQmlEngine* engine, QJSEngine* scriptEngine) {
   Q_UNUSED(scriptEngine)
@@ -24,6 +22,11 @@
 
   QQmlApplicationEngine engine;
 
+  qRegisterMetaType<EngineInstance::SimpleEventType>();
+  qRegisterMetaType<EngineInstance::LongEventType>();
+  qRegisterMetaType<EngineInstance::LongEventState>();
+  qRegisterMetaType<EngineInstance::PositionedEventType>();
+
   qmlRegisterSingletonType<PreviewAcceptor>(
       "Hedgewars.Engine", 1, 0, "PreviewAcceptor",
       previewacceptor_singletontype_provider);
--- a/rust/lib-hedgewars-engine/src/lib.rs	Mon Apr 29 23:13:52 2019 +0200
+++ b/rust/lib-hedgewars-engine/src/lib.rs	Mon Apr 29 23:41:25 2019 +0200
@@ -23,6 +23,64 @@
     land: *const u8,
 }
 
+#[repr(C)]
+#[derive(Debug, PartialEq, Clone)]
+pub enum SimpleEventType {
+    SwitchHedgehog,
+    Timer,
+    LongJump,
+    HighJump,
+    Accept,
+    Deny,
+}
+
+#[repr(C)]
+#[derive(Debug, PartialEq, Clone)]
+pub enum LongEventType {
+    ArrowUp,
+    ArrowDown,
+    ArrowLeft,
+    ArrowRight,
+    Precision,
+    Attack,
+}
+
+#[repr(C)]
+#[derive(Debug, PartialEq, Clone)]
+pub enum LongEventState {
+    Set,
+    Unset,
+}
+
+#[repr(C)]
+#[derive(Debug, PartialEq, Clone)]
+pub enum PositionedEventType {
+    CursorMove,
+    CursorClick,
+}
+
+#[no_mangle]
+pub extern "C" fn simple_event(engine_state: &mut EngineInstance, event_type: SimpleEventType) {}
+
+#[no_mangle]
+pub extern "C" fn long_event(
+    engine_state: &mut EngineInstance,
+    event_type: LongEventType,
+    state: LongEventState,
+) {
+    println!("{:?}: {:?}", event_type, state);
+}
+
+#[no_mangle]
+pub extern "C" fn positioned_event(
+    engine_state: &mut EngineInstance,
+    event_type: PositionedEventType,
+    x: i32,
+    y: i32,
+) {
+
+}
+
 #[no_mangle]
 pub extern "C" fn hedgewars_engine_protocol_version() -> u32 {
     58