Compare commits

...

3 Commits

Author SHA1 Message Date
gem
d7699c93cd no message 2025-02-07 18:05:26 +08:00
gem
e5f1398bc3 Merge commit 'f3e0de51226a3d322ae1b6ddd0d7c40b1ad1d44d' 2025-02-07 10:40:39 +08:00
cpdl
f3e0de5122 no message 2025-02-07 10:38:54 +08:00
13 changed files with 698 additions and 69 deletions

View File

@@ -1,63 +1,37 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'dart:async'; import 'package:flutter_cocos_view_example/screens/no_interaction_screen.dart';
import 'package:flutter_cocos_view_example/screens/orientation_screen.dart';
import 'package:flutter/services.dart'; import 'menu_screen.dart';
import 'package:flutter_cocos_view/flutter_cocos_view.dart'; import 'screens/api_screen.dart';
import 'screens/loader_screen.dart';
import 'screens/simple_screen.dart';
void main() { void main() {
runApp(const MyApp()); runApp(const MyApp());
} }
class MyApp extends StatefulWidget { class MyApp extends StatelessWidget {
const MyApp({super.key}); const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
final _flutterCocosViewPlugin = FlutterCocosView();
@override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
// We also handle the message potentially returning null.
try {
platformVersion =
await _flutterCocosViewPlugin.getPlatformVersion() ?? 'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
// This widget is the root of your application.
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
home: Scaffold( title: 'Flutter Cocos Demo',
appBar: AppBar( theme: ThemeData(
title: const Text('Plugin example app'), primarySwatch: Colors.blue,
), visualDensity: VisualDensity.adaptivePlatformDensity,
body: Center(
child: Text('Running on: $_platformVersion\n'),
),
), ),
initialRoute: '/',
routes: {
'/': (context) => const MenuScreen(),
'/simple': (context) => const SimpleScreen(),
'/loader': (context) => const LoaderScreen(),
'/orientation': (context) => const OrientationScreen(),
'/api': (context) => const ApiScreen(),
'/none': (context) => const NoInteractionScreen(),
},
); );
} }
} }

View File

@@ -0,0 +1,76 @@
import 'package:flutter/material.dart';
class MenuScreen extends StatefulWidget {
const MenuScreen({Key? key}) : super(key: key);
@override
State<MenuScreen> createState() => _MenuScreenState();
}
class _MenuScreenState extends State<MenuScreen> {
List<_MenuListItem> menus = [
_MenuListItem(
description: 'Simple demonstration of cocos flutter library',
route: '/simple',
title: 'Simple Cocos Demo',
),
_MenuListItem(
description: 'No interaction of cocos flutter library',
route: '/none',
title: 'No Interaction Cocos Demo',
),
_MenuListItem(
description: 'Cocos load and unload cocos demo',
route: '/loader',
title: 'Safe mode Demo',
),
_MenuListItem(
description:
'This example shows various native API exposed by the library',
route: '/api',
title: 'Native exposed API demo',
),
_MenuListItem(
title: 'Test Orientation',
route: '/orientation',
description: 'test orientation change',
),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Menu List'),
),
body: Center(
child: ListView.builder(
itemCount: menus.length,
itemBuilder: (BuildContext context, int i) {
return ListTile(
title: Text(menus[i].title),
subtitle: Text(menus[i].description),
onTap: () {
Navigator.of(context).pushNamed(
menus[i].route,
);
},
);
},
),
),
);
}
}
class _MenuListItem {
final String title;
final String description;
final String route;
_MenuListItem({
required this.title,
required this.description,
required this.route,
});
}

View File

