commit cfe5c0e2be36019797efbd299763400d7578de7f
parent 598fcfb0fde56ff6e309ae46fe7a156affd82dd0
Author: Sebastiano Tronto <sebastiano@tronto.net>
Date: Sun, 18 Jun 2023 14:53:27 +0200
MVE for nissy ffi flutter bindings
Diffstat:
11 files changed, 226 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,5 +1,6 @@
buildtables
-nissy_flutter
nissy
+nissy_flutter
+nissy_flutter_ffi
tables
tables-old
diff --git a/Makefile b/Makefile
@@ -18,11 +18,18 @@ CC = clang
all: nissy
clean:
- rm -rf nissy
+ rm -rf nissy nissy_flutter nissy_flutter_ffi
nissy: clean
flutter create nissy_flutter
+ flutter create --template=plugin_ffi \
+ --platforms=linux,android,windows,macos,ios nissy_flutter_ffi
cp -R flutter/* nissy_flutter/
+ rm -rf nissy_flutter_ffi/src
+ cp -R flutter_ffi/* nissy_flutter_ffi/
+ cp src/* nissy_flutter_ffi/src/
+ cd nissy_flutter_ffi && \
+ flutter pub run ffigen --config ffigen.yaml
debug:
${CC} ${DBFLAGS} -o nissy cli/*.c src/*.c
diff --git a/TODO.md b/TODO.md
@@ -1,4 +1,4 @@
-* Figure out FFI
+* Figure out FFI: long-running stuff with await?
* Read data file from flutter and pass it to C backend
* show EOs in gui (for example scramble)
* input text box for scramble, get EOs for that
diff --git a/flutter_ffi/example/lib/main.dart b/flutter_ffi/example/lib/main.dart
@@ -0,0 +1,55 @@
+import 'package:flutter/material.dart';
+
+import 'package:nissy_flutter_ffi/nissy_flutter_ffi.dart' as nissy_flutter_ffi;
+
+void main() {
+ runApp(const MyApp());
+}
+
+class MyApp extends StatefulWidget {
+ const MyApp({super.key});
+
+ @override
+ State<MyApp> createState() => _MyAppState();
+}
+
+class _MyAppState extends State<MyApp> {
+ @override
+ final response = nissy_flutter_ffi.nissy_test();
+ void initState() {
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ const textStyle = TextStyle(fontSize: 25);
+ const spacerSmall = SizedBox(height: 10);
+ return MaterialApp(
+ home: Scaffold(
+ appBar: AppBar(
+ title: const Text('Nissy ffi test run'),
+ ),
+ body: SingleChildScrollView(
+ child: Container(
+ padding: const EdgeInsets.all(10),
+ child: Column(
+ children: [
+ const Text(
+ 'Calling a nissy function from nissy.h',
+ style: textStyle,
+ textAlign: TextAlign.center,
+ ),
+ spacerSmall,
+ Text(
+ 'Response: $response',
+ style: textStyle,
+ textAlign: TextAlign.center,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/flutter_ffi/example/pubspec.yaml b/flutter_ffi/example/pubspec.yaml
@@ -0,0 +1,28 @@
+name: nissy_flutter_ffi_example
+description: Demonstrates how to use the nissy_flutter_ffi plugin.
+publish_to: 'none' # Remove this line if you wish to publish to pub.dev
+
+version: 1.0.0+1
+
+environment:
+ sdk: '>=3.0.5 <4.0.0'
+
+dependencies:
+ flutter:
+ sdk: flutter
+
+ nissy_flutter_ffi:
+ path: ../
+
+ ffi: ^1.0.0
+
+ cupertino_icons: ^1.0.2
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+
+ flutter_lints: ^2.0.0
+
+flutter:
+ uses-material-design: true
diff --git a/flutter_ffi/ffigen.yaml b/flutter_ffi/ffigen.yaml
@@ -0,0 +1,19 @@
+# Run with `flutter pub run ffigen --config ffigen.yaml`.
+name: NissyFlutterFfiBindings
+description: |
+ Bindings for `src/nissy.h`.
+
+ Regenerate bindings with `flutter pub run ffigen --config ffigen.yaml`.
+output: 'lib/nissy_flutter_ffi_bindings_generated.dart'
+headers:
+ entry-points:
+ - 'src/nissy.h'
+ include-directives:
+ - 'src/nissy.h'
+preamble: |
+ // ignore_for_file: always_specify_types
+ // ignore_for_file: camel_case_types
+ // ignore_for_file: non_constant_identifier_names
+comments:
+ style: any
+ length: full
diff --git a/flutter_ffi/lib/nissy_flutter_ffi.dart b/flutter_ffi/lib/nissy_flutter_ffi.dart
@@ -0,0 +1,36 @@
+import 'dart:async';
+import 'dart:ffi';
+import 'dart:io';
+import 'dart:isolate';
+
+import 'package:ffi/ffi.dart';
+import 'nissy_flutter_ffi_bindings_generated.dart';
+
+String ptrCharToString(Pointer<Char> ptr) => ptr.cast<Utf8>().toDartString();
+
+String nissy_test() {
+ final ptr = calloc<Char>(50);
+ _bindings.nissy_test(ptr);
+ final str = ptrCharToString(ptr);
+ calloc.free(ptr);
+ return str;
+}
+
+const String _libName = 'nissy_flutter_ffi';
+
+/// The dynamic library in which the symbols for [NissyFlutterFfiBindings] can be found.
+final DynamicLibrary _dylib = () {
+ if (Platform.isMacOS || Platform.isIOS) {
+ return DynamicLibrary.open('$_libName.framework/$_libName');
+ }
+ if (Platform.isAndroid || Platform.isLinux) {
+ return DynamicLibrary.open('lib$_libName.so');
+ }
+ if (Platform.isWindows) {
+ return DynamicLibrary.open('$_libName.dll');
+ }
+ throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}');
+}();
+
+/// The bindings to the native functions in [_dylib].
+final NissyFlutterFfiBindings _bindings = NissyFlutterFfiBindings(_dylib);
diff --git a/flutter_ffi/pubspec.yaml b/flutter_ffi/pubspec.yaml
@@ -0,0 +1,44 @@
+name: nissy_flutter_ffi
+description: Flutter FFI bindings for nissy
+version: 1.0.0
+
+environment:
+ sdk: '>=3.0.5 <4.0.0'
+ flutter: ">=3.3.0"
+
+dependencies:
+ flutter:
+ sdk: flutter
+ plugin_platform_interface: ^2.0.2
+
+dev_dependencies:
+ ffi: ^2.0.1
+ ffigen: ^8.0.2
+ flutter_test:
+ sdk: flutter
+ flutter_lints: ^2.0.0
+
+flutter:
+ plugin:
+ platforms:
+ android:
+ ffiPlugin: true
+ ios:
+ ffiPlugin: true
+ linux:
+ ffiPlugin: true
+ macos:
+ ffiPlugin: true
+ windows:
+ ffiPlugin: true
+
+ # To add assets to your plugin package, add an assets section, like this:
+ # assets:
+ # - images/a_dot_burr.jpeg
+ # - images/a_dot_ham.jpeg
+ #
+ # For details regarding assets in packages, see
+ # https://flutter.dev/assets-and-images/#from-packages
+ #
+ # An image asset can refer to one or more resolution-specific "variants", see
+ # https://flutter.dev/assets-and-images/#resolution-aware
diff --git a/flutter_ffi/src/CMakeLists.txt b/flutter_ffi/src/CMakeLists.txt
@@ -0,0 +1,23 @@
+# The Flutter tooling requires that developers have CMake 3.10 or later
+# installed. You should not increase this version, as doing so will cause
+# the plugin to fail to compile for some customers of the plugin.
+cmake_minimum_required(VERSION 3.10)
+
+project(nissy_flutter_ffi_library VERSION 1.0.0 LANGUAGES C)
+
+add_library(nissy_flutter_ffi SHARED
+ coord.c coord.h cube.c cube.h nissy.c solve.c solve.h steps.c steps.h
+)
+
+set_target_properties(nissy_flutter_ffi PROPERTIES
+ PUBLIC_HEADER nissy.h
+ OUTPUT_NAME "nissy_flutter_ffi"
+)
+
+if (WIN32)
+set_target_properties(ffigen_app PROPERTIES
+ WINDOWS_EXPORT_ALL_SYMBOLS ON
+)
+endif (WIN32)
+
+target_compile_definitions(nissy_flutter_ffi PUBLIC DART_SHARED_LIB)
diff --git a/src/nissy.c b/src/nissy.c
@@ -93,3 +93,9 @@ nissy_solve(char *step, char *trans, int d, char *type, char *scramble, char *so
return solve(s, t, d, st, &c, sol);
}
+
+void
+nissy_test(char *response)
+{
+ strcpy(response, "nissy is running");
+}
diff --git a/src/nissy.h b/src/nissy.h
@@ -1,7 +1,11 @@
/* TODO: find a better way to define this */
#define TABLESFILESIZE 150000000 /* 150Mb */
+/* Initialize nissy, to be called on startup */
void nissy_init(char *);
+/* Test that nissy is responsive */
+void nissy_test(char *);
+
/* Returns 0 on success, 1-based index of bad arg on failure */
int nissy_solve(char *s, char *trans, int d, char *type, char *scr, char *sol);