linux flutter example with bridge to rust and build system
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'dart:async';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:flutter/services.dart';
 | 
			
		||||
import 'package:veilid/veilid.dart';
 | 
			
		||||
 | 
			
		||||
@@ -16,7 +16,7 @@ class MyApp extends StatefulWidget {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _MyAppState extends State<MyApp> {
 | 
			
		||||
  String _platformVersion = 'Unknown';
 | 
			
		||||
  String _veilidVersion = 'Unknown';
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
@@ -26,14 +26,13 @@ class _MyAppState extends State<MyApp> {
 | 
			
		||||
 | 
			
		||||
  // Platform messages are asynchronous, so we initialize in an async method.
 | 
			
		||||
  Future<void> initPlatformState() async {
 | 
			
		||||
    String platformVersion;
 | 
			
		||||
    String veilidVersion;
 | 
			
		||||
    // Platform messages may fail, so we use a try/catch PlatformException.
 | 
			
		||||
    // We also handle the message potentially returning null.
 | 
			
		||||
    try {
 | 
			
		||||
      platformVersion =
 | 
			
		||||
          await Veilid.platformVersion ?? 'Unknown platform version';
 | 
			
		||||
      veilidVersion = await Veilid.api.veilidVersionString();
 | 
			
		||||
    } on PlatformException {
 | 
			
		||||
      platformVersion = 'Failed to get platform version.';
 | 
			
		||||
      veilidVersion = 'Failed to get veilid version.';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If the widget was removed from the tree while the asynchronous platform
 | 
			
		||||
@@ -42,7 +41,7 @@ class _MyAppState extends State<MyApp> {
 | 
			
		||||
    if (!mounted) return;
 | 
			
		||||
 | 
			
		||||
    setState(() {
 | 
			
		||||
      _platformVersion = platformVersion;
 | 
			
		||||
      _veilidVersion = veilidVersion;
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -51,10 +50,10 @@ class _MyAppState extends State<MyApp> {
 | 
			
		||||
    return MaterialApp(
 | 
			
		||||
      home: Scaffold(
 | 
			
		||||
        appBar: AppBar(
 | 
			
		||||
          title: const Text('Plugin example app'),
 | 
			
		||||
          title: const Text('Veilid Plugin Example App'),
 | 
			
		||||
        ),
 | 
			
		||||
        body: Center(
 | 
			
		||||
          child: Text('Running on: $_platformVersion\n'),
 | 
			
		||||
          child: Text('Veilid version: $_veilidVersion\n'),
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								veilid-flutter/ios/Classes/Bridging-Header.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								veilid-flutter/ios/Classes/Bridging-Header.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
#import "GeneratedPluginRegistrant.h"
 | 
			
		||||
#import "bridge_generated.h"
 | 
			
		||||
@@ -3,12 +3,12 @@ import UIKit
 | 
			
		||||
 | 
			
		||||
public class SwiftVeilidPlugin: NSObject, FlutterPlugin {
 | 
			
		||||
  public static func register(with registrar: FlutterPluginRegistrar) {
 | 
			
		||||
    let channel = FlutterMethodChannel(name: "veilid", binaryMessenger: registrar.messenger())
 | 
			
		||||
    let instance = SwiftVeilidPlugin()
 | 
			
		||||
    registrar.addMethodCallDelegate(instance, channel: channel)
 | 
			
		||||
    // No channel, FFI plugin
 | 
			
		||||
    print("dummy_value=\(dummy_method_to_enforce_bundling())");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
 | 
			
		||||
    result("iOS " + UIDevice.current.systemVersion)
 | 
			
		||||
    // Noop
 | 
			
		||||
    result(nil)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@ typedef struct wire_StringList {
 | 
			
		||||
 | 
			
		||||
typedef struct wire_VeilidConfig {
 | 
			
		||||
  struct wire_uint_8_list *program_name;
 | 
			
		||||
  struct wire_uint_8_list *namespace_;
 | 
			
		||||
  struct wire_uint_8_list *veilid_namespace;
 | 
			
		||||
  bool capabilities__protocol_udp;
 | 
			
		||||
  bool capabilities__protocol_connect_tcp;
 | 
			
		||||
  bool capabilities__protocol_accept_tcp;
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ enum AttachmentState {
 | 
			
		||||
 | 
			
		||||
class VeilidConfig {
 | 
			
		||||
  final String programName;
 | 
			
		||||
  final String namespace;
 | 
			
		||||
  final String veilidNamespace;
 | 
			
		||||
  final bool capabilitiesProtocolUdp;
 | 
			
		||||
  final bool capabilitiesProtocolConnectTcp;
 | 
			
		||||
  final bool capabilitiesProtocolAcceptTcp;
 | 
			
		||||
@@ -108,7 +108,7 @@ class VeilidConfig {
 | 
			
		||||
 | 
			
		||||
  VeilidConfig({
 | 
			
		||||
    required this.programName,
 | 
			
		||||
    required this.namespace,
 | 
			
		||||
    required this.veilidNamespace,
 | 
			
		||||
    required this.capabilitiesProtocolUdp,
 | 
			
		||||
    required this.capabilitiesProtocolConnectTcp,
 | 
			
		||||
    required this.capabilitiesProtocolAcceptTcp,
 | 
			
		||||
@@ -332,7 +332,7 @@ class VeilidFlutterImpl extends FlutterRustBridgeBase<VeilidFlutterWire>
 | 
			
		||||
  void _api_fill_to_wire_veilid_config(
 | 
			
		||||
      VeilidConfig apiObj, wire_VeilidConfig wireObj) {
 | 
			
		||||
    wireObj.program_name = _api2wire_String(apiObj.programName);
 | 
			
		||||
    wireObj.namespace = _api2wire_String(apiObj.namespace);
 | 
			
		||||
    wireObj.veilid_namespace = _api2wire_String(apiObj.veilidNamespace);
 | 
			
		||||
    wireObj.capabilities__protocol_udp =
 | 
			
		||||
        _api2wire_bool(apiObj.capabilitiesProtocolUdp);
 | 
			
		||||
    wireObj.capabilities__protocol_connect_tcp =
 | 
			
		||||
@@ -708,7 +708,7 @@ class wire_StringList extends ffi.Struct {
 | 
			
		||||
class wire_VeilidConfig extends ffi.Struct {
 | 
			
		||||
  external ffi.Pointer<wire_uint_8_list> program_name;
 | 
			
		||||
 | 
			
		||||
  external ffi.Pointer<wire_uint_8_list> namespace_;
 | 
			
		||||
  external ffi.Pointer<wire_uint_8_list> veilid_namespace;
 | 
			
		||||
 | 
			
		||||
  @ffi.Uint8()
 | 
			
		||||
  external int capabilities__protocol_udp;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										230
									
								
								veilid-flutter/lib/bridge_generated.freezed.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								veilid-flutter/lib/bridge_generated.freezed.dart
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,230 @@
 | 
			
		||||
// coverage:ignore-file
 | 
			
		||||
// GENERATED CODE - DO NOT MODIFY BY HAND
 | 
			
		||||
// ignore_for_file: type=lint
 | 
			
		||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target
 | 
			
		||||
 | 
			
		||||
part of 'bridge_generated.dart';
 | 
			
		||||
 | 
			
		||||
// **************************************************************************
 | 
			
		||||
// FreezedGenerator
 | 
			
		||||
// **************************************************************************
 | 
			
		||||
 | 
			
		||||
T _$identity<T>(T value) => value;
 | 
			
		||||
 | 
			
		||||
final _privateConstructorUsedError = UnsupportedError(
 | 
			
		||||
    'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more informations: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
 | 
			
		||||
 | 
			
		||||
/// @nodoc
 | 
			
		||||
class _$VeilidUpdateTearOff {
 | 
			
		||||
  const _$VeilidUpdateTearOff();
 | 
			
		||||
 | 
			
		||||
  Attachment attachment(AttachmentState field0) {
 | 
			
		||||
    return Attachment(
 | 
			
		||||
      field0,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @nodoc
 | 
			
		||||
const $VeilidUpdate = _$VeilidUpdateTearOff();
 | 
			
		||||
 | 
			
		||||
/// @nodoc
 | 
			
		||||
mixin _$VeilidUpdate {
 | 
			
		||||
  AttachmentState get field0 => throw _privateConstructorUsedError;
 | 
			
		||||
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult when<TResult extends Object?>({
 | 
			
		||||
    required TResult Function(AttachmentState field0) attachment,
 | 
			
		||||
  }) =>
 | 
			
		||||
      throw _privateConstructorUsedError;
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult? whenOrNull<TResult extends Object?>({
 | 
			
		||||
    TResult Function(AttachmentState field0)? attachment,
 | 
			
		||||
  }) =>
 | 
			
		||||
      throw _privateConstructorUsedError;
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult maybeWhen<TResult extends Object?>({
 | 
			
		||||
    TResult Function(AttachmentState field0)? attachment,
 | 
			
		||||
    required TResult orElse(),
 | 
			
		||||
  }) =>
 | 
			
		||||
      throw _privateConstructorUsedError;
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult map<TResult extends Object?>({
 | 
			
		||||
    required TResult Function(Attachment value) attachment,
 | 
			
		||||
  }) =>
 | 
			
		||||
      throw _privateConstructorUsedError;
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult? mapOrNull<TResult extends Object?>({
 | 
			
		||||
    TResult Function(Attachment value)? attachment,
 | 
			
		||||
  }) =>
 | 
			
		||||
      throw _privateConstructorUsedError;
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult maybeMap<TResult extends Object?>({
 | 
			
		||||
    TResult Function(Attachment value)? attachment,
 | 
			
		||||
    required TResult orElse(),
 | 
			
		||||
  }) =>
 | 
			
		||||
      throw _privateConstructorUsedError;
 | 
			
		||||
 | 
			
		||||
  @JsonKey(ignore: true)
 | 
			
		||||
  $VeilidUpdateCopyWith<VeilidUpdate> get copyWith =>
 | 
			
		||||
      throw _privateConstructorUsedError;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @nodoc
 | 
			
		||||
abstract class $VeilidUpdateCopyWith<$Res> {
 | 
			
		||||
  factory $VeilidUpdateCopyWith(
 | 
			
		||||
          VeilidUpdate value, $Res Function(VeilidUpdate) then) =
 | 
			
		||||
      _$VeilidUpdateCopyWithImpl<$Res>;
 | 
			
		||||
  $Res call({AttachmentState field0});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @nodoc
 | 
			
		||||
class _$VeilidUpdateCopyWithImpl<$Res> implements $VeilidUpdateCopyWith<$Res> {
 | 
			
		||||
  _$VeilidUpdateCopyWithImpl(this._value, this._then);
 | 
			
		||||
 | 
			
		||||
  final VeilidUpdate _value;
 | 
			
		||||
  // ignore: unused_field
 | 
			
		||||
  final $Res Function(VeilidUpdate) _then;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  $Res call({
 | 
			
		||||
    Object? field0 = freezed,
 | 
			
		||||
  }) {
 | 
			
		||||
    return _then(_value.copyWith(
 | 
			
		||||
      field0: field0 == freezed
 | 
			
		||||
          ? _value.field0
 | 
			
		||||
          : field0 // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
              as AttachmentState,
 | 
			
		||||
    ));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @nodoc
 | 
			
		||||
abstract class $AttachmentCopyWith<$Res>
 | 
			
		||||
    implements $VeilidUpdateCopyWith<$Res> {
 | 
			
		||||
  factory $AttachmentCopyWith(
 | 
			
		||||
          Attachment value, $Res Function(Attachment) then) =
 | 
			
		||||
      _$AttachmentCopyWithImpl<$Res>;
 | 
			
		||||
  @override
 | 
			
		||||
  $Res call({AttachmentState field0});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @nodoc
 | 
			
		||||
class _$AttachmentCopyWithImpl<$Res> extends _$VeilidUpdateCopyWithImpl<$Res>
 | 
			
		||||
    implements $AttachmentCopyWith<$Res> {
 | 
			
		||||
  _$AttachmentCopyWithImpl(Attachment _value, $Res Function(Attachment) _then)
 | 
			
		||||
      : super(_value, (v) => _then(v as Attachment));
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Attachment get _value => super._value as Attachment;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  $Res call({
 | 
			
		||||
    Object? field0 = freezed,
 | 
			
		||||
  }) {
 | 
			
		||||
    return _then(Attachment(
 | 
			
		||||
      field0 == freezed
 | 
			
		||||
          ? _value.field0
 | 
			
		||||
          : field0 // ignore: cast_nullable_to_non_nullable
 | 
			
		||||
              as AttachmentState,
 | 
			
		||||
    ));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// @nodoc
 | 
			
		||||
 | 
			
		||||
class _$Attachment implements Attachment {
 | 
			
		||||
  const _$Attachment(this.field0);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  final AttachmentState field0;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  String toString() {
 | 
			
		||||
    return 'VeilidUpdate.attachment(field0: $field0)';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  bool operator ==(dynamic other) {
 | 
			
		||||
    return identical(this, other) ||
 | 
			
		||||
        (other.runtimeType == runtimeType &&
 | 
			
		||||
            other is Attachment &&
 | 
			
		||||
            const DeepCollectionEquality().equals(other.field0, field0));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  int get hashCode =>
 | 
			
		||||
      Object.hash(runtimeType, const DeepCollectionEquality().hash(field0));
 | 
			
		||||
 | 
			
		||||
  @JsonKey(ignore: true)
 | 
			
		||||
  @override
 | 
			
		||||
  $AttachmentCopyWith<Attachment> get copyWith =>
 | 
			
		||||
      _$AttachmentCopyWithImpl<Attachment>(this, _$identity);
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult when<TResult extends Object?>({
 | 
			
		||||
    required TResult Function(AttachmentState field0) attachment,
 | 
			
		||||
  }) {
 | 
			
		||||
    return attachment(field0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult? whenOrNull<TResult extends Object?>({
 | 
			
		||||
    TResult Function(AttachmentState field0)? attachment,
 | 
			
		||||
  }) {
 | 
			
		||||
    return attachment?.call(field0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult maybeWhen<TResult extends Object?>({
 | 
			
		||||
    TResult Function(AttachmentState field0)? attachment,
 | 
			
		||||
    required TResult orElse(),
 | 
			
		||||
  }) {
 | 
			
		||||
    if (attachment != null) {
 | 
			
		||||
      return attachment(field0);
 | 
			
		||||
    }
 | 
			
		||||
    return orElse();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult map<TResult extends Object?>({
 | 
			
		||||
    required TResult Function(Attachment value) attachment,
 | 
			
		||||
  }) {
 | 
			
		||||
    return attachment(this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult? mapOrNull<TResult extends Object?>({
 | 
			
		||||
    TResult Function(Attachment value)? attachment,
 | 
			
		||||
  }) {
 | 
			
		||||
    return attachment?.call(this);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  @optionalTypeArgs
 | 
			
		||||
  TResult maybeMap<TResult extends Object?>({
 | 
			
		||||
    TResult Function(Attachment value)? attachment,
 | 
			
		||||
    required TResult orElse(),
 | 
			
		||||
  }) {
 | 
			
		||||
    if (attachment != null) {
 | 
			
		||||
      return attachment(this);
 | 
			
		||||
    }
 | 
			
		||||
    return orElse();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
abstract class Attachment implements VeilidUpdate {
 | 
			
		||||
  const factory Attachment(AttachmentState field0) = _$Attachment;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  AttachmentState get field0;
 | 
			
		||||
  @override
 | 
			
		||||
  @JsonKey(ignore: true)
 | 
			
		||||
  $AttachmentCopyWith<Attachment> get copyWith =>
 | 
			
		||||
      throw _privateConstructorUsedError;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,13 +1,38 @@
 | 
			
		||||
 | 
			
		||||
import 'dart:async';
 | 
			
		||||
import 'dart:ffi';
 | 
			
		||||
import 'dart:io';
 | 
			
		||||
import 'dart:typed_data';
 | 
			
		||||
 | 
			
		||||
import 'package:flutter/services.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'package:veilid/bridge_generated.dart';
 | 
			
		||||
 | 
			
		||||
class Veilid {
 | 
			
		||||
  static const MethodChannel _channel = MethodChannel('veilid');
 | 
			
		||||
const base = 'veilid_flutter';
 | 
			
		||||
final path = Platform.isWindows
 | 
			
		||||
    ? '$base.dll'
 | 
			
		||||
    : Platform.isMacOS
 | 
			
		||||
        ? 'lib$base.dylib'
 | 
			
		||||
        : 'lib$base.so';
 | 
			
		||||
late final dylib = Platform.isIOS ? DynamicLibrary.process() : DynamicLibrary.open(path);
 | 
			
		||||
late final veilidApi = VeilidFlutterImpl(dylib);
 | 
			
		||||
 | 
			
		||||
  static Future<String?> get platformVersion async {
 | 
			
		||||
    final String? version = await _channel.invokeMethod('getPlatformVersion');
 | 
			
		||||
    return version;
 | 
			
		||||
class Veilid {
 | 
			
		||||
 | 
			
		||||
  static VeilidFlutterImpl get api {
 | 
			
		||||
    if (veilidApi == null) {
 | 
			
		||||
      throw PlatformException(
 | 
			
		||||
        code: 'Library missing',
 | 
			
		||||
        details: 'veilid_core library could not be loaded dynamically',
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
    return veilidApi;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // static const MethodChannel _channel = MethodChannel('veilid');
 | 
			
		||||
 | 
			
		||||
  // static Future<String?> get platformVersion async {
 | 
			
		||||
  //   final String? version = await _channel.invokeMethod('getPlatformVersion');
 | 
			
		||||
  //   return version;
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,37 +8,34 @@ import 'dart:html' as html show window;
 | 
			
		||||
import 'package:flutter/services.dart';
 | 
			
		||||
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
 | 
			
		||||
 | 
			
		||||
// xxx link in WASM version of veilid-flutter
 | 
			
		||||
 | 
			
		||||
/// A web implementation of the Veilid plugin.
 | 
			
		||||
class VeilidWeb {
 | 
			
		||||
  static void registerWith(Registrar registrar) {
 | 
			
		||||
    final MethodChannel channel = MethodChannel(
 | 
			
		||||
      'veilid',
 | 
			
		||||
      const StandardMethodCodec(),
 | 
			
		||||
      registrar,
 | 
			
		||||
    );
 | 
			
		||||
    // final MethodChannel channel = MethodChannel(
 | 
			
		||||
    //   'veilid',
 | 
			
		||||
    //   const StandardMethodCodec(),
 | 
			
		||||
    //   registrar,
 | 
			
		||||
    // );
 | 
			
		||||
 | 
			
		||||
    final pluginInstance = VeilidWeb();
 | 
			
		||||
    channel.setMethodCallHandler(pluginInstance.handleMethodCall);
 | 
			
		||||
    // final pluginInstance = VeilidWeb();
 | 
			
		||||
    // channel.setMethodCallHandler(pluginInstance.handleMethodCall);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// Handles method calls over the MethodChannel of this plugin.
 | 
			
		||||
  /// Note: Check the "federated" architecture for a new way of doing this:
 | 
			
		||||
  /// https://flutter.dev/go/federated-plugins
 | 
			
		||||
  Future<dynamic> handleMethodCall(MethodCall call) async {
 | 
			
		||||
    switch (call.method) {
 | 
			
		||||
      case 'getPlatformVersion':
 | 
			
		||||
        return getPlatformVersion();
 | 
			
		||||
      default:
 | 
			
		||||
    // switch (call.method) {
 | 
			
		||||
    //   case 'getPlatformVersion':
 | 
			
		||||
    //     return getPlatformVersion();
 | 
			
		||||
    //   default:
 | 
			
		||||
        throw PlatformException(
 | 
			
		||||
          code: 'Unimplemented',
 | 
			
		||||
          details: 'veilid for web doesn\'t implement \'${call.method}\'',
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    // }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// Returns a [String] containing the version of the platform.
 | 
			
		||||
  Future<String> getPlatformVersion() {
 | 
			
		||||
    final version = html.window.navigator.userAgent;
 | 
			
		||||
    return Future.value(version);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,8 +18,9 @@ target_include_directories(${PLUGIN_NAME} INTERFACE
 | 
			
		||||
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter)
 | 
			
		||||
target_link_libraries(${PLUGIN_NAME} PRIVATE PkgConfig::GTK)
 | 
			
		||||
 | 
			
		||||
include(./rust.cmake)
 | 
			
		||||
# List of absolute paths to libraries that should be bundled with the plugin
 | 
			
		||||
set(veilid_bundled_libraries
 | 
			
		||||
  ""
 | 
			
		||||
  "$<TARGET_FILE:${CRATE_NAME}-shared>"
 | 
			
		||||
  PARENT_SCOPE
 | 
			
		||||
)
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										23
									
								
								veilid-flutter/linux/rust.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								veilid-flutter/linux/rust.cmake
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
# We include Corrosion inline here, but ideally in a project with
 | 
			
		||||
# many dependencies we would need to install Corrosion on the system.
 | 
			
		||||
# See instructions on https://github.com/AndrewGaspar/corrosion#cmake-install
 | 
			
		||||
# Once done, uncomment this line:
 | 
			
		||||
# find_package(Corrosion REQUIRED)
 | 
			
		||||
 | 
			
		||||
include(FetchContent)
 | 
			
		||||
 | 
			
		||||
FetchContent_Declare(
 | 
			
		||||
    Corrosion
 | 
			
		||||
    GIT_REPOSITORY https://github.com/AndrewGaspar/corrosion.git
 | 
			
		||||
    GIT_TAG origin/master # Optionally specify a version tag or branch here
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
FetchContent_MakeAvailable(Corrosion)
 | 
			
		||||
 | 
			
		||||
corrosion_import_crate(MANIFEST_PATH ${CMAKE_SOURCE_DIR}/../../rust/Cargo.toml)
 | 
			
		||||
 | 
			
		||||
# Flutter-specific
 | 
			
		||||
 | 
			
		||||
set(CRATE_NAME "veilid-flutter")
 | 
			
		||||
target_link_libraries(${PLUGIN_NAME} PUBLIC ${CRATE_NAME})
 | 
			
		||||
# list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${CRATE_NAME}-shared>)
 | 
			
		||||
@@ -6,11 +6,12 @@
 | 
			
		||||
 | 
			
		||||
#include <cstring>
 | 
			
		||||
 | 
			
		||||
#define VEILID_PLUGIN(obj) \
 | 
			
		||||
#define VEILID_PLUGIN(obj)                                     \
 | 
			
		||||
  (G_TYPE_CHECK_INSTANCE_CAST((obj), veilid_plugin_get_type(), \
 | 
			
		||||
                              VeilidPlugin))
 | 
			
		||||
 | 
			
		||||
struct _VeilidPlugin {
 | 
			
		||||
struct _VeilidPlugin
 | 
			
		||||
{
 | 
			
		||||
  GObject parent_instance;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -18,43 +19,48 @@ G_DEFINE_TYPE(VeilidPlugin, veilid_plugin, g_object_get_type())
 | 
			
		||||
 | 
			
		||||
// Called when a method call is received from Flutter.
 | 
			
		||||
static void veilid_plugin_handle_method_call(
 | 
			
		||||
    VeilidPlugin* self,
 | 
			
		||||
    FlMethodCall* method_call) {
 | 
			
		||||
    VeilidPlugin *self,
 | 
			
		||||
    FlMethodCall *method_call)
 | 
			
		||||
{
 | 
			
		||||
  g_autoptr(FlMethodResponse) response = nullptr;
 | 
			
		||||
 | 
			
		||||
  const gchar* method = fl_method_call_get_name(method_call);
 | 
			
		||||
  //const gchar *method = fl_method_call_get_name(method_call);
 | 
			
		||||
 | 
			
		||||
  if (strcmp(method, "getPlatformVersion") == 0) {
 | 
			
		||||
    struct utsname uname_data = {};
 | 
			
		||||
    uname(&uname_data);
 | 
			
		||||
    g_autofree gchar *version = g_strdup_printf("Linux %s", uname_data.version);
 | 
			
		||||
    g_autoptr(FlValue) result = fl_value_new_string(version);
 | 
			
		||||
    response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
 | 
			
		||||
  } else {
 | 
			
		||||
    response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
 | 
			
		||||
  }
 | 
			
		||||
  // if (strcmp(method, "getPlatformVersion") == 0) {
 | 
			
		||||
  //   struct utsname uname_data = {};
 | 
			
		||||
  //   uname(&uname_data);
 | 
			
		||||
  //   g_autofree gchar *version = g_strdup_printf("Linux %s", uname_data.version);
 | 
			
		||||
  //   g_autoptr(FlValue) result = fl_value_new_string(version);
 | 
			
		||||
  //   response = FL_METHOD_RESPONSE(fl_method_success_response_new(result));
 | 
			
		||||
  // } else {
 | 
			
		||||
  response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
  fl_method_call_respond(method_call, response, nullptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void veilid_plugin_dispose(GObject* object) {
 | 
			
		||||
static void veilid_plugin_dispose(GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  G_OBJECT_CLASS(veilid_plugin_parent_class)->dispose(object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void veilid_plugin_class_init(VeilidPluginClass* klass) {
 | 
			
		||||
static void veilid_plugin_class_init(VeilidPluginClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  G_OBJECT_CLASS(klass)->dispose = veilid_plugin_dispose;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void veilid_plugin_init(VeilidPlugin* self) {}
 | 
			
		||||
static void veilid_plugin_init(VeilidPlugin *self) {}
 | 
			
		||||
 | 
			
		||||
static void method_call_cb(FlMethodChannel* channel, FlMethodCall* method_call,
 | 
			
		||||
                           gpointer user_data) {
 | 
			
		||||
  VeilidPlugin* plugin = VEILID_PLUGIN(user_data);
 | 
			
		||||
static void method_call_cb(FlMethodChannel *channel, FlMethodCall *method_call,
 | 
			
		||||
                           gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  VeilidPlugin *plugin = VEILID_PLUGIN(user_data);
 | 
			
		||||
  veilid_plugin_handle_method_call(plugin, method_call);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void veilid_plugin_register_with_registrar(FlPluginRegistrar* registrar) {
 | 
			
		||||
  VeilidPlugin* plugin = VEILID_PLUGIN(
 | 
			
		||||
void veilid_plugin_register_with_registrar(FlPluginRegistrar *registrar)
 | 
			
		||||
{
 | 
			
		||||
  VeilidPlugin *plugin = VEILID_PLUGIN(
 | 
			
		||||
      g_object_new(veilid_plugin_get_type(), nullptr));
 | 
			
		||||
 | 
			
		||||
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
 | 
			
		||||
 
 | 
			
		||||
@@ -94,5 +94,21 @@ fn main() {
 | 
			
		||||
        .wait()
 | 
			
		||||
        .expect("flutter_rust_bridge_codegen was not running");
 | 
			
		||||
 | 
			
		||||
    //println!("cargo:rerun-if-changed={}", input_path.to_str().unwrap());
 | 
			
		||||
    // Build freezed
 | 
			
		||||
    // Run: flutter pub run build_runner build
 | 
			
		||||
 | 
			
		||||
    let mut command = Command::new("flutter");
 | 
			
		||||
    command.args([
 | 
			
		||||
        OsStr::new("pub"),
 | 
			
		||||
        OsStr::new("run"),
 | 
			
		||||
        OsStr::new("build_runner"),
 | 
			
		||||
        OsStr::new("build"),
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    let mut child = command
 | 
			
		||||
        .spawn()
 | 
			
		||||
        .expect("'flutter pub run build_runner build' did not execute correctly");
 | 
			
		||||
    child
 | 
			
		||||
        .wait()
 | 
			
		||||
        .expect("'flutter pub run build_runner build' was not running");
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,7 @@ async fn take_veilid_api() -> Result<veilid_core::VeilidAPI> {
 | 
			
		||||
#[allow(non_snake_case)]
 | 
			
		||||
pub struct VeilidConfig {
 | 
			
		||||
    pub program_name: String,
 | 
			
		||||
    pub namespace: String,
 | 
			
		||||
    pub veilid_namespace: String,
 | 
			
		||||
    // Capabilities
 | 
			
		||||
    pub capabilities__protocol_udp: bool,
 | 
			
		||||
    pub capabilities__protocol_connect_tcp: bool,
 | 
			
		||||
@@ -126,7 +126,7 @@ impl VeilidConfig {
 | 
			
		||||
    pub fn get_by_str(&self, key: &str) -> std::result::Result<Box<dyn std::any::Any + Send + 'static>, String> {
 | 
			
		||||
        let out: Box<dyn core::any::Any + Send> = match key {
 | 
			
		||||
            "program_name" => Box::new(self.program_name.clone()),
 | 
			
		||||
            "namespace" => Box::new(self.namespace.clone()),
 | 
			
		||||
            "namespace" => Box::new(self.veilid_namespace.clone()),
 | 
			
		||||
            "capabilities.protocol_udp" => Box::new(self.capabilities__protocol_udp.clone()),
 | 
			
		||||
            "capabilities.protocol_connect_tcp" => Box::new(self.capabilities__protocol_connect_tcp.clone()),
 | 
			
		||||
            "capabilities.protocol_accept_tcp" => Box::new(self.capabilities__protocol_accept_tcp.clone()),
 | 
			
		||||
 
 | 
			
		||||
@@ -96,7 +96,7 @@ pub struct wire_uint_8_list {
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
pub struct wire_VeilidConfig {
 | 
			
		||||
    program_name: *mut wire_uint_8_list,
 | 
			
		||||
    namespace: *mut wire_uint_8_list,
 | 
			
		||||
    veilid_namespace: *mut wire_uint_8_list,
 | 
			
		||||
    capabilities__protocol_udp: bool,
 | 
			
		||||
    capabilities__protocol_connect_tcp: bool,
 | 
			
		||||
    capabilities__protocol_accept_tcp: bool,
 | 
			
		||||
@@ -275,7 +275,7 @@ impl Wire2Api<VeilidConfig> for wire_VeilidConfig {
 | 
			
		||||
    fn wire2api(self) -> VeilidConfig {
 | 
			
		||||
        VeilidConfig {
 | 
			
		||||
            program_name: self.program_name.wire2api(),
 | 
			
		||||
            namespace: self.namespace.wire2api(),
 | 
			
		||||
            veilid_namespace: self.veilid_namespace.wire2api(),
 | 
			
		||||
            capabilities__protocol_udp: self.capabilities__protocol_udp.wire2api(),
 | 
			
		||||
            capabilities__protocol_connect_tcp: self.capabilities__protocol_connect_tcp.wire2api(),
 | 
			
		||||
            capabilities__protocol_accept_tcp: self.capabilities__protocol_accept_tcp.wire2api(),
 | 
			
		||||
@@ -404,7 +404,7 @@ impl NewWithNullPtr for wire_VeilidConfig {
 | 
			
		||||
    fn new_with_null_ptr() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            program_name: core::ptr::null_mut(),
 | 
			
		||||
            namespace: core::ptr::null_mut(),
 | 
			
		||||
            veilid_namespace: core::ptr::null_mut(),
 | 
			
		||||
            capabilities__protocol_udp: Default::default(),
 | 
			
		||||
            capabilities__protocol_connect_tcp: Default::default(),
 | 
			
		||||
            capabilities__protocol_accept_tcp: Default::default(),
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user