@@ -0,0 +1,168 @@
// ignore_for_file: avoid_print
import 'package:flutter/material.dart';
import "package:flutter_cocos_view/flutter_cocos_view.dart";
import 'package:pointer_interceptor/pointer_interceptor.dart';
class ApiScreen extends StatefulWidget {
const ApiScreen({Key? key}) : super(key: key);
@override
State<ApiScreen> createState() => _ApiScreenState();
}
class _ApiScreenState extends State<ApiScreen> {
CocosWidgetController? _cocosWidgetController;
double _sliderValue = 0.0;
@override
void initState() {
super.initState();
}
@override
void dispose() {
_cocosWidgetController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('API Screen'),
),
body: Card(
margin: const EdgeInsets.all(8),
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Stack(
children: [
CocosWidget(
onCocosCreated: onCocosCreated,
onCocosMessage: onCocosMessage,
onCocosSceneLoaded: onCocosSceneLoaded,
fullscreen: false,
useAndroidViewSurface: false,
),
Positioned(
bottom: 20,
left: 20,
right: 20,
child: PointerInterceptor(
child: Card(
elevation: 10,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
const Padding(
padding: EdgeInsets.only(top: 20),
child: Text("Rotation speed:"),
),
Slider(
onChanged: (value) {
setState(() {
_sliderValue = value;
});
setRotationSpeed(value.toString());
},
value: _sliderValue,
min: 0,
max: 20,
),
FittedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MaterialButton(
onPressed: () {
_cocosWidgetController?.quit();
},
child: const Text("Quit"),
),
MaterialButton(
onPressed: () {
_cocosWidgetController?.create();
},
child: const Text("Create"),
),
MaterialButton(
onPressed: () {
_cocosWidgetController?.pause();
},
child: const Text("Pause"),
),
MaterialButton(
onPressed: () {
_cocosWidgetController?.resume();
},
child: const Text("Resume"),
),
],
),
),
FittedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
MaterialButton(
onPressed: () async {
await _cocosWidgetController
?.openInNativeProcess();
},
child: const Text("Open Native"),
),
MaterialButton(
onPressed: () {
_cocosWidgetController?.unload();
},
child: const Text("Unload"),
),
MaterialButton(
onPressed: () {
_cocosWidgetController?.quit();
},
child: const Text("Silent Quit"),
),
],
),
),
],
),
),
),
),
],
),
),
);
}
void setRotationSpeed(String speed) {
_cocosWidgetController?.postMessage(
'Cube',
'SetRotationSpeed',
speed,
);
}
void onCocosMessage(message) {
print('Received message from cocos: ${message.toString()}');
}
void onCocosSceneLoaded(SceneLoaded? scene) {
if (scene != null) {
print('Received scene loaded from cocos: ${scene.name}');
print('Received scene loaded from cocos buildIndex: ${scene.buildIndex}');
} else {
print('Received scene loaded from cocos: null');
}
}
// Callback that connects the created controller to the cocos controller
void onCocosCreated(controller) {
_cocosWidgetController = controller;
}
}

View File

@@ -0,0 +1,93 @@
// ignore_for_file: avoid_print
import 'package:flutter/material.dart';
import 'package:flutter_cocos_view/flutter_cocos_view.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
class LoaderScreen extends StatefulWidget {
const LoaderScreen({Key? key}) : super(key: key);
@override
State<LoaderScreen> createState() => _LoaderScreenState();
}
class _LoaderScreenState extends State<LoaderScreen> {
CocosWidgetController? _cocosWidgetController;
double _sliderValue = 0.0;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Safe Mode Screen'),
),
body: Card(
margin: const EdgeInsets.all(8),
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Stack(
children: <Widget>[
CocosWidget(
onCocosCreated: onCocosCreated,
onCocosMessage: onCocosMessage,
useAndroidViewSurface: true,
),
Positioned(
bottom: 20,
left: 20,
right: 20,
child: PointerInterceptor(
child: Card(
elevation: 10,
child: Column(
children: <Widget>[
const Padding(
padding: EdgeInsets.only(top: 20),
child: Text("Rotation speed:"),
),
Slider(
onChanged: (value) {
setState(() {
_sliderValue = value;
});
setRotationSpeed(value.toString());
},
value: _sliderValue,
min: 0,
max: 20,
),
],
),
),
),
),
],
),
),
);
}
void setRotationSpeed(String speed) {
_cocosWidgetController?.postMessage(
'Cube',
'SetRotationSpeed',
speed,
);
}
void onCocosMessage(message) {
print('Received message from cocos: ${message.toString()}');
}
// Callback that connects the created controller to the cocos controller
void onCocosCreated(controller) {
_cocosWidgetController = controller;
}
}

