From 7738a36bcfccee768e7bd657b5ac34f87f4b04d1 Mon Sep 17 00:00:00 2001
From: Alnitak <lil.deimos@gmail.com>
Date: Mon, 3 Jun 2024 19:07:56 +0200
Subject: [PATCH] fix free pointer on Win. Test ok

---
 .vscode/launch.json                    |  4 ++--
 example/pubspec.lock                   |  6 +++---
 example/windows/flutter/CMakeLists.txt |  7 ++++++-
 lib/src/bindings_player_ffi.dart       | 28 ++++++++++++++++++++------
 src/bindings.cpp                       |  4 ++++
 src/ffi_gen_tmp.h                      |  2 ++
 6 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/.vscode/launch.json b/.vscode/launch.json
index ff6e6132..8e76531b 100755
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -42,7 +42,7 @@
             "type": "cppvsdbg",
             "request": "launch",
             "args": [],
-            "program": "${workspaceFolder}/example/build/windows/runner/Debug/flutter_soloud_example.exe",
+            "program": "${workspaceFolder}/example/build/windows/x64/runner/Debug/flutter_soloud_example.exe",
             "cwd": "${workspaceFolder}"
         },
         {
@@ -51,7 +51,7 @@
             "type": "cppvsdbg",
             "request": "launch",
             "args": [],
-            "program": "${workspaceFolder}/example/build/windows/runner/Debug/flutter_soloud_example.exe",
+            "program": "${workspaceFolder}/example/build/windows/x64//runner/Debug/flutter_soloud_example.exe",
             "cwd": "${workspaceFolder}"
         },
         {
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 8aa2b73d..5ca483a0 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -392,10 +392,10 @@ packages:
     dependency: transitive
     description:
       name: win32
-      sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4
+      sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
       url: "https://pub.dev"
     source: hosted
-    version: "5.5.1"
+    version: "5.5.0"
   xdg_directories:
     dependency: transitive
     description:
@@ -405,5 +405,5 @@ packages:
     source: hosted
     version: "1.0.4"
 sdks:
-  dart: ">=3.4.0 <4.0.0"
+  dart: ">=3.3.0 <4.0.0"
   flutter: ">=3.18.0-18.0.pre.54"
diff --git a/example/windows/flutter/CMakeLists.txt b/example/windows/flutter/CMakeLists.txt
index 930d2071..903f4899 100755
--- a/example/windows/flutter/CMakeLists.txt
+++ b/example/windows/flutter/CMakeLists.txt
@@ -10,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake)
 # https://github.com/flutter/flutter/issues/57146.
 set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
 
+# Set fallback configurations for older versions of the flutter tool.
+if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
+  set(FLUTTER_TARGET_PLATFORM "windows-x64")
+endif()
+
 # === Flutter Library ===
 set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
 
@@ -92,7 +97,7 @@ add_custom_command(
   COMMAND ${CMAKE_COMMAND} -E env
     ${FLUTTER_TOOL_ENVIRONMENT}
     "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
-      windows-x64 $<CONFIG>
+      ${FLUTTER_TARGET_PLATFORM} $<CONFIG>
   VERBATIM
 )
 add_custom_target(flutter_assemble DEPENDS
diff --git a/lib/src/bindings_player_ffi.dart b/lib/src/bindings_player_ffi.dart
index 74cb20b6..afdf1f22 100644
--- a/lib/src/bindings_player_ffi.dart
+++ b/lib/src/bindings_player_ffi.dart
@@ -80,6 +80,16 @@ class FlutterSoLoudFfi {
   ///////////////////////////////////////////////////////////////////////////
   ///////////////////////////////////////////////////////////////////////////
 
+  void nativeFree(ffi.Pointer<ffi.Void> pointer) {
+    return _nativeFree(pointer);
+  }
+
+  late final _nativeFreePtr =
+      _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
+          'nativeFree');
+  late final _nativeFree =
+      _nativeFreePtr.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
+
   /// Controller to listen to voice ended events.
   late final StreamController<int> voiceEndedEventController =
       StreamController.broadcast();
@@ -91,7 +101,10 @@ class FlutterSoLoudFfi {
   void _voiceEndedCallback(ffi.Pointer<ffi.UnsignedInt> handle) {
     _log.fine(() => 'VOICE ENDED EVENT handle: ${handle.value}');
     voiceEndedEventController.add(handle.value);
-    calloc.free(handle);
+        // Must free a pointer made on cpp. On Windows this must be freed
+    // there and cannot use `calloc.free(...)`
+    nativeFree(handle.cast<ffi.Void>());
+
   }
 
   /// Controller to listen to file loaded events.
@@ -117,10 +130,11 @@ class FlutterSoLoudFfi {
       'hash': hash.value,
     };
     fileLoadedEventsController.add(result);
-    calloc
-      ..free(error)
-      ..free(completeFileName)
-      ..free(hash);
+    // Must free a pointer made on cpp. On Windows this must be freed
+    // there and cannot use `calloc.free(...)`
+    nativeFree(error.cast<ffi.Void>());
+    nativeFree(completeFileName.cast<ffi.Void>());
+    nativeFree(hash.cast<ffi.Void>());
   }
 
   /// Controller to listen to voice ended events.
@@ -133,9 +147,11 @@ class FlutterSoLoudFfi {
 
   void _stateChangedCallback(ffi.Pointer<ffi.Int32> state) {
     final s = PlayerStateNotification.values[state.value];
+    // Must free a pointer made on cpp. On Windows this must be freed
+    // there and cannot use `calloc.free(state)`
+    nativeFree(state.cast<ffi.Void>());
     _log.fine(() => 'STATE CHANGED EVENT state: $s');
     stateChangedController.add(s);
-    calloc.free(state);
   }
 
   /// Set a Dart function to call when a sound ends.
diff --git a/src/bindings.cpp b/src/bindings.cpp
index 68ef5b8b..e2ea9624 100644
--- a/src/bindings.cpp
+++ b/src/bindings.cpp
@@ -31,6 +31,10 @@ extern "C"
     void (*dartFileLoadedCallback)(enum PlayerErrors *, char *completeFileName, unsigned int *) = nullptr;
     void (*dartStateChangedCallback)(enum PlayerStateEvents *) = nullptr;
 
+    FFI_PLUGIN_EXPORT void nativeFree(void *pointer) {
+        free(pointer);
+    }
+    
     /// The callback to monitor when a voice ends.
     ///
     /// It is called by void `Soloud::stopVoice_internal(unsigned int aVoice)` when a voice ends.
diff --git a/src/ffi_gen_tmp.h b/src/ffi_gen_tmp.h
index a7fa5939..ae0a34f0 100644
--- a/src/ffi_gen_tmp.h
+++ b/src/ffi_gen_tmp.h
@@ -34,3 +34,5 @@ FFI_PLUGIN_EXPORT void setDartEventCallback(
         dartVoiceEndedCallback_t voice_ended_callback,
         dartFileLoadedCallback_t file_loaded_callback,
         dartStateChangedCallback_t state_changed_callback);
+
+FFI_PLUGIN_EXPORT void nativeFree(void *pointer);
\ No newline at end of file