View File

@@ -0,0 +1,96 @@
import 'package:flutter/material.dart';
import 'package:flutter_cocos_view/flutter_cocos_view.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
class NoInteractionScreen extends StatefulWidget {
const NoInteractionScreen({Key? key}) : super(key: key);
@override
State<NoInteractionScreen> createState() => _NoInteractionScreenState();
}
class _NoInteractionScreenState extends State<NoInteractionScreen> {
static final GlobalKey<ScaffoldState> _scaffoldKey =
GlobalKey<ScaffoldState>();
CocosWidgetController? _cocosWidgetController;
@override
void initState() {
super.initState();
}
@override
void dispose() {
_cocosWidgetController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text('No Interaction Screen'),
),
body: Card(
margin: const EdgeInsets.all(8),
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Stack(
children: [
CocosWidget(
onCocosCreated: _onCocosCreated,
onCocosMessage: onCocosMessage,
onCocosSceneLoaded: onCocosSceneLoaded,
useAndroidViewSurface: true,
borderRadius: const BorderRadius.all(Radius.circular(70)),
),
Positioned(
bottom: 20,
left: 20,
right: 20,
child: PointerInterceptor(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pushNamed('/simple');
},
child: const Text('Switch Flutter Screen'),
),
),
),
],
),
),
);
}
void setRotationSpeed(String speed) {
_cocosWidgetController?.postMessage(
'Cube',
'SetRotationSpeed',
speed,
);
}
void onCocosMessage(message) {
print('Received message from cocos: ${message.toString()}');
}
void onCocosSceneLoaded(SceneLoaded? scene) {
if (scene != null) {
print('Received scene loaded from cocos: ${scene.name}');
print('Received scene loaded from cocos buildIndex: ${scene.buildIndex}');
} else {
print('Received scene loaded from cocos: null');
}
}
// Callback that connects the created controller to the cocos controller
void _onCocosCreated(controller) {
controller.resume();
_cocosWidgetController = controller;
}
}

View File

@@ -0,0 +1,108 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_cocos_view/flutter_cocos_view.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
class OrientationScreen extends StatefulWidget {
const OrientationScreen({Key? key}) : super(key: key);
@override
State<OrientationScreen> createState() => _OrientationScreenState();
}
class _OrientationScreenState extends State<OrientationScreen> {
CocosWidgetController? _cocosWidgetController;
double _sliderValue = 0.0;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Orientation Screen'),
),
body: Card(
margin: const EdgeInsets.all(8),
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Stack(
children: <Widget>[
CocosWidget(
onCocosCreated: onCocosCreated,
onCocosMessage: onCocosMessage,
useAndroidViewSurface: true,
),
Positioned(
bottom: 20,
left: 20,
right: 20,
child: PointerInterceptor(
child: Card(
elevation: 10,
child: Column(
children: <Widget>[
ElevatedButton(
onPressed: () {
if (MediaQuery.of(context).orientation ==
Orientation.portrait) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight
]);
} else if (MediaQuery.of(context).orientation ==
Orientation.landscape) {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp]);
}
},
child: const Text("Change Orientation"),
),
const Padding(
padding: EdgeInsets.only(top: 20),
child: Text("Rotation speed:"),
),
Slider(
onChanged: (value) {
setState(() {
_sliderValue = value;
});
setRotationSpeed(value.toString());
},
value: _sliderValue,
min: 0,
max: 20,
),
],
),
),
),
),
],
),
),
);
}
void setRotationSpeed(String speed) {
_cocosWidgetController?.postMessage(
'Cube',
'SetRotationSpeed',
speed,
);
}
void onCocosMessage(message) {
print('Received message from cocos: ${message.toString()}');
}
// Callback that connects the created controller to the cocos controller
void onCocosCreated(controller) {
_cocosWidgetController = controller;
}
}

View File

@@ -0,0 +1,112 @@
import 'package:flutter/material.dart';
import 'package:flutter_cocos_view/flutter_cocos_view.dart';
import 'package:pointer_interceptor/pointer_interceptor.dart';
class SimpleScreen extends StatefulWidget {
const SimpleScreen({Key? key}) : super(key: key);
@override
State<SimpleScreen> createState() => _SimpleScreenState();
}
class _SimpleScreenState extends State<SimpleScreen> {
static final GlobalKey<ScaffoldState> _scaffoldKey =
GlobalKey<ScaffoldState>();
CocosWidgetController? _cocosWidgetController;
double _sliderValue = 0.0;
@override
void initState() {
super.initState();
}
@override
void dispose() {
_cocosWidgetController?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text('Simple Screen'),
),
body: Card(
margin: const EdgeInsets.all(0),
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
child: Stack(
children: [
CocosWidget(
onCocosCreated: _onCocosCreated,
onCocosMessage: onCocosMessage,
onCocosSceneLoaded: onCocosSceneLoaded,
useAndroidViewSurface: false,
borderRadius: const BorderRadius.all(Radius.circular(70)),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: PointerInterceptor(
child: Card(
elevation: 10,
child: Column(
children: <Widget>[
const Padding(
padding: EdgeInsets.only(top: 20),
child: Text("Rotation speed:"),
),
Slider(
onChanged: (value) {
setState(() {
_sliderValue = value;
});
setRotationSpeed(value.toString());
},
value: _sliderValue,
min: 0.0,
max: 1.0,
),
],
),
),
),
),
],
)),
);
}
void setRotationSpeed(String speed) {
_cocosWidgetController?.postMessage(
'Cube',
'SetRotationSpeed',
speed,
);
}
void onCocosMessage(message) {
print('Received message from cocos: ${message.toString()}');
}
void onCocosSceneLoaded(SceneLoaded? scene) {
if (scene != null) {
print('Received scene loaded from cocos: ${scene.name}');
print('Received scene loaded from cocos buildIndex: ${scene.buildIndex}');
} else {
print('Received scene loaded from cocos: null');
}
}
// Callback that connects the created controller to the cocos controller
void _onCocosCreated(controller) {
controller.resume();
_cocosWidgetController = controller;
}
}

View File

@@ -185,6 +185,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.8" version: "2.1.8"
pointer_interceptor:
dependency: "direct main"
description:
name: pointer_interceptor
sha256: adf7a637f97c077041d36801b43be08559fd4322d2127b3f20bb7be1b9eebc22
url: "https://pub.dev"
source: hosted
version: "0.9.3+7"
process: process:
dependency: transitive dependency: transitive
description: description:

View File

@@ -28,7 +28,7 @@ dependencies:
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8 cupertino_icons: ^1.0.8
pointer_interceptor: ^0.9.3+2
dev_dependencies: dev_dependencies:
integration_test: integration_test:
sdk: flutter sdk: flutter

View File

@@ -6,6 +6,7 @@
// //
import Foundation import Foundation
import cocos_view_pod
private var cocos_warmed_up = false private var cocos_warmed_up = false
@@ -37,16 +38,9 @@ public func InitCocosIntegrationWithOptions(
// Load cocos framework for fisrt run // Load cocos framework for fisrt run
func CocosFrameworkLoad() -> CocosFramework? { func CocosFrameworkLoad() -> CocosFramework? {
var bundlePath: String? = nil
bundlePath = Bundle.main.bundlePath
bundlePath = (bundlePath ?? "") + "/Frameworks/CocosFramework.framework"
let bundle = Bundle(path: bundlePath ?? "")
if bundle?.isLoaded == false {
bundle?.load()
}
return bundle?.principalClass?.getInstance() return dcocos_bridge.instance()
} }
/*********************************** GLOBAL FUNCS & VARS START**************************************/ /*********************************** GLOBAL FUNCS & VARS START**************************************/
@@ -87,10 +81,10 @@ var sharedApplication: UIApplication?
self.ufw = CocosFrameworkLoad() self.ufw = CocosFrameworkLoad()
self.ufw?.setDataBundleId("com.cocos3d.framework") //self.ufw?.setDataBundleId("com.cocos3d.framework")
registerCocosListener() registerCocosListener()
self.ufw?.runEmbedded(withArgc: gArgc, argv: gArgv, appLaunchOpts: appLaunchOpts) // self.ufw?.runEmbedded(withArgc: gArgc, argv: gArgv, appLaunchOpts: appLaunchOpts)
if self.ufw?.appController() != nil { if self.ufw?.appController() != nil {
controller = self.ufw?.appController() controller = self.ufw?.appController()
@@ -147,13 +141,13 @@ var sharedApplication: UIApplication?
func registerCocosListener() { func registerCocosListener() {
if self.cocosIsInitiallized() { if self.cocosIsInitiallized() {
self.ufw?.register(self) // self.ufw?.register(self)
} }
} }
func unregisterCocosListener() { func unregisterCocosListener() {
if self.cocosIsInitiallized() { if self.cocosIsInitiallized() {
self.ufw?.unregisterFrameworkListener(self) // self.ufw?.unregisterFrameworkListener(self)
} }
} }

View File

@@ -6,7 +6,7 @@
// //
import Foundation import Foundation
import CocosFramework
// Defines cocos controllable from Flutter. // Defines cocos controllable from Flutter.
public class FLTCocosWidgetController: NSObject, FLTCocosOptionsSink, FlutterPlatformView { public class FLTCocosWidgetController: NSObject, FLTCocosOptionsSink, FlutterPlatformView {
@@ -30,7 +30,7 @@ public class FLTCocosWidgetController: NSObject, FLTCocosOptionsSink, FlutterPla
self.viewId = viewId self.viewId = viewId
let channelName = String(format: "plugin.xraph.com/cocos_view_%lld", viewId) let channelName = String(format: "plugin.gem.com/cocos_view_%lld", viewId)
self.channel = FlutterMethodChannel(name: channelName, binaryMessenger: registrar.messenger()) self.channel = FlutterMethodChannel(name: channelName, binaryMessenger: registrar.messenger())
self.channel?.setMethodCallHandler(self.methodHandler) self.channel?.setMethodCallHandler(self.methodHandler)

View File

@@ -1,18 +1,18 @@
#import FlutterCocosWidgetPlugin.h #import FlutterCocosWidgetPlugin.h
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#if __has_include(<flutter_unity_widget/flutter_unity_widget-Swift.h>) #if __has_include(<flutter_cocos_widget/flutter_cocos_widget-Swift.h>)
#import <flutter_unity_widget/flutter_unity_widget-Swift.h> #import <flutter_cocos_widget/flutter_cocos_widget-Swift.h>
#else #else
// Support project import fallback if the generated compatibility header // Support project import fallback if the generated compatibility header
// is not copied when this plugin is created as a library. // is not copied when this plugin is created as a library.
// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816
#import "flutter_unity_widget-Swift.h" #import "flutter_cocos_widget-Swift.h"
#endif #endif
@implementation FlutterCocosWidgetPlugin { @implementation FlutterCocosWidgetPlugin {
NSObject<FlutterPluginRegistrar>* _registrar; NSObject<FlutterPluginRegistrar>* _registrar;
FlutterMethodChannel* _channel; FlutterMethodChannel* _channel;
NSMutableDictionary* _unityControllers; NSMutableDictionary* _cocosControllers;
} }
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar { + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {

View File

@@ -5,7 +5,7 @@
// platforms in the `pubspec.yaml` at // platforms in the `pubspec.yaml` at
// https://flutter.dev/to/pubspec-plugin-platforms. // https://flutter.dev/to/pubspec-plugin-platforms.
library flutter_Cocos_widget; library flutter_cocos_view;
export 'src/facade_controller.dart'; export 'src/facade_controller.dart';
export 'src/facade_widget.dart' export 'src/facade_widget.dart'