mirror of
https://github.com/blanking003/cx-cocos.git
synced 2024-12-25 11:19:00 +00:00
init
This commit is contained in:
parent
74d5947e9d
commit
346fc42e67
27
.gitignore
vendored
Normal file
27
.gitignore
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
#///////////////////////////
|
||||||
|
# Cocos Creator 3D Project
|
||||||
|
#///////////////////////////
|
||||||
|
build/
|
||||||
|
library/
|
||||||
|
local/
|
||||||
|
native
|
||||||
|
temp/
|
||||||
|
|
||||||
|
#//////////////////////////
|
||||||
|
# NPM
|
||||||
|
#//////////////////////////
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
#//////////////////////////
|
||||||
|
# VSCode
|
||||||
|
#//////////////////////////
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
#//////////////////////////
|
||||||
|
# WebStorm
|
||||||
|
#//////////////////////////
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
.gradle/
|
||||||
|
*.iml
|
288
README.cn.md
Normal file
288
README.cn.md
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
# cx-cocos
|
||||||
|
**一个基于cocos creator3.1.1的应用App和游戏开发框架**
|
||||||
|
|
||||||
|
关键词:cocos creator、应用开发、App开发、游戏开发、跨平台、框架
|
||||||
|
|
||||||
|
cocos creator是一个开源的游戏开发引擎,在游戏开发方面,拥有大量开发者。然而在应用App方面,却少有人使用,cx-cocos的出现,填补了cocos creator在应用App开发上的空白。
|
||||||
|
|
||||||
|
使用cx-cocos,你可以轻松愉快地开发出一个跨平台应用App,包括ios、mac、android、web等,当然你也可以使用cx-cocos开发游戏,这是一个高效简洁的开发框架,极大提升开发者的效率。
|
||||||
|
|
||||||
|
**本说明文档包括以下内容:**
|
||||||
|
- cx-cocos主要功能
|
||||||
|
- cx-cocos结构和原理
|
||||||
|
- 如何运行demo app
|
||||||
|
- 如何使用cx-cocos开始一个自己的项目
|
||||||
|
- 问题和技术支持
|
||||||
|
|
||||||
|
|
||||||
|
## 1. 主要功能
|
||||||
|
**cx-cocos的主要功能包括以下内容:**
|
||||||
|
- 应用App的核心UI交互
|
||||||
|
- 页面和组件访问、资源访问、远程服务访问
|
||||||
|
- 与原生代码的交互
|
||||||
|
- 真正的启动屏
|
||||||
|
- 热更新
|
||||||
|
|
||||||
|
|
||||||
|
### 1.1 应用App的核心UI交互
|
||||||
|
----
|
||||||
|
cx-cocos在页面的显示与交互细节上,与iOS原生App有着相似的体验,
|
||||||
|
包括页面的进入退出与手势、提示弹窗、ScrollView、Loading等待、选择器等等。
|
||||||
|
cx3-demo是一个demo,建议你从它入手,了解cx-cocos。
|
||||||
|
|
||||||
|
- **屏幕适配:** 通常情况下,应用App是宽度适应(fitWidth)、高度随着屏幕高度自动铺满。cx-cocos提供了一个“最小设计宽/高度”的配置,即使在浏览器或Pad上,App也能按最佳的方式显示界面——你只需按你的设计尺寸来设计UI。
|
||||||
|
|
||||||
|
- **刘海屏适配:** 对于iphoneX等屏幕,通过添加cx.safearea脚本,可自动调节标题栏、内容层、底部导航栏的高度和位置。
|
||||||
|
|
||||||
|
- **界面进入与退出:** 动画进入与退出、手势划动退出、上一页面随动、阴影效果、响应android返回键。
|
||||||
|
|
||||||
|
- **对话框:** Alert提示框、Confirm确认框。框架还提供了一种Hint动画文字提示,你可以多点击几次试试。
|
||||||
|
|
||||||
|
- **选择器:** 框架提供了1栏或多栏的选择器,你可以轻松地实现年月日选择、年月选择、文字或对象列表选择。
|
||||||
|
|
||||||
|
- **ScrollView:** 扩展了下拉刷新、上滑增量添加数据的能力。
|
||||||
|
|
||||||
|
- **PageView:** 扩展了定时自动下一页、循环播放、点击回调的能力。
|
||||||
|
|
||||||
|
- **等待动画:** 可以在页面正中或任意控件内显示Loading动画,并且有延时显示能力,这在查询数据时非常实用,比如0.5秒后还没有返回数据,才显示Loading动画。
|
||||||
|
|
||||||
|
- **原生视图:** 原生UI在cocos UI中显示,并且随着ScrollView滚动或窗体滑动;原生UI遮罩能力,例如对话弹框、标题栏在原生UI之上显示,不被遮挡。
|
||||||
|
|
||||||
|
|
||||||
|
### 1.2 页面和组件访问、资源访问、远程服务访问
|
||||||
|
----
|
||||||
|
操作UI组件在应用开发中非常频繁,cx-cocos提供了便捷的方式对组件进行访问和操作。
|
||||||
|
|
||||||
|
| UI常用方法 | 说明 |
|
||||||
|
| ---- | ---- |
|
||||||
|
| cx.sw | 适配后的屏幕宽度 |
|
||||||
|
| cx.sh | 适配后的屏幕高度 |
|
||||||
|
| cx.gn(pageOrNode, nodeName) | 获取场景树中的节点 |
|
||||||
|
| setTouchCallback(page, callback, ...params) | 给Node添加点击事件 |
|
||||||
|
| cx.hint(content) | 显示提示 |
|
||||||
|
| cx.alert(content, callback?, labelOK?) | 显示对话窗 |
|
||||||
|
| cx.confrm(content, callback?, labelOK?, labelCancel?) | 显示确认窗 |
|
||||||
|
| cx.showLoading(page, parentNode, delayShowSeconds?) | 显示等待动画 |
|
||||||
|
| cx.removeLoading(parentNode) | 移除等待动画 |
|
||||||
|
| cx.addPage(parentNode, prefabName, scripts?, callbackOrParams, runAction?) | 添加一个页面 |
|
||||||
|
| cx.showPage(prefabName, scripts?, callbackOrParams) | 添加一个页面(动画进入) |
|
||||||
|
| cx.closePage(pageOrSender) | 关闭本页面 |
|
||||||
|
| | |
|
||||||
|
|
||||||
|
**示例代码:**
|
||||||
|
```typescript
|
||||||
|
var lblTitle: Node = cx.gn(this, "lblTitle"); //获取场景树中的名称为lblTitle的节点
|
||||||
|
|
||||||
|
//给lblTitle添加一个点击事件
|
||||||
|
lblTitle.setTouchCallback(this, this.myClick);
|
||||||
|
|
||||||
|
//你也可以定义回调时的参数:
|
||||||
|
lblTitle.setTouchCallback(this, this.myClick, 1, "a", {tip:"任意类型和数量的参数"});
|
||||||
|
|
||||||
|
myClick(sender, p1, p2, p3)
|
||||||
|
{
|
||||||
|
//sender = lblTitle
|
||||||
|
//p1 = 1
|
||||||
|
//p2 = "a"
|
||||||
|
//p3 = {remark:"任意类型和数量的参数"}
|
||||||
|
}
|
||||||
|
|
||||||
|
cx.showPage("ui/pageChild"); //显示ui/pageChild.prefab
|
||||||
|
cx.hint("cx.hint(content)");
|
||||||
|
cx.alert("cx.alert(content, callback, labelOk)");
|
||||||
|
cx.confirm("cx.confirm(content, callback, labelOk, labelCancel)", cx.hint);
|
||||||
|
cx.showLoading(this);
|
||||||
|
cx.removeLoading(this);
|
||||||
|
cx.closePage(this);
|
||||||
|
|
||||||
|
//给scrollView添加增量新增数据能力
|
||||||
|
cx.script.scrollView.initDeltaInsert(this, "view", this.queryData);
|
||||||
|
|
||||||
|
//给scrollView添加下拉刷新能力
|
||||||
|
cx.script.scrollView.initDropRefresh(this, "view", this.refreshData);
|
||||||
|
|
||||||
|
//给PageView添加自动循环滚动能力
|
||||||
|
cx.script.pageView.initAutoScroll(this, "viewBanner", 2, true, this.onBannerClick);
|
||||||
|
````
|
||||||
|
|
||||||
|
| 资源常用方法 | 说明 |
|
||||||
|
| ---- | ---- |
|
||||||
|
| cx.setImageFromRes(spriteOrNode, prefab, sizeMode?, callback?) | 给节点设置图片(从resources) |
|
||||||
|
| cx.setImageFromBundle(spriteOrNode, prefab, sizeMode?, callback?) | 给节点设置图片(从bundle) |
|
||||||
|
| cx.setImageFromRemote(spriteOrNode, url, localPath?, sizeMode?, callback?) | 给节点设置图片(从远程url,存储至本地localPath,并优先从localPath加载图片) |
|
||||||
|
| cx.loadBundleRes(prefab, callback?) | 加载1个或多个prefab |
|
||||||
|
| | |
|
||||||
|
|
||||||
|
|
||||||
|
| 远程访问常用方法 | 说明 |
|
||||||
|
| ---- | ---- |
|
||||||
|
| cx.call(url, callback?, context?) | 调用服务端服务(call方式) |
|
||||||
|
| cx.post(url, data?, callback?, context?) | 调用服务端服务(post方式) |
|
||||||
|
| cx.upload(url, filePath, callback?) | 调用服务端服务,上传文件 |
|
||||||
|
| cx.setCommonHeaders(headers: string[]) | 设置http请求的默认headers |
|
||||||
|
| cx.loadFile(url, localPath?, callback?) | 从url加载文件,存储至本地并优先从本地加载 |
|
||||||
|
| cx.loadAsset(url: string, callback?) | 从url加载Asset |
|
||||||
|
| | |
|
||||||
|
|
||||||
|
|
||||||
|
| utils常用方法 | 说明 |
|
||||||
|
| ---- | ---- |
|
||||||
|
| cx.utils.xxx | cx.func中定义了常用的工具方法,如时间等,具体参见cx.d.ts |
|
||||||
|
| | |
|
||||||
|
|
||||||
|
|
||||||
|
### 1.3 与原生代码的交互
|
||||||
|
----
|
||||||
|
cx-cocos提供了一个cxnative原生类,通过它可以方便地与原生代码、第三方SDK交互。
|
||||||
|
与iOS/mac的交互是通过jsb/c++ ———— 避免了苹果审核风险
|
||||||
|
与android的交互是通过jsb.reflection
|
||||||
|
|
||||||
|
* 可参照demo中的SystemIntf编写你自己的原生类
|
||||||
|
|
||||||
|
**原生类的定义:**
|
||||||
|
iOS/mac:在jsIntf.cpp中定义你的类名和处理类,类继承自cxDefine.h中的NativeIntfClass
|
||||||
|
android:在jsIntf.java中定义你的类名和处理类
|
||||||
|
|
||||||
|
- 在JavaScript/TypeScript中调用原生方法:
|
||||||
|
```typescript
|
||||||
|
cx.native.ins("className").call("functionName", [...params], callback);
|
||||||
|
````
|
||||||
|
|
||||||
|
- 在iOS/mac中调用JS方法:
|
||||||
|
```c++
|
||||||
|
this->callback(int, string);
|
||||||
|
````
|
||||||
|
|
||||||
|
- 在android中调用JS方法:
|
||||||
|
```java
|
||||||
|
NativeIntf.callJs("className", int, string);
|
||||||
|
````
|
||||||
|
|
||||||
|
|
||||||
|
### 1.4 真正的启动屏
|
||||||
|
----
|
||||||
|
cocos creator提供了一个定时长的启动画面,你无法在首页渲染完成后再移除画面,也无法提前移除。并且它只能在加载cc.js之后显示,而不是在App真正启动时。
|
||||||
|
cx-cocos针对iOS/mac和Android,提供了原生的启动画面处理,你可以在App启动时显示,在任意时刻移除。
|
||||||
|
|
||||||
|
iOS/mac启动屏实现代码:见demo中的AppController.mm
|
||||||
|
android启动屏实现代码:见demo中的CocosActivity.java
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ios/Mac: LaunchImage.png
|
||||||
|
// android: lanuch_image.png
|
||||||
|
// 移除启动屏,如果你在config.ts中配置了自动移除,那么不需要执行这句,cx会在开始页(startPage)加入场景时自动调用
|
||||||
|
cx.removeLaunchImage();
|
||||||
|
````
|
||||||
|
|
||||||
|
|
||||||
|
### 1.5 热更新
|
||||||
|
----
|
||||||
|
cx-cocos在执行main.js之前执行热更新。
|
||||||
|
cx-cocos提供了一个update.js工具用于生成热更新需要的manifest文件,执行命令为:
|
||||||
|
$ node update.js -v 1.0
|
||||||
|
* 在执行之前,你需要将update.js中的更新地址替换为你的服务器地址。
|
||||||
|
|
||||||
|
****实现原理:见demo中的boot.js***
|
||||||
|
|
||||||
|
|
||||||
|
## 2. cx-cocos结构和原理
|
||||||
|
|
||||||
|
>**cx-framework目录结构:**
|
||||||
|
- **cocos3-libs:** 这里是从creator构建项目中提取的引擎libs,我们把它独立出来,所有项目就只需要assets
|
||||||
|
- **cocos-libcc:** cocos android jar,你的android工程需要依赖它
|
||||||
|
- **cocos-libso:** cocos android so,编译生成libcocos.so的工程,android需要这个.so
|
||||||
|
- **cocos3-ios.xcodeproj:** 编译生成libcocos3 iOS.a的工程,iOS需要这个.a
|
||||||
|
- **cocos3-mac.xcodeproj:** 编译生成libcocos3 Mac.a的工程,mac需要这个.a
|
||||||
|
- **cx:** cx-cocos的ts代码,你的creator工程需要它,请拷贝到你项目中的assets目录,或在assets目录中建立链接cx链接到它,链接命令:ln -s ../../cx-framework3.1/cx cx
|
||||||
|
- **core:** cx-cocos框架实现类
|
||||||
|
- **prefab:** cx-cocos内置的预制资源
|
||||||
|
- **scripts:** cx-cocos内置的组件脚本
|
||||||
|
- **template:** cx-cocos提供的组件模板,在设计页面时可以使用它
|
||||||
|
- **cx-native:** 负责原生交互,你的iOS/mac工程需要它,android不需要(它已经在libcocos.so中)
|
||||||
|
- **cx.d.ts:** cx-cocos的TypeScript声明文件
|
||||||
|
|
||||||
|
|
||||||
|
>**demo的目录结构:**
|
||||||
|
- **project:** 原生工程都在这里了(并非creator构建生成的工程)
|
||||||
|
- **assets: 注意,** 它来源于cocos构建发布,你可以创建iOS、mac、android任意一种构建,将生成的assets拷贝到这里,建议你在这里建立一个assets链接,链接到你构建生成的assets目录,这样在每次重新构建后就不需再拷贝assets,链接命令:ln -s 路径 assets
|
||||||
|
- **boot:** 启动js和热更新manifest文件
|
||||||
|
- **cxdemo.android:** demo android studio工程
|
||||||
|
- **cxdemo.ios:** demo iOS/mac工程
|
||||||
|
- **statics:** 一些仅供原生使用的静态资源
|
||||||
|
- **update.js:** 生成热更新文件的脚本
|
||||||
|
- **其他目录:** cocos creator生成的目录
|
||||||
|
|
||||||
|
|
||||||
|
>**cx-cocos设计结构**
|
||||||
|
- 在ts层面,cx-cocos包括:
|
||||||
|
- cx: 常用变量、常用方法、UI方法
|
||||||
|
- cx.native: 与原生交互相关
|
||||||
|
- cx.picker: 选择器相关
|
||||||
|
- cx.res: 资源处理相关
|
||||||
|
- cx.script: 组件扩展功能脚本,例如为ScrollView扩展下拉刷新能力
|
||||||
|
- cx.serv: 服务交互相关
|
||||||
|
- cx.sys: 系统环境和配置相关
|
||||||
|
- 在原生层面,cx-cocos包括:
|
||||||
|
- cxnative: 原生JSB接口类,对应于cx.native的实现
|
||||||
|
- sysIntf: 内置的系统原生类,用于获取包名、环境等
|
||||||
|
- maskIntf:内置的遮罩原生类,用于给原生UI添加遮罩
|
||||||
|
|
||||||
|
>**cx-cocos运行机制**
|
||||||
|
- app启动首先加载boot.js,处理热更新,然后加载assets的main.js、cc.js等
|
||||||
|
- app加载cc.js后,加载项目js,cx作为项目的一部分被加载,cx作为全局对象存储于window.cx
|
||||||
|
- 在你的组件脚本中,你不需要import cx-cocos的任何脚本,因为它是全局的,直接使用就可以
|
||||||
|
- **整个app只有一个场景,所有页面都是预制资源**
|
||||||
|
- 在主场景中有一个根节点RootNode,负责滑动事件、android返回键的处理
|
||||||
|
- 你在config.ts中定义的startPage,在主场景启动时,被addPage到RootNode中
|
||||||
|
- 其他页面你可以通过addPage或showPage方法显示,默认会运行与页面同名的脚本(可在该方法的参数中指定加载的脚本)
|
||||||
|
- 通过addPage或showPage方法显示的页面,它们的parent都是RootNode
|
||||||
|
- 在addPage或showPage方法回调参数中,你可以向子页面传递参数或控制子页面
|
||||||
|
- 如果页面定义了onChildPageClosed方法,那么子页面在关闭时,会触发这个方法
|
||||||
|
- 你可以自定义页面进入和退出时的动画
|
||||||
|
- cx-cocos定义和实现了通用的原生交互方式
|
||||||
|
- 通过cx.native.ins("名称").call("方法", [...参数], 回调方法)调用原生方法
|
||||||
|
- 分别在iOS的jsIntf-ios.mm、android的jsIntf.java定义你自己的“名称”处理类
|
||||||
|
|
||||||
|
|
||||||
|
## 3 如何运行demo app
|
||||||
|
1. 安装cocos creator 3.1.1
|
||||||
|
2. 确保cx-framework3.1和cx3-demo在同一目录下
|
||||||
|
3. iOS/mac环境:在xcode中打开cx3-demo/project/cxdemo.ios/cx3-demo.xcodeproj,运行
|
||||||
|
4. android环境:在android studio中打开cx3-demo/project/cxdemo.android,运行
|
||||||
|
```typescript
|
||||||
|
* 在iOS/mac、android上编译或运行demo,你可以不需要打开cocos creator
|
||||||
|
* android的video遮罩暂未完成(技术困难,如果你有好的实现方式,请告诉我)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 4 如何使用cx-cocos开始一个自己的项目
|
||||||
|
1. 使用cocos creator3.1.1创建一个项目,与cx-framework3.1在同一目录下
|
||||||
|
```typescript
|
||||||
|
* 建议你使用cocos creator3.1.1 (2021.06.01发布)
|
||||||
|
* 如果你使用的是creator3.1.0,可能需要重新编译cx-framework3.1中.so和.a
|
||||||
|
重新编译前,可使用vscode编辑器,查找3.1.1,全部替换成3.1.0
|
||||||
|
* 如果你使用的是creator3.0.x,那么cx-framework3.1中的libs工程不适用,你需要从creator构建生成的项目中,提取cocos2d(支持3.0.x的框架我并未上传至git,如有需要请联系我)
|
||||||
|
```
|
||||||
|
2. 拷贝cx3-demo中的tsconfig.json文件和project目录到你的项目目录下
|
||||||
|
```typescript
|
||||||
|
* 拷贝tsconfig.json的目的仅仅是因为——它定义了cx.d.ts的引用,你也可以不拷贝而自行定义:
|
||||||
|
"compilerOptions": {"types": ["../cx-framework3.1/cx"]}
|
||||||
|
```
|
||||||
|
3. 根据自己的需要,修改project目录内的工程的内容
|
||||||
|
4. creator项目设置
|
||||||
|
- 项目数据
|
||||||
|
- 设计宽度:750
|
||||||
|
- 设计高度:1334
|
||||||
|
- 适配屏幕宽度:是
|
||||||
|
- 适配屏幕高度:否
|
||||||
|
- 功能裁剪:
|
||||||
|
- 去掉3D
|
||||||
|
- 去掉2D中的:2D物理系统、2D相交检测算法、2D粒子系统、Tiled地图、Spine动画
|
||||||
|
5. creator构建发布设置:
|
||||||
|
- 发布路径:不要填写成project,那会弄乱你的project目录,建议设置为native或build
|
||||||
|
- MD5缓存:不要勾选
|
||||||
|
- 替换插屏:**勾选,并且最小显示时间设置为0**
|
||||||
|
- 屏幕方向(Orientation):只勾选portrait
|
||||||
|
|
||||||
|
|
||||||
|
## 5 问题和技术支持
|
291
README.md
291
README.md
@ -1,2 +1,291 @@
|
|||||||
|
todo: Waiting for English translation
|
||||||
|
|
||||||
# cx-cocos
|
# cx-cocos
|
||||||
App development framework based on cocos creator3.1.0
|
**一个基于cocos creator3.1.1的应用App和游戏开发框架**
|
||||||
|
|
||||||
|
关键词:cocos creator、应用开发、App开发、游戏开发、跨平台、框架
|
||||||
|
|
||||||
|
cocos creator是一个开源的游戏开发引擎,在游戏开发方面,拥有大量开发者。然而在应用App方面,却少有人使用,cx-cocos的出现,填补了cocos creator在应用App开发上的空白。
|
||||||
|
|
||||||
|
使用cx-cocos,你可以轻松愉快地开发出一个跨平台应用App,包括ios、mac、android、web等,当然你也可以使用cx-cocos开发游戏,这是一个高效简洁的开发框架,极大提升开发者的效率。
|
||||||
|
|
||||||
|
**本说明文档包括以下内容:**
|
||||||
|
- cx-cocos主要功能
|
||||||
|
- cx-cocos结构和原理
|
||||||
|
- 如何运行demo app
|
||||||
|
- 如何使用cx-cocos开始一个自己的项目
|
||||||
|
- 问题和技术支持
|
||||||
|
|
||||||
|
|
||||||
|
## 1. 主要功能
|
||||||
|
**cx-cocos的主要功能包括以下内容:**
|
||||||
|
- 应用App的核心UI交互
|
||||||
|
- 页面和组件访问、资源访问、远程服务访问
|
||||||
|
- 与原生代码的交互
|
||||||
|
- 真正的启动屏
|
||||||
|
- 热更新
|
||||||
|
|
||||||
|
|
||||||
|
### 1.1 应用App的核心UI交互
|
||||||
|
----
|
||||||
|
cx-cocos在页面的显示与交互细节上,与iOS原生App有着相似的体验,
|
||||||
|
包括页面的进入退出与手势、提示弹窗、ScrollView、Loading等待、选择器等等。
|
||||||
|
cx3-demo是一个demo,建议你从它入手,了解cx-cocos。
|
||||||
|
|
||||||
|
- **屏幕适配:** 通常情况下,应用App是宽度适应(fitWidth)、高度随着屏幕高度自动铺满。cx-cocos提供了一个“最小设计宽/高度”的配置,即使在浏览器或Pad上,App也能按最佳的方式显示界面——你只需按你的设计尺寸来设计UI。
|
||||||
|
|
||||||
|
- **刘海屏适配:** 对于iphoneX等屏幕,通过添加cx.safearea脚本,可自动调节标题栏、内容层、底部导航栏的高度和位置。
|
||||||
|
|
||||||
|
- **界面进入与退出:** 动画进入与退出、手势划动退出、上一页面随动、阴影效果、响应android返回键。
|
||||||
|
|
||||||
|
- **对话框:** Alert提示框、Confirm确认框。框架还提供了一种Hint动画文字提示,你可以多点击几次试试。
|
||||||
|
|
||||||
|
- **选择器:** 框架提供了1栏或多栏的选择器,你可以轻松地实现年月日选择、年月选择、文字或对象列表选择。
|
||||||
|
|
||||||
|
- **ScrollView:** 扩展了下拉刷新、上滑增量添加数据的能力。
|
||||||
|
|
||||||
|
- **PageView:** 扩展了定时自动下一页、循环播放、点击回调的能力。
|
||||||
|
|
||||||
|
- **等待动画:** 可以在页面正中或任意控件内显示Loading动画,并且有延时显示能力,这在查询数据时非常实用,比如0.5秒后还没有返回数据,才显示Loading动画。
|
||||||
|
|
||||||
|
- **原生视图:** 原生UI在cocos UI中显示,并且随着ScrollView滚动或窗体滑动;原生UI遮罩能力,例如对话弹框、标题栏在原生UI之上显示,不被遮挡。
|
||||||
|
|
||||||
|
|
||||||
|
### 1.2 页面和组件访问、资源访问、远程服务访问
|
||||||
|
----
|
||||||
|
操作UI组件在应用开发中非常频繁,cx-cocos提供了便捷的方式对组件进行访问和操作。
|
||||||
|
|
||||||
|
| UI常用方法 | 说明 |
|
||||||
|
| ---- | ---- |
|
||||||
|
| cx.sw | 适配后的屏幕宽度 |
|
||||||
|
| cx.sh | 适配后的屏幕高度 |
|
||||||
|
| cx.gn(pageOrNode, nodeName) | 获取场景树中的节点 |
|
||||||
|
| setTouchCallback(page, callback, ...params) | 给Node添加点击事件 |
|
||||||
|
| cx.hint(content) | 显示提示 |
|
||||||
|
| cx.alert(content, callback?, labelOK?) | 显示对话窗 |
|
||||||
|
| cx.confrm(content, callback?, labelOK?, labelCancel?) | 显示确认窗 |
|
||||||
|
| cx.showLoading(page, parentNode, delayShowSeconds?) | 显示等待动画 |
|
||||||
|
| cx.removeLoading(parentNode) | 移除等待动画 |
|
||||||
|
| cx.addPage(parentNode, prefabName, scripts?, callbackOrParams, runAction?) | 添加一个页面 |
|
||||||
|
| cx.showPage(prefabName, scripts?, callbackOrParams) | 添加一个页面(动画进入) |
|
||||||
|
| cx.closePage(pageOrSender) | 关闭本页面 |
|
||||||
|
| | |
|
||||||
|
|
||||||
|
**示例代码:**
|
||||||
|
```typescript
|
||||||
|
var lblTitle: Node = cx.gn(this, "lblTitle"); //获取场景树中的名称为lblTitle的节点
|
||||||
|
|
||||||
|
//给lblTitle添加一个点击事件
|
||||||
|
lblTitle.setTouchCallback(this, this.myClick);
|
||||||
|
|
||||||
|
//你也可以定义回调时的参数:
|
||||||
|
lblTitle.setTouchCallback(this, this.myClick, 1, "a", {tip:"任意类型和数量的参数"});
|
||||||
|
|
||||||
|
myClick(sender, p1, p2, p3)
|
||||||
|
{
|
||||||
|
//sender = lblTitle
|
||||||
|
//p1 = 1
|
||||||
|
//p2 = "a"
|
||||||
|
//p3 = {remark:"任意类型和数量的参数"}
|
||||||
|
}
|
||||||
|
|
||||||
|
cx.showPage("ui/pageChild"); //显示ui/pageChild.prefab
|
||||||
|
cx.hint("cx.hint(content)");
|
||||||
|
cx.alert("cx.alert(content, callback, labelOk)");
|
||||||
|
cx.confirm("cx.confirm(content, callback, labelOk, labelCancel)", cx.hint);
|
||||||
|
cx.showLoading(this);
|
||||||
|
cx.removeLoading(this);
|
||||||
|
cx.closePage(this);
|
||||||
|
|
||||||
|
//给scrollView添加增量新增数据能力
|
||||||
|
cx.script.scrollView.initDeltaInsert(this, "view", this.queryData);
|
||||||
|
|
||||||
|
//给scrollView添加下拉刷新能力
|
||||||
|
cx.script.scrollView.initDropRefresh(this, "view", this.refreshData);
|
||||||
|
|
||||||
|
//给PageView添加自动循环滚动能力
|
||||||
|
cx.script.pageView.initAutoScroll(this, "viewBanner", 2, true, this.onBannerClick);
|
||||||
|
````
|
||||||
|
|
||||||
|
| 资源常用方法 | 说明 |
|
||||||
|
| ---- | ---- |
|
||||||
|
| cx.setImageFromRes(spriteOrNode, prefab, sizeMode?, callback?) | 给节点设置图片(从resources) |
|
||||||
|
| cx.setImageFromBundle(spriteOrNode, prefab, sizeMode?, callback?) | 给节点设置图片(从bundle) |
|
||||||
|
| cx.setImageFromRemote(spriteOrNode, url, localPath?, sizeMode?, callback?) | 给节点设置图片(从远程url,存储至本地localPath,并优先从localPath加载图片) |
|
||||||
|
| cx.loadBundleRes(prefab, callback?) | 加载1个或多个prefab |
|
||||||
|
| | |
|
||||||
|
|
||||||
|
|
||||||
|
| 远程访问常用方法 | 说明 |
|
||||||
|
| ---- | ---- |
|
||||||
|
| cx.call(url, callback?, context?) | 调用服务端服务(call方式) |
|
||||||
|
| cx.post(url, data?, callback?, context?) | 调用服务端服务(post方式) |
|
||||||
|
| cx.upload(url, filePath, callback?) | 调用服务端服务,上传文件 |
|
||||||
|
| cx.setCommonHeaders(headers: string[]) | 设置http请求的默认headers |
|
||||||
|
| cx.loadFile(url, localPath?, callback?) | 从url加载文件,存储至本地并优先从本地加载 |
|
||||||
|
| cx.loadAsset(url: string, callback?) | 从url加载Asset |
|
||||||
|
| | |
|
||||||
|
|
||||||
|
|
||||||
|
| utils常用方法 | 说明 |
|
||||||
|
| ---- | ---- |
|
||||||
|
| cx.utils.xxx | cx.func中定义了常用的工具方法,如时间等,具体参见cx.d.ts |
|
||||||
|
| | |
|
||||||
|
|
||||||
|
|
||||||
|
### 1.3 与原生代码的交互
|
||||||
|
----
|
||||||
|
cx-cocos提供了一个cxnative原生类,通过它可以方便地与原生代码、第三方SDK交互。
|
||||||
|
与iOS/mac的交互是通过jsb/c++ ———— 避免了苹果审核风险
|
||||||
|
与android的交互是通过jsb.reflection
|
||||||
|
|
||||||
|
* 可参照demo中的SystemIntf编写你自己的原生类
|
||||||
|
|
||||||
|
**原生类的定义:**
|
||||||
|
iOS/mac:在jsIntf.cpp中定义你的类名和处理类,类继承自cxDefine.h中的NativeIntfClass
|
||||||
|
android:在jsIntf.java中定义你的类名和处理类
|
||||||
|
|
||||||
|
- 在JavaScript/TypeScript中调用原生方法:
|
||||||
|
```typescript
|
||||||
|
cx.native.ins("className").call("functionName", [...params], callback);
|
||||||
|
````
|
||||||
|
|
||||||
|
- 在iOS/mac中调用JS方法:
|
||||||
|
```c++
|
||||||
|
this->callback(int, string);
|
||||||
|
````
|
||||||
|
|
||||||
|
- 在android中调用JS方法:
|
||||||
|
```java
|
||||||
|
NativeIntf.callJs("className", int, string);
|
||||||
|
````
|
||||||
|
|
||||||
|
|
||||||
|
### 1.4 真正的启动屏
|
||||||
|
----
|
||||||
|
cocos creator提供了一个定时长的启动画面,你无法在首页渲染完成后再移除画面,也无法提前移除。并且它只能在加载cc.js之后显示,而不是在App真正启动时。
|
||||||
|
cx-cocos针对iOS/mac和Android,提供了原生的启动画面处理,你可以在App启动时显示,在任意时刻移除。
|
||||||
|
|
||||||
|
iOS/mac启动屏实现代码:见demo中的AppController.mm
|
||||||
|
android启动屏实现代码:见demo中的CocosActivity.java
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ios/Mac: LaunchImage.png
|
||||||
|
// android: lanuch_image.png
|
||||||
|
// 移除启动屏,如果你在config.ts中配置了自动移除,那么不需要执行这句,cx会在开始页(startPage)加入场景时自动调用
|
||||||
|
cx.removeLaunchImage();
|
||||||
|
````
|
||||||
|
|
||||||
|
|
||||||
|
### 1.5 热更新
|
||||||
|
----
|
||||||
|
cx-cocos在执行main.js之前执行热更新。
|
||||||
|
cx-cocos提供了一个update.js工具用于生成热更新需要的manifest文件,执行命令为:
|
||||||
|
$ node update.js -v 1.0
|
||||||
|
* 在执行之前,你需要将update.js中的更新地址替换为你的服务器地址。
|
||||||
|
|
||||||
|
****实现原理:见demo中的boot.js***
|
||||||
|
|
||||||
|
|
||||||
|
## 2. cx-cocos结构和原理
|
||||||
|
|
||||||
|
>**cx-framework目录结构:**
|
||||||
|
- **cocos3-libs:** 这里是从creator构建项目中提取的引擎libs,我们把它独立出来,所有项目就只需要assets
|
||||||
|
- **cocos-libcc:** cocos android jar,你的android工程需要依赖它
|
||||||
|
- **cocos-libso:** cocos android so,编译生成libcocos.so的工程,android需要这个.so
|
||||||
|
- **cocos3-ios.xcodeproj:** 编译生成libcocos3 iOS.a的工程,iOS需要这个.a
|
||||||
|
- **cocos3-mac.xcodeproj:** 编译生成libcocos3 Mac.a的工程,mac需要这个.a
|
||||||
|
- **cx:** cx-cocos的ts代码,你的creator工程需要它,请拷贝到你项目中的assets目录,或在assets目录中建立链接cx链接到它,链接命令:ln -s ../../cx-framework3.1/cx cx
|
||||||
|
- **core:** cx-cocos框架实现类
|
||||||
|
- **prefab:** cx-cocos内置的预制资源
|
||||||
|
- **scripts:** cx-cocos内置的组件脚本
|
||||||
|
- **template:** cx-cocos提供的组件模板,在设计页面时可以使用它
|
||||||
|
- **cx-native:** 负责原生交互,你的iOS/mac工程需要它,android不需要(它已经在libcocos.so中)
|
||||||
|
- **cx.d.ts:** cx-cocos的TypeScript声明文件
|
||||||
|
|
||||||
|
|
||||||
|
>**demo的目录结构:**
|
||||||
|
- **project:** 原生工程都在这里了(并非creator构建生成的工程)
|
||||||
|
- **assets: 注意,** 它来源于cocos构建发布,你可以创建iOS、mac、android任意一种构建,将生成的assets拷贝到这里,建议你在这里建立一个assets链接,链接到你构建生成的assets目录,这样在每次重新构建后就不需再拷贝assets,链接命令:ln -s 路径 assets
|
||||||
|
- **boot:** 启动js和热更新manifest文件
|
||||||
|
- **cxdemo.android:** demo android studio工程
|
||||||
|
- **cxdemo.ios:** demo iOS/mac工程
|
||||||
|
- **statics:** 一些仅供原生使用的静态资源
|
||||||
|
- **update.js:** 生成热更新文件的脚本
|
||||||
|
- **其他目录:** cocos creator生成的目录
|
||||||
|
|
||||||
|
|
||||||
|
>**cx-cocos设计结构**
|
||||||
|
- 在ts层面,cx-cocos包括:
|
||||||
|
- cx: 常用变量、常用方法、UI方法
|
||||||
|
- cx.native: 与原生交互相关
|
||||||
|
- cx.picker: 选择器相关
|
||||||
|
- cx.res: 资源处理相关
|
||||||
|
- cx.script: 组件扩展功能脚本,例如为ScrollView扩展下拉刷新能力
|
||||||
|
- cx.serv: 服务交互相关
|
||||||
|
- cx.sys: 系统环境和配置相关
|
||||||
|
- 在原生层面,cx-cocos包括:
|
||||||
|
- cxnative: 原生JSB接口类,对应于cx.native的实现
|
||||||
|
- sysIntf: 内置的系统原生类,用于获取包名、环境等
|
||||||
|
- maskIntf:内置的遮罩原生类,用于给原生UI添加遮罩
|
||||||
|
|
||||||
|
>**cx-cocos运行机制**
|
||||||
|
- app启动首先加载boot.js,处理热更新,然后加载assets的main.js、cc.js等
|
||||||
|
- app加载cc.js后,加载项目js,cx作为项目的一部分被加载,cx作为全局对象存储于window.cx
|
||||||
|
- 在你的组件脚本中,你不需要import cx-cocos的任何脚本,因为它是全局的,直接使用就可以
|
||||||
|
- **整个app只有一个场景,所有页面都是预制资源**
|
||||||
|
- 在主场景中有一个根节点RootNode,负责滑动事件、android返回键的处理
|
||||||
|
- 你在config.ts中定义的startPage,在主场景启动时,被addPage到RootNode中
|
||||||
|
- 其他页面你可以通过addPage或showPage方法显示,默认会运行与页面同名的脚本(可在该方法的参数中指定加载的脚本)
|
||||||
|
- 通过addPage或showPage方法显示的页面,它们的parent都是RootNode
|
||||||
|
- 在addPage或showPage方法回调参数中,你可以向子页面传递参数或控制子页面
|
||||||
|
- 如果页面定义了onChildPageClosed方法,那么子页面在关闭时,会触发这个方法
|
||||||
|
- 你可以自定义页面进入和退出时的动画
|
||||||
|
- cx-cocos定义和实现了通用的原生交互方式
|
||||||
|
- 通过cx.native.ins("名称").call("方法", [...参数], 回调方法)调用原生方法
|
||||||
|
- 分别在iOS的jsIntf-ios.mm、android的jsIntf.java定义你自己的“名称”处理类
|
||||||
|
|
||||||
|
|
||||||
|
## 3 如何运行demo app
|
||||||
|
1. 安装cocos creator 3.1.1
|
||||||
|
2. 确保cx-framework3.1和cx3-demo在同一目录下
|
||||||
|
3. iOS/mac环境:在xcode中打开cx3-demo/project/cxdemo.ios/cx3-demo.xcodeproj,运行
|
||||||
|
4. android环境:在android studio中打开cx3-demo/project/cxdemo.android,运行
|
||||||
|
```typescript
|
||||||
|
* 在iOS/mac、android上编译或运行demo,你可以不需要打开cocos creator
|
||||||
|
* android的video遮罩暂未完成(技术困难,如果你有好的实现方式,请告诉我)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 4 如何使用cx-cocos开始一个自己的项目
|
||||||
|
1. 使用cocos creator3.1.1创建一个项目,与cx-framework3.1在同一目录下
|
||||||
|
```typescript
|
||||||
|
* 建议你使用cocos creator3.1.1 (2021.06.01发布)
|
||||||
|
* 如果你使用的是creator3.1.0,可能需要重新编译cx-framework3.1中.so和.a
|
||||||
|
重新编译前,可使用vscode编辑器,查找3.1.1,全部替换成3.1.0
|
||||||
|
* 如果你使用的是creator3.0.x,那么cx-framework3.1中的libs工程不适用,你需要从creator构建生成的项目中,提取cocos2d(支持3.0.x的框架我并未上传至git,如有需要请联系我)
|
||||||
|
```
|
||||||
|
2. 拷贝cx3-demo中的tsconfig.json文件和project目录到你的项目目录下
|
||||||
|
```typescript
|
||||||
|
* 拷贝tsconfig.json的目的仅仅是因为——它定义了cx.d.ts的引用,你也可以不拷贝而自行定义:
|
||||||
|
"compilerOptions": {"types": ["../cx-framework3.1/cx"]}
|
||||||
|
```
|
||||||
|
3. 根据自己的需要,修改project目录内的工程的内容
|
||||||
|
4. creator项目设置
|
||||||
|
- 项目数据
|
||||||
|
- 设计宽度:750
|
||||||
|
- 设计高度:1334
|
||||||
|
- 适配屏幕宽度:是
|
||||||
|
- 适配屏幕高度:否
|
||||||
|
- 功能裁剪:
|
||||||
|
- 去掉3D
|
||||||
|
- 去掉2D中的:2D物理系统、2D相交检测算法、2D粒子系统、Tiled地图、Spine动画
|
||||||
|
5. creator构建发布设置:
|
||||||
|
- 发布路径:不要填写成project,那会弄乱你的project目录,建议设置为native或build
|
||||||
|
- MD5缓存:不要勾选
|
||||||
|
- 替换插屏:**勾选,并且最小显示时间设置为0**
|
||||||
|
- 屏幕方向(Orientation):只勾选portrait
|
||||||
|
|
||||||
|
|
||||||
|
## 5 问题和技术支持
|
||||||
|
|
||||||
|
3232
cx-framework3.1/cocos3-libs/cocos3-ios.xcodeproj/project.pbxproj
Normal file
3232
cx-framework3.1/cocos3-libs/cocos3-ios.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load Diff
7
cx-framework3.1/cocos3-libs/cocos3-ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
cx-framework3.1/cocos3-libs/cocos3-ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:/Users/blank/ccapp3/cx-framework3.1/cocos3-libs/cocos3-ios.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>BuildSystemType</key>
|
||||||
|
<string>Latest</string>
|
||||||
|
<key>DisableBuildSystemDeprecationWarning</key>
|
||||||
|
<true/>
|
||||||
|
<key>PreviewsEnabled</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
Binary file not shown.
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>BuildLocationStyle</key>
|
||||||
|
<string>UseAppPreferences</string>
|
||||||
|
<key>CustomBuildIntermediatesPath</key>
|
||||||
|
<string>cocos3.1-libs/Intermediates.noindex</string>
|
||||||
|
<key>CustomBuildLocationType</key>
|
||||||
|
<string>RelativeToDerivedData</string>
|
||||||
|
<key>CustomBuildProductsPath</key>
|
||||||
|
<string>cocos3.1-libs/Products</string>
|
||||||
|
<key>DerivedDataLocationStyle</key>
|
||||||
|
<string>Default</string>
|
||||||
|
<key>IssueFilterStyle</key>
|
||||||
|
<string>ShowActiveSchemeOnly</string>
|
||||||
|
<key>LiveSourceIssuesEnabled</key>
|
||||||
|
<true/>
|
||||||
|
<key>ShowSharedSchemesAutomaticallyEnabled</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1240"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "46916E52264CD4B0000C7B53"
|
||||||
|
BuildableName = "libcocos3 iOS.a"
|
||||||
|
BlueprintName = "cocos3 iOS"
|
||||||
|
ReferencedContainer = "container:cocos3-iOS.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<Testables>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "46916E52264CD4B0000C7B53"
|
||||||
|
BuildableName = "libcocos3 iOS.a"
|
||||||
|
BlueprintName = "cocos3 iOS"
|
||||||
|
ReferencedContainer = "container:cocos3-iOS.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>SchemeUserState</key>
|
||||||
|
<dict>
|
||||||
|
<key>cocos3 iOS.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>SuppressBuildableAutocreation</key>
|
||||||
|
<dict>
|
||||||
|
<key>46916BBC264CCEF4000C7B53</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>46916D11264CD362000C7B53</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>46916E52264CD4B0000C7B53</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>C0436D9181584B92A7E37006</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,4 @@
|
|||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cocos.lib">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
|
</manifest>
|
33
cx-framework3.1/cocos3-libs/cocos3-libcc/build.gradle
Normal file
33
cx-framework3.1/cocos3-libs/cocos3-libcc/build.gradle
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
apply plugin: 'com.android.library'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
minSdkVersion PROP_MIN_SDK_VERSION
|
||||||
|
targetSdkVersion PROP_TARGET_SDK_VERSION
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets.main {
|
||||||
|
aidl.srcDir "../java/src"
|
||||||
|
java.srcDir "../java/src"
|
||||||
|
manifest.srcFile "AndroidManifest.xml"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(include: ['*.jar'], dir: '../java/libs')
|
||||||
|
}
|
Binary file not shown.
BIN
cx-framework3.1/cocos3-libs/cocos3-libcc/libs/okhttp-3.12.7.jar
Normal file
BIN
cx-framework3.1/cocos3-libs/cocos3-libcc/libs/okhttp-3.12.7.jar
Normal file
Binary file not shown.
BIN
cx-framework3.1/cocos3-libs/cocos3-libcc/libs/okio-1.15.0.jar
Normal file
BIN
cx-framework3.1/cocos3-libs/cocos3-libcc/libs/okio-1.15.0.jar
Normal file
Binary file not shown.
17
cx-framework3.1/cocos3-libs/cocos3-libcc/proguard-rules.pro
vendored
Normal file
17
cx-framework3.1/cocos3-libs/cocos3-libcc/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in E:\developSoftware\Android\SDK/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<!-- 填充颜色 -->
|
||||||
|
<solid android:color="@color/navy"></solid>
|
||||||
|
|
||||||
|
<!-- 线的宽度,颜色 -->
|
||||||
|
<stroke android:width="0dp" android:color="@color/navy"></stroke>
|
||||||
|
|
||||||
|
<!-- 矩形的圆角半径 -->
|
||||||
|
<corners android:radius="20dp" />
|
||||||
|
</shape>
|
||||||
|
|
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<!-- 填充颜色 -->
|
||||||
|
<solid android:color="#00000000"></solid>
|
||||||
|
|
||||||
|
<!-- 线的宽度,颜色 -->
|
||||||
|
<stroke android:width="1dp" android:color="@color/navy"></stroke>
|
||||||
|
|
||||||
|
<!-- 矩形的圆角半径 -->
|
||||||
|
<corners android:radius="20dp" />
|
||||||
|
</shape>
|
||||||
|
|
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
|
<size android:width="4dp"
|
||||||
|
android:height="4dp" />
|
||||||
|
|
||||||
|
<solid android:color="@android:color/transparent" />
|
||||||
|
</shape>
|
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<!-- 填充颜色 -->
|
||||||
|
<solid android:color="#33fff000"></solid>
|
||||||
|
|
||||||
|
<!-- 线的宽度,颜色 -->
|
||||||
|
<stroke android:width="1dp" android:color="@color/navy"></stroke>
|
||||||
|
|
||||||
|
<!-- 矩形的圆角半径 -->
|
||||||
|
<corners android:radius="6dp" />
|
||||||
|
|
||||||
|
<padding android:left="5dp" android:right="5dp" />
|
||||||
|
</shape>
|
||||||
|
|
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<!-- 填充颜色 -->
|
||||||
|
<solid android:color="@color/white_e0"></solid>
|
||||||
|
|
||||||
|
<!-- 线的宽度,颜色 -->
|
||||||
|
<stroke android:width="1dp" android:color="@color/gray9"></stroke>
|
||||||
|
|
||||||
|
<!-- 矩形的圆角半径 -->
|
||||||
|
<corners android:radius="6dp" />
|
||||||
|
|
||||||
|
<padding android:left="5dp" android:right="5dp" />
|
||||||
|
</shape>
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<!-- 填充颜色 -->
|
||||||
|
<solid android:color="@color/white_f7"></solid>
|
||||||
|
|
||||||
|
<!-- 线的宽度,颜色 -->
|
||||||
|
<stroke android:width="1dp" android:color="@color/gray9"></stroke>
|
||||||
|
|
||||||
|
<!-- 矩形的圆角半径 -->
|
||||||
|
<corners android:radius="6dp" />
|
||||||
|
|
||||||
|
<padding android:left="5dp" android:right="5dp" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
|
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_selected="true" android:drawable="@drawable/edit_focus"/>
|
||||||
|
<item android:state_focused="true" android:drawable="@drawable/edit_focus" />
|
||||||
|
<item android:state_pressed="true" android:drawable="@drawable/edit_focus"/>
|
||||||
|
<item android:drawable="@drawable/edit_normal"/>
|
||||||
|
</selector>
|
Binary file not shown.
After Width: | Height: | Size: 155 B |
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!--EditBox Confirm Button Name-->
|
||||||
|
<string name="done" translatable="false">完成</string>
|
||||||
|
<string name="next" translatable="false">下一个</string>
|
||||||
|
<string name="search" translatable="false">搜索</string>
|
||||||
|
<string name="go" translatable="false">前往</string>
|
||||||
|
<string name="send" translatable="false">发送</string>
|
||||||
|
</resources>
|
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<color name="none">#00000000</color>
|
||||||
|
<color name="white">#ffffff</color>
|
||||||
|
<color name="white_f7">#f7f7f7</color>
|
||||||
|
<color name="white_f0">#f0f0f0</color>
|
||||||
|
<color name="white_d0">#d0d0d0</color>
|
||||||
|
<color name="white_e0">#e0e0e0</color>
|
||||||
|
<color name="black">#000000</color>
|
||||||
|
<color name="gray3">#333333</color>
|
||||||
|
<color name="gray4">#444444</color>
|
||||||
|
<color name="gray7">#777777</color>
|
||||||
|
<color name="gray9">#999999</color>
|
||||||
|
<color name="red">#ff0000</color>
|
||||||
|
<color name="red1">#e51300</color>
|
||||||
|
<color name="red2">#ff6900</color>
|
||||||
|
<color name="blue">#0000ff</color>
|
||||||
|
<color name="blue1">#009ecf</color>
|
||||||
|
<color name="blue2">#41a9b6</color>
|
||||||
|
<color name="navy">#333b73</color>
|
||||||
|
<color name="navy1">#1d2241</color>
|
||||||
|
<color name="green">#00ff00</color>
|
||||||
|
<color name="yellow">#ffff00</color>
|
||||||
|
<color name="gold">#fff000</color>
|
||||||
|
|
||||||
|
</resources>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<dimen name="title_size">16sp</dimen>
|
||||||
|
|
||||||
|
</resources>
|
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<!--EditBox Confirm Button Title-->
|
||||||
|
<string name="done" translatable="false">Done</string>
|
||||||
|
<string name="next" translatable="false">Next</string>
|
||||||
|
<string name="search" translatable="false">Search</string>
|
||||||
|
<string name="go" translatable="false">Go</string>
|
||||||
|
<string name="send" translatable="false">Send</string>
|
||||||
|
</resources>
|
@ -0,0 +1,18 @@
|
|||||||
|
<resources>
|
||||||
|
|
||||||
|
<style name="notAnimation">
|
||||||
|
<item name="android:activityOpenEnterAnimation">@null</item>
|
||||||
|
<item name="android:activityOpenExitAnimation">@null</item>
|
||||||
|
<item name="android:activityCloseEnterAnimation">@null</item>
|
||||||
|
<item name="android:activityCloseExitAnimation">@null</item>
|
||||||
|
<item name="android:taskOpenEnterAnimation">@null</item>
|
||||||
|
<item name="android:taskOpenExitAnimation">@null</item>
|
||||||
|
<item name="android:taskCloseEnterAnimation">@null</item>
|
||||||
|
<item name="android:taskCloseExitAnimation">@null</item>
|
||||||
|
<item name="android:taskToFrontEnterAnimation">@null</item>
|
||||||
|
<item name="android:taskToFrontExitAnimation">@null</item>
|
||||||
|
<item name="android:taskToBackEnterAnimation">@null</item>
|
||||||
|
<item name="android:taskToBackExitAnimation">@null</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
@ -0,0 +1,509 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
*
|
||||||
|
* http://www.cocos.com
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Path;
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.text.TextPaint;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class CanvasRenderingContext2DImpl {
|
||||||
|
|
||||||
|
private static final String TAG = "CanvasContext2D";
|
||||||
|
|
||||||
|
private static final int TEXT_ALIGN_LEFT = 0;
|
||||||
|
private static final int TEXT_ALIGN_CENTER = 1;
|
||||||
|
private static final int TEXT_ALIGN_RIGHT = 2;
|
||||||
|
|
||||||
|
private static final int TEXT_BASELINE_TOP = 0;
|
||||||
|
private static final int TEXT_BASELINE_MIDDLE = 1;
|
||||||
|
private static final int TEXT_BASELINE_BOTTOM = 2;
|
||||||
|
private static final int TEXT_BASELINE_ALPHABETIC = 3;
|
||||||
|
|
||||||
|
private static WeakReference<Context> sContext;
|
||||||
|
private TextPaint mTextPaint;
|
||||||
|
private Paint mLinePaint;
|
||||||
|
private Path mLinePath;
|
||||||
|
private Canvas mCanvas = new Canvas();
|
||||||
|
private Bitmap mBitmap;
|
||||||
|
private int mTextAlign = TEXT_ALIGN_LEFT;
|
||||||
|
private int mTextBaseline = TEXT_BASELINE_BOTTOM;
|
||||||
|
private int mFillStyleR = 0;
|
||||||
|
private int mFillStyleG = 0;
|
||||||
|
private int mFillStyleB = 0;
|
||||||
|
private int mFillStyleA = 255;
|
||||||
|
|
||||||
|
private int mStrokeStyleR = 0;
|
||||||
|
private int mStrokeStyleG = 0;
|
||||||
|
private int mStrokeStyleB = 0;
|
||||||
|
private int mStrokeStyleA = 255;
|
||||||
|
|
||||||
|
private String mFontName = "Arial";
|
||||||
|
private float mFontSize = 40.0f;
|
||||||
|
private float mLineWidth = 0.0f;
|
||||||
|
private static float _sApproximatingOblique = -0.25f;//please check paint api documentation
|
||||||
|
private boolean mIsBoldFont = false;
|
||||||
|
private boolean mIsItalicFont = false;
|
||||||
|
private boolean mIsObliqueFont = false;
|
||||||
|
private boolean mIsSmallCapsFontVariant = false;
|
||||||
|
private String mLineCap = "butt";
|
||||||
|
private String mLineJoin = "miter";
|
||||||
|
|
||||||
|
private class Size {
|
||||||
|
Size(float w, float h) {
|
||||||
|
this.width = w;
|
||||||
|
this.height = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size() {
|
||||||
|
this.width = 0;
|
||||||
|
this.height = 0;
|
||||||
|
}
|
||||||
|
public float width;
|
||||||
|
public float height;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Point {
|
||||||
|
Point(float x, float y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point() {
|
||||||
|
this.x = this.y = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point(Point pt) {
|
||||||
|
this.x = pt.x;
|
||||||
|
this.y = pt.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(float x, float y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float x;
|
||||||
|
public float y;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init(Context context) {
|
||||||
|
sContext = new WeakReference<>(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroy() {
|
||||||
|
sContext = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HashMap<String, Typeface> sTypefaceCache = new HashMap<>();
|
||||||
|
|
||||||
|
// url is a full path started with '@assets/'
|
||||||
|
private static void loadTypeface(String familyName, String url) {
|
||||||
|
if (!sTypefaceCache.containsKey(familyName)) {
|
||||||
|
try {
|
||||||
|
Typeface typeface = null;
|
||||||
|
if (url.startsWith("/")) {
|
||||||
|
typeface = Typeface.createFromFile(url);
|
||||||
|
} else if (sContext.get() != null) {
|
||||||
|
final String prefix = "@assets/";
|
||||||
|
if (url.startsWith(prefix)) {
|
||||||
|
url = url.substring(prefix.length());
|
||||||
|
}
|
||||||
|
typeface = Typeface.createFromAsset(sContext.get().getAssets(), url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeface != null) {
|
||||||
|
sTypefaceCache.put(familyName, typeface);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// REFINE:: native should clear font cache before exiting game.
|
||||||
|
private static void clearTypefaceCache() {
|
||||||
|
sTypefaceCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TextPaint newPaint(String fontName, int fontSize, boolean enableBold, boolean enableItalic, boolean obliqueFont, boolean smallCapsFontVariant) {
|
||||||
|
TextPaint paint = new TextPaint();
|
||||||
|
paint.setTextSize(fontSize);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
paint.setSubpixelText(true);
|
||||||
|
|
||||||
|
String key = fontName;
|
||||||
|
if (enableBold) {
|
||||||
|
key += "-Bold";
|
||||||
|
paint.setFakeBoldText(true);
|
||||||
|
}
|
||||||
|
if (enableItalic) {
|
||||||
|
key += "-Italic";
|
||||||
|
}
|
||||||
|
|
||||||
|
Typeface typeFace;
|
||||||
|
if (sTypefaceCache.containsKey(key)) {
|
||||||
|
typeFace = sTypefaceCache.get(key);
|
||||||
|
} else {
|
||||||
|
int style = Typeface.NORMAL;
|
||||||
|
if (enableBold && enableItalic) {
|
||||||
|
style = Typeface.BOLD_ITALIC;
|
||||||
|
} else if (enableBold) {
|
||||||
|
style = Typeface.BOLD;
|
||||||
|
} else if (enableItalic) {
|
||||||
|
style = Typeface.ITALIC;
|
||||||
|
}
|
||||||
|
typeFace = Typeface.create(fontName, style);
|
||||||
|
}
|
||||||
|
paint.setTypeface(typeFace);
|
||||||
|
if(obliqueFont) {
|
||||||
|
paint.setTextSkewX(_sApproximatingOblique);
|
||||||
|
}
|
||||||
|
if(smallCapsFontVariant && Build.VERSION.SDK_INT >= 21) {
|
||||||
|
CocosReflectionHelper.<Void>invokeInstanceMethod(paint,
|
||||||
|
"setFontFeatureSettings",
|
||||||
|
new Class[]{String.class},
|
||||||
|
new Object[]{"smcp"});
|
||||||
|
}
|
||||||
|
return paint;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CanvasRenderingContext2DImpl() {
|
||||||
|
// Log.d(TAG, "constructor");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void recreateBuffer(float w, float h) {
|
||||||
|
// Log.d(TAG, "recreateBuffer:" + w + ", " + h);
|
||||||
|
if (mBitmap != null) {
|
||||||
|
mBitmap.recycle();
|
||||||
|
}
|
||||||
|
mBitmap = Bitmap.createBitmap((int)Math.ceil(w), (int)Math.ceil(h), Bitmap.Config.ARGB_8888);
|
||||||
|
// FIXME: in MIX 2S, its API level is 28, but can not find invokeInstanceMethod. It seems
|
||||||
|
// devices may not obey the specification, so comment the codes.
|
||||||
|
// if (Build.VERSION.SDK_INT >= 19) {
|
||||||
|
// CocosReflectionHelper.<Void>invokeInstanceMethod(mBitmap,
|
||||||
|
// "setPremultiplied",
|
||||||
|
// new Class[]{Boolean.class},
|
||||||
|
// new Object[]{Boolean.FALSE});
|
||||||
|
// }
|
||||||
|
mCanvas.setBitmap(mBitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void beginPath() {
|
||||||
|
if (mLinePath == null) {
|
||||||
|
mLinePath = new Path();
|
||||||
|
}
|
||||||
|
mLinePath.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closePath() {
|
||||||
|
mLinePath.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveTo(float x, float y) {
|
||||||
|
mLinePath.moveTo(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void lineTo(float x, float y) {
|
||||||
|
mLinePath.lineTo(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stroke() {
|
||||||
|
if (mLinePaint == null) {
|
||||||
|
mLinePaint = new Paint();
|
||||||
|
mLinePaint.setAntiAlias(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mLinePath == null) {
|
||||||
|
mLinePath = new Path();
|
||||||
|
}
|
||||||
|
|
||||||
|
mLinePaint.setARGB(mStrokeStyleA, mStrokeStyleR, mStrokeStyleG, mStrokeStyleB);
|
||||||
|
mLinePaint.setStyle(Paint.Style.STROKE);
|
||||||
|
mLinePaint.setStrokeWidth(mLineWidth);
|
||||||
|
this.setStrokeCap(mLinePaint);
|
||||||
|
this.setStrokeJoin(mLinePaint);
|
||||||
|
mCanvas.drawPath(mLinePath, mLinePaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setStrokeCap(Paint paint) {
|
||||||
|
switch (mLineCap) {
|
||||||
|
case "butt":
|
||||||
|
paint.setStrokeCap(Paint.Cap.BUTT);
|
||||||
|
break;
|
||||||
|
case "round":
|
||||||
|
paint.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
break;
|
||||||
|
case "square":
|
||||||
|
paint.setStrokeCap(Paint.Cap.SQUARE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setStrokeJoin(Paint paint) {
|
||||||
|
switch (mLineJoin) {
|
||||||
|
case "bevel":
|
||||||
|
paint.setStrokeJoin(Paint.Join.BEVEL);
|
||||||
|
break;
|
||||||
|
case "round":
|
||||||
|
paint.setStrokeJoin(Paint.Join.ROUND);
|
||||||
|
break;
|
||||||
|
case "miter":
|
||||||
|
paint.setStrokeJoin(Paint.Join.MITER);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fill() {
|
||||||
|
if (mLinePaint == null) {
|
||||||
|
mLinePaint = new Paint();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mLinePath == null) {
|
||||||
|
mLinePath = new Path();
|
||||||
|
}
|
||||||
|
|
||||||
|
mLinePaint.setARGB(mFillStyleA, mFillStyleR, mFillStyleG, mFillStyleB);
|
||||||
|
mLinePaint.setStyle(Paint.Style.FILL);
|
||||||
|
mCanvas.drawPath(mLinePath, mLinePaint);
|
||||||
|
// workaround: draw a hairline to cover the border
|
||||||
|
mLinePaint.setStrokeWidth(0);
|
||||||
|
this.setStrokeCap(mLinePaint);
|
||||||
|
this.setStrokeJoin(mLinePaint);
|
||||||
|
mLinePaint.setStyle(Paint.Style.STROKE);
|
||||||
|
mCanvas.drawPath(mLinePath, mLinePaint);
|
||||||
|
mLinePaint.setStrokeWidth(mLineWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLineCap(String lineCap) {
|
||||||
|
mLineCap = lineCap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLineJoin(String lineJoin) {
|
||||||
|
mLineJoin = lineJoin;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveContext() {
|
||||||
|
mCanvas.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restoreContext() {
|
||||||
|
// If there is no saved state, this method should do nothing.
|
||||||
|
if (mCanvas.getSaveCount() > 1){
|
||||||
|
mCanvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rect(float x, float y, float w, float h) {
|
||||||
|
// Log.d(TAG, "this: " + this + ", rect: " + x + ", " + y + ", " + w + ", " + h);
|
||||||
|
beginPath();
|
||||||
|
moveTo(x, y);
|
||||||
|
lineTo(x, y + h);
|
||||||
|
lineTo(x + w, y + h);
|
||||||
|
lineTo(x + w, y);
|
||||||
|
closePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearRect(float x, float y, float w, float h) {
|
||||||
|
// Log.d(TAG, "this: " + this + ", clearRect: " + x + ", " + y + ", " + w + ", " + h);
|
||||||
|
int clearSize = (int)(w * h);
|
||||||
|
int[] clearColor = new int[clearSize];
|
||||||
|
for (int i = 0; i < clearSize; ++i) {
|
||||||
|
clearColor[i] = Color.TRANSPARENT;
|
||||||
|
}
|
||||||
|
mBitmap.setPixels(clearColor, 0, (int) w, (int) x, (int) y, (int) w, (int) h);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTextPaintIfNeeded() {
|
||||||
|
if (mTextPaint == null) {
|
||||||
|
mTextPaint = newPaint(mFontName, (int) mFontSize, mIsBoldFont, mIsItalicFont, mIsObliqueFont, mIsSmallCapsFontVariant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillRect(float x, float y, float w, float h) {
|
||||||
|
// Log.d(TAG, "fillRect: " + x + ", " + y + ", " + ", " + w + ", " + h);
|
||||||
|
int pixelValue = (mFillStyleA & 0xff) << 24 | (mFillStyleR & 0xff) << 16 | (mFillStyleG & 0xff) << 8 | (mFillStyleB & 0xff);
|
||||||
|
int fillSize = (int)(w * h);
|
||||||
|
int[] fillColors = new int[fillSize];
|
||||||
|
for (int i = 0; i < fillSize; ++i) {
|
||||||
|
fillColors[i] = pixelValue;
|
||||||
|
}
|
||||||
|
mBitmap.setPixels(fillColors, 0, (int) w, (int)x, (int)y, (int)w, (int)h);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scaleX(TextPaint textPaint, String text, float maxWidth) {
|
||||||
|
if(maxWidth < Float.MIN_VALUE) return;
|
||||||
|
float measureWidth = this.measureText(text);
|
||||||
|
if((measureWidth - maxWidth) < Float.MIN_VALUE) return;
|
||||||
|
float scaleX = maxWidth/measureWidth;
|
||||||
|
textPaint.setTextScaleX(scaleX);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillText(String text, float x, float y, float maxWidth) {
|
||||||
|
// Log.d(TAG, "this: " + this + ", fillText: " + text + ", " + x + ", " + y + ", " + ", " + maxWidth);
|
||||||
|
createTextPaintIfNeeded();
|
||||||
|
mTextPaint.setARGB(mFillStyleA, mFillStyleR, mFillStyleG, mFillStyleB);
|
||||||
|
mTextPaint.setStyle(Paint.Style.FILL);
|
||||||
|
scaleX(mTextPaint, text, maxWidth);
|
||||||
|
Point pt = convertDrawPoint(new Point(x, y), text);
|
||||||
|
mCanvas.drawText(text, pt.x, pt.y, mTextPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void strokeText(String text, float x, float y, float maxWidth) {
|
||||||
|
// Log.d(TAG, "strokeText: " + text + ", " + x + ", " + y + ", " + ", " + maxWidth);
|
||||||
|
createTextPaintIfNeeded();
|
||||||
|
mTextPaint.setARGB(mStrokeStyleA, mStrokeStyleR, mStrokeStyleG, mStrokeStyleB);
|
||||||
|
mTextPaint.setStyle(Paint.Style.STROKE);
|
||||||
|
mTextPaint.setStrokeWidth(mLineWidth);
|
||||||
|
scaleX(mTextPaint, text, maxWidth);
|
||||||
|
Point pt = convertDrawPoint(new Point(x, y), text);
|
||||||
|
mCanvas.drawText(text, pt.x, pt.y, mTextPaint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private float measureText(String text) {
|
||||||
|
createTextPaintIfNeeded();
|
||||||
|
float ret = mTextPaint.measureText(text);
|
||||||
|
// Log.d(TAG, "measureText: " + text + ", return: " + ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFont(String fontName, float fontSize, boolean bold, boolean italic, boolean oblique, boolean smallCaps) {
|
||||||
|
// Log.d(TAG, "updateFont: " + fontName + ", " + fontSize);
|
||||||
|
mFontName = fontName;
|
||||||
|
mFontSize = fontSize;
|
||||||
|
mIsBoldFont = bold;
|
||||||
|
mIsItalicFont = italic;
|
||||||
|
mIsObliqueFont = oblique;
|
||||||
|
mIsSmallCapsFontVariant = smallCaps;
|
||||||
|
mTextPaint = null; // Reset paint to re-create paint object in createTextPaintIfNeeded
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTextAlign(int align) {
|
||||||
|
// Log.d(TAG, "setTextAlign: " + align);
|
||||||
|
mTextAlign = align;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTextBaseline(int baseline) {
|
||||||
|
// Log.d(TAG, "setTextBaseline: " + baseline);
|
||||||
|
mTextBaseline = baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFillStyle(float r, float g, float b, float a) {
|
||||||
|
// Log.d(TAG, "setFillStyle: " + r + ", " + g + ", " + b + ", " + a);
|
||||||
|
mFillStyleR = (int)(r * 255.0f);
|
||||||
|
mFillStyleG = (int)(g * 255.0f);
|
||||||
|
mFillStyleB = (int)(b * 255.0f);
|
||||||
|
mFillStyleA = (int)(a * 255.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setStrokeStyle(float r, float g, float b, float a) {
|
||||||
|
// Log.d(TAG, "setStrokeStyle: " + r + ", " + g + ", " + b + ", " + a);
|
||||||
|
mStrokeStyleR = (int)(r * 255.0f);
|
||||||
|
mStrokeStyleG = (int)(g * 255.0f);
|
||||||
|
mStrokeStyleB = (int)(b * 255.0f);
|
||||||
|
mStrokeStyleA = (int)(a * 255.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLineWidth(float lineWidth) {
|
||||||
|
mLineWidth = lineWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _fillImageData(byte[] imageData, float imageWidth, float imageHeight, float offsetX, float offsetY) {
|
||||||
|
Log.d(TAG, "_fillImageData: ");
|
||||||
|
int fillSize = (int) (imageWidth * imageHeight);
|
||||||
|
int[] fillColors = new int[fillSize];
|
||||||
|
int r, g, b, a;
|
||||||
|
for (int i = 0; i < fillSize; ++i) {
|
||||||
|
// imageData Pixel (RGBA) -> fillColors int (ARGB)
|
||||||
|
r = ((int)imageData[4 * i + 0]) & 0xff;
|
||||||
|
g = ((int)imageData[4 * i + 1]) & 0xff;
|
||||||
|
b = ((int)imageData[4 * i + 2]) & 0xff;
|
||||||
|
a = ((int)imageData[4 * i + 3]) & 0xff;
|
||||||
|
fillColors[i] = (a & 0xff) << 24 | (r & 0xff) << 16 | (g & 0xff) << 8 | (b & 0xff);
|
||||||
|
}
|
||||||
|
mBitmap.setPixels(fillColors, 0, (int) imageWidth, (int) offsetX, (int) offsetY, (int) imageWidth, (int) imageHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Point convertDrawPoint(final Point point, String text) {
|
||||||
|
// The parameter 'point' is located at left-bottom position.
|
||||||
|
// Need to adjust 'point' according 'text align' & 'text base line'.
|
||||||
|
Point ret = new Point(point);
|
||||||
|
createTextPaintIfNeeded();
|
||||||
|
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
|
||||||
|
float width = measureText(text);
|
||||||
|
|
||||||
|
if (mTextAlign == TEXT_ALIGN_CENTER)
|
||||||
|
{
|
||||||
|
ret.x -= width / 2;
|
||||||
|
}
|
||||||
|
else if (mTextAlign == TEXT_ALIGN_RIGHT)
|
||||||
|
{
|
||||||
|
ret.x -= width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Canvas.drawText accepts the y parameter as the baseline position, not the most bottom
|
||||||
|
if (mTextBaseline == TEXT_BASELINE_TOP)
|
||||||
|
{
|
||||||
|
ret.y += -fm.ascent;
|
||||||
|
}
|
||||||
|
else if (mTextBaseline == TEXT_BASELINE_MIDDLE)
|
||||||
|
{
|
||||||
|
ret.y += (fm.descent - fm.ascent) / 2 - fm.descent;
|
||||||
|
}
|
||||||
|
else if (mTextBaseline == TEXT_BASELINE_BOTTOM)
|
||||||
|
{
|
||||||
|
ret.y += -fm.descent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] getDataRef() {
|
||||||
|
// Log.d(TAG, "this: " + this + ", getDataRef ...");
|
||||||
|
if (mBitmap != null) {
|
||||||
|
final int len = mBitmap.getWidth() * mBitmap.getHeight() * 4;
|
||||||
|
final byte[] pixels = new byte[len];
|
||||||
|
final ByteBuffer buf = ByteBuffer.wrap(pixels);
|
||||||
|
buf.order(ByteOrder.nativeOrder());
|
||||||
|
mBitmap.copyPixelsToBuffer(buf);
|
||||||
|
|
||||||
|
return pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.e(TAG, "getDataRef return null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,331 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (c) 2020 Xiamen Yaji Software Co., Ltd.
|
||||||
|
*
|
||||||
|
* http://www.cocos.com
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public class CocosActivity extends Activity implements SurfaceHolder.Callback
|
||||||
|
{
|
||||||
|
private boolean mDestroyed;
|
||||||
|
private SurfaceHolder mSurfaceHolder;
|
||||||
|
protected FrameLayout mFrameLayout;
|
||||||
|
private CocosSurfaceView mSurfaceView;
|
||||||
|
private CocosWebViewHelper mWebViewHelper = null;
|
||||||
|
private CocosVideoHelper mVideoHelper = null;
|
||||||
|
private CocosOrientationHelper mOrientationHelper = null;
|
||||||
|
|
||||||
|
private boolean engineInit = false;
|
||||||
|
|
||||||
|
private CocosKeyCodeHandler mKeyCodeHandler;
|
||||||
|
private CocosSensorHandler mSensorHandler;
|
||||||
|
|
||||||
|
|
||||||
|
private native void onCreateNative(Activity activity, AssetManager assetManager, String obbPath, int sdkVersion);
|
||||||
|
|
||||||
|
private native void onSurfaceCreatedNative(Surface surface);
|
||||||
|
|
||||||
|
private native void onSurfaceChangedNative(int width, int height);
|
||||||
|
|
||||||
|
private native void onSurfaceDestroyNative();
|
||||||
|
|
||||||
|
private native void onPauseNative();
|
||||||
|
|
||||||
|
private native void onResumeNative();
|
||||||
|
|
||||||
|
private native void onStopNative();
|
||||||
|
|
||||||
|
private native void onStartNative();
|
||||||
|
|
||||||
|
private native void onLowMemoryNative();
|
||||||
|
|
||||||
|
private native void onWindowFocusChangedNative(boolean hasFocus);
|
||||||
|
|
||||||
|
////blank
|
||||||
|
public static CocosActivity app;
|
||||||
|
|
||||||
|
public FrameLayout getFrameLayout()
|
||||||
|
{
|
||||||
|
return mFrameLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
////blank 显示启动图
|
||||||
|
app = this;
|
||||||
|
ViewGroup.LayoutParams frameLayoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
mFrameLayout = new FrameLayout(this);
|
||||||
|
mFrameLayout.setLayoutParams(frameLayoutParams);
|
||||||
|
setContentView(mFrameLayout);
|
||||||
|
ImageView imageView = new ImageView(this);
|
||||||
|
imageView.setBackgroundColor(Color.WHITE);
|
||||||
|
imageView.setTag("launchImage");
|
||||||
|
mFrameLayout.addView(imageView, frameLayoutParams);
|
||||||
|
imageView.setImageResource(R.drawable.launch_image);
|
||||||
|
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||||
|
|
||||||
|
GlobalObject.setActivity(this);
|
||||||
|
CocosHelper.registerBatteryLevelReceiver(this);
|
||||||
|
CocosHelper.init(this);
|
||||||
|
CanvasRenderingContext2DImpl.init(this);
|
||||||
|
onLoadNativeLibraries();
|
||||||
|
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||||
|
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
|
||||||
|
initView();
|
||||||
|
onCreateNative(this, getAssets(), getAbsolutePath(getObbDir()), Build.VERSION.SDK_INT);
|
||||||
|
|
||||||
|
mKeyCodeHandler = new CocosKeyCodeHandler(this);
|
||||||
|
mSensorHandler = new CocosSensorHandler(this);
|
||||||
|
|
||||||
|
setImmersiveMode();
|
||||||
|
|
||||||
|
Utils.hideVirtualButton();
|
||||||
|
|
||||||
|
mOrientationHelper = new CocosOrientationHelper(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setImmersiveMode()
|
||||||
|
{
|
||||||
|
WindowManager.LayoutParams lp = getWindow().getAttributes();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Field field = lp.getClass().getField("layoutInDisplayCutoutMode");
|
||||||
|
//Field constValue = lp.getClass().getDeclaredField("LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER");
|
||||||
|
Field constValue = lp.getClass().getDeclaredField("LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES");
|
||||||
|
field.setInt(lp, constValue.getInt(null));
|
||||||
|
|
||||||
|
// https://developer.android.com/training/system-ui/immersive
|
||||||
|
int flag = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
||||||
|
|
||||||
|
flag |= View.class.getDeclaredField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY").getInt(null);
|
||||||
|
View view = getWindow().getDecorView();
|
||||||
|
view.setSystemUiVisibility(flag);
|
||||||
|
|
||||||
|
} catch (NoSuchFieldException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getAbsolutePath(File file)
|
||||||
|
{
|
||||||
|
return (file != null) ? file.getAbsolutePath() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initView()
|
||||||
|
{
|
||||||
|
////blank 改在create中初始化,以显示splash启动图
|
||||||
|
/*
|
||||||
|
ViewGroup.LayoutParams frameLayoutParams = new ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
mFrameLayout = new FrameLayout(this);
|
||||||
|
mFrameLayout.setLayoutParams(frameLayoutParams);
|
||||||
|
setContentView(mFrameLayout);
|
||||||
|
*/
|
||||||
|
|
||||||
|
mSurfaceView = new CocosSurfaceView(this);
|
||||||
|
mSurfaceView.getHolder().addCallback(this);
|
||||||
|
|
||||||
|
////blank 加到最底层去,这样才能显示启动屏
|
||||||
|
// mFrameLayout.addView(mSurfaceView);
|
||||||
|
mFrameLayout.addView(mSurfaceView, 0);
|
||||||
|
|
||||||
|
if (mWebViewHelper == null)
|
||||||
|
{
|
||||||
|
mWebViewHelper = new CocosWebViewHelper(mFrameLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mVideoHelper == null)
|
||||||
|
{
|
||||||
|
mVideoHelper = new CocosVideoHelper(this, mFrameLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CocosSurfaceView getSurfaceView()
|
||||||
|
{
|
||||||
|
return this.mSurfaceView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy()
|
||||||
|
{
|
||||||
|
mDestroyed = true;
|
||||||
|
if (mSurfaceHolder != null)
|
||||||
|
{
|
||||||
|
onSurfaceDestroyNative();
|
||||||
|
mSurfaceHolder = null;
|
||||||
|
}
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause()
|
||||||
|
{
|
||||||
|
super.onPause();
|
||||||
|
mSensorHandler.onPause();
|
||||||
|
mOrientationHelper.onPause();
|
||||||
|
onPauseNative();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume()
|
||||||
|
{
|
||||||
|
super.onResume();
|
||||||
|
mSensorHandler.onResume();
|
||||||
|
mOrientationHelper.onResume();
|
||||||
|
onResumeNative();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop()
|
||||||
|
{
|
||||||
|
super.onStop();
|
||||||
|
onStopNative();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart()
|
||||||
|
{
|
||||||
|
super.onStart();
|
||||||
|
onStartNative();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLowMemory()
|
||||||
|
{
|
||||||
|
super.onLowMemory();
|
||||||
|
if (!mDestroyed)
|
||||||
|
{
|
||||||
|
onLowMemoryNative();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWindowFocusChanged(boolean hasFocus)
|
||||||
|
{
|
||||||
|
super.onWindowFocusChanged(hasFocus);
|
||||||
|
if (!mDestroyed)
|
||||||
|
{
|
||||||
|
onWindowFocusChangedNative(hasFocus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceCreated(SurfaceHolder holder)
|
||||||
|
{
|
||||||
|
if (!mDestroyed)
|
||||||
|
{
|
||||||
|
mSurfaceHolder = holder;
|
||||||
|
onSurfaceCreatedNative(holder.getSurface());
|
||||||
|
|
||||||
|
engineInit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
|
||||||
|
{
|
||||||
|
if (!mDestroyed)
|
||||||
|
{
|
||||||
|
mSurfaceHolder = holder;
|
||||||
|
onSurfaceChangedNative(width, height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void surfaceDestroyed(SurfaceHolder holder)
|
||||||
|
{
|
||||||
|
mSurfaceHolder = null;
|
||||||
|
if (!mDestroyed)
|
||||||
|
{
|
||||||
|
onSurfaceDestroyNative();
|
||||||
|
engineInit = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onLoadNativeLibraries()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
|
||||||
|
Bundle bundle = ai.metaData;
|
||||||
|
String libName = bundle.getString("android.app.lib_name");
|
||||||
|
System.loadLibrary(libName);
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keyCode, KeyEvent event)
|
||||||
|
{
|
||||||
|
return mKeyCodeHandler.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyUp(int keyCode, KeyEvent event)
|
||||||
|
{
|
||||||
|
return mKeyCodeHandler.onKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
////blank
|
||||||
|
@Override
|
||||||
|
public void onBackPressed()
|
||||||
|
{
|
||||||
|
CocosHelper.runOnGameThread(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
CocosJavascriptJavaBridge.evalString("cx.rootNode.onBackPressed()");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,370 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos.com
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated engine source code (the "Software"), a limited,
|
||||||
|
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||||
|
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||||
|
not use Cocos Creator software for developing other software or tools that's
|
||||||
|
used for developing games. You are not granted to publish, distribute,
|
||||||
|
sublicense, and/or sell copies of Cocos Creator.
|
||||||
|
|
||||||
|
The software or tools in this License Agreement are licensed, not sold.
|
||||||
|
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Queue;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
// Rename package okhttp3 to org.cocos2dx.okhttp3
|
||||||
|
// Github repo: https://github.com/PatriceJiang/okhttp/tree/cocos2dx-rename-3.12.x
|
||||||
|
// and https://github.com/PatriceJiang/okio/tree/cocos2dx-rename-1.15.0
|
||||||
|
import org.cocos2dx.okhttp3.Call;
|
||||||
|
import org.cocos2dx.okhttp3.Callback;
|
||||||
|
import org.cocos2dx.okhttp3.OkHttpClient;
|
||||||
|
import org.cocos2dx.okhttp3.Request;
|
||||||
|
import org.cocos2dx.okhttp3.Response;
|
||||||
|
|
||||||
|
public class CocosDownloader {
|
||||||
|
|
||||||
|
private int _id;
|
||||||
|
private OkHttpClient _httpClient = null;
|
||||||
|
|
||||||
|
private String _tempFileNameSuffix;
|
||||||
|
private int _countOfMaxProcessingTasks;
|
||||||
|
private ConcurrentHashMap<Integer,Call> _taskMap = new ConcurrentHashMap<>();
|
||||||
|
private Queue<Runnable> _taskQueue = new LinkedList<>();
|
||||||
|
private int _runningTaskCount = 0;
|
||||||
|
private static ConcurrentHashMap<String, Boolean> _resumingSupport = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private void onProgress(final int id, final long downloadBytes, final long downloadNow, final long downloadTotal) {
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
nativeOnProgress(_id, id, downloadBytes, downloadNow, downloadTotal);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onFinish(final int id, final int errCode, final String errStr, final byte[] data) {
|
||||||
|
Call task =_taskMap.get(id);
|
||||||
|
if (null == task) return;
|
||||||
|
_taskMap.remove(id);
|
||||||
|
_runningTaskCount -= 1;
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
nativeOnFinish(_id, id, errCode, errStr, data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
runNextTaskIfExists();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CocosDownloader createDownloader(int id, int timeoutInSeconds, String tempFileSuffix, int maxProcessingTasks) {
|
||||||
|
CocosDownloader downloader = new CocosDownloader();
|
||||||
|
downloader._id = id;
|
||||||
|
|
||||||
|
if (timeoutInSeconds > 0) {
|
||||||
|
downloader._httpClient = new OkHttpClient().newBuilder()
|
||||||
|
.followRedirects(true)
|
||||||
|
.followSslRedirects(true)
|
||||||
|
.callTimeout(timeoutInSeconds, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
} else {
|
||||||
|
downloader._httpClient = new OkHttpClient().newBuilder()
|
||||||
|
.followRedirects(true)
|
||||||
|
.followSslRedirects(true)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
downloader._tempFileNameSuffix = tempFileSuffix;
|
||||||
|
downloader._countOfMaxProcessingTasks = maxProcessingTasks;
|
||||||
|
return downloader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createTask(final CocosDownloader downloader, int id_, String url_, String path_, String []header_) {
|
||||||
|
final int id = id_;
|
||||||
|
final String url = url_;
|
||||||
|
final String path = path_;
|
||||||
|
final String[] header = header_;
|
||||||
|
|
||||||
|
Runnable taskRunnable = new Runnable() {
|
||||||
|
String domain = null;
|
||||||
|
String host = null;
|
||||||
|
File tempFile = null;
|
||||||
|
File finalFile = null;
|
||||||
|
long downloadStart = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Call task = null;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (path.length() > 0) {
|
||||||
|
try {
|
||||||
|
URI uri = new URI(url);
|
||||||
|
domain = uri.getHost();
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
break;
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// file task
|
||||||
|
tempFile = new File(path + downloader._tempFileNameSuffix);
|
||||||
|
if (tempFile.isDirectory()) break;
|
||||||
|
|
||||||
|
File parent = tempFile.getParentFile();
|
||||||
|
if (!parent.isDirectory() && !parent.mkdirs()) break;
|
||||||
|
|
||||||
|
finalFile = new File(path);
|
||||||
|
if (finalFile.isDirectory()) break;
|
||||||
|
long fileLen = tempFile.length();
|
||||||
|
|
||||||
|
host = domain.startsWith("www.") ? domain.substring(4) : domain;
|
||||||
|
if (fileLen > 0) {
|
||||||
|
if (_resumingSupport.containsKey(host) && _resumingSupport.get(host)) {
|
||||||
|
downloadStart = fileLen;
|
||||||
|
} else {
|
||||||
|
// Remove previous downloaded context
|
||||||
|
try {
|
||||||
|
PrintWriter writer = new PrintWriter(tempFile);
|
||||||
|
writer.print("");
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
// Not found then nothing to do
|
||||||
|
catch (FileNotFoundException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Request.Builder builder = new Request.Builder().url(url);
|
||||||
|
for (int i = 0; i < header.length / 2; i++) {
|
||||||
|
builder.addHeader(header[i * 2], header[(i * 2) + 1]);
|
||||||
|
}
|
||||||
|
if (downloadStart > 0) {
|
||||||
|
builder.addHeader("RANGE", "bytes=" + downloadStart + "-");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Request request = builder.build();
|
||||||
|
task = downloader._httpClient.newCall(request);
|
||||||
|
task.enqueue(new Callback() {
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call call, IOException e) {
|
||||||
|
downloader.onFinish(id, 0, e.toString(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call call, Response response) throws IOException {
|
||||||
|
InputStream is = null;
|
||||||
|
byte[] buf = new byte[4096];
|
||||||
|
FileOutputStream fos = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if(!(response.code() >= 200 && response.code() <= 206)) {
|
||||||
|
// it is encourage to delete the tmp file when requested range not satisfiable.
|
||||||
|
if (response.code() == 416) {
|
||||||
|
File file = new File(path + downloader._tempFileNameSuffix);
|
||||||
|
if (file.exists() && file.isFile()) {
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
downloader.onFinish(id, -2, response.message(), null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long total = response.body().contentLength();
|
||||||
|
if (path.length() > 0 && !_resumingSupport.containsKey(host)) {
|
||||||
|
if (total > 0) {
|
||||||
|
_resumingSupport.put(host, true);
|
||||||
|
} else {
|
||||||
|
_resumingSupport.put(host, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long current = downloadStart;
|
||||||
|
is = response.body().byteStream();
|
||||||
|
|
||||||
|
if (path.length() > 0) {
|
||||||
|
if (downloadStart > 0) {
|
||||||
|
fos = new FileOutputStream(tempFile, true);
|
||||||
|
} else {
|
||||||
|
fos = new FileOutputStream(tempFile, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int len;
|
||||||
|
while ((len = is.read(buf)) != -1) {
|
||||||
|
current += len;
|
||||||
|
fos.write(buf, 0, len);
|
||||||
|
downloader.onProgress(id, len, current, total);
|
||||||
|
}
|
||||||
|
fos.flush();
|
||||||
|
|
||||||
|
String errStr = null;
|
||||||
|
do {
|
||||||
|
// rename temp file to final file, if final file exist, remove it
|
||||||
|
if (finalFile.exists()) {
|
||||||
|
if (finalFile.isDirectory()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!finalFile.delete()) {
|
||||||
|
errStr = "Can't remove old file:" + finalFile.getAbsolutePath();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tempFile.renameTo(finalFile);
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
if (errStr == null) {
|
||||||
|
downloader.onFinish(id, 0, null, null);
|
||||||
|
downloader.runNextTaskIfExists();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
downloader.onFinish(id, 0, errStr, null);
|
||||||
|
} else {
|
||||||
|
// 非文件
|
||||||
|
ByteArrayOutputStream buffer;
|
||||||
|
if(total > 0) {
|
||||||
|
buffer = new ByteArrayOutputStream((int) total);
|
||||||
|
} else {
|
||||||
|
buffer = new ByteArrayOutputStream(4096);
|
||||||
|
}
|
||||||
|
|
||||||
|
int len;
|
||||||
|
while ((len = is.read(buf)) != -1) {
|
||||||
|
current += len;
|
||||||
|
buffer.write(buf, 0, len);
|
||||||
|
downloader.onProgress(id, len, current, total);
|
||||||
|
}
|
||||||
|
downloader.onFinish(id, 0, null, buffer.toByteArray());
|
||||||
|
downloader.runNextTaskIfExists();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
downloader.onFinish(id, 0, e.toString(), null);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (is != null) {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
if (fos != null) {
|
||||||
|
fos.close();
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("CocosDownloader", e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} while (false);
|
||||||
|
|
||||||
|
if (null == task) {
|
||||||
|
final String errStr = "Can't create DownloadTask for " + url;
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
downloader.nativeOnFinish(downloader._id, id, 0, errStr, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
downloader._taskMap.put(id, task);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
downloader.enqueueTask(taskRunnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void abort(final CocosDownloader downloader, final int id) {
|
||||||
|
GlobalObject.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Iterator iter = downloader._taskMap.entrySet().iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
Map.Entry entry = (Map.Entry) iter.next();
|
||||||
|
Object key = entry.getKey();
|
||||||
|
Call task = (Call) entry.getValue();
|
||||||
|
if (null != task && Integer.parseInt(key.toString()) == id) {
|
||||||
|
task.cancel();
|
||||||
|
downloader._taskMap.remove(id);
|
||||||
|
downloader.runNextTaskIfExists();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelAllRequests(final CocosDownloader downloader) {
|
||||||
|
GlobalObject.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (Object o : downloader._taskMap.entrySet()) {
|
||||||
|
Map.Entry entry = (Map.Entry) o;
|
||||||
|
Call task = (Call) entry.getValue();
|
||||||
|
if (null != task) {
|
||||||
|
task.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void enqueueTask(Runnable taskRunnable) {
|
||||||
|
synchronized (_taskQueue) {
|
||||||
|
if (_runningTaskCount < _countOfMaxProcessingTasks) {
|
||||||
|
GlobalObject.getActivity().runOnUiThread(taskRunnable);
|
||||||
|
_runningTaskCount++;
|
||||||
|
} else {
|
||||||
|
_taskQueue.add(taskRunnable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runNextTaskIfExists() {
|
||||||
|
synchronized (_taskQueue) {
|
||||||
|
while (_runningTaskCount < _countOfMaxProcessingTasks &&
|
||||||
|
CocosDownloader.this._taskQueue.size() > 0) {
|
||||||
|
|
||||||
|
Runnable taskRunnable = CocosDownloader.this._taskQueue.poll();
|
||||||
|
GlobalObject.getActivity().runOnUiThread(taskRunnable);
|
||||||
|
_runningTaskCount += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
native void nativeOnProgress(int id, int taskId, long dl, long dlnow, long dltotal);
|
||||||
|
native void nativeOnFinish(int id, int taskId, int errCode, String errStr, final byte[] data);
|
||||||
|
}
|
@ -0,0 +1,466 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2012 cocos2d-x.org
|
||||||
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.graphics.drawable.ShapeDrawable;
|
||||||
|
import android.graphics.drawable.StateListDrawable;
|
||||||
|
import android.graphics.drawable.shapes.RoundRectShape;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.InputFilter;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.RelativeLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
public class CocosEditBoxActivity extends Activity {
|
||||||
|
|
||||||
|
// a color of dark green, was used for confirm button background
|
||||||
|
private static final int DARK_GREEN = Color.parseColor("#1fa014");
|
||||||
|
private static final int DARK_GREEN_PRESS = Color.parseColor("#008e26");
|
||||||
|
|
||||||
|
private static CocosEditBoxActivity sThis = null;
|
||||||
|
private Cocos2dxEditText mEditText = null;
|
||||||
|
private Button mButton = null;
|
||||||
|
private String mButtonTitle = null;
|
||||||
|
private boolean mConfirmHold = true;
|
||||||
|
private RelativeLayout mButtonLayout = null;
|
||||||
|
private RelativeLayout.LayoutParams mButtonParams;
|
||||||
|
private int mEditTextID = 1;
|
||||||
|
private int mButtonLayoutID = 2;
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
Inner class.
|
||||||
|
**************************************************************************************/
|
||||||
|
class Cocos2dxEditText extends EditText {
|
||||||
|
private final String TAG = "Cocos2dxEditBox";
|
||||||
|
private boolean mIsMultiLine = false;
|
||||||
|
private TextWatcher mTextWatcher = null;
|
||||||
|
private Paint mPaint;
|
||||||
|
private int mLineColor = DARK_GREEN;
|
||||||
|
private float mLineWidth = 2f;
|
||||||
|
private boolean keyboardVisible = false;
|
||||||
|
private int mScreenHeight;
|
||||||
|
|
||||||
|
public Cocos2dxEditText(Activity context){
|
||||||
|
super(context);
|
||||||
|
//remove focus border
|
||||||
|
this.setBackground(null);
|
||||||
|
this.setTextColor(Color.BLACK);
|
||||||
|
mScreenHeight = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).
|
||||||
|
getDefaultDisplay().getHeight();
|
||||||
|
mPaint = new Paint();
|
||||||
|
mPaint.setStrokeWidth(mLineWidth);
|
||||||
|
mPaint.setStyle(Paint.Style.FILL);
|
||||||
|
mPaint.setColor(mLineColor);
|
||||||
|
|
||||||
|
mTextWatcher = new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
// Pass text to c++.
|
||||||
|
CocosEditBoxActivity.this.onKeyboardInput(s.toString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
registKeyboardVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
Override functions.
|
||||||
|
**************************************************************************************/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
// draw the underline
|
||||||
|
int padB = this.getPaddingBottom();
|
||||||
|
canvas.drawLine(getScrollX(), this.getHeight() - padB / 2 - mLineWidth,
|
||||||
|
getScrollX() + this.getWidth(),
|
||||||
|
this.getHeight() - padB / 2 - mLineWidth, mPaint);
|
||||||
|
super.onDraw(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
Public functions.
|
||||||
|
**************************************************************************************/
|
||||||
|
|
||||||
|
public void show(String defaultValue, int maxLength, boolean isMultiline, boolean confirmHold, String confirmType, String inputType) {
|
||||||
|
mIsMultiLine = isMultiline;
|
||||||
|
this.setFilters(new InputFilter[]{new InputFilter.LengthFilter(maxLength) });
|
||||||
|
this.setText(defaultValue);
|
||||||
|
if (this.getText().length() >= defaultValue.length()) {
|
||||||
|
this.setSelection(defaultValue.length());
|
||||||
|
} else {
|
||||||
|
this.setSelection(this.getText().length());
|
||||||
|
}
|
||||||
|
this.setConfirmType(confirmType);
|
||||||
|
this.setInputType(inputType, mIsMultiLine);
|
||||||
|
this.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
|
// Open soft keyboard manually. Should request focus to open soft keyboard.
|
||||||
|
this.requestFocus();
|
||||||
|
|
||||||
|
this.addListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hide() {
|
||||||
|
mEditText.setVisibility(View.INVISIBLE);
|
||||||
|
this.removeListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
Private functions.
|
||||||
|
**************************************************************************************/
|
||||||
|
|
||||||
|
private void setConfirmType(final String confirmType) {
|
||||||
|
if (confirmType.contentEquals("done")) {
|
||||||
|
this.setImeOptions(EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||||
|
mButtonTitle = getResources().getString(R.string.done);
|
||||||
|
} else if (confirmType.contentEquals("next")) {
|
||||||
|
this.setImeOptions(EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||||
|
mButtonTitle = getResources().getString(R.string.next);
|
||||||
|
} else if (confirmType.contentEquals("search")) {
|
||||||
|
this.setImeOptions(EditorInfo.IME_ACTION_SEARCH | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||||
|
mButtonTitle = getResources().getString(R.string.search);
|
||||||
|
} else if (confirmType.contentEquals("go")) {
|
||||||
|
this.setImeOptions(EditorInfo.IME_ACTION_GO | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||||
|
mButtonTitle = getResources().getString(R.string.go);
|
||||||
|
} else if (confirmType.contentEquals("send")) {
|
||||||
|
this.setImeOptions(EditorInfo.IME_ACTION_SEND | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
|
||||||
|
mButtonTitle = getResources().getString(R.string.send);
|
||||||
|
} else{
|
||||||
|
mButtonTitle = null;
|
||||||
|
Log.e(TAG, "unknown confirm type " + confirmType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setInputType(final String inputType, boolean isMultiLine){
|
||||||
|
if (inputType.contentEquals("text")) {
|
||||||
|
if (isMultiLine)
|
||||||
|
this.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_MULTI_LINE);
|
||||||
|
else
|
||||||
|
this.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
|
}
|
||||||
|
else if (inputType.contentEquals("email"))
|
||||||
|
this.setInputType(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
||||||
|
else if (inputType.contentEquals("number"))
|
||||||
|
this.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED);
|
||||||
|
else if (inputType.contentEquals("phone"))
|
||||||
|
this.setInputType(InputType.TYPE_CLASS_PHONE);
|
||||||
|
else if (inputType.contentEquals("password"))
|
||||||
|
this.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||||
|
else
|
||||||
|
Log.e(TAG, "unknown input type " + inputType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addListeners() {
|
||||||
|
|
||||||
|
this.setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
|
if (! mIsMultiLine) {
|
||||||
|
CocosEditBoxActivity.this.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // pass on to other listeners.
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
this.addTextChangedListener(mTextWatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeListeners() {
|
||||||
|
this.setOnEditorActionListener(null);
|
||||||
|
this.removeTextChangedListener(mTextWatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registKeyboardVisible() {
|
||||||
|
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||||
|
@Override
|
||||||
|
public void onGlobalLayout() {
|
||||||
|
Rect r = new Rect();
|
||||||
|
getWindowVisibleDisplayFrame(r);
|
||||||
|
int heightDiff = getRootView().getHeight() - (r.bottom - r.top);
|
||||||
|
// if more than a quarter of the screen, its probably a keyboard
|
||||||
|
if (heightDiff > mScreenHeight/4) {
|
||||||
|
if (!keyboardVisible) {
|
||||||
|
keyboardVisible = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (keyboardVisible) {
|
||||||
|
keyboardVisible = false;
|
||||||
|
CocosEditBoxActivity.this.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
||||||
|
CocosEditBoxActivity.sThis = this;
|
||||||
|
|
||||||
|
ViewGroup.LayoutParams frameLayoutParams =
|
||||||
|
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
RelativeLayout frameLayout = new RelativeLayout(this);
|
||||||
|
frameLayout.setLayoutParams(frameLayoutParams);
|
||||||
|
setContentView(frameLayout);
|
||||||
|
|
||||||
|
this.addItems(frameLayout);
|
||||||
|
|
||||||
|
Bundle extras = getIntent().getExtras();
|
||||||
|
show(extras.getString("defaultValue"),
|
||||||
|
extras.getInt("maxLength"),
|
||||||
|
extras.getBoolean("isMultiline"),
|
||||||
|
extras.getBoolean("confirmHold"),
|
||||||
|
extras.getString("confirmType"),
|
||||||
|
extras.getString("inputType"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
Public functions.
|
||||||
|
**************************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
Private functions.
|
||||||
|
**************************************************************************************/
|
||||||
|
private void addItems(RelativeLayout layout) {
|
||||||
|
RelativeLayout myLayout = new RelativeLayout(this);
|
||||||
|
this.addEditText(myLayout);
|
||||||
|
this.addButton(myLayout);
|
||||||
|
|
||||||
|
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
|
||||||
|
layout.addView(myLayout, layoutParams);
|
||||||
|
|
||||||
|
//FXI ME: Is it needed?
|
||||||
|
// When touch area outside EditText and soft keyboard, then hide.
|
||||||
|
// layout.setOnTouchListener(new View.OnTouchListener() {
|
||||||
|
// @Override
|
||||||
|
// public boolean onTouch(View v, MotionEvent event) {
|
||||||
|
// Cocos2dxEditBox.this.hide();
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addEditText(RelativeLayout layout) {
|
||||||
|
mEditText = new Cocos2dxEditText(this);
|
||||||
|
mEditText.setVisibility(View.INVISIBLE);
|
||||||
|
mEditText.setBackgroundColor(Color.WHITE);
|
||||||
|
mEditText.setId(mEditTextID);
|
||||||
|
RelativeLayout.LayoutParams editParams = new RelativeLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
editParams.addRule(RelativeLayout.LEFT_OF, mButtonLayoutID);
|
||||||
|
layout.addView(mEditText, editParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addButton(RelativeLayout layout) {
|
||||||
|
mButton = new Button(this);
|
||||||
|
mButtonParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
mButton.setTextColor(Color.WHITE);
|
||||||
|
mButton.setBackground(getRoundRectShape());
|
||||||
|
mButtonLayout = new RelativeLayout(GlobalObject.getActivity());
|
||||||
|
mButtonLayout.setBackgroundColor(Color.WHITE);
|
||||||
|
RelativeLayout.LayoutParams buttonLayoutParams = new RelativeLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
buttonLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||||
|
buttonLayoutParams.addRule(RelativeLayout.ALIGN_BOTTOM, mEditTextID);
|
||||||
|
buttonLayoutParams.addRule(RelativeLayout.ALIGN_TOP, mEditTextID);
|
||||||
|
mButtonLayout.addView(mButton, mButtonParams);
|
||||||
|
mButtonLayout.setId(mButtonLayoutID);
|
||||||
|
layout.addView(mButtonLayout, buttonLayoutParams);
|
||||||
|
|
||||||
|
mButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
CocosEditBoxActivity.this.onKeyboardConfirm(mEditText.getText().toString());
|
||||||
|
|
||||||
|
if (!CocosEditBoxActivity.this.mConfirmHold)
|
||||||
|
CocosEditBoxActivity.this.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable getRoundRectShape() {
|
||||||
|
int radius = 7;
|
||||||
|
float[] outerRadii = new float[]{radius, radius, radius, radius, radius, radius, radius, radius};
|
||||||
|
RoundRectShape roundRectShape = new RoundRectShape(outerRadii, null, null);
|
||||||
|
ShapeDrawable shapeDrawableNormal = new ShapeDrawable();
|
||||||
|
shapeDrawableNormal.setShape(roundRectShape);
|
||||||
|
shapeDrawableNormal.getPaint().setStyle(Paint.Style.FILL);
|
||||||
|
shapeDrawableNormal.getPaint().setColor(DARK_GREEN);
|
||||||
|
ShapeDrawable shapeDrawablePress = new ShapeDrawable();
|
||||||
|
shapeDrawablePress.setShape(roundRectShape);
|
||||||
|
shapeDrawablePress.getPaint().setStyle(Paint.Style.FILL);
|
||||||
|
shapeDrawablePress.getPaint().setColor(DARK_GREEN_PRESS);
|
||||||
|
StateListDrawable drawable = new StateListDrawable();
|
||||||
|
drawable.addState(new int[]{android.R.attr.state_pressed}, shapeDrawablePress);
|
||||||
|
drawable.addState(new int[]{}, shapeDrawableNormal);
|
||||||
|
return drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void hide() {
|
||||||
|
Utils.hideVirtualButton();
|
||||||
|
this.closeKeyboard();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(String defaultValue, int maxLength, boolean isMultiline, boolean confirmHold, String confirmType, String inputType) {
|
||||||
|
mConfirmHold = confirmHold;
|
||||||
|
mEditText.show(defaultValue, maxLength, isMultiline, confirmHold, confirmType, inputType);
|
||||||
|
int editPaddingBottom = mEditText.getPaddingBottom();
|
||||||
|
int editPadding = mEditText.getPaddingTop();
|
||||||
|
mEditText.setPadding(editPadding, editPadding, editPadding, editPaddingBottom);
|
||||||
|
mButton.setText(mButtonTitle);
|
||||||
|
if (TextUtils.isEmpty(mButtonTitle)) {
|
||||||
|
mButton.setPadding(0, 0, 0, 0);
|
||||||
|
mButtonParams.setMargins(0, 0, 0, 0);
|
||||||
|
mButtonLayout.setVisibility(View.INVISIBLE);
|
||||||
|
} else {
|
||||||
|
int buttonTextPadding = mEditText.getPaddingBottom() / 2;
|
||||||
|
mButton.setPadding(editPadding, buttonTextPadding, editPadding, buttonTextPadding);
|
||||||
|
mButtonParams.setMargins(0, buttonTextPadding, 2, 0);
|
||||||
|
mButtonLayout.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.openKeyboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeKeyboard() {
|
||||||
|
InputMethodManager imm = (InputMethodManager) getSystemService(this.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
|
||||||
|
|
||||||
|
this.onKeyboardComplete(mEditText.getText().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openKeyboard() {
|
||||||
|
InputMethodManager imm = (InputMethodManager) getSystemService(this.INPUT_METHOD_SERVICE);
|
||||||
|
imm.showSoftInput(mEditText, InputMethodManager.SHOW_IMPLICIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
Functions invoked by CPP.
|
||||||
|
**************************************************************************************/
|
||||||
|
|
||||||
|
private static void showNative(String defaultValue, int maxLength, boolean isMultiline, boolean confirmHold, String confirmType, String inputType) {
|
||||||
|
|
||||||
|
GlobalObject.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Intent i = new Intent(GlobalObject.getActivity(), CocosEditBoxActivity.class);
|
||||||
|
i.putExtra("defaultValue", defaultValue);
|
||||||
|
i.putExtra("maxLength", maxLength);
|
||||||
|
i.putExtra("isMultiline", isMultiline);
|
||||||
|
i.putExtra("confirmHold", confirmHold);
|
||||||
|
i.putExtra("confirmType", confirmType);
|
||||||
|
i.putExtra("inputType", inputType);
|
||||||
|
GlobalObject.getActivity().startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void hideNative() {
|
||||||
|
if (null != CocosEditBoxActivity.sThis) {
|
||||||
|
GlobalObject.getActivity().runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosEditBoxActivity.sThis.hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************************
|
||||||
|
Native functions invoked by UI.
|
||||||
|
**************************************************************************************/
|
||||||
|
private void onKeyboardInput(String text) {
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosEditBoxActivity.onKeyboardInputNative(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onKeyboardComplete(String text) {
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosEditBoxActivity.onKeyboardCompleteNative(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onKeyboardConfirm(String text) {
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosEditBoxActivity.onKeyboardConfirmNative(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void onKeyboardInputNative(String text);
|
||||||
|
private static native void onKeyboardCompleteNative(String text);
|
||||||
|
private static native void onKeyboardConfirmNative(String text);
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2013 cocos2d-x.org
|
||||||
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
public class CocosHandler extends Handler {
|
||||||
|
// ===========================================================
|
||||||
|
// Constants
|
||||||
|
// ===========================================================
|
||||||
|
public final static int HANDLER_SHOW_DIALOG = 1;
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Fields
|
||||||
|
// ===========================================================
|
||||||
|
private WeakReference<Activity> mActivity;
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Constructors
|
||||||
|
// ===========================================================
|
||||||
|
public CocosHandler(Activity activity) {
|
||||||
|
this.mActivity = new WeakReference<Activity>(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Getter & Setter
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Methods for/from SuperClass/Interfaces
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Methods
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case CocosHandler.HANDLER_SHOW_DIALOG:
|
||||||
|
showDialog(msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDialog(Message msg) {
|
||||||
|
Activity theActivity = this.mActivity.get();
|
||||||
|
DialogMessage dialogMessage = (DialogMessage)msg.obj;
|
||||||
|
new AlertDialog.Builder(theActivity)
|
||||||
|
.setTitle(dialogMessage.title)
|
||||||
|
.setMessage(dialogMessage.message)
|
||||||
|
.setPositiveButton("Ok",
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
// REFINE: Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
}).create().show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Inner and Anonymous Classes
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
public static class DialogMessage {
|
||||||
|
public String title;
|
||||||
|
public String message;
|
||||||
|
|
||||||
|
public DialogMessage(String title, String message) {
|
||||||
|
this.title = title;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,349 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2012 cocos2d-x.org
|
||||||
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
import android.content.res.AssetFileDescriptor;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.BatteryManager;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.os.ParcelFileDescriptor;
|
||||||
|
import android.os.Vibrator;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.WindowInsets;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
|
import com.android.vending.expansion.zipfile.APKExpansionSupport;
|
||||||
|
import com.android.vending.expansion.zipfile.ZipResourceFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
|
||||||
|
public class CocosHelper {
|
||||||
|
// ===========================================================
|
||||||
|
// Constants
|
||||||
|
// ===========================================================
|
||||||
|
private static final String TAG = CocosHelper.class.getSimpleName();
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Fields
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
private static Activity sActivity;
|
||||||
|
private static Vibrator sVibrateService;
|
||||||
|
private static BatteryReceiver sBatteryReceiver = new BatteryReceiver();
|
||||||
|
|
||||||
|
public static final int NETWORK_TYPE_NONE = 0;
|
||||||
|
public static final int NETWORK_TYPE_LAN = 1;
|
||||||
|
public static final int NETWORK_TYPE_WWAN = 2;
|
||||||
|
|
||||||
|
// The absolute path to the OBB if it exists.
|
||||||
|
private static String sObbFilePath = "";
|
||||||
|
|
||||||
|
// The OBB file
|
||||||
|
private static ZipResourceFile sOBBFile = null;
|
||||||
|
|
||||||
|
private static List<Runnable> sTaskOnGameThread = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Battery receiver to getting battery level.
|
||||||
|
*/
|
||||||
|
static class BatteryReceiver extends BroadcastReceiver {
|
||||||
|
public float sBatteryLevel = 0.0f;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
setBatteryLevelByIntent(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBatteryLevelByIntent(Intent intent) {
|
||||||
|
if (null != intent) {
|
||||||
|
int current = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
|
||||||
|
int total = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);
|
||||||
|
float level = current * 1.0f / total;
|
||||||
|
// clamp to 0~1
|
||||||
|
sBatteryLevel = Math.min(Math.max(level, 0.0f), 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void registerBatteryLevelReceiver(Context context) {
|
||||||
|
Intent intent = context.registerReceiver(sBatteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
|
||||||
|
sBatteryReceiver.setBatteryLevelByIntent(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unregisterBatteryLevelReceiver(Context context) {
|
||||||
|
context.unregisterReceiver(sBatteryReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void runOnGameThread(final Runnable runnable) {
|
||||||
|
sTaskOnGameThread.add(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flushTasksOnGameThread() {
|
||||||
|
while(sTaskOnGameThread.size() > 0) {
|
||||||
|
Runnable r = sTaskOnGameThread.remove(0);
|
||||||
|
if(r != null) {
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getNetworkType() {
|
||||||
|
int status = NETWORK_TYPE_NONE;
|
||||||
|
NetworkInfo networkInfo;
|
||||||
|
try {
|
||||||
|
ConnectivityManager connMgr = (ConnectivityManager) sActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
networkInfo = connMgr.getActiveNetworkInfo();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
if (networkInfo == null) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
int nType = networkInfo.getType();
|
||||||
|
if (nType == ConnectivityManager.TYPE_MOBILE) {
|
||||||
|
status = NETWORK_TYPE_WWAN;
|
||||||
|
} else if (nType == ConnectivityManager.TYPE_WIFI) {
|
||||||
|
status = NETWORK_TYPE_LAN;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Constructors
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
private static boolean sInited = false;
|
||||||
|
public static void init(final Activity activity) {
|
||||||
|
sActivity = activity;
|
||||||
|
if (!sInited) {
|
||||||
|
CocosHelper.sVibrateService = (Vibrator)activity.getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
|
CocosHelper.initObbFilePath();
|
||||||
|
CocosHelper.initializeOBBFile();
|
||||||
|
|
||||||
|
sInited = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getBatteryLevel() { return sBatteryReceiver.sBatteryLevel; }
|
||||||
|
public static String getObbFilePath() { return CocosHelper.sObbFilePath; }
|
||||||
|
public static String getWritablePath() {
|
||||||
|
return sActivity.getFilesDir().getAbsolutePath();
|
||||||
|
}
|
||||||
|
public static String getCurrentLanguage() {
|
||||||
|
return Locale.getDefault().getLanguage();
|
||||||
|
}
|
||||||
|
public static String getCurrentLanguageCode() {
|
||||||
|
return Locale.getDefault().toString();
|
||||||
|
}
|
||||||
|
public static String getDeviceModel(){
|
||||||
|
return Build.MODEL;
|
||||||
|
}
|
||||||
|
public static String getSystemVersion() {
|
||||||
|
return Build.VERSION.RELEASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void vibrate(float duration) {
|
||||||
|
try {
|
||||||
|
if (sVibrateService != null && sVibrateService.hasVibrator()) {
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= 26) {
|
||||||
|
Class<?> vibrationEffectClass = Class.forName("android.os.VibrationEffect");
|
||||||
|
if(vibrationEffectClass != null) {
|
||||||
|
final int DEFAULT_AMPLITUDE = CocosReflectionHelper.<Integer>getConstantValue(vibrationEffectClass,
|
||||||
|
"DEFAULT_AMPLITUDE");
|
||||||
|
//VibrationEffect.createOneShot(long milliseconds, int amplitude)
|
||||||
|
final Method method = vibrationEffectClass.getMethod("createOneShot",
|
||||||
|
new Class[]{Long.TYPE, Integer.TYPE});
|
||||||
|
Class<?> type = method.getReturnType();
|
||||||
|
|
||||||
|
Object effect = method.invoke(vibrationEffectClass,
|
||||||
|
new Object[]{(long) (duration * 1000), DEFAULT_AMPLITUDE});
|
||||||
|
//sVibrateService.vibrate(VibrationEffect effect);
|
||||||
|
CocosReflectionHelper.invokeInstanceMethod(sVibrateService,"vibrate",
|
||||||
|
new Class[]{type}, new Object[]{(effect)});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sVibrateService.vibrate((long) (duration * 1000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean openURL(String url) {
|
||||||
|
boolean ret = false;
|
||||||
|
try {
|
||||||
|
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||||
|
i.setData(Uri.parse(url));
|
||||||
|
sActivity.startActivity(i);
|
||||||
|
ret = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void copyTextToClipboard(final String text){
|
||||||
|
sActivity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ClipboardManager myClipboard = (ClipboardManager)sActivity.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
ClipData myClip = ClipData.newPlainText("text", text);
|
||||||
|
myClipboard.setPrimaryClip(myClip);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long[] getObbAssetFileDescriptor(final String path) {
|
||||||
|
long[] array = new long[3];
|
||||||
|
if (CocosHelper.sOBBFile != null) {
|
||||||
|
AssetFileDescriptor descriptor = CocosHelper.sOBBFile.getAssetFileDescriptor(path);
|
||||||
|
if (descriptor != null) {
|
||||||
|
try {
|
||||||
|
ParcelFileDescriptor parcel = descriptor.getParcelFileDescriptor();
|
||||||
|
Method method = parcel.getClass().getMethod("getFd", new Class[] {});
|
||||||
|
array[0] = (Integer)method.invoke(parcel);
|
||||||
|
array[1] = descriptor.getStartOffset();
|
||||||
|
array[2] = descriptor.getLength();
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
Log.e(CocosHelper.TAG, "Accessing file descriptor directly from the OBB is only supported from Android 3.1 (API level 12) and above.");
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
Log.e(CocosHelper.TAG, e.toString());
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
Log.e(CocosHelper.TAG, e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getDeviceRotation() {
|
||||||
|
try {
|
||||||
|
Display display = ((WindowManager) sActivity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
||||||
|
return display.getRotation();
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return Surface.ROTATION_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Private functions.
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
// Initialize asset path:
|
||||||
|
// - absolute path to the OBB if it exists,
|
||||||
|
// - else empty string.
|
||||||
|
private static void initObbFilePath() {
|
||||||
|
int versionCode = 1;
|
||||||
|
final ApplicationInfo applicationInfo = sActivity.getApplicationInfo();
|
||||||
|
try {
|
||||||
|
versionCode = CocosHelper.sActivity.getPackageManager().getPackageInfo(applicationInfo.packageName, 0).versionCode;
|
||||||
|
} catch (NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
String pathToOBB = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/obb/" + applicationInfo.packageName + "/main." + versionCode + "." + applicationInfo.packageName + ".obb";
|
||||||
|
File obbFile = new File(pathToOBB);
|
||||||
|
if (obbFile.exists())
|
||||||
|
CocosHelper.sObbFilePath = pathToOBB;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void initializeOBBFile() {
|
||||||
|
int versionCode = 1;
|
||||||
|
final ApplicationInfo applicationInfo = sActivity.getApplicationInfo();
|
||||||
|
try {
|
||||||
|
versionCode = sActivity.getPackageManager().getPackageInfo(applicationInfo.packageName, 0).versionCode;
|
||||||
|
} catch (NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
CocosHelper.sOBBFile = APKExpansionSupport.getAPKExpansionZipFile(sActivity, versionCode, 0);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float[] getSafeArea() {
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= 28) {
|
||||||
|
do {
|
||||||
|
Object windowInsectObj = GlobalObject.getActivity().getWindow().getDecorView().getRootWindowInsets();
|
||||||
|
|
||||||
|
if(windowInsectObj == null) break;
|
||||||
|
|
||||||
|
Class<?> windowInsets = WindowInsets.class;
|
||||||
|
try {
|
||||||
|
Method wiGetDisplayCutout = windowInsets.getMethod("getDisplayCutout");
|
||||||
|
Object cutout = wiGetDisplayCutout.invoke(windowInsectObj);
|
||||||
|
|
||||||
|
if(cutout == null) break;
|
||||||
|
|
||||||
|
Class<?> displayCutout = cutout.getClass();
|
||||||
|
Method dcGetLeft = displayCutout.getMethod("getSafeInsetLeft");
|
||||||
|
Method dcGetRight = displayCutout.getMethod("getSafeInsetRight");
|
||||||
|
Method dcGetBottom = displayCutout.getMethod("getSafeInsetBottom");
|
||||||
|
Method dcGetTop = displayCutout.getMethod("getSafeInsetTop");
|
||||||
|
|
||||||
|
if (dcGetLeft != null && dcGetRight != null && dcGetBottom != null && dcGetTop != null) {
|
||||||
|
int left = (Integer) dcGetLeft.invoke(cutout);
|
||||||
|
int right = (Integer) dcGetRight.invoke(cutout);
|
||||||
|
int top = (Integer) dcGetTop.invoke(cutout);
|
||||||
|
int bottom = (Integer) dcGetBottom.invoke(cutout);
|
||||||
|
return new float[]{top, left, bottom, right};
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}while(false);
|
||||||
|
}
|
||||||
|
return new float[]{0,0,0,0};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,413 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2014 cocos2d-x.org
|
||||||
|
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.ProtocolException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.security.cert.CertificateFactory;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.InflaterInputStream;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.TrustManagerFactory;
|
||||||
|
|
||||||
|
public class CocosHttpURLConnection
|
||||||
|
{
|
||||||
|
private static String TAG = "CocosHttpURLConnection";
|
||||||
|
private static final String POST_METHOD = "POST" ;
|
||||||
|
private static final String PUT_METHOD = "PUT" ;
|
||||||
|
|
||||||
|
static HttpURLConnection createHttpURLConnection(String linkURL) {
|
||||||
|
URL url;
|
||||||
|
HttpURLConnection urlConnection;
|
||||||
|
try {
|
||||||
|
url = new URL(linkURL);
|
||||||
|
urlConnection = (HttpURLConnection) url.openConnection();
|
||||||
|
//Accept-Encoding
|
||||||
|
urlConnection.setRequestProperty("Accept-Encoding", "identity");
|
||||||
|
urlConnection.setDoInput(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Log.e(TAG, "createHttpURLConnection:" + e.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return urlConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setReadAndConnectTimeout(HttpURLConnection urlConnection, int readMiliseconds, int connectMiliseconds) {
|
||||||
|
urlConnection.setReadTimeout(readMiliseconds);
|
||||||
|
urlConnection.setConnectTimeout(connectMiliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setRequestMethod(HttpURLConnection urlConnection, String method){
|
||||||
|
try {
|
||||||
|
urlConnection.setRequestMethod(method);
|
||||||
|
if(method.equalsIgnoreCase(POST_METHOD) || method.equalsIgnoreCase(PUT_METHOD)) {
|
||||||
|
urlConnection.setDoOutput(true);
|
||||||
|
}
|
||||||
|
} catch (ProtocolException e) {
|
||||||
|
Log.e(TAG, "setRequestMethod:" + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setVerifySSL(HttpURLConnection urlConnection, String sslFilename) {
|
||||||
|
if(!(urlConnection instanceof HttpsURLConnection))
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
HttpsURLConnection httpsURLConnection = (HttpsURLConnection)urlConnection;
|
||||||
|
|
||||||
|
try {
|
||||||
|
InputStream caInput = null;
|
||||||
|
if (sslFilename.startsWith("/")) {
|
||||||
|
caInput = new BufferedInputStream(new FileInputStream(sslFilename));
|
||||||
|
}else {
|
||||||
|
String assetString = "assets/";
|
||||||
|
String assetsfilenameString = sslFilename.substring(assetString.length());
|
||||||
|
caInput = new BufferedInputStream(GlobalObject.getActivity().getAssets().open(assetsfilenameString));
|
||||||
|
}
|
||||||
|
|
||||||
|
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||||
|
Certificate ca;
|
||||||
|
ca = cf.generateCertificate(caInput);
|
||||||
|
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
|
||||||
|
caInput.close();
|
||||||
|
|
||||||
|
// Create a KeyStore containing our trusted CAs
|
||||||
|
String keyStoreType = KeyStore.getDefaultType();
|
||||||
|
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
|
||||||
|
keyStore.load(null, null);
|
||||||
|
keyStore.setCertificateEntry("ca", ca);
|
||||||
|
|
||||||
|
// Create a TrustManager that trusts the CAs in our KeyStore
|
||||||
|
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
|
||||||
|
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
|
||||||
|
tmf.init(keyStore);
|
||||||
|
|
||||||
|
// Create an SSLContext that uses our TrustManager
|
||||||
|
SSLContext context = SSLContext.getInstance("TLS");
|
||||||
|
context.init(null, tmf.getTrustManagers(), null);
|
||||||
|
|
||||||
|
httpsURLConnection.setSSLSocketFactory(context.getSocketFactory());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Log.e(TAG, "setVerifySSL:" + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add header
|
||||||
|
static void addRequestHeader(HttpURLConnection urlConnection, String key, String value) {
|
||||||
|
urlConnection.setRequestProperty(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int connect(HttpURLConnection http) {
|
||||||
|
int suc = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
http.connect();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Log.e(TAG, "connect" + e.toString());
|
||||||
|
suc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return suc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disconnect(HttpURLConnection http) {
|
||||||
|
http.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sendRequest(HttpURLConnection http, byte[] byteArray) {
|
||||||
|
try {
|
||||||
|
OutputStream out = http.getOutputStream();
|
||||||
|
if(null != byteArray) {
|
||||||
|
out.write(byteArray);
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Log.e(TAG, "sendRequest:" + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getResponseHeaders(HttpURLConnection http) {
|
||||||
|
Map<String, List<String>> headers = http.getHeaderFields();
|
||||||
|
if (null == headers) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String header = "";
|
||||||
|
|
||||||
|
for (Entry<String, List<String>> entry: headers.entrySet()) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
if (null == key) {
|
||||||
|
header += listToString(entry.getValue(), ",") + "\n";
|
||||||
|
} else {
|
||||||
|
header += key + ":" + listToString(entry.getValue(), ",") + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getResponseHeaderByIdx(HttpURLConnection http, int idx) {
|
||||||
|
Map<String, List<String>> headers = http.getHeaderFields();
|
||||||
|
if (null == headers) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String header = null;
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
for (Entry<String, List<String>> entry: headers.entrySet()) {
|
||||||
|
if (counter == idx) {
|
||||||
|
String key = entry.getKey();
|
||||||
|
if (null == key) {
|
||||||
|
header = listToString(entry.getValue(), ",") + "\n";
|
||||||
|
} else {
|
||||||
|
header = key + ":" + listToString(entry.getValue(), ",") + "\n";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getResponseHeaderByKey(HttpURLConnection http, String key) {
|
||||||
|
if (null == key) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, List<String>> headers = http.getHeaderFields();
|
||||||
|
if (null == headers) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String header = null;
|
||||||
|
|
||||||
|
for (Entry<String, List<String>> entry: headers.entrySet()) {
|
||||||
|
if (key.equalsIgnoreCase(entry.getKey())) {
|
||||||
|
if ("set-cookie".equalsIgnoreCase(key)) {
|
||||||
|
header = combinCookies(entry.getValue(), http.getURL().getHost());
|
||||||
|
} else {
|
||||||
|
header = listToString(entry.getValue(), ",");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getResponseHeaderByKeyInt(HttpURLConnection http, String key) {
|
||||||
|
String value = http.getHeaderField(key);
|
||||||
|
|
||||||
|
if (null == value) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return Integer.parseInt(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static byte[] getResponseContent(HttpURLConnection http) {
|
||||||
|
InputStream in;
|
||||||
|
try {
|
||||||
|
in = http.getInputStream();
|
||||||
|
String contentEncoding = http.getContentEncoding();
|
||||||
|
if (contentEncoding != null) {
|
||||||
|
if(contentEncoding.equalsIgnoreCase("gzip")){
|
||||||
|
in = new GZIPInputStream(http.getInputStream()); //reads 2 bytes to determine GZIP stream!
|
||||||
|
}
|
||||||
|
else if(contentEncoding.equalsIgnoreCase("deflate")){
|
||||||
|
in = new InflaterInputStream(http.getInputStream());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
in = http.getErrorStream();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Log.e(TAG, "1 getResponseContent: " + e.toString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int size = 0;
|
||||||
|
ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
|
||||||
|
while((size = in.read(buffer, 0 , 1024)) != -1)
|
||||||
|
{
|
||||||
|
bytestream.write(buffer, 0, size);
|
||||||
|
}
|
||||||
|
byte retbuffer[] = bytestream.toByteArray();
|
||||||
|
bytestream.close();
|
||||||
|
return retbuffer;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Log.e(TAG, "2 getResponseContent:" + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getResponseCode(HttpURLConnection http) {
|
||||||
|
int code = 0;
|
||||||
|
try {
|
||||||
|
code = http.getResponseCode();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Log.e(TAG, "getResponseCode:" + e.toString());
|
||||||
|
}
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getResponseMessage(HttpURLConnection http) {
|
||||||
|
String msg;
|
||||||
|
try {
|
||||||
|
msg = http.getResponseMessage();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
msg = e.toString();
|
||||||
|
Log.e(TAG, "getResponseMessage: " + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String listToString(List<String> list, String strInterVal) {
|
||||||
|
if (list == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
boolean flag = false;
|
||||||
|
for (String str : list) {
|
||||||
|
if (flag) {
|
||||||
|
result.append(strInterVal);
|
||||||
|
}
|
||||||
|
if (null == str) {
|
||||||
|
str = "";
|
||||||
|
}
|
||||||
|
result.append(str);
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String combinCookies(List<String> list, String hostDomain) {
|
||||||
|
StringBuilder sbCookies = new StringBuilder();
|
||||||
|
String domain = hostDomain;
|
||||||
|
String tailmatch = "FALSE";
|
||||||
|
String path = "/";
|
||||||
|
String secure = "FALSE";
|
||||||
|
String key = null;
|
||||||
|
String value = null;
|
||||||
|
String expires = null;
|
||||||
|
for (String str : list) {
|
||||||
|
String[] parts = str.split(";");
|
||||||
|
for (String part : parts) {
|
||||||
|
int firstIndex = part.indexOf("=");
|
||||||
|
if (-1 == firstIndex)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
String[] item = {part.substring(0, firstIndex), part.substring(firstIndex + 1)};
|
||||||
|
if ("expires".equalsIgnoreCase(item[0].trim())) {
|
||||||
|
expires = str2Seconds(item[1].trim());
|
||||||
|
} else if("path".equalsIgnoreCase(item[0].trim())) {
|
||||||
|
path = item[1];
|
||||||
|
} else if("secure".equalsIgnoreCase(item[0].trim())) {
|
||||||
|
secure = item[1];
|
||||||
|
} else if("domain".equalsIgnoreCase(item[0].trim())) {
|
||||||
|
domain = item[1];
|
||||||
|
} else if("version".equalsIgnoreCase(item[0].trim()) || "max-age".equalsIgnoreCase(item[0].trim())) {
|
||||||
|
//do nothing
|
||||||
|
} else {
|
||||||
|
key = item[0];
|
||||||
|
value = item[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null == domain) {
|
||||||
|
domain = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
sbCookies.append(domain);
|
||||||
|
sbCookies.append('\t');
|
||||||
|
sbCookies.append(tailmatch); //access
|
||||||
|
sbCookies.append('\t');
|
||||||
|
sbCookies.append(path); //path
|
||||||
|
sbCookies.append('\t');
|
||||||
|
sbCookies.append(secure); //secure
|
||||||
|
sbCookies.append('\t');
|
||||||
|
sbCookies.append(expires); //expires
|
||||||
|
sbCookies.append("\t");
|
||||||
|
sbCookies.append(key); //key
|
||||||
|
sbCookies.append("\t");
|
||||||
|
sbCookies.append(value); //value
|
||||||
|
sbCookies.append('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
return sbCookies.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String str2Seconds(String strTime) {
|
||||||
|
Calendar c = Calendar.getInstance();
|
||||||
|
long milliseconds = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
c.setTime(new SimpleDateFormat("EEE, dd-MMM-yy hh:mm:ss zzz", Locale.US).parse(strTime));
|
||||||
|
milliseconds = c.getTimeInMillis() / 1000;
|
||||||
|
} catch (ParseException e) {
|
||||||
|
Log.e(TAG, "str2Seconds: " + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Long.toString(milliseconds);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||||
|
* Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
public class CocosJavascriptJavaBridge {
|
||||||
|
public static native int evalString(String value);
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2013 cocos2d-x.org
|
||||||
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
|
public class CocosKeyCodeHandler {
|
||||||
|
private CocosActivity mAct;
|
||||||
|
|
||||||
|
public native void handleKeyDown(final int keyCode);
|
||||||
|
|
||||||
|
public native void handleKeyUp(final int keyCode);
|
||||||
|
|
||||||
|
public CocosKeyCodeHandler(CocosActivity act) {
|
||||||
|
mAct = act;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onKeyDown(final int keyCode, final KeyEvent event) {
|
||||||
|
switch (keyCode) {
|
||||||
|
// blank js响应不到KEYCODE_BACK ?
|
||||||
|
// case KeyEvent.KEYCODE_BACK:
|
||||||
|
// CocosVideoHelper.mVideoHandler.sendEmptyMessage(CocosVideoHelper.KeyEventBack);
|
||||||
|
case KeyEvent.KEYCODE_MENU:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_UP:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||||
|
case KeyEvent.KEYCODE_ENTER:
|
||||||
|
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
handleKeyDown(keyCode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onKeyUp(final int keyCode, KeyEvent event) {
|
||||||
|
switch (keyCode) {
|
||||||
|
// blank js响应不到KEYCODE_BACK ?
|
||||||
|
// case KeyEvent.KEYCODE_BACK:
|
||||||
|
case KeyEvent.KEYCODE_MENU:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_UP:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||||
|
case KeyEvent.KEYCODE_ENTER:
|
||||||
|
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
|
||||||
|
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
handleKeyUp(keyCode);
|
||||||
|
} ////blank cocos bug, 原来写的是handleKeyDown(keyCode)
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,170 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class CocosLocalStorage {
|
||||||
|
|
||||||
|
private static final String TAG = "CocosLocalStorage";
|
||||||
|
|
||||||
|
private static String DATABASE_NAME = "jsb.sqlite";
|
||||||
|
private static String TABLE_NAME = "data";
|
||||||
|
private static final int DATABASE_VERSION = 1;
|
||||||
|
|
||||||
|
private static DBOpenHelper mDatabaseOpenHelper = null;
|
||||||
|
private static SQLiteDatabase mDatabase = null;
|
||||||
|
|
||||||
|
public static boolean init(String dbName, String tableName) {
|
||||||
|
if (GlobalObject.getActivity() != null) {
|
||||||
|
DATABASE_NAME = dbName;
|
||||||
|
TABLE_NAME = tableName;
|
||||||
|
mDatabaseOpenHelper = new DBOpenHelper(GlobalObject.getActivity());
|
||||||
|
mDatabase = mDatabaseOpenHelper.getWritableDatabase();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void destroy() {
|
||||||
|
if (mDatabase != null) {
|
||||||
|
mDatabase.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setItem(String key, String value) {
|
||||||
|
try {
|
||||||
|
String sql = "replace into "+TABLE_NAME+"(key,value)values(?,?)";
|
||||||
|
mDatabase.execSQL(sql, new Object[] { key, value });
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getItem(String key) {
|
||||||
|
String ret = null;
|
||||||
|
try {
|
||||||
|
String sql = "select value from "+TABLE_NAME+" where key=?";
|
||||||
|
Cursor c = mDatabase.rawQuery(sql, new String[]{key});
|
||||||
|
while (c.moveToNext()) {
|
||||||
|
// only return the first value
|
||||||
|
if (ret != null)
|
||||||
|
{
|
||||||
|
Log.e(TAG, "The key contains more than one value.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret = c.getString(c.getColumnIndex("value"));
|
||||||
|
}
|
||||||
|
c.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeItem(String key) {
|
||||||
|
try {
|
||||||
|
String sql = "delete from "+TABLE_NAME+" where key=?";
|
||||||
|
mDatabase.execSQL(sql, new Object[] {key});
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clear() {
|
||||||
|
try {
|
||||||
|
String sql = "delete from "+TABLE_NAME;
|
||||||
|
mDatabase.execSQL(sql);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getKey(int nIndex) {
|
||||||
|
String ret = null;
|
||||||
|
try {
|
||||||
|
int nCount = 0;
|
||||||
|
String sql = "select key from "+TABLE_NAME + " order by rowid asc";
|
||||||
|
Cursor c = mDatabase.rawQuery(sql, null);
|
||||||
|
if(nIndex < 0 || nIndex >= c.getCount()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (c.moveToNext()) {
|
||||||
|
if(nCount == nIndex) {
|
||||||
|
ret = c.getString(c.getColumnIndex("key"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nCount++;
|
||||||
|
}
|
||||||
|
c.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getLength() {
|
||||||
|
int res = 0;
|
||||||
|
try {
|
||||||
|
String sql = "select count(*) as nums from "+TABLE_NAME;
|
||||||
|
Cursor c = mDatabase.rawQuery(sql, null);
|
||||||
|
if (c.moveToNext()){
|
||||||
|
res = c.getInt(c.getColumnIndex("nums"));
|
||||||
|
}
|
||||||
|
c.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This creates/opens the database.
|
||||||
|
*/
|
||||||
|
private static class DBOpenHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
|
DBOpenHelper(Context context) {
|
||||||
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(SQLiteDatabase db) {
|
||||||
|
db.execSQL("CREATE TABLE IF NOT EXISTS "+TABLE_NAME+"(key TEXT PRIMARY KEY,value TEXT);");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||||
|
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
|
||||||
|
+ newVersion + ", which will destroy all old data");
|
||||||
|
//db.execSQL("DROP TABLE IF EXISTS " + VIRTUAL_TABLE);
|
||||||
|
//onCreate(db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,164 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2013 cocos2d-x.org
|
||||||
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.app.NativeActivity;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
|
||||||
|
public abstract class CocosNativeActivity extends NativeActivity {
|
||||||
|
// ===========================================================
|
||||||
|
// Constants
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
private final static String TAG = CocosNativeActivity.class.getSimpleName();
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Fields
|
||||||
|
// ===========================================================
|
||||||
|
private boolean hasFocus = false;
|
||||||
|
private boolean paused = true;
|
||||||
|
|
||||||
|
protected FrameLayout mFrameLayout = null;
|
||||||
|
|
||||||
|
private CocosVideoHelper mVideoHelper = null;
|
||||||
|
private CocosWebViewHelper mWebViewHelper = null;
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Override functions
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(final Bundle savedInstanceState) {
|
||||||
|
Log.d(TAG, "CocosNativeActivity onCreate: " + this + ", savedInstanceState: " + savedInstanceState);
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508
|
||||||
|
if (!isTaskRoot()) {
|
||||||
|
// Android launched another instance of the root activity into an existing task
|
||||||
|
// so just quietly finish and go away, dropping the user back into the activity
|
||||||
|
// at the top of the stack (ie: the last state of this task)
|
||||||
|
finish();
|
||||||
|
Log.w(TAG, "[Workaround] Ignore the activity started from icon!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalObject.setActivity(this);
|
||||||
|
Utils.hideVirtualButton();
|
||||||
|
|
||||||
|
CocosHelper.registerBatteryLevelReceiver(this);
|
||||||
|
// Load native library to enable invoke native API.
|
||||||
|
onLoadNativeLibraries();
|
||||||
|
|
||||||
|
CocosHelper.init(this);
|
||||||
|
CanvasRenderingContext2DImpl.init(this);
|
||||||
|
|
||||||
|
|
||||||
|
if (mFrameLayout == null) {
|
||||||
|
ViewGroup.LayoutParams frameLayoutParams = new ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT);
|
||||||
|
mFrameLayout = new FrameLayout(this);
|
||||||
|
mFrameLayout.setLayoutParams(frameLayoutParams);
|
||||||
|
|
||||||
|
//
|
||||||
|
setContentView(mFrameLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mVideoHelper == null) {
|
||||||
|
mVideoHelper = new CocosVideoHelper(this, mFrameLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mWebViewHelper == null) {
|
||||||
|
mWebViewHelper = new CocosWebViewHelper(mFrameLayout);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||||
|
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
Log.d(TAG, "onResume()");
|
||||||
|
paused = false;
|
||||||
|
super.onResume();
|
||||||
|
Utils.hideVirtualButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWindowFocusChanged(boolean hasFocus) {
|
||||||
|
Log.d(TAG, "onWindowFocusChanged() hasFocus=" + hasFocus);
|
||||||
|
super.onWindowFocusChanged(hasFocus);
|
||||||
|
|
||||||
|
this.hasFocus = hasFocus;
|
||||||
|
resumeIfHasFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
Log.d(TAG, "onPause()");
|
||||||
|
paused = true;
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
|
// Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508
|
||||||
|
if (!isTaskRoot()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CocosHelper.unregisterBatteryLevelReceiver(this);;
|
||||||
|
CanvasRenderingContext2DImpl.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Protected and private methods
|
||||||
|
// ===========================================================
|
||||||
|
protected void onLoadNativeLibraries() {
|
||||||
|
try {
|
||||||
|
ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
|
||||||
|
Bundle bundle = ai.metaData;
|
||||||
|
String libName = bundle.getString("android.app.lib_name");
|
||||||
|
System.loadLibrary(libName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resumeIfHasFocus() {
|
||||||
|
if(hasFocus && !paused) {
|
||||||
|
Utils.hideVirtualButton();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (c) 2020 Xiamen Yaji Software Co., Ltd.
|
||||||
|
*
|
||||||
|
* http://www.cocos.com
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.OrientationEventListener;
|
||||||
|
|
||||||
|
public class CocosOrientationHelper extends OrientationEventListener {
|
||||||
|
|
||||||
|
private int mCurrentOrientation;
|
||||||
|
|
||||||
|
public CocosOrientationHelper(Context context) {
|
||||||
|
super(context);
|
||||||
|
mCurrentOrientation = CocosHelper.getDeviceRotation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPause() {
|
||||||
|
this.disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResume() {
|
||||||
|
this.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOrientationChanged(int orientation) {
|
||||||
|
int curOrientation = CocosHelper.getDeviceRotation();
|
||||||
|
if (curOrientation != mCurrentOrientation) {
|
||||||
|
mCurrentOrientation = CocosHelper.getDeviceRotation();
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
nativeOnOrientationChanged(mCurrentOrientation);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native void nativeOnOrientationChanged(int rotation);
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2016 cocos2d-x.org
|
||||||
|
Copyright (c) 2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class CocosReflectionHelper {
|
||||||
|
public static <T> T getConstantValue(final Class aClass, final String constantName) {
|
||||||
|
try {
|
||||||
|
return (T)aClass.getDeclaredField(constantName).get(null);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
Log.e("error", "can not find " + constantName + " in " + aClass.getName());
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e) {
|
||||||
|
Log.e("error", constantName + " is not accessable");
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
Log.e("error", "arguments error when get " + constantName);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
Log.e("error", "can not get constant" + constantName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T invokeInstanceMethod(final Object instance, final String methodName,
|
||||||
|
final Class[] parameterTypes, final Object[] parameters) {
|
||||||
|
|
||||||
|
final Class aClass = instance.getClass();
|
||||||
|
try {
|
||||||
|
final Method method = aClass.getMethod(methodName, parameterTypes);
|
||||||
|
return (T)method.invoke(instance, parameters);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
Log.e("error", "can not find " + methodName + " in " + aClass.getName());
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException e) {
|
||||||
|
Log.e("error", methodName + " is not accessible");
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
Log.e("error", "arguments are error when invoking " + methodName);
|
||||||
|
}
|
||||||
|
catch (InvocationTargetException e) {
|
||||||
|
Log.e("error", "an exception was thrown by the invoked method when invoking " + methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,139 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2013 cocos2d-x.org
|
||||||
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.hardware.Sensor;
|
||||||
|
import android.hardware.SensorEvent;
|
||||||
|
import android.hardware.SensorEventListener;
|
||||||
|
import android.hardware.SensorManager;
|
||||||
|
|
||||||
|
public class CocosSensorHandler implements SensorEventListener {
|
||||||
|
// ===========================================================
|
||||||
|
// Constants
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
private static final String TAG = "CocosSensorHandler";
|
||||||
|
private static CocosSensorHandler mSensorHandler;
|
||||||
|
|
||||||
|
private final Context mContext;
|
||||||
|
private final SensorManager mSensorManager;
|
||||||
|
private final Sensor mAcceleration;
|
||||||
|
private final Sensor mAccelerationIncludingGravity;
|
||||||
|
private final Sensor mGyroscope;
|
||||||
|
private int mSamplingPeriodUs = SensorManager.SENSOR_DELAY_GAME;
|
||||||
|
|
||||||
|
private static float[] sDeviceMotionValues = new float[9];
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Constructors
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
public CocosSensorHandler(final Context context) {
|
||||||
|
mContext = context;
|
||||||
|
|
||||||
|
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
|
||||||
|
mAcceleration = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
|
||||||
|
mAccelerationIncludingGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
|
||||||
|
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
|
||||||
|
|
||||||
|
mSensorHandler = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Getter & Setter
|
||||||
|
// ===========================================================
|
||||||
|
public void enable() {
|
||||||
|
mSensorManager.registerListener(this, mAcceleration, mSamplingPeriodUs);
|
||||||
|
mSensorManager.registerListener(this, mAccelerationIncludingGravity, mSamplingPeriodUs);
|
||||||
|
mSensorManager.registerListener(this, mGyroscope, mSamplingPeriodUs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disable() {
|
||||||
|
this.mSensorManager.unregisterListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterval(float interval) {
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||||
|
mSamplingPeriodUs = (int) (interval * 1000000);
|
||||||
|
}
|
||||||
|
disable();
|
||||||
|
enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Methods for/from SuperClass/Interfaces
|
||||||
|
// ===========================================================
|
||||||
|
@Override
|
||||||
|
public void onSensorChanged(final SensorEvent sensorEvent) {
|
||||||
|
int type = sensorEvent.sensor.getType();
|
||||||
|
if (type == Sensor.TYPE_ACCELEROMETER) {
|
||||||
|
sDeviceMotionValues[0] = sensorEvent.values[0];
|
||||||
|
sDeviceMotionValues[1] = sensorEvent.values[1];
|
||||||
|
// Issue https://github.com/cocos-creator/2d-tasks/issues/2532
|
||||||
|
// use negative event.acceleration.z to match iOS value
|
||||||
|
sDeviceMotionValues[2] = -sensorEvent.values[2];
|
||||||
|
} else if (type == Sensor.TYPE_LINEAR_ACCELERATION) {
|
||||||
|
sDeviceMotionValues[3] = sensorEvent.values[0];
|
||||||
|
sDeviceMotionValues[4] = sensorEvent.values[1];
|
||||||
|
sDeviceMotionValues[5] = sensorEvent.values[2];
|
||||||
|
} else if (type == Sensor.TYPE_GYROSCOPE) {
|
||||||
|
// The unit is rad/s, need to be converted to deg/s
|
||||||
|
sDeviceMotionValues[6] = (float) Math.toDegrees(sensorEvent.values[0]);
|
||||||
|
sDeviceMotionValues[7] = (float) Math.toDegrees(sensorEvent.values[1]);
|
||||||
|
sDeviceMotionValues[8] = (float) Math.toDegrees(sensorEvent.values[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAccuracyChanged(final Sensor sensor, final int accuracy) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPause() {
|
||||||
|
disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResume() {
|
||||||
|
enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setAccelerometerInterval(float interval) {
|
||||||
|
mSensorHandler.setInterval(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setAccelerometerEnabled(boolean enabled) {
|
||||||
|
if (enabled) {
|
||||||
|
mSensorHandler.enable();
|
||||||
|
} else {
|
||||||
|
mSensorHandler.disable();
|
||||||
|
}
|
||||||
|
mSensorHandler.enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float[] getDeviceMotionValue() {
|
||||||
|
return sDeviceMotionValues;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (c) 2020 Xiamen Yaji Software Co., Ltd.
|
||||||
|
*
|
||||||
|
* http://www.cocos.com
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
|
||||||
|
public class CocosSurfaceView extends SurfaceView {
|
||||||
|
private CocosTouchHandler mTouchHandler;
|
||||||
|
|
||||||
|
public CocosSurfaceView(Context context) {
|
||||||
|
super(context);
|
||||||
|
mTouchHandler = new CocosTouchHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
private native void nativeOnSizeChanged(final int width, final int height);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||||
|
super.onSizeChanged(w, h, oldw, oldh);
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
nativeOnSizeChanged(w, h);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
return mTouchHandler.onTouchEvent(event);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,181 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2013 cocos2d-x.org
|
||||||
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
public class CocosTouchHandler {
|
||||||
|
public final static String TAG = "CocosTouchHandler";
|
||||||
|
private boolean mStopHandleTouchAndKeyEvents = false;
|
||||||
|
|
||||||
|
public CocosTouchHandler() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean onTouchEvent(MotionEvent pMotionEvent) {
|
||||||
|
// these data are used in ACTION_MOVE and ACTION_CANCEL
|
||||||
|
final int pointerNumber = pMotionEvent.getPointerCount();
|
||||||
|
final int[] ids = new int[pointerNumber];
|
||||||
|
final float[] xs = new float[pointerNumber];
|
||||||
|
final float[] ys = new float[pointerNumber];
|
||||||
|
|
||||||
|
for (int i = 0; i < pointerNumber; i++) {
|
||||||
|
ids[i] = pMotionEvent.getPointerId(i);
|
||||||
|
xs[i] = pMotionEvent.getX(i);
|
||||||
|
ys[i] = pMotionEvent.getY(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (pMotionEvent.getAction() & MotionEvent.ACTION_MASK) {
|
||||||
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
|
if (mStopHandleTouchAndKeyEvents) {
|
||||||
|
// Cocos2dxEditBox.complete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int indexPointerDown = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||||
|
final int idPointerDown = pMotionEvent.getPointerId(indexPointerDown);
|
||||||
|
final float xPointerDown = pMotionEvent.getX(indexPointerDown);
|
||||||
|
final float yPointerDown = pMotionEvent.getY(indexPointerDown);
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
handleActionDown(idPointerDown, xPointerDown, yPointerDown);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
if (mStopHandleTouchAndKeyEvents) {
|
||||||
|
// Cocos2dxEditBox.complete();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// there are only one finger on the screen
|
||||||
|
final int idDown = pMotionEvent.getPointerId(0);
|
||||||
|
final float xDown = xs[0];
|
||||||
|
final float yDown = ys[0];
|
||||||
|
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
handleActionDown(idDown, xDown, yDown);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
handleActionMove(ids, xs, ys);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
|
final int indexPointUp = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||||
|
final int idPointerUp = pMotionEvent.getPointerId(indexPointUp);
|
||||||
|
final float xPointerUp = pMotionEvent.getX(indexPointUp);
|
||||||
|
final float yPointerUp = pMotionEvent.getY(indexPointUp);
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
handleActionUp(idPointerUp, xPointerUp, yPointerUp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
// there are only one finger on the screen
|
||||||
|
final int idUp = pMotionEvent.getPointerId(0);
|
||||||
|
final float xUp = xs[0];
|
||||||
|
final float yUp = ys[0];
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
handleActionUp(idUp, xUp, yUp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
handleActionCancel(ids, xs, ys);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
// CocosTouchHandler.dumpMotionEvent(pMotionEvent);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStopHandleTouchAndKeyEvents(boolean value) {
|
||||||
|
mStopHandleTouchAndKeyEvents = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void dumpMotionEvent(final MotionEvent event) {
|
||||||
|
final String names[] = {"DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?"};
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
final int action = event.getAction();
|
||||||
|
final int actionCode = action & MotionEvent.ACTION_MASK;
|
||||||
|
sb.append("event ACTION_").append(names[actionCode]);
|
||||||
|
if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) {
|
||||||
|
sb.append("(pid ").append(action >> MotionEvent.ACTION_POINTER_INDEX_SHIFT);
|
||||||
|
sb.append(")");
|
||||||
|
}
|
||||||
|
sb.append("[");
|
||||||
|
for (int i = 0; i < event.getPointerCount(); i++) {
|
||||||
|
sb.append("#").append(i);
|
||||||
|
sb.append("(pid ").append(event.getPointerId(i));
|
||||||
|
sb.append(")=").append((int) event.getX(i));
|
||||||
|
sb.append(",").append((int) event.getY(i));
|
||||||
|
if (i + 1 < event.getPointerCount()) {
|
||||||
|
sb.append(";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append("]");
|
||||||
|
Log.d(TAG, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
native void handleActionDown(final int id, final float x, final float y);
|
||||||
|
|
||||||
|
native void handleActionMove(final int[] ids, final float[] xPointerList, final float[] yPointerList);
|
||||||
|
|
||||||
|
native void handleActionUp(final int id, final float x, final float y);
|
||||||
|
|
||||||
|
native void handleActionCancel(final int[] ids, final float[] xPointerList, final float[] yPointerList);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,431 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
import com.cocos.lib.CocosVideoView.OnVideoEventListener;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.FutureTask;
|
||||||
|
|
||||||
|
public class CocosVideoHelper {
|
||||||
|
|
||||||
|
private FrameLayout mLayout = null;
|
||||||
|
private Activity mActivity = null;
|
||||||
|
private static SparseArray<CocosVideoView> sVideoViews = null;
|
||||||
|
static VideoHandler mVideoHandler = null;
|
||||||
|
private static Handler sHandler = null;
|
||||||
|
|
||||||
|
CocosVideoHelper(Activity activity, FrameLayout layout)
|
||||||
|
{
|
||||||
|
mActivity = activity;
|
||||||
|
mLayout = layout;
|
||||||
|
|
||||||
|
mVideoHandler = new VideoHandler(this);
|
||||||
|
sVideoViews = new SparseArray<CocosVideoView>();
|
||||||
|
sHandler = new Handler(Looper.myLooper());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int videoTag = 0;
|
||||||
|
private final static int VideoTaskCreate = 0;
|
||||||
|
private final static int VideoTaskRemove = 1;
|
||||||
|
private final static int VideoTaskSetSource = 2;
|
||||||
|
private final static int VideoTaskSetRect = 3;
|
||||||
|
private final static int VideoTaskStart = 4;
|
||||||
|
private final static int VideoTaskPause = 5;
|
||||||
|
private final static int VideoTaskResume = 6;
|
||||||
|
private final static int VideoTaskStop = 7;
|
||||||
|
private final static int VideoTaskSeek = 8;
|
||||||
|
private final static int VideoTaskSetVisible = 9;
|
||||||
|
private final static int VideoTaskRestart = 10;
|
||||||
|
private final static int VideoTaskKeepRatio = 11;
|
||||||
|
private final static int VideoTaskFullScreen = 12;
|
||||||
|
private final static int VideoTaskSetVolume = 13;
|
||||||
|
|
||||||
|
final static int KeyEventBack = 1000;
|
||||||
|
|
||||||
|
static class VideoHandler extends Handler{
|
||||||
|
WeakReference<CocosVideoHelper> mReference;
|
||||||
|
|
||||||
|
VideoHandler(CocosVideoHelper helper){
|
||||||
|
mReference = new WeakReference<CocosVideoHelper>(helper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
CocosVideoHelper helper = mReference.get();
|
||||||
|
switch (msg.what) {
|
||||||
|
case VideoTaskCreate: {
|
||||||
|
helper._createVideoView(msg.arg1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VideoTaskRemove: {
|
||||||
|
helper._removeVideoView(msg.arg1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VideoTaskSetSource: {
|
||||||
|
helper._setVideoURL(msg.arg1, msg.arg2, (String)msg.obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VideoTaskStart: {
|
||||||
|
helper._startVideo(msg.arg1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VideoTaskSetRect: {
|
||||||
|
Rect rect = (Rect)msg.obj;
|
||||||
|
helper._setVideoRect(msg.arg1, rect.left, rect.top, rect.right, rect.bottom);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VideoTaskFullScreen:{
|
||||||
|
if (msg.arg2 == 1) {
|
||||||
|
helper._setFullScreenEnabled(msg.arg1, true);
|
||||||
|
} else {
|
||||||
|
helper._setFullScreenEnabled(msg.arg1, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VideoTaskPause: {
|
||||||
|
helper._pauseVideo(msg.arg1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case VideoTaskStop: {
|
||||||
|
helper._stopVideo(msg.arg1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VideoTaskSeek: {
|
||||||
|
helper._seekVideoTo(msg.arg1, msg.arg2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VideoTaskSetVisible: {
|
||||||
|
if (msg.arg2 == 1) {
|
||||||
|
helper._setVideoVisible(msg.arg1, true);
|
||||||
|
} else {
|
||||||
|
helper._setVideoVisible(msg.arg1, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VideoTaskKeepRatio: {
|
||||||
|
if (msg.arg2 == 1) {
|
||||||
|
helper._setVideoKeepRatio(msg.arg1, true);
|
||||||
|
} else {
|
||||||
|
helper._setVideoKeepRatio(msg.arg1, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case KeyEventBack: {
|
||||||
|
helper.onBackKeyEvent();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VideoTaskSetVolume: {
|
||||||
|
float volume = (float) msg.arg2 / 10;
|
||||||
|
helper._setVolume(msg.arg1, volume);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.handleMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static native void nativeExecuteVideoCallback(int index,int event);
|
||||||
|
|
||||||
|
OnVideoEventListener videoEventListener = new OnVideoEventListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onVideoEvent(int tag,int event) {
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
nativeExecuteVideoCallback(tag, event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public static int createVideoWidget() {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskCreate;
|
||||||
|
msg.arg1 = videoTag;
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
|
||||||
|
return videoTag++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _createVideoView(int index) {
|
||||||
|
CocosVideoView videoView = new CocosVideoView(mActivity,index);
|
||||||
|
sVideoViews.put(index, videoView);
|
||||||
|
FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(
|
||||||
|
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
mLayout.addView(videoView, lParams);
|
||||||
|
|
||||||
|
videoView.setZOrderOnTop(true);
|
||||||
|
videoView.setVideoViewEventListener(videoEventListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeVideoWidget(int index){
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskRemove;
|
||||||
|
msg.arg1 = index;
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _removeVideoView(int index) {
|
||||||
|
CocosVideoView view = sVideoViews.get(index);
|
||||||
|
if (view != null) {
|
||||||
|
view.stopPlayback();
|
||||||
|
sVideoViews.remove(index);
|
||||||
|
mLayout.removeView(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setVideoUrl(int index, int videoSource, String videoUrl) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskSetSource;
|
||||||
|
msg.arg1 = index;
|
||||||
|
msg.arg2 = videoSource;
|
||||||
|
msg.obj = videoUrl;
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _setVideoURL(int index, int videoSource, String videoUrl) {
|
||||||
|
CocosVideoView videoView = sVideoViews.get(index);
|
||||||
|
if (videoView != null) {
|
||||||
|
switch (videoSource) {
|
||||||
|
case 0:
|
||||||
|
videoView.setVideoFileName(videoUrl);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
videoView.setVideoURL(videoUrl);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setVideoRect(int index, int left, int top, int maxWidth, int maxHeight) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskSetRect;
|
||||||
|
msg.arg1 = index;
|
||||||
|
msg.obj = new Rect(left, top, maxWidth, maxHeight);
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _setVideoRect(int index, int left, int top, int maxWidth, int maxHeight) {
|
||||||
|
CocosVideoView videoView = sVideoViews.get(index);
|
||||||
|
if (videoView != null) {
|
||||||
|
videoView.setVideoRect(left, top, maxWidth, maxHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setFullScreenEnabled(int index, boolean enabled) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskFullScreen;
|
||||||
|
msg.arg1 = index;
|
||||||
|
if (enabled) {
|
||||||
|
msg.arg2 = 1;
|
||||||
|
} else {
|
||||||
|
msg.arg2 = 0;
|
||||||
|
}
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _setFullScreenEnabled(int index, boolean enabled) {
|
||||||
|
CocosVideoView videoView = sVideoViews.get(index);
|
||||||
|
if (videoView != null) {
|
||||||
|
videoView.setFullScreenEnabled(enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onBackKeyEvent() {
|
||||||
|
int viewCount = sVideoViews.size();
|
||||||
|
for (int i = 0; i < viewCount; i++) {
|
||||||
|
int key = sVideoViews.keyAt(i);
|
||||||
|
CocosVideoView videoView = sVideoViews.get(key);
|
||||||
|
if (videoView != null) {
|
||||||
|
videoView.setFullScreenEnabled(false);
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
nativeExecuteVideoCallback(key, KeyEventBack);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startVideo(int index) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskStart;
|
||||||
|
msg.arg1 = index;
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _startVideo(int index) {
|
||||||
|
CocosVideoView videoView = sVideoViews.get(index);
|
||||||
|
if (videoView != null) {
|
||||||
|
videoView.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void pauseVideo(int index) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskPause;
|
||||||
|
msg.arg1 = index;
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _pauseVideo(int index) {
|
||||||
|
CocosVideoView videoView = sVideoViews.get(index);
|
||||||
|
if (videoView != null) {
|
||||||
|
videoView.pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopVideo(int index) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskStop;
|
||||||
|
msg.arg1 = index;
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _stopVideo(int index) {
|
||||||
|
CocosVideoView videoView = sVideoViews.get(index);
|
||||||
|
if (videoView != null) {
|
||||||
|
videoView.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void seekVideoTo(int index,int msec) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskSeek;
|
||||||
|
msg.arg1 = index;
|
||||||
|
msg.arg2 = msec;
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _seekVideoTo(int index,int msec) {
|
||||||
|
CocosVideoView videoView = sVideoViews.get(index);
|
||||||
|
if (videoView != null) {
|
||||||
|
videoView.seekTo(msec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getCurrentTime(final int index) {
|
||||||
|
CocosVideoView video = sVideoViews.get(index);
|
||||||
|
float currentPosition = -1;
|
||||||
|
if (video != null) {
|
||||||
|
currentPosition = video.getCurrentPosition() / 1000.0f;
|
||||||
|
}
|
||||||
|
return currentPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getDuration(final int index) {
|
||||||
|
CocosVideoView video = sVideoViews.get(index);
|
||||||
|
float duration = -1;
|
||||||
|
if (video != null) {
|
||||||
|
duration = video.getDuration() / 1000.0f;
|
||||||
|
}
|
||||||
|
if (duration <= 0) {
|
||||||
|
Log.w("CocosVideoHelper", "Video player's duration is not ready to get now!");
|
||||||
|
}
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setVideoVisible(int index, boolean visible) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskSetVisible;
|
||||||
|
msg.arg1 = index;
|
||||||
|
if (visible) {
|
||||||
|
msg.arg2 = 1;
|
||||||
|
} else {
|
||||||
|
msg.arg2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _setVideoVisible(int index, boolean visible) {
|
||||||
|
CocosVideoView videoView = sVideoViews.get(index);
|
||||||
|
if (videoView != null) {
|
||||||
|
if (visible) {
|
||||||
|
videoView.fixSize();
|
||||||
|
videoView.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
videoView.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setVideoKeepRatioEnabled(int index, boolean enable) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskKeepRatio;
|
||||||
|
msg.arg1 = index;
|
||||||
|
if (enable) {
|
||||||
|
msg.arg2 = 1;
|
||||||
|
} else {
|
||||||
|
msg.arg2 = 0;
|
||||||
|
}
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _setVideoKeepRatio(int index, boolean enable) {
|
||||||
|
CocosVideoView videoView = sVideoViews.get(index);
|
||||||
|
if (videoView != null) {
|
||||||
|
videoView.setKeepRatio(enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _setVolume(final int index, final float volume) {
|
||||||
|
CocosVideoView videoView = sVideoViews.get(index);
|
||||||
|
if (videoView != null) {
|
||||||
|
videoView.setVolume(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setVolume(final int index, final float volume) {
|
||||||
|
Message msg = new Message();
|
||||||
|
msg.what = VideoTaskSetVolume;
|
||||||
|
msg.arg1 = index;
|
||||||
|
msg.arg2 = (int) (volume * 10);
|
||||||
|
mVideoHandler.sendMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,595 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2006 The Android Open Source Project
|
||||||
|
* Copyright (c) 2014-2016 Chukong Technologies Inc.
|
||||||
|
* Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.AssetFileDescriptor;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.media.MediaPlayer;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.SurfaceHolder;
|
||||||
|
import android.view.SurfaceView;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.graphics.Point;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class CocosVideoView extends SurfaceView {
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Internal classes and interfaces.
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
public interface OnVideoEventListener {
|
||||||
|
void onVideoEvent(int tag,int event);
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum State {
|
||||||
|
IDLE,
|
||||||
|
ERROR,
|
||||||
|
INITIALIZED,
|
||||||
|
PREPARING,
|
||||||
|
PREPARED,
|
||||||
|
STARTED,
|
||||||
|
PAUSED,
|
||||||
|
STOPPED,
|
||||||
|
PLAYBACK_COMPLETED,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Constants
|
||||||
|
// ===========================================================
|
||||||
|
private static final String AssetResourceRoot = "@assets/";
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Fields
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
private String TAG = "CocosVideoView";
|
||||||
|
|
||||||
|
private Uri mVideoUri;
|
||||||
|
private int mDuration;
|
||||||
|
private int mPosition;
|
||||||
|
|
||||||
|
private State mCurrentState = State.IDLE;
|
||||||
|
|
||||||
|
// All the stuff we need for playing and showing a video
|
||||||
|
private SurfaceHolder mSurfaceHolder = null;
|
||||||
|
private MediaPlayer mMediaPlayer = null;
|
||||||
|
private int mVideoWidth = 0;
|
||||||
|
private int mVideoHeight = 0;
|
||||||
|
|
||||||
|
private OnVideoEventListener mOnVideoEventListener;
|
||||||
|
|
||||||
|
// recording the seek position while preparing
|
||||||
|
private int mSeekWhenPrepared = 0;
|
||||||
|
|
||||||
|
protected Activity mActivity = null;
|
||||||
|
|
||||||
|
protected int mViewLeft = 0;
|
||||||
|
protected int mViewTop = 0;
|
||||||
|
protected int mViewWidth = 0;
|
||||||
|
protected int mViewHeight = 0;
|
||||||
|
|
||||||
|
protected int mVisibleLeft = 0;
|
||||||
|
protected int mVisibleTop = 0;
|
||||||
|
protected int mVisibleWidth = 0;
|
||||||
|
protected int mVisibleHeight = 0;
|
||||||
|
|
||||||
|
protected boolean mFullScreenEnabled = false;
|
||||||
|
|
||||||
|
private boolean mIsAssetRouse = false;
|
||||||
|
private String mVideoFilePath = null;
|
||||||
|
|
||||||
|
private int mViewTag = 0;
|
||||||
|
private boolean mKeepRatio = false;
|
||||||
|
private boolean mMetaUpdated = false;
|
||||||
|
|
||||||
|
// MediaPlayer will be released when surface view is destroyed, so should record the position,
|
||||||
|
// and use it to play after MedialPlayer is created again.
|
||||||
|
private int mPositionBeforeRelease = 0;
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Constructors
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
public CocosVideoView(Activity activity, int tag) {
|
||||||
|
super(activity);
|
||||||
|
|
||||||
|
mViewTag = tag;
|
||||||
|
mActivity = activity;
|
||||||
|
initVideoView();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Getter & Setter
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
public void setVideoRect(int left, int top, int maxWidth, int maxHeight) {
|
||||||
|
if (mViewLeft == left && mViewTop == top && mViewWidth == maxWidth && mViewHeight == maxHeight)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mViewLeft = left;
|
||||||
|
mViewTop = top;
|
||||||
|
mViewWidth = maxWidth;
|
||||||
|
mViewHeight = maxHeight;
|
||||||
|
|
||||||
|
fixSize(mViewLeft, mViewTop, mViewWidth, mViewHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFullScreenEnabled(boolean enabled) {
|
||||||
|
if (mFullScreenEnabled != enabled) {
|
||||||
|
mFullScreenEnabled = enabled;
|
||||||
|
fixSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVolume (float volume) {
|
||||||
|
if (mMediaPlayer != null) {
|
||||||
|
mMediaPlayer.setVolume(volume, volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeepRatio(boolean enabled) {
|
||||||
|
mKeepRatio = enabled;
|
||||||
|
fixSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVideoURL(String url) {
|
||||||
|
mIsAssetRouse = false;
|
||||||
|
setVideoURI(Uri.parse(url), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVideoFileName(String path) {
|
||||||
|
if (path.startsWith(AssetResourceRoot)) {
|
||||||
|
path = path.substring(AssetResourceRoot.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.startsWith("/")) {
|
||||||
|
mIsAssetRouse = false;
|
||||||
|
setVideoURI(Uri.parse(path),null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
mVideoFilePath = path;
|
||||||
|
mIsAssetRouse = true;
|
||||||
|
setVideoURI(Uri.parse(path), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurrentPosition() {
|
||||||
|
if (! (mCurrentState == State.IDLE ||
|
||||||
|
mCurrentState == State.ERROR ||
|
||||||
|
mCurrentState == State.INITIALIZED ||
|
||||||
|
mCurrentState == State.STOPPED ||
|
||||||
|
mMediaPlayer == null) ) {
|
||||||
|
mPosition = mMediaPlayer.getCurrentPosition();
|
||||||
|
}
|
||||||
|
return mPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDuration() {
|
||||||
|
if (! (mCurrentState == State.IDLE ||
|
||||||
|
mCurrentState == State.ERROR ||
|
||||||
|
mCurrentState == State.INITIALIZED ||
|
||||||
|
mCurrentState == State.STOPPED ||
|
||||||
|
mMediaPlayer == null) ) {
|
||||||
|
mDuration = mMediaPlayer.getDuration();
|
||||||
|
}
|
||||||
|
|
||||||
|
return mDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a callback to be invoked when some video event triggered.
|
||||||
|
*
|
||||||
|
* @param l The callback that will be run
|
||||||
|
*/
|
||||||
|
public void setVideoViewEventListener(OnVideoEventListener l)
|
||||||
|
{
|
||||||
|
mOnVideoEventListener = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Overrides
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setVisibility(int visibility) {
|
||||||
|
super.setVisibility(visibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
setMeasuredDimension(mVisibleWidth, mVisibleHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) {
|
||||||
|
this.sendEvent(EVENT_CLICKED);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Public functions
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
if (!(mCurrentState == State.IDLE || mCurrentState == State.INITIALIZED || mCurrentState == State.ERROR || mCurrentState == State.STOPPED)
|
||||||
|
&& mMediaPlayer != null) {
|
||||||
|
mCurrentState = State.STOPPED;
|
||||||
|
mMediaPlayer.stop();
|
||||||
|
this.sendEvent(EVENT_STOPPED);
|
||||||
|
|
||||||
|
// after the video is stop, it shall prepare to be playable again
|
||||||
|
try {
|
||||||
|
mMediaPlayer.prepare();
|
||||||
|
this.showFirstFrame();
|
||||||
|
} catch (Exception ex) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopPlayback() {
|
||||||
|
this.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
if ((mCurrentState == State.PREPARED ||
|
||||||
|
mCurrentState == State.PAUSED ||
|
||||||
|
mCurrentState == State.PLAYBACK_COMPLETED) &&
|
||||||
|
mMediaPlayer != null) {
|
||||||
|
|
||||||
|
mCurrentState = State.STARTED;
|
||||||
|
mMediaPlayer.start();
|
||||||
|
this.sendEvent(EVENT_PLAYING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pause() {
|
||||||
|
if ((mCurrentState == State.STARTED || mCurrentState == State.PLAYBACK_COMPLETED) &&
|
||||||
|
mMediaPlayer != null) {
|
||||||
|
mCurrentState = State.PAUSED;
|
||||||
|
mMediaPlayer.pause();
|
||||||
|
this.sendEvent(EVENT_PAUSED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void seekTo(int ms) {
|
||||||
|
if (mCurrentState == State.IDLE || mCurrentState == State.INITIALIZED ||
|
||||||
|
mCurrentState == State.STOPPED || mCurrentState == State.ERROR ||
|
||||||
|
mMediaPlayer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
try {
|
||||||
|
Method seekTo = mMediaPlayer.getClass().getMethod("seekTo", long.class, int.class);
|
||||||
|
// The mode argument added in API level 26, 3 = MediaPlayer.SEEK_CLOSEST
|
||||||
|
// https://developer.android.com/reference/android/media/MediaPlayer#seekTo(int)
|
||||||
|
seekTo.invoke(mMediaPlayer, ms, 3);
|
||||||
|
} catch (Exception e) {
|
||||||
|
mMediaPlayer.seekTo(ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mMediaPlayer.seekTo(ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fixSize() {
|
||||||
|
if (mFullScreenEnabled) {
|
||||||
|
Point screenSize = new Point();
|
||||||
|
mActivity.getWindowManager().getDefaultDisplay().getSize(screenSize);
|
||||||
|
fixSize(0, 0, screenSize.x, screenSize.y);
|
||||||
|
} else {
|
||||||
|
fixSize(mViewLeft, mViewTop, mViewWidth, mViewHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fixSize(int left, int top, int width, int height) {
|
||||||
|
if (mVideoWidth == 0 || mVideoHeight == 0) {
|
||||||
|
mVisibleLeft = left;
|
||||||
|
mVisibleTop = top;
|
||||||
|
mVisibleWidth = width;
|
||||||
|
mVisibleHeight = height;
|
||||||
|
}
|
||||||
|
else if (width != 0 && height != 0) {
|
||||||
|
if (mKeepRatio && !mFullScreenEnabled) {
|
||||||
|
if ( mVideoWidth * height > width * mVideoHeight ) {
|
||||||
|
mVisibleWidth = width;
|
||||||
|
mVisibleHeight = width * mVideoHeight / mVideoWidth;
|
||||||
|
} else if ( mVideoWidth * height < width * mVideoHeight ) {
|
||||||
|
mVisibleWidth = height * mVideoWidth / mVideoHeight;
|
||||||
|
mVisibleHeight = height;
|
||||||
|
}
|
||||||
|
mVisibleLeft = left + (width - mVisibleWidth) / 2;
|
||||||
|
mVisibleTop = top + (height - mVisibleHeight) / 2;
|
||||||
|
} else {
|
||||||
|
mVisibleLeft = left;
|
||||||
|
mVisibleTop = top;
|
||||||
|
mVisibleWidth = width;
|
||||||
|
mVisibleHeight = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mVisibleLeft = left;
|
||||||
|
mVisibleTop = top;
|
||||||
|
mVisibleWidth = mVideoWidth;
|
||||||
|
mVisibleHeight = mVideoHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
getHolder().setFixedSize(mVisibleWidth, mVisibleHeight);
|
||||||
|
|
||||||
|
FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
FrameLayout.LayoutParams.MATCH_PARENT);
|
||||||
|
lParams.leftMargin = mVisibleLeft;
|
||||||
|
lParams.topMargin = mVisibleTop;
|
||||||
|
setLayoutParams(lParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int resolveAdjustedSize(int desiredSize, int measureSpec) {
|
||||||
|
int result = desiredSize;
|
||||||
|
int specMode = MeasureSpec.getMode(measureSpec);
|
||||||
|
int specSize = MeasureSpec.getSize(measureSpec);
|
||||||
|
|
||||||
|
switch (specMode) {
|
||||||
|
case MeasureSpec.UNSPECIFIED:
|
||||||
|
/* Parent says we can be as big as we want. Just don't be larger
|
||||||
|
* than max size imposed on ourselves.
|
||||||
|
*/
|
||||||
|
result = desiredSize;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MeasureSpec.AT_MOST:
|
||||||
|
/* Parent says we can be as big as we want, up to specSize.
|
||||||
|
* Don't be larger than specSize, and don't be larger than
|
||||||
|
* the max size imposed on ourselves.
|
||||||
|
*/
|
||||||
|
result = Math.min(desiredSize, specSize);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MeasureSpec.EXACTLY:
|
||||||
|
// No choice. Do what we are told.
|
||||||
|
result = specSize;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// Private functions
|
||||||
|
// ===========================================================
|
||||||
|
|
||||||
|
private void initVideoView() {
|
||||||
|
mVideoWidth = 0;
|
||||||
|
mVideoHeight = 0;
|
||||||
|
getHolder().addCallback(mSHCallback);
|
||||||
|
//Fix issue#11516:Can't play video on Android 2.3.x
|
||||||
|
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
|
||||||
|
setFocusable(true);
|
||||||
|
setFocusableInTouchMode(true);
|
||||||
|
mCurrentState = State.IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
private void setVideoURI(Uri uri, Map<String, String> headers) {
|
||||||
|
mVideoUri = uri;
|
||||||
|
mVideoWidth = 0;
|
||||||
|
mVideoHeight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openVideo() {
|
||||||
|
if (mSurfaceHolder == null) {
|
||||||
|
// not ready for playback just yet, will try again later
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mIsAssetRouse) {
|
||||||
|
if(mVideoFilePath == null)
|
||||||
|
return;
|
||||||
|
} else if(mVideoUri == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pausePlaybackService();
|
||||||
|
|
||||||
|
try {
|
||||||
|
mMediaPlayer = new MediaPlayer();
|
||||||
|
mMediaPlayer.setOnPreparedListener(mPreparedListener);
|
||||||
|
mMediaPlayer.setOnCompletionListener(mCompletionListener);
|
||||||
|
mMediaPlayer.setOnErrorListener(mErrorListener);
|
||||||
|
mMediaPlayer.setDisplay(mSurfaceHolder);
|
||||||
|
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||||
|
mMediaPlayer.setScreenOnWhilePlaying(true);
|
||||||
|
|
||||||
|
if (mIsAssetRouse) {
|
||||||
|
AssetFileDescriptor afd = mActivity.getAssets().openFd(mVideoFilePath);
|
||||||
|
mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
|
||||||
|
} else {
|
||||||
|
mMediaPlayer.setDataSource(mVideoUri.toString());
|
||||||
|
}
|
||||||
|
mCurrentState = State.INITIALIZED;
|
||||||
|
|
||||||
|
|
||||||
|
// Use Prepare() instead of PrepareAsync to make things easy.
|
||||||
|
mMediaPlayer.prepare();
|
||||||
|
this.showFirstFrame();
|
||||||
|
|
||||||
|
// mMediaPlayer.prepareAsync();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
Log.w(TAG, "Unable to open content: " + mVideoUri, ex);
|
||||||
|
mCurrentState = State.ERROR;
|
||||||
|
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
|
||||||
|
return;
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
Log.w(TAG, "Unable to open content: " + mVideoUri, ex);
|
||||||
|
mCurrentState = State.ERROR;
|
||||||
|
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
|
||||||
|
public void onPrepared(MediaPlayer mp) {
|
||||||
|
mVideoWidth = mp.getVideoWidth();
|
||||||
|
mVideoHeight = mp.getVideoHeight();
|
||||||
|
|
||||||
|
if (mVideoWidth != 0 && mVideoHeight != 0) {
|
||||||
|
fixSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mMetaUpdated) {
|
||||||
|
CocosVideoView.this.sendEvent(EVENT_META_LOADED);
|
||||||
|
CocosVideoView.this.sendEvent(EVENT_READY_TO_PLAY);
|
||||||
|
mMetaUpdated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCurrentState = State.PREPARED;
|
||||||
|
|
||||||
|
if (mPositionBeforeRelease > 0) {
|
||||||
|
CocosVideoView.this.start();
|
||||||
|
CocosVideoView.this.seekTo(mPositionBeforeRelease);
|
||||||
|
mPositionBeforeRelease = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private MediaPlayer.OnCompletionListener mCompletionListener =
|
||||||
|
new MediaPlayer.OnCompletionListener() {
|
||||||
|
public void onCompletion(MediaPlayer mp) {
|
||||||
|
mCurrentState = State.PLAYBACK_COMPLETED;
|
||||||
|
CocosVideoView.this.sendEvent(EVENT_COMPLETED);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private static final int EVENT_PLAYING = 0;
|
||||||
|
private static final int EVENT_PAUSED = 1;
|
||||||
|
private static final int EVENT_STOPPED = 2;
|
||||||
|
private static final int EVENT_COMPLETED = 3;
|
||||||
|
private static final int EVENT_META_LOADED = 4;
|
||||||
|
private static final int EVENT_CLICKED = 5;
|
||||||
|
private static final int EVENT_READY_TO_PLAY = 6;
|
||||||
|
|
||||||
|
private MediaPlayer.OnErrorListener mErrorListener =
|
||||||
|
new MediaPlayer.OnErrorListener() {
|
||||||
|
public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
|
||||||
|
Log.d(TAG, "Error: " + framework_err + "," + impl_err);
|
||||||
|
mCurrentState = State.ERROR;
|
||||||
|
|
||||||
|
/* Otherwise, pop up an error dialog so the user knows that
|
||||||
|
* something bad has happened. Only try and pop up the dialog
|
||||||
|
* if we're attached to a window. When we're going away and no
|
||||||
|
* longer have a window, don't bother showing the user an error.
|
||||||
|
*/
|
||||||
|
if (getWindowToken() != null) {
|
||||||
|
Resources r = mActivity.getResources();
|
||||||
|
int messageId;
|
||||||
|
|
||||||
|
if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
|
||||||
|
// messageId = com.android.internal.R.string.VideoView_error_text_invalid_progressive_playback;
|
||||||
|
messageId = r.getIdentifier("VideoView_error_text_invalid_progressive_playback", "string", "android");
|
||||||
|
} else {
|
||||||
|
// messageId = com.android.internal.R.string.VideoView_error_text_unknown;
|
||||||
|
messageId = r.getIdentifier("VideoView_error_text_unknown", "string", "android");
|
||||||
|
}
|
||||||
|
|
||||||
|
int titleId = r.getIdentifier("VideoView_error_title", "string", "android");
|
||||||
|
int buttonStringId = r.getIdentifier("VideoView_error_button", "string", "android");
|
||||||
|
|
||||||
|
new AlertDialog.Builder(mActivity)
|
||||||
|
.setTitle(r.getString(titleId))
|
||||||
|
.setMessage(messageId)
|
||||||
|
.setPositiveButton(r.getString(buttonStringId),
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
|
/* If we get here, there is no onError listener, so
|
||||||
|
* at least inform them that the video is over.
|
||||||
|
*/
|
||||||
|
CocosVideoView.this.sendEvent(EVENT_COMPLETED);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setCancelable(false)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback()
|
||||||
|
{
|
||||||
|
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void surfaceCreated(SurfaceHolder holder) {
|
||||||
|
mSurfaceHolder = holder;
|
||||||
|
CocosVideoView.this.openVideo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void surfaceDestroyed(SurfaceHolder holder) {
|
||||||
|
// after we return from this we can't use the surface any more
|
||||||
|
mSurfaceHolder = null;
|
||||||
|
mPositionBeforeRelease = getCurrentPosition();
|
||||||
|
CocosVideoView.this.release();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* release the media player in any state
|
||||||
|
*/
|
||||||
|
private void release() {
|
||||||
|
if (mMediaPlayer != null) {
|
||||||
|
mMediaPlayer.release();
|
||||||
|
mMediaPlayer = null;
|
||||||
|
mCurrentState = State.IDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showFirstFrame() {
|
||||||
|
mMediaPlayer.seekTo(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendEvent(int event) {
|
||||||
|
if (this.mOnVideoEventListener != null) {
|
||||||
|
this.mOnVideoEventListener.onVideoEvent(this.mViewTag, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell the music playback service to pause
|
||||||
|
// REFINE: these constants need to be published somewhere in the framework.
|
||||||
|
private void pausePlaybackService() {
|
||||||
|
Intent i = new Intent("com.android.music.musicservicecommand");
|
||||||
|
i.putExtra("command", "pause");
|
||||||
|
mActivity.sendBroadcast(i);
|
||||||
|
}
|
||||||
|
}
|
175
cx-framework3.1/cocos3-libs/cocos3-libcc/src/com/cocos/lib/CocosWebView.java
Executable file
175
cx-framework3.1/cocos3-libs/cocos3-libcc/src/com/cocos/lib/CocosWebView.java
Executable file
@ -0,0 +1,175 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos.com
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated engine source code (the "Software"), a limited,
|
||||||
|
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||||
|
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||||
|
not use Cocos Creator software for developing other software or tools that's
|
||||||
|
used for developing games. You are not granted to publish, distribute,
|
||||||
|
sublicense, and/or sell copies of Cocos Creator.
|
||||||
|
|
||||||
|
The software or tools in this License Agreement are licensed, not sold.
|
||||||
|
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.webkit.WebChromeClient;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import android.webkit.WebViewClient;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
class ShouldStartLoadingWorker implements Runnable {
|
||||||
|
private CountDownLatch mLatch;
|
||||||
|
private boolean[] mResult;
|
||||||
|
private final int mViewTag;
|
||||||
|
private final String mUrlString;
|
||||||
|
|
||||||
|
ShouldStartLoadingWorker(CountDownLatch latch, boolean[] result, int viewTag, String urlString) {
|
||||||
|
this.mLatch = latch;
|
||||||
|
this.mResult = result;
|
||||||
|
this.mViewTag = viewTag;
|
||||||
|
this.mUrlString = urlString;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
this.mResult[0] = CocosWebViewHelper._shouldStartLoading(mViewTag, mUrlString);
|
||||||
|
this.mLatch.countDown(); // notify that result is ready
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CocosWebView extends WebView {
|
||||||
|
private static final String TAG = CocosWebViewHelper.class.getSimpleName();
|
||||||
|
|
||||||
|
private int mViewTag;
|
||||||
|
private String mJSScheme;
|
||||||
|
|
||||||
|
public CocosWebView(Context context) {
|
||||||
|
this(context, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
|
public CocosWebView(Context context, int viewTag) {
|
||||||
|
super(context);
|
||||||
|
this.mViewTag = viewTag;
|
||||||
|
this.mJSScheme = "";
|
||||||
|
|
||||||
|
this.setFocusable(true);
|
||||||
|
this.setFocusableInTouchMode(true);
|
||||||
|
|
||||||
|
this.getSettings().setSupportZoom(false);
|
||||||
|
|
||||||
|
this.getSettings().setDomStorageEnabled(true);
|
||||||
|
this.getSettings().setJavaScriptEnabled(true);
|
||||||
|
|
||||||
|
// `searchBoxJavaBridge_` has big security risk. http://jvn.jp/en/jp/JVN53768697
|
||||||
|
try {
|
||||||
|
Method method = this.getClass().getMethod("removeJavascriptInterface", new Class[]{String.class});
|
||||||
|
method.invoke(this, "searchBoxJavaBridge_");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d(TAG, "This API level do not support `removeJavascriptInterface`");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setWebViewClient(new Cocos2dxWebViewClient());
|
||||||
|
this.setWebChromeClient(new WebChromeClient());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setJavascriptInterfaceScheme(String scheme) {
|
||||||
|
this.mJSScheme = scheme != null ? scheme : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScalesPageToFit(boolean scalesPageToFit) {
|
||||||
|
this.getSettings().setSupportZoom(scalesPageToFit);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Cocos2dxWebViewClient extends WebViewClient {
|
||||||
|
@Override
|
||||||
|
public boolean shouldOverrideUrlLoading(WebView view, final String urlString) {
|
||||||
|
CocosActivity activity = (CocosActivity)GlobalObject.getActivity();
|
||||||
|
|
||||||
|
try {
|
||||||
|
URI uri = URI.create(urlString);
|
||||||
|
if (uri != null && uri.getScheme().equals(mJSScheme)) {
|
||||||
|
activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebViewHelper._onJsCallback(mViewTag, urlString);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.d(TAG, "Failed to create URI from url");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean[] result = new boolean[] { true };
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
|
||||||
|
// run worker on cocos thread
|
||||||
|
activity.runOnUiThread(new ShouldStartLoadingWorker(latch, result, mViewTag, urlString));
|
||||||
|
|
||||||
|
// wait for result from cocos thread
|
||||||
|
try {
|
||||||
|
latch.await();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
Log.d(TAG, "'shouldOverrideUrlLoading' failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageFinished(WebView view, final String url) {
|
||||||
|
super.onPageFinished(view, url);
|
||||||
|
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebViewHelper._didFinishLoading(mViewTag, url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceivedError(WebView view, int errorCode, String description, final String failingUrl) {
|
||||||
|
super.onReceivedError(view, errorCode, description, failingUrl);
|
||||||
|
|
||||||
|
CocosHelper.runOnGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebViewHelper._didFailLoading(mViewTag, failingUrl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWebViewRect(int left, int top, int maxWidth, int maxHeight) {
|
||||||
|
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
|
||||||
|
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
FrameLayout.LayoutParams.MATCH_PARENT);
|
||||||
|
layoutParams.leftMargin = left;
|
||||||
|
layoutParams.topMargin = top;
|
||||||
|
layoutParams.width = maxWidth;
|
||||||
|
layoutParams.height = maxHeight;
|
||||||
|
this.setLayoutParams(layoutParams);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,312 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2010-2011 cocos2d-x.org
|
||||||
|
Copyright (c) 2013-2016 Chukong Technologies Inc.
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.util.SparseArray;
|
||||||
|
import android.view.View;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.PopupWindow;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.FutureTask;
|
||||||
|
|
||||||
|
|
||||||
|
public class CocosWebViewHelper {
|
||||||
|
private static final String TAG = CocosWebViewHelper.class.getSimpleName();
|
||||||
|
private static Handler sHandler;
|
||||||
|
private static CocosActivity sCocos2Activity;
|
||||||
|
private static PopupWindow sPopUp;
|
||||||
|
private static FrameLayout sLayout;
|
||||||
|
|
||||||
|
private static SparseArray<CocosWebView> webViews;
|
||||||
|
private static int viewTag = 0;
|
||||||
|
|
||||||
|
public CocosWebViewHelper(FrameLayout layout) {
|
||||||
|
|
||||||
|
CocosWebViewHelper.sLayout = layout;
|
||||||
|
CocosWebViewHelper.sHandler = new Handler(Looper.myLooper());
|
||||||
|
|
||||||
|
CocosWebViewHelper.sCocos2Activity = (CocosActivity) GlobalObject.getActivity();
|
||||||
|
CocosWebViewHelper.webViews = new SparseArray<CocosWebView>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static native boolean shouldStartLoading(int index, String message);
|
||||||
|
private static native void didFinishLoading(int index, String message);
|
||||||
|
private static native void didFailLoading(int index, String message);
|
||||||
|
private static native void onJsCallback(int index, String message);
|
||||||
|
|
||||||
|
public static boolean _shouldStartLoading(int index, String message) { return !shouldStartLoading(index, message); }
|
||||||
|
public static void _didFinishLoading(int index, String message) { didFinishLoading(index, message); }
|
||||||
|
public static void _didFailLoading(int index, String message) { didFailLoading(index, message); }
|
||||||
|
public static void _onJsCallback(int index, String message) { onJsCallback(index, message); }
|
||||||
|
|
||||||
|
public static int createWebView() {
|
||||||
|
final int index = viewTag;
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = new CocosWebView(sCocos2Activity, index);
|
||||||
|
FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(
|
||||||
|
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
sLayout.addView(webView, lParams);
|
||||||
|
|
||||||
|
webViews.put(index, webView);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return viewTag++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeWebView(final int index) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webViews.remove(index);
|
||||||
|
sLayout.removeView(webView);
|
||||||
|
webView.destroy();
|
||||||
|
webView = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setVisible(final int index, final boolean visible) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setWebViewRect(final int index, final int left, final int top, final int maxWidth, final int maxHeight) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.setWebViewRect(left, top, maxWidth, maxHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setBackgroundTransparent(final int index, final boolean isTransparent) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.setBackgroundColor(isTransparent ? Color.TRANSPARENT : Color.WHITE);
|
||||||
|
webView.setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setJavascriptInterfaceScheme(final int index, final String scheme) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.setJavascriptInterfaceScheme(scheme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadData(final int index, final String data, final String mimeType, final String encoding, final String baseURL) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.loadDataWithBaseURL(baseURL, data, mimeType, encoding, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadHTMLString(final int index, final String data, final String baseUrl) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.loadDataWithBaseURL(baseUrl, data, null, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadUrl(final int index, final String url) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.loadUrl(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadFile(final int index, final String filePath) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.loadUrl(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopLoading(final int index) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.stopLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void reload(final int index) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T callInMainThread(Callable<T> call) throws ExecutionException, InterruptedException {
|
||||||
|
FutureTask<T> task = new FutureTask<T>(call);
|
||||||
|
sHandler.post(task);
|
||||||
|
return task.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canGoBack(final int index) {
|
||||||
|
Callable<Boolean> callable = new Callable<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean call() throws Exception {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
return webView != null && webView.canGoBack();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
return callInMainThread(callable);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
return false;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean canGoForward(final int index) {
|
||||||
|
Callable<Boolean> callable = new Callable<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean call() throws Exception {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
return webView != null && webView.canGoForward();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
return callInMainThread(callable);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
return false;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void goBack(final int index) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.goBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void goForward(final int index) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.goForward();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void evaluateJS(final int index, final String js) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.loadUrl("javascript:" + js);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setScalesPageToFit(final int index, final boolean scalesPageToFit) {
|
||||||
|
sCocos2Activity.runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
CocosWebView webView = webViews.get(index);
|
||||||
|
if (webView != null) {
|
||||||
|
webView.setScalesPageToFit(scalesPageToFit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2020 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
public class GlobalObject {
|
||||||
|
private static Activity sActivity = null;
|
||||||
|
|
||||||
|
public static void setActivity(Activity activity) {
|
||||||
|
GlobalObject.sActivity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Activity getActivity() {
|
||||||
|
return GlobalObject.sActivity;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos2d-x.org
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
package com.cocos.lib;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
|
||||||
|
public static void hideVirtualButton() {
|
||||||
|
if (Build.VERSION.SDK_INT >= 19 &&
|
||||||
|
null != GlobalObject.getActivity()) {
|
||||||
|
// use reflection to remove dependence of API level
|
||||||
|
|
||||||
|
Class viewClass = View.class;
|
||||||
|
final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = CocosReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION");
|
||||||
|
final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = CocosReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN");
|
||||||
|
final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = CocosReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_HIDE_NAVIGATION");
|
||||||
|
final int SYSTEM_UI_FLAG_FULLSCREEN = CocosReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_FULLSCREEN");
|
||||||
|
final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = CocosReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_IMMERSIVE_STICKY");
|
||||||
|
final int SYSTEM_UI_FLAG_LAYOUT_STABLE = CocosReflectionHelper.<Integer>getConstantValue(viewClass, "SYSTEM_UI_FLAG_LAYOUT_STABLE");
|
||||||
|
|
||||||
|
// getWindow().getDecorView().setSystemUiVisibility();
|
||||||
|
final Object[] parameters = new Object[]{SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||||
|
| SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
|
| SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||||
|
| SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
|
||||||
|
| SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
|
||||||
|
| SYSTEM_UI_FLAG_IMMERSIVE_STICKY};
|
||||||
|
|
||||||
|
////blank 注释掉才可以全屏显示到状态栏
|
||||||
|
/*
|
||||||
|
CocosReflectionHelper.<Void>invokeInstanceMethod(GlobalObject.getActivity().getWindow().getDecorView(),
|
||||||
|
"setSystemUiVisibility",
|
||||||
|
new Class[]{Integer.TYPE},
|
||||||
|
parameters);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package cx;
|
||||||
|
|
||||||
|
import com.cocos.lib.CocosHelper;
|
||||||
|
import com.cocos.lib.CocosJavascriptJavaBridge;
|
||||||
|
|
||||||
|
import cx.mask.MaskIntf;
|
||||||
|
import cx.sys.SysIntf;
|
||||||
|
|
||||||
|
public class NativeIntf
|
||||||
|
{
|
||||||
|
public interface JsInterface
|
||||||
|
{
|
||||||
|
String call(NativeParams params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JsInterface jsInterface = null;
|
||||||
|
public static void setJsIntf(JsInterface jsInterface)
|
||||||
|
{
|
||||||
|
NativeIntf.jsInterface = jsInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String call(String classname, String fname, String params)
|
||||||
|
{
|
||||||
|
NativeParams nativeParams = new NativeParams(classname, fname, params.split("#@#"));
|
||||||
|
if (classname.equals("cx.sys"))
|
||||||
|
return SysIntf.ins().call(nativeParams);
|
||||||
|
|
||||||
|
if (classname.equals("cx.mask"))
|
||||||
|
return MaskIntf.ins().call(nativeParams);
|
||||||
|
|
||||||
|
if (jsInterface != null)
|
||||||
|
return jsInterface.call(nativeParams);
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void callJs(final String classname, final int v1, final String v2)
|
||||||
|
{
|
||||||
|
CocosHelper.runOnGameThread(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
CocosJavascriptJavaBridge.evalString("cx.native.androidCallback('" + classname + "'," + v1 + ",'" + v2 + "')");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// CocosActivity.app.runOnUiThread(new Runnable()
|
||||||
|
// {
|
||||||
|
// @Override
|
||||||
|
// public void run()
|
||||||
|
// {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package cx;
|
||||||
|
|
||||||
|
public class NativeParams
|
||||||
|
{
|
||||||
|
public class NativeParam
|
||||||
|
{
|
||||||
|
private String param;
|
||||||
|
|
||||||
|
public NativeParam(String param)
|
||||||
|
{
|
||||||
|
this.param = param;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String asString()
|
||||||
|
{
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int asInt()
|
||||||
|
{
|
||||||
|
return Integer.parseInt(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float asFloat()
|
||||||
|
{
|
||||||
|
return Float.parseFloat(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean asBool()
|
||||||
|
{
|
||||||
|
return Boolean.parseBoolean(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String classname;
|
||||||
|
public String fname;
|
||||||
|
private String[] params;
|
||||||
|
public NativeParams(String classname, String fname, String[] params)
|
||||||
|
{
|
||||||
|
this.classname = classname;
|
||||||
|
this.fname = fname;
|
||||||
|
this.params = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeParam at(int index)
|
||||||
|
{
|
||||||
|
return new NativeParam(params[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
String s = "";
|
||||||
|
for (int i=0; i<params.length; i++)
|
||||||
|
s += "," + params[i];
|
||||||
|
return s.isEmpty() ? s : s.substring(1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,160 @@
|
|||||||
|
package cx.mask;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import com.cocos.lib.CocosActivity;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import cx.NativeParams;
|
||||||
|
|
||||||
|
public class MaskIntf
|
||||||
|
{
|
||||||
|
private static MaskIntf s_sharedMaskIntf = null;
|
||||||
|
public static MaskIntf ins()
|
||||||
|
{
|
||||||
|
if (s_sharedMaskIntf == null)
|
||||||
|
s_sharedMaskIntf = new MaskIntf();
|
||||||
|
return s_sharedMaskIntf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String call(NativeParams params)
|
||||||
|
{
|
||||||
|
CocosActivity.app.runOnUiThread(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
callInternal(params);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String callInternal(NativeParams params)
|
||||||
|
{
|
||||||
|
String fname = params.fname;
|
||||||
|
String maskName = params.at(0).asString();
|
||||||
|
if (fname.equals("createMask"))
|
||||||
|
{
|
||||||
|
float rectX = params.at(1).asFloat();
|
||||||
|
float rectY = params.at(2).asFloat();
|
||||||
|
float rectW = params.at(3).asFloat();
|
||||||
|
float rectH = params.at(4).asFloat();
|
||||||
|
this.createMask(maskName, rectX, rectY, rectW, rectH);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (fname.equals("setMaskVisible"))
|
||||||
|
{
|
||||||
|
boolean visible = params.at(1).asBool();
|
||||||
|
this.setMaskVisible(maskName, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (fname.equals("setMaskSize"))
|
||||||
|
{
|
||||||
|
float rectW = params.at(1).asFloat();
|
||||||
|
float rectH = params.at(2).asFloat();
|
||||||
|
this.setMaskSize(maskName, rectW, rectH);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (fname.equals("setMaskMask"))
|
||||||
|
{
|
||||||
|
float maskX = params.at(1).asFloat();
|
||||||
|
float maskY = params.at(2).asFloat();
|
||||||
|
float maskW = params.at(3).asFloat();
|
||||||
|
float maskH = params.at(4).asFloat();
|
||||||
|
float radius = params.at(5).asFloat();
|
||||||
|
this.setMaskMask(maskName, maskX, maskY, maskW, maskH, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (fname.equals("clearMaskMask"))
|
||||||
|
{
|
||||||
|
this.clearMaskMask(maskName);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (fname.equals("removeMask"))
|
||||||
|
{
|
||||||
|
this.removeMask(maskName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashMap<String, MaskView> maskMap = new HashMap<>();
|
||||||
|
public void createMask(String maskName, float rectX, float rectY, float rectW, float rectH)
|
||||||
|
{
|
||||||
|
if (!maskMap.containsKey(maskName))
|
||||||
|
{
|
||||||
|
MaskView maskView = new MaskView();
|
||||||
|
maskView.initFrame(Math.round(rectX), Math.round(rectY), Math.round(rectW), Math.round(rectH));
|
||||||
|
maskMap.put(maskName, maskView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addNativeView(String maskName, View view, String viewTag, FrameLayout.LayoutParams params)
|
||||||
|
{
|
||||||
|
MaskView maskView = maskMap.get(maskName);
|
||||||
|
if (maskView != null)
|
||||||
|
{
|
||||||
|
view.setTag(viewTag);
|
||||||
|
maskView.contentView.addView(view, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNativeView(String maskName, String viewTag)
|
||||||
|
{
|
||||||
|
MaskView maskView = maskMap.get(maskName);
|
||||||
|
if (maskView != null)
|
||||||
|
{
|
||||||
|
int count = maskView.contentView.getChildCount();
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
if (viewTag.equals(maskView.contentView.getChildAt(i).getTag()))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaskVisible(String maskName, boolean value)
|
||||||
|
{
|
||||||
|
MaskView maskView = maskMap.get(maskName);
|
||||||
|
if (maskView != null)
|
||||||
|
maskView.setMaskVisible(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaskSize(String maskName, float width, float height)
|
||||||
|
{
|
||||||
|
MaskView maskView = maskMap.get(maskName);
|
||||||
|
if (maskView != null)
|
||||||
|
maskView.setMaskSize(Math.round(width), Math.round(height));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeMask(String maskName)
|
||||||
|
{
|
||||||
|
MaskView maskView = maskMap.get(maskName);
|
||||||
|
if (maskView != null)
|
||||||
|
{
|
||||||
|
maskView.remove();
|
||||||
|
maskMap.remove(maskView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaskMask(String maskName, float maskX, float maskY, float maskW, float maskH, float radius)
|
||||||
|
{
|
||||||
|
MaskView maskView = maskMap.get(maskName);
|
||||||
|
if (maskView != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearMaskMask(String maskName)
|
||||||
|
{
|
||||||
|
MaskView maskView = maskMap.get(maskName);
|
||||||
|
if (maskView != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package cx.mask;
|
||||||
|
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
|
import com.cocos.lib.CocosActivity;
|
||||||
|
|
||||||
|
import cx.sys.SysIntf;
|
||||||
|
|
||||||
|
public class MaskView
|
||||||
|
{
|
||||||
|
public FrameLayout view;
|
||||||
|
public FrameLayout contentView;
|
||||||
|
private int viewWidth;
|
||||||
|
private int viewHeight;
|
||||||
|
|
||||||
|
public MaskView()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initFrame(final int rectX, final int rectY, final int rectW, final int rectH)
|
||||||
|
{
|
||||||
|
FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
lParams.leftMargin = rectX;
|
||||||
|
lParams.topMargin = rectY;
|
||||||
|
lParams.width = rectW;
|
||||||
|
lParams.height = rectH;
|
||||||
|
view = new FrameLayout(CocosActivity.app);
|
||||||
|
CocosActivity.app.getFrameLayout().addView(view, lParams);
|
||||||
|
// view.setBackgroundColor(Color.parseColor("#500000ff"));
|
||||||
|
|
||||||
|
Point screenSize = SysIntf.getScreenSize();
|
||||||
|
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
params.leftMargin = -rectX;
|
||||||
|
params.topMargin = -rectY;
|
||||||
|
params.width = screenSize.x;
|
||||||
|
params.height = screenSize.y;
|
||||||
|
contentView = new FrameLayout(CocosActivity.app);
|
||||||
|
view.addView(contentView, params);
|
||||||
|
// contentView.setBackgroundColor(Color.parseColor("#50ff0000"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaskSize(int width, int height)
|
||||||
|
{
|
||||||
|
this.viewWidth = width;
|
||||||
|
this.viewHeight = height;
|
||||||
|
FrameLayout.LayoutParams lParams = (FrameLayout.LayoutParams) view.getLayoutParams();
|
||||||
|
lParams.width = viewWidth;
|
||||||
|
lParams.height = viewHeight;
|
||||||
|
view.setLayoutParams(lParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaskVisible(final boolean value)
|
||||||
|
{
|
||||||
|
view.setVisibility(value ? View.VISIBLE : View.INVISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove()
|
||||||
|
{
|
||||||
|
CocosActivity.app.getFrameLayout().removeView(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
112
cx-framework3.1/cocos3-libs/cocos3-libcc/src/cx/sys/SysIntf.java
Normal file
112
cx-framework3.1/cocos3-libs/cocos3-libcc/src/cx/sys/SysIntf.java
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package cx.sys;
|
||||||
|
|
||||||
|
import android.graphics.Point;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import com.cocos.lib.CocosActivity;
|
||||||
|
|
||||||
|
import cx.NativeParams;
|
||||||
|
|
||||||
|
public class SysIntf
|
||||||
|
{
|
||||||
|
private static SysIntf s_sharedSysIntf = null;
|
||||||
|
public static SysIntf ins()
|
||||||
|
{
|
||||||
|
if (s_sharedSysIntf == null)
|
||||||
|
s_sharedSysIntf = new SysIntf();
|
||||||
|
return s_sharedSysIntf;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Point screenSize = null;
|
||||||
|
public static Point getScreenSize()
|
||||||
|
{
|
||||||
|
if (screenSize != null)
|
||||||
|
return screenSize;
|
||||||
|
Display display = CocosActivity.app.getWindowManager().getDefaultDisplay();
|
||||||
|
screenSize = new Point();
|
||||||
|
display.getRealSize(screenSize);
|
||||||
|
return screenSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String call(NativeParams params)
|
||||||
|
{
|
||||||
|
String fname = params.fname;
|
||||||
|
if (fname.equals("moveTaskToBack"))
|
||||||
|
this.moveTaskToBack();
|
||||||
|
|
||||||
|
else if (fname.equals("getPackageName"))
|
||||||
|
return this.getPackageName();
|
||||||
|
|
||||||
|
else if (fname.equals("getVersionCode"))
|
||||||
|
return this.getVersionCode();
|
||||||
|
|
||||||
|
else if (fname.equals("getVersionName"))
|
||||||
|
return this.getVersionName();
|
||||||
|
|
||||||
|
else if (fname.equals("removeLaunchImage"))
|
||||||
|
this.removeLaunchImage();
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void moveTaskToBack()
|
||||||
|
{
|
||||||
|
CocosActivity.app.moveTaskToBack(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPackageName()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String packName = CocosActivity.app.getPackageName();
|
||||||
|
return String.valueOf(CocosActivity.app.getPackageManager().getPackageInfo(packName, 0).packageName);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersionCode()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String packName = CocosActivity.app.getPackageName();
|
||||||
|
return String.valueOf(CocosActivity.app.getPackageManager().getPackageInfo(packName, 0).versionCode);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersionName()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String packName = CocosActivity.app.getPackageName();
|
||||||
|
return CocosActivity.app.getPackageManager().getPackageInfo(packName, 0).versionName;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeLaunchImage()
|
||||||
|
{
|
||||||
|
View view = CocosActivity.app.getFrameLayout().findViewWithTag("launchImage");
|
||||||
|
if (view != null)
|
||||||
|
{
|
||||||
|
CocosActivity.app.runOnUiThread(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
CocosActivity.app.getFrameLayout().removeView(view);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="cx3.blank.so"
|
||||||
|
android:installLocation="auto">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
|
||||||
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission android:name="android.permission.CALL_PHONE"/>
|
||||||
|
<uses-permission android:name="android.permission.CAMERA"/>
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:usesCleartextTraffic="true">
|
||||||
|
|
||||||
|
<meta-data android:name="android.app.lib_name"
|
||||||
|
android:value="cocos" />
|
||||||
|
|
||||||
|
<meta-data android:name="com.amap.api.v2.apikey" android:value="94f84f93c7305329b9ebe12f761dbbac"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".AppActivity"
|
||||||
|
android:screenOrientation="portrait"
|
||||||
|
android:configChanges="orientation|keyboardHidden|screenSize|screenLayout"
|
||||||
|
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||||
|
android:launchMode="singleTask"
|
||||||
|
android:taskAffinity="" >
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
81
cx-framework3.1/cocos3-libs/cocos3-libso/app/build.gradle
Normal file
81
cx-framework3.1/cocos3-libs/cocos3-libso/app/build.gradle
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
RES_PATH = RES_PATH.replace("\\", "/")
|
||||||
|
COCOS_ENGINE_PATH = COCOS_ENGINE_PATH.replace("\\", "/")
|
||||||
|
|
||||||
|
buildDir = "${RES_PATH}/build/$project.name"
|
||||||
|
android {
|
||||||
|
compileSdkVersion PROP_COMPILE_SDK_VERSION.toInteger()
|
||||||
|
buildToolsVersion PROP_BUILD_TOOLS_VERSION
|
||||||
|
// ndkPath PROP_NDK_PATH
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId APPLICATION_ID
|
||||||
|
minSdkVersion PROP_MIN_SDK_VERSION
|
||||||
|
targetSdkVersion PROP_TARGET_SDK_VERSION
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
targets "cocos"
|
||||||
|
arguments "-DRES_DIR=${RES_PATH}", "-DCOCOS_X_PATH=${COCOS_ENGINE_PATH}", "-DANDROID_STL=c++_static", "-DANDROID_TOOLCHAIN=clang", "-DANDROID_ARM_NEON=TRUE", "-DANDROID_LD=gold"
|
||||||
|
cppFlags "-frtti -fexceptions -fsigned-char"
|
||||||
|
}
|
||||||
|
ndk { abiFilters PROP_APP_ABI.split(':') }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
path "../engine/CMakeLists.txt"
|
||||||
|
buildStagingDirectory "${RES_PATH}/build"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets.main {
|
||||||
|
manifest.srcFile "AndroidManifest.xml"
|
||||||
|
java.srcDirs "src"
|
||||||
|
jniLibs.srcDirs = ["libs"]
|
||||||
|
}
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
if (project.hasProperty("RELEASE_STORE_FILE")) {
|
||||||
|
storeFile file(RELEASE_STORE_FILE)
|
||||||
|
storePassword RELEASE_STORE_PASSWORD
|
||||||
|
keyAlias RELEASE_KEY_ALIAS
|
||||||
|
keyPassword RELEASE_KEY_PASSWORD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
debuggable false
|
||||||
|
jniDebuggable false
|
||||||
|
renderscriptDebuggable false
|
||||||
|
minifyEnabled true
|
||||||
|
shrinkResources true
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
if (project.hasProperty("RELEASE_STORE_FILE")) {
|
||||||
|
signingConfig signingConfigs.release
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug {
|
||||||
|
debuggable true
|
||||||
|
jniDebuggable true
|
||||||
|
renderscriptDebuggable true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
|
||||||
|
}
|
40
cx-framework3.1/cocos3-libs/cocos3-libso/app/proguard-rules.pro
vendored
Normal file
40
cx-framework3.1/cocos3-libs/cocos3-libso/app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in E:\developSoftware\Android\SDK/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Proguard Cocos2d-x-lite for release
|
||||||
|
-keep public class com.cocos.** { *; }
|
||||||
|
-dontwarn com.cocos.**
|
||||||
|
|
||||||
|
# Proguard Apache HTTP for release
|
||||||
|
-keep class org.apache.http.** { *; }
|
||||||
|
-dontwarn org.apache.http.**
|
||||||
|
|
||||||
|
# Proguard okhttp for release
|
||||||
|
-keep class okhttp3.** { *; }
|
||||||
|
-dontwarn okhttp3.**
|
||||||
|
|
||||||
|
-keep class okio.** { *; }
|
||||||
|
-dontwarn okio.**
|
||||||
|
|
||||||
|
# Proguard Android Webivew for release. you can comment if you are not using a webview
|
||||||
|
-keep public class android.net.http.SslError
|
||||||
|
-keep public class android.webkit.WebViewClient
|
||||||
|
|
||||||
|
-dontwarn android.webkit.WebView
|
||||||
|
-dontwarn android.net.http.SslError
|
||||||
|
-dontwarn android.webkit.WebViewClient
|
@ -0,0 +1,9 @@
|
|||||||
|
package cx3.blank.so;
|
||||||
|
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
public class AppActivity extends Activity
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
28
cx-framework3.1/cocos3-libs/cocos3-libso/build.gradle
Normal file
28
cx-framework3.1/cocos3-libs/cocos3-libso/build.gradle
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:3.2.0'
|
||||||
|
|
||||||
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
// in the individual module build.gradle files
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
jcenter()
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task clean(type: Delete) {
|
||||||
|
delete rootProject.buildDir
|
||||||
|
}
|
||||||
|
|
53
cx-framework3.1/cocos3-libs/cocos3-libso/engine/CMakeLists.txt
Executable file
53
cx-framework3.1/cocos3-libs/cocos3-libso/engine/CMakeLists.txt
Executable file
@ -0,0 +1,53 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.8)
|
||||||
|
|
||||||
|
option(APP_NAME "Project Name" "cx3-so")
|
||||||
|
project(${APP_NAME} CXX)
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_LIST_DIR}/common/CMakeLists.txt)
|
||||||
|
|
||||||
|
|
||||||
|
set(LIB_NAME cocos)
|
||||||
|
|
||||||
|
set(PROJ_SOURCES
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../../cx-native/cxCreator.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../../cx-native/cxCreator.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../../cx-native/cxDefine.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../../cx-native/cxIntf.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../../cx-native/cxIntf.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../../cx-native/cxJsb.hpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../../cx-native/cxJsb.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../../cx-native/Game.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../../cx-native/Game.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../../cx-native/jsb_module_register.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/jni/main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# -------------- SRART ---------------
|
||||||
|
# USED BY COCOS SERVICE, DON'T REMOVE!
|
||||||
|
if(EXISTS ${RES_DIR}/service.cmake)
|
||||||
|
set(SERVICE_NATIVE_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||||
|
include(${RES_DIR}/service.cmake)
|
||||||
|
endif()
|
||||||
|
# -------------- END ----------------
|
||||||
|
|
||||||
|
#list(APPEND PROJ_SOURCES
|
||||||
|
# ${CMAKE_CURRENT_LIST_DIR}/../../../cx-native/jsb_module_register.cpp
|
||||||
|
#)
|
||||||
|
|
||||||
|
add_library(${LIB_NAME} SHARED ${PROJ_SOURCES})
|
||||||
|
|
||||||
|
# -------------- SRART ---------------
|
||||||
|
# USED BY COCOS SERVICE, DON'T REMOVE!
|
||||||
|
if(COMMAND service_insert_library)
|
||||||
|
service_insert_library()
|
||||||
|
endif()
|
||||||
|
# -------------- END ----------------
|
||||||
|
|
||||||
|
target_link_libraries(${LIB_NAME}
|
||||||
|
"-Wl,--whole-archive" cocos2d_jni "-Wl,--no-whole-archive"
|
||||||
|
cocos2d
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${LIB_NAME} PRIVATE
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/../../../cx-native
|
||||||
|
)
|
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"ndk_module_path" :[
|
||||||
|
"${COCOS_ROOT}",
|
||||||
|
"${COCOS_ROOT}/cocos",
|
||||||
|
"${COCOS_ROOT}/external"
|
||||||
|
],
|
||||||
|
"copy_resources": []
|
||||||
|
}
|
13
cx-framework3.1/cocos3-libs/cocos3-libso/engine/cfg.cmake
Normal file
13
cx-framework3.1/cocos3-libs/cocos3-libso/engine/cfg.cmake
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
set(CC_USE_GLES3 ON)
|
||||||
|
set(CC_USE_GLES2 ON)
|
||||||
|
set(APP_NAME cx3-so)
|
||||||
|
set(COCOS_X_PATH "/Applications/CocosCreator/Creator/3.1.1/CocosCreator.app/Contents/Resources/resources/3d/engine-native")
|
||||||
|
set(CC_USE_VULKAN OFF)
|
||||||
|
set(USE_PHYSICS_PHYSX OFF)
|
||||||
|
set(USE_AUDIO ON)
|
||||||
|
set(USE_VIDEO ON)
|
||||||
|
set(USE_WEBVIEW ON)
|
||||||
|
set(USE_SPINE OFF)
|
||||||
|
set(USE_DRAGONBONES ON)
|
||||||
|
set(USE_JOB_SYSTEM_TBB ON)
|
||||||
|
|
64
cx-framework3.1/cocos3-libs/cocos3-libso/engine/common/CMakeLists.txt
Executable file
64
cx-framework3.1/cocos3-libs/cocos3-libso/engine/common/CMakeLists.txt
Executable file
@ -0,0 +1,64 @@
|
|||||||
|
enable_language(C ASM)
|
||||||
|
|
||||||
|
|
||||||
|
set(DEVELOPMENT_TEAM "" CACHE STRING "APPLE Developtment Team")
|
||||||
|
set(RES_DIR "" CACHE STRING "Resource path")
|
||||||
|
set(COCOS_X_PATH "" CACHE STRING "Path to cocos2d-x-lite/")
|
||||||
|
|
||||||
|
set(TARGET_OSX_VERSION "10.14" CACHE STRING "Target MacOSX version" FORCE)
|
||||||
|
set(TARGET_IOS_VERSION "12.0" CACHE STRING "Target iOS version" FORCE)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
option(USE_SE_V8 "Use V8 JavaScript Engine" ON)
|
||||||
|
option(USE_V8_DEBUGGER "Enable Chrome Remote inspector" OFF)
|
||||||
|
option(USE_SOCKET "Enable WebSocket & SocketIO" OFF)
|
||||||
|
option(USE_AUDIO "Enable Audio" ON) #Enable AudioEngine
|
||||||
|
option(USE_EDIT_BOX "Enable EditBox" ON)
|
||||||
|
option(USE_SE_JSC "Use JavaScriptCore on MacOSX/iOS" OFF)
|
||||||
|
option(USE_VIDEO "Enable VideoPlayer Component" ON)
|
||||||
|
option(USE_WEBVIEW "Enable WebView Component" ON)
|
||||||
|
option(USE_MIDDLEWARE "Enable Middleware" ON)
|
||||||
|
option(USE_DRAGONBONES "Enable Dragonbones" ON)
|
||||||
|
option(USE_SPINE "Enable Spine" OFF)
|
||||||
|
option(USE_WEBSOCKET_SERVER "Enable WebSocket Server" OFF)
|
||||||
|
option(USE_JOB_SYSTEM_TASKFLOW "Use taskflow as job system backend" OFF)
|
||||||
|
option(USE_JOB_SYSTEM_TBB "Use tbb as job system backend" OFF)
|
||||||
|
option(USE_PHYSICS_PHYSX "USE PhysX Physics" OFF)
|
||||||
|
|
||||||
|
if(NOT RES_DIR)
|
||||||
|
message(FATAL_ERROR "RES_DIR is not set!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(${RES_DIR}/engine/cfg.cmake)
|
||||||
|
|
||||||
|
if(NOT COCOS_X_PATH)
|
||||||
|
message(FATAL_ERROR "COCOS_X_PATH is not set!")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(${COCOS_X_PATH}/CMakeLists.txt)
|
||||||
|
|
||||||
|
set(ASSET_FILES)
|
||||||
|
macro(include_resources ARG_RES_ROOT)
|
||||||
|
foreach(res ${ARG_RES_ROOT})
|
||||||
|
set(res_list)
|
||||||
|
if(NOT EXISTS ${res})
|
||||||
|
continue()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(IS_DIRECTORY ${res})
|
||||||
|
file(GLOB_RECURSE res_list "${res}/*")
|
||||||
|
else()
|
||||||
|
set(res_list ${res})
|
||||||
|
endif()
|
||||||
|
foreach(res ${res_list})
|
||||||
|
get_filename_component(res_abs ${res} ABSOLUTE)
|
||||||
|
file(RELATIVE_PATH res_rel ${ARG_RES_ROOT} ${res_abs})
|
||||||
|
get_filename_component(res_dir ${res_rel} PATH)
|
||||||
|
set_source_files_properties(${res_abs} PROPERTIES
|
||||||
|
MACOSX_PACKAGE_LOCATION "Resources/${res_dir}/"
|
||||||
|
HEADER_FILE_ONLY 1
|
||||||
|
)
|
||||||
|
list(APPEND ASSET_FILES ${res_abs})
|
||||||
|
endforeach()
|
||||||
|
endforeach()
|
||||||
|
endmacro()
|
29
cx-framework3.1/cocos3-libs/cocos3-libso/engine/jni/main.cpp
Normal file
29
cx-framework3.1/cocos3-libs/cocos3-libso/engine/jni/main.cpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos.com
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated engine source code (the "Software"), a limited,
|
||||||
|
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||||
|
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||||
|
not use Cocos Creator software for developing other software or tools that's
|
||||||
|
used for developing games. You are not granted to publish, distribute,
|
||||||
|
sublicense, and/or sell copies of Cocos Creator.
|
||||||
|
|
||||||
|
The software or tools in this License Agreement are licensed, not sold.
|
||||||
|
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "Game.h"
|
||||||
|
|
||||||
|
cc::Application *cocos_main(int width, int height) {
|
||||||
|
return new Game(width, height);
|
||||||
|
}
|
38
cx-framework3.1/cocos3-libs/cocos3-libso/gradle.properties
Normal file
38
cx-framework3.1/cocos3-libs/cocos3-libso/gradle.properties
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# Project-wide Gradle settings.
|
||||||
|
|
||||||
|
android.injected.testOnly=false
|
||||||
|
|
||||||
|
# Android SDK version that will be used as the compile project
|
||||||
|
PROP_COMPILE_SDK_VERSION=28
|
||||||
|
|
||||||
|
# Android SDK version that will be used as the earliest version of android this application can run on
|
||||||
|
PROP_MIN_SDK_VERSION=21
|
||||||
|
|
||||||
|
# Android SDK version that will be used as the latest version of android this application has been tested on
|
||||||
|
PROP_TARGET_SDK_VERSION=27
|
||||||
|
|
||||||
|
# Android Build Tools version that will be used as the compile project
|
||||||
|
PROP_BUILD_TOOLS_VERSION=28.0.2
|
||||||
|
|
||||||
|
PROP_NDK_PATH=/Users/blank/Library/Android/sdk/ndk-bundle
|
||||||
|
|
||||||
|
# Cocos Engine Path
|
||||||
|
COCOS_ENGINE_PATH=/Applications/CocosCreator/Creator/3.1.1/CocosCreator.app/Contents/Resources/resources/3d/engine-native
|
||||||
|
|
||||||
|
# Res path
|
||||||
|
RES_PATH=/Users/blank/ccapp3/cx-framework3.1/cocos3-libs/cocos3-libso
|
||||||
|
|
||||||
|
# Application ID
|
||||||
|
APPLICATION_ID=cx3.blank.so
|
||||||
|
|
||||||
|
# List of CPU Archtexture to build that application with
|
||||||
|
# Available architextures (armeabi-v7a | arm64-v8a | x86)
|
||||||
|
# To build for multiple architexture, use the `:` between them
|
||||||
|
# Example - PROP_APP_ABI=armeabi-v7a
|
||||||
|
#PROP_APP_ABI=armeabi-v7a:x86_64
|
||||||
|
PROP_APP_ABI=armeabi-v7a
|
||||||
|
|
||||||
|
RELEASE_STORE_FILE=/Applications/CocosCreator/Creator/3.1.1/CocosCreator.app/Contents/Resources/tools/keystore/debug.keystore
|
||||||
|
RELEASE_STORE_PASSWORD=123456
|
||||||
|
RELEASE_KEY_ALIAS=debug_keystore
|
||||||
|
RELEASE_KEY_PASSWORD=123456
|
6
cx-framework3.1/cocos3-libs/cocos3-libso/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
cx-framework3.1/cocos3-libs/cocos3-libso/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#Wed May 05 22:20:29 CST 2021
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip
|
164
cx-framework3.1/cocos3-libs/cocos3-libso/gradlew
vendored
Executable file
164
cx-framework3.1/cocos3-libs/cocos3-libso/gradlew
vendored
Executable file
@ -0,0 +1,164 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >&-
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >&-
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
90
cx-framework3.1/cocos3-libs/cocos3-libso/gradlew.bat
vendored
Normal file
90
cx-framework3.1/cocos3-libs/cocos3-libso/gradlew.bat
vendored
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
@ -0,0 +1,9 @@
|
|||||||
|
## This file must *NOT* be checked into Version Control Systems,
|
||||||
|
# as it contains information specific to your local configuration.
|
||||||
|
#
|
||||||
|
# Location of the SDK. This is only used by Gradle.
|
||||||
|
# For customization when using a Version Control System, please read the
|
||||||
|
# header note.
|
||||||
|
#Wed May 05 22:19:02 CST 2021
|
||||||
|
ndk.dir=/Users/blank/Library/Android/sdk/ndk-bundle
|
||||||
|
sdk.dir=/Users/blank/Library/Android/sdk
|
1
cx-framework3.1/cocos3-libs/cocos3-libso/settings.gradle
Normal file
1
cx-framework3.1/cocos3-libs/cocos3-libso/settings.gradle
Normal file
@ -0,0 +1 @@
|
|||||||
|
include ':app'
|
3144
cx-framework3.1/cocos3-libs/cocos3-mac.xcodeproj/project.pbxproj
Normal file
3144
cx-framework3.1/cocos3-libs/cocos3-mac.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load Diff
7
cx-framework3.1/cocos3-libs/cocos3-mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
cx-framework3.1/cocos3-libs/cocos3-mac.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:/Users/blank/ccapp3/cx-framework3.1/cocos3-libs/cocos3-mac.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDEDidComputeMac32BitWarning</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>BuildSystemType</key>
|
||||||
|
<string>Latest</string>
|
||||||
|
<key>DisableBuildSystemDeprecationWarning</key>
|
||||||
|
<true/>
|
||||||
|
<key>PreviewsEnabled</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
Binary file not shown.
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>BuildLocationStyle</key>
|
||||||
|
<string>UseAppPreferences</string>
|
||||||
|
<key>CustomBuildIntermediatesPath</key>
|
||||||
|
<string>Build/Intermediates.noindex</string>
|
||||||
|
<key>CustomBuildLocationType</key>
|
||||||
|
<string>RelativeToDerivedData</string>
|
||||||
|
<key>CustomBuildProductsPath</key>
|
||||||
|
<string>Build/Products</string>
|
||||||
|
<key>DerivedDataLocationStyle</key>
|
||||||
|
<string>Default</string>
|
||||||
|
<key>IssueFilterStyle</key>
|
||||||
|
<string>ShowActiveSchemeOnly</string>
|
||||||
|
<key>LiveSourceIssuesEnabled</key>
|
||||||
|
<true/>
|
||||||
|
<key>ShowSharedSchemesAutomaticallyEnabled</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "1240"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "46916FCB264D6D28000C7B53"
|
||||||
|
BuildableName = "libcocos3 Mac.a"
|
||||||
|
BlueprintName = "cocos3 Mac"
|
||||||
|
ReferencedContainer = "container:cocos3-mac.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "Debug"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<Testables>
|
||||||
|
</Testables>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "46916FCB264D6D28000C7B53"
|
||||||
|
BuildableName = "libcocos3 Mac.a"
|
||||||
|
BlueprintName = "cocos3 Mac"
|
||||||
|
ReferencedContainer = "container:cocos3-mac.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "Debug">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Bucket
|
||||||
|
uuid = "ABE5CDBB-B2EC-4486-A952-379CAA2C5C0A"
|
||||||
|
type = "1"
|
||||||
|
version = "2.0">
|
||||||
|
</Bucket>
|
@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>SchemeUserState</key>
|
||||||
|
<dict>
|
||||||
|
<key>ALL_BUILD.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
<key>ZERO_CHECK.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>2</integer>
|
||||||
|
</dict>
|
||||||
|
<key>cocos3 Mac.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
<key>cx3-demo-desktop.xcscheme_^#shared#^_</key>
|
||||||
|
<dict>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>SuppressBuildableAutocreation</key>
|
||||||
|
<dict>
|
||||||
|
<key>46916FCB264D6D28000C7B53</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>E77C5DADC6FB43A28EC868C1</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
BIN
cx-framework3.1/cocos3-libs/libcocos3 Mac.a
Normal file
BIN
cx-framework3.1/cocos3-libs/libcocos3 Mac.a
Normal file
Binary file not shown.
BIN
cx-framework3.1/cocos3-libs/libcocos3 iOS.a
Normal file
BIN
cx-framework3.1/cocos3-libs/libcocos3 iOS.a
Normal file
Binary file not shown.
101
cx-framework3.1/cx-native/Game.cpp
Normal file
101
cx-framework3.1/cx-native/Game.cpp
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos.com
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated engine source code (the "Software"), a limited,
|
||||||
|
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||||
|
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||||
|
not use Cocos Creator software for developing other software or tools that's
|
||||||
|
used for developing games. You are not granted to publish, distribute,
|
||||||
|
sublicense, and/or sell copies of Cocos Creator.
|
||||||
|
|
||||||
|
The software or tools in this License Agreement are licensed, not sold.
|
||||||
|
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "Game.h"
|
||||||
|
#include "cocos/bindings/event/CustomEventTypes.h"
|
||||||
|
#include "cocos/bindings/event/EventDispatcher.h"
|
||||||
|
#include "cocos/bindings/jswrapper/SeApi.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_classtype.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_global.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_module_register.h"
|
||||||
|
|
||||||
|
#if (CC_PLATFORM == CC_PLATFORM_MAC_IOS)
|
||||||
|
#include "platform/Device.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////blank
|
||||||
|
#include "cxJsb.hpp"
|
||||||
|
|
||||||
|
Game::Game(int width, int height) : cc::Application(width, height) {}
|
||||||
|
|
||||||
|
bool Game::init()
|
||||||
|
{
|
||||||
|
cc::Application::init();
|
||||||
|
|
||||||
|
se::ScriptEngine *se = se::ScriptEngine::getInstance();
|
||||||
|
|
||||||
|
jsb_set_xxtea_key("");
|
||||||
|
jsb_init_file_operation_delegate();
|
||||||
|
|
||||||
|
#if defined(CC_DEBUG) && (CC_DEBUG > 0)
|
||||||
|
// Enable debugger here
|
||||||
|
jsb_enable_debugger("0.0.0.0", 6086, false);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
se->setExceptionCallback([](const char *location, const char *message, const char *stack) {
|
||||||
|
// Send exception information to server like Tencent Bugly.
|
||||||
|
CC_LOG_ERROR("\nUncaught Exception:\n - location : %s\n - msg : %s\n - detail : \n %s\n", location, message, stack);
|
||||||
|
});
|
||||||
|
|
||||||
|
se->addRegisterCallback(register_all_cx);
|
||||||
|
|
||||||
|
jsb_register_all_modules();
|
||||||
|
|
||||||
|
se->start();
|
||||||
|
|
||||||
|
se::AutoHandleScope hs;
|
||||||
|
jsb_run_script("jsb-adapter/jsb-builtin.js");
|
||||||
|
jsb_run_script("boot.js");
|
||||||
|
|
||||||
|
se->addAfterCleanupHook([]() {
|
||||||
|
JSBClassType::destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
#if (CC_PLATFORM == CC_PLATFORM_MAC_IOS)
|
||||||
|
cc::Vec2 logicSize = getViewLogicalSize();
|
||||||
|
float pixelRatio = cc::Device::getDevicePixelRatio();
|
||||||
|
cc::EventDispatcher::dispatchResizeEvent(logicSize.x * pixelRatio, logicSize.y * pixelRatio);
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::onPause()
|
||||||
|
{
|
||||||
|
cc::Application::onPause();
|
||||||
|
|
||||||
|
cc::CustomEvent event;
|
||||||
|
event.name = EVENT_COME_TO_BACKGROUND;
|
||||||
|
cc::EventDispatcher::dispatchCustomEvent(event);
|
||||||
|
cc::EventDispatcher::dispatchEnterBackgroundEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Game::onResume()
|
||||||
|
{
|
||||||
|
cc::Application::onResume();
|
||||||
|
|
||||||
|
cc::CustomEvent event;
|
||||||
|
event.name = EVENT_COME_TO_FOREGROUND;
|
||||||
|
cc::EventDispatcher::dispatchCustomEvent(event);
|
||||||
|
cc::EventDispatcher::dispatchEnterForegroundEvent();
|
||||||
|
}
|
43
cx-framework3.1/cx-native/Game.h
Normal file
43
cx-framework3.1/cx-native/Game.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2018 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos.com
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated engine source code (the "Software"), a limited,
|
||||||
|
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||||
|
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||||
|
not use Cocos Creator software for developing other software or tools that's
|
||||||
|
used for developing games. You are not granted to publish, distribute,
|
||||||
|
sublicense, and/or sell copies of Cocos Creator.
|
||||||
|
|
||||||
|
The software or tools in this License Agreement are licensed, not sold.
|
||||||
|
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "platform/Application.h"
|
||||||
|
/**
|
||||||
|
@brief The cocos2d Application.
|
||||||
|
|
||||||
|
The reason for implement as private inheritance is to hide some interface call by Director.
|
||||||
|
*/
|
||||||
|
class Game : public cc::Application
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* width and height in logical pixel unit
|
||||||
|
*/
|
||||||
|
Game(int width, int height);
|
||||||
|
virtual bool init() override;
|
||||||
|
virtual void onPause() override;
|
||||||
|
virtual void onResume() override;
|
||||||
|
};
|
36
cx-framework3.1/cx-native/cxCreator.cpp
Normal file
36
cx-framework3.1/cx-native/cxCreator.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#include "cxCreator.h"
|
||||||
|
#include "cxIntf.h"
|
||||||
|
|
||||||
|
#if CC_PLATFORM == CC_PLATFORM_MAC_IOS
|
||||||
|
#include "cxMask/cxMaskIntf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CC_PLATFORM != CC_PLATFORM_ANDROID
|
||||||
|
#include "cxSys/cxSysIntf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NativeIntfClass* NativeCreator::createNativeClass(std::string classname)
|
||||||
|
{
|
||||||
|
if (classname == "cx")
|
||||||
|
return CxIntf::ins();
|
||||||
|
|
||||||
|
#if CC_PLATFORM == CC_PLATFORM_MAC_IOS
|
||||||
|
|
||||||
|
if (classname == "cx.mask")
|
||||||
|
return CxMaskIntf::ins();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if CC_PLATFORM != CC_PLATFORM_ANDROID
|
||||||
|
|
||||||
|
if (classname == "cx.sys")
|
||||||
|
return CxSysIntf::ins();
|
||||||
|
|
||||||
|
return createAppNativeClass(classname);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
15
cx-framework3.1/cx-native/cxCreator.h
Normal file
15
cx-framework3.1/cx-native/cxCreator.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cxDefine.h"
|
||||||
|
|
||||||
|
#if CC_PLATFORM != CC_PLATFORM_ANDROID
|
||||||
|
extern NativeIntfClass* createAppNativeClass(std::string classname);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class NativeCreator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static NativeIntfClass* createNativeClass(std::string classname);
|
||||||
|
};
|
||||||
|
|
13
cx-framework3.1/cx-native/cxDefine.h
Normal file
13
cx-framework3.1/cx-native/cxDefine.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cocos/base/Value.h"
|
||||||
|
|
||||||
|
typedef std::function<void(int v1, std::string v2)> DataCallback;
|
||||||
|
|
||||||
|
class NativeIntfClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual std::string call(std::string fname, cc::ValueVector params, const DataCallback& callback){ return nullptr; };
|
||||||
|
};
|
||||||
|
|
23
cx-framework3.1/cx-native/cxIntf.cpp
Normal file
23
cx-framework3.1/cx-native/cxIntf.cpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
#include "cxIntf.h"
|
||||||
|
|
||||||
|
DataCallback CxIntf::m_cxCallback = NULL;
|
||||||
|
|
||||||
|
static CxIntf* s_sharedCxIntf = nullptr;
|
||||||
|
CxIntf* CxIntf::ins()
|
||||||
|
{
|
||||||
|
if (!s_sharedCxIntf)
|
||||||
|
s_sharedCxIntf = new CxIntf();
|
||||||
|
return s_sharedCxIntf;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CxIntf::call(std::string fname, cc::ValueVector params, const DataCallback& callback)
|
||||||
|
{
|
||||||
|
if (fname == "encode" || fname == "decode" || fname == "md5")
|
||||||
|
return params.at(0).asString();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
20
cx-framework3.1/cx-native/cxIntf.h
Normal file
20
cx-framework3.1/cx-native/cxIntf.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cocos/base/Value.h"
|
||||||
|
#include "cxDefine.h"
|
||||||
|
|
||||||
|
class CxIntf : public NativeIntfClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static CxIntf* ins();
|
||||||
|
|
||||||
|
virtual std::string call(std::string fname, cc::ValueVector params, const DataCallback& callback) override;
|
||||||
|
|
||||||
|
static DataCallback m_cxCallback;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
228
cx-framework3.1/cx-native/cxJsb.cpp
Normal file
228
cx-framework3.1/cx-native/cxJsb.cpp
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
#include "cxJsb.hpp"
|
||||||
|
#include "cocos/bindings/manual/jsb_conversions.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_global.h"
|
||||||
|
#include "platform/FileUtils.h"
|
||||||
|
#include "cxCreator.h"
|
||||||
|
|
||||||
|
se::Object* __jsb_NativeCreator_proto = nullptr;
|
||||||
|
se::Class* __jsb_NativeCreator_class = nullptr;
|
||||||
|
|
||||||
|
//***********************************
|
||||||
|
//NativeCreator
|
||||||
|
//***********************************
|
||||||
|
static bool js_cx_NativeCreator_createNativeClass(se::State& s)
|
||||||
|
{
|
||||||
|
const auto& args = s.args();
|
||||||
|
size_t argc = args.size();
|
||||||
|
CC_UNUSED bool ok = true;
|
||||||
|
if (argc == 1) {
|
||||||
|
std::string arg0;
|
||||||
|
ok &= seval_to_std_string(args[0], &arg0);
|
||||||
|
SE_PRECONDITION2(ok, false, "js_cx_NativeCreator_createNativeClass : Error processing arguments");
|
||||||
|
NativeIntfClass* result = NativeCreator::createNativeClass(arg0);
|
||||||
|
ok &= native_ptr_to_seval<NativeIntfClass>((NativeIntfClass*)result, &s.rval());
|
||||||
|
SE_PRECONDITION2(ok, false, "js_cx_NativeCreator_createNativeClass : Error processing arguments");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SE_BIND_FUNC(js_cx_NativeCreator_createNativeClass)
|
||||||
|
|
||||||
|
static bool js_NativeCreator_finalize(se::State& s)
|
||||||
|
{
|
||||||
|
// SE_LOGD("jsbindings: finalizing JS object %p (NativeCreator)", s.nativeThisObject());
|
||||||
|
auto iter = se::NonRefNativePtrCreatedByCtorMap::find(s.nativeThisObject());
|
||||||
|
if (iter != se::NonRefNativePtrCreatedByCtorMap::end())
|
||||||
|
{
|
||||||
|
se::NonRefNativePtrCreatedByCtorMap::erase(iter);
|
||||||
|
NativeCreator* cobj = (NativeCreator*)s.nativeThisObject();
|
||||||
|
delete cobj;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
SE_BIND_FINALIZE_FUNC(js_NativeCreator_finalize)
|
||||||
|
|
||||||
|
bool js_register_cx_NativeCreator(se::Object* obj)
|
||||||
|
{
|
||||||
|
auto cls = se::Class::create("NativeCreator", obj, nullptr, nullptr);
|
||||||
|
|
||||||
|
cls->defineStaticFunction("createNativeClass", _SE(js_cx_NativeCreator_createNativeClass));
|
||||||
|
cls->defineFinalizeFunction(_SE(js_NativeCreator_finalize));
|
||||||
|
cls->install();
|
||||||
|
JSBClassType::registerClass<NativeCreator>(cls);
|
||||||
|
|
||||||
|
__jsb_NativeCreator_proto = cls->getProto();
|
||||||
|
__jsb_NativeCreator_class = cls;
|
||||||
|
|
||||||
|
se::ScriptEngine::getInstance()->clearException();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***********************************
|
||||||
|
//NativeIntfClass
|
||||||
|
//***********************************
|
||||||
|
|
||||||
|
se::Object* __jsb_NativeIntfClass_proto = nullptr;
|
||||||
|
se::Class* __jsb_NativeIntfClass_class = nullptr;
|
||||||
|
|
||||||
|
static bool js_cx_NativeIntfClass_call(se::State& s)
|
||||||
|
{
|
||||||
|
const auto& args = s.args();
|
||||||
|
size_t argc = args.size();
|
||||||
|
CC_UNUSED bool ok = true;
|
||||||
|
std::string arg0;
|
||||||
|
cc::ValueVector arg1;
|
||||||
|
std::function<void (int, std::string)> arg2 = nullptr;
|
||||||
|
|
||||||
|
if (argc >= 1)
|
||||||
|
{
|
||||||
|
ok &= seval_to_std_string(args[0], &arg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc >= 2)
|
||||||
|
{
|
||||||
|
ok &= seval_to_std_string(args[0], &arg0);
|
||||||
|
ok &= seval_to_ccvaluevector(args[1], &arg1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok && argc == 3)
|
||||||
|
{
|
||||||
|
if (args[2].isObject() && args[2].toObject()->isFunction())
|
||||||
|
{
|
||||||
|
se::Value jsThis(s.thisObject());
|
||||||
|
se::Value jsFunc(args[2]);
|
||||||
|
//https://docs.cocos.com/creator/manual/zh/advanced-topics/JSB2.0-learning.html
|
||||||
|
//如果当前类是一个单例类,或者永远只有一个实例的类,我们不能用 se::Object::attachObject 去关联, 必须使用 se::Object::root
|
||||||
|
//jsThis.toObject()->attachObject(jsFunc.toObject());
|
||||||
|
jsFunc.toObject()->root();
|
||||||
|
jsThis.toObject()->root();
|
||||||
|
|
||||||
|
auto lambda = [=](int larg0, std::string larg1) -> void
|
||||||
|
{
|
||||||
|
se::ScriptEngine::getInstance()->clearException();
|
||||||
|
se::AutoHandleScope hs;
|
||||||
|
CC_UNUSED bool ok = true;
|
||||||
|
se::ValueArray args;
|
||||||
|
args.resize(2);
|
||||||
|
ok &= int32_to_seval(larg0, &args[0]);
|
||||||
|
ok &= std_string_to_seval(larg1, &args[1]);
|
||||||
|
se::Value rval;
|
||||||
|
se::Object* thisObj = jsThis.isObject() ? jsThis.toObject() : nullptr;
|
||||||
|
se::Object* funcObj = jsFunc.toObject();
|
||||||
|
bool succeed = funcObj->call(args, thisObj, &rval);
|
||||||
|
if (!succeed)
|
||||||
|
{
|
||||||
|
se::ScriptEngine::getInstance()->clearException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
arg2 = lambda;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SE_PRECONDITION2(ok, false, "js_cx_NativeIntfClass_func : Error processing arguments");
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
NativeIntfClass* cobj = (NativeIntfClass*)s.nativeThisObject();
|
||||||
|
std::string result = cobj->call(arg0, arg1, arg2);
|
||||||
|
std_string_to_seval(result, &s.rval());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SE_BIND_FUNC(js_cx_NativeIntfClass_call)
|
||||||
|
|
||||||
|
static bool js_NativeIntfClass_finalize(se::State& s)
|
||||||
|
{
|
||||||
|
// SE_LOGD("jsbindings: finalizing JS object %p (NativeCreator)", s.nativeThisObject());
|
||||||
|
auto iter = se::NonRefNativePtrCreatedByCtorMap::find(s.nativeThisObject());
|
||||||
|
if (iter != se::NonRefNativePtrCreatedByCtorMap::end())
|
||||||
|
{
|
||||||
|
se::NonRefNativePtrCreatedByCtorMap::erase(iter);
|
||||||
|
NativeIntfClass* cobj = (NativeIntfClass*)s.nativeThisObject();
|
||||||
|
delete cobj;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
SE_BIND_FINALIZE_FUNC(js_NativeIntfClass_finalize)
|
||||||
|
|
||||||
|
bool js_register_cx_NativeIntfClass(se::Object* obj)
|
||||||
|
{
|
||||||
|
auto cls = se::Class::create("NativeIntfClass", obj, nullptr, nullptr);
|
||||||
|
|
||||||
|
cls->defineFunction("call", _SE(js_cx_NativeIntfClass_call));
|
||||||
|
cls->defineFinalizeFunction(_SE(js_NativeIntfClass_finalize));
|
||||||
|
cls->install();
|
||||||
|
JSBClassType::registerClass<NativeIntfClass>(cls);
|
||||||
|
|
||||||
|
__jsb_NativeIntfClass_proto = cls->getProto();
|
||||||
|
__jsb_NativeIntfClass_class = cls;
|
||||||
|
|
||||||
|
se::ScriptEngine::getInstance()->clearException();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***********************************
|
||||||
|
//NativeUtils
|
||||||
|
//***********************************
|
||||||
|
|
||||||
|
se::Object* __jsb_NativeUtils_proto = nullptr;
|
||||||
|
se::Class* __jsb_NativeUtils_class = nullptr;
|
||||||
|
|
||||||
|
static bool js_cx_NativeUtils_writeDataToFile(se::State& s)
|
||||||
|
{
|
||||||
|
const auto& args = s.args();
|
||||||
|
size_t argc = args.size();
|
||||||
|
CC_UNUSED bool ok = true;
|
||||||
|
if (argc == 2) {
|
||||||
|
cc::Data arg0;
|
||||||
|
std::string arg1;
|
||||||
|
ok &= seval_to_Data(args[0], &arg0);
|
||||||
|
ok &= seval_to_std_string(args[1], &arg1);
|
||||||
|
SE_PRECONDITION2(ok, false, "js_engine_FileUtils_writeDataToFile : Error processing arguments");
|
||||||
|
bool result = cc::FileUtils::getInstance()->writeDataToFile(arg0, arg1);
|
||||||
|
ok &= boolean_to_seval(result, &s.rval());
|
||||||
|
SE_PRECONDITION2(ok, false, "js_engine_FileUtils_writeDataToFile : Error processing result");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 2);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SE_BIND_FUNC(js_cx_NativeUtils_writeDataToFile)
|
||||||
|
|
||||||
|
bool js_register_cx_NativeUtils(se::Object* obj)
|
||||||
|
{
|
||||||
|
auto cls = se::Class::create("NativeUtils", obj, nullptr, nullptr);
|
||||||
|
|
||||||
|
cls->defineStaticFunction("writeDataToFile", _SE(js_cx_NativeUtils_writeDataToFile));
|
||||||
|
cls->install();
|
||||||
|
|
||||||
|
__jsb_NativeUtils_proto = cls->getProto();
|
||||||
|
__jsb_NativeUtils_class = cls;
|
||||||
|
|
||||||
|
se::ScriptEngine::getInstance()->clearException();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//***********************************
|
||||||
|
//register
|
||||||
|
//***********************************
|
||||||
|
|
||||||
|
bool register_all_cx(se::Object* obj)
|
||||||
|
{
|
||||||
|
// Get the ns
|
||||||
|
se::Value nsVal;
|
||||||
|
if (!obj->getProperty("cxnative", &nsVal))
|
||||||
|
{
|
||||||
|
se::HandleObject jsobj(se::Object::createPlainObject());
|
||||||
|
nsVal.setObject(jsobj);
|
||||||
|
obj->setProperty("cxnative", nsVal);
|
||||||
|
}
|
||||||
|
se::Object* ns = nsVal.toObject();
|
||||||
|
|
||||||
|
js_register_cx_NativeCreator(ns);
|
||||||
|
js_register_cx_NativeIntfClass(ns);
|
||||||
|
js_register_cx_NativeUtils(ns);
|
||||||
|
return true;
|
||||||
|
}
|
11
cx-framework3.1/cx-native/cxJsb.hpp
Normal file
11
cx-framework3.1/cx-native/cxJsb.hpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cocos/bindings/jswrapper/SeApi.h"
|
||||||
|
|
||||||
|
extern se::Object* __jsb_NativeCreator_proto;
|
||||||
|
extern se::Class* __jsb_NativeCreator_class;
|
||||||
|
|
||||||
|
bool js_register_NativeCreator(se::Object* obj);
|
||||||
|
bool register_all_cx(se::Object* obj);
|
||||||
|
SE_DECLARE_FUNC(js_cx_NativeCreator_createNativeClass);
|
||||||
|
|
20
cx-framework3.1/cx-native/cxMask/cxMaskIntf.h
Normal file
20
cx-framework3.1/cx-native/cxMask/cxMaskIntf.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cxDefine.h"
|
||||||
|
|
||||||
|
class CxMaskIntf : public NativeIntfClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static CxMaskIntf* ins();
|
||||||
|
|
||||||
|
virtual std::string call(std::string fname, cc::ValueVector params, const DataCallback& callback) override;
|
||||||
|
|
||||||
|
void addNativeView(std::string maskName, void* view);
|
||||||
|
bool hasNativeView(std::string maskName, void* view);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
127
cx-framework3.1/cx-native/cxMask/cxMaskIntf.mm
Normal file
127
cx-framework3.1/cx-native/cxMask/cxMaskIntf.mm
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
|
||||||
|
#include "cxMaskIntf.h"
|
||||||
|
|
||||||
|
#include "AppController.h"
|
||||||
|
#include "cxMaskView.h"
|
||||||
|
|
||||||
|
std::unordered_map<std::string, CxMaskView*> m_maskViewList;
|
||||||
|
CxMaskView* getMaskView(std::string name)
|
||||||
|
{
|
||||||
|
auto itr = m_maskViewList.find(name);
|
||||||
|
if (itr != m_maskViewList.end())
|
||||||
|
return itr->second;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CxMaskIntf* s_sharedCxMaskIntf = nullptr;
|
||||||
|
CxMaskIntf* CxMaskIntf::ins()
|
||||||
|
{
|
||||||
|
if (!s_sharedCxMaskIntf)
|
||||||
|
s_sharedCxMaskIntf = new CxMaskIntf();
|
||||||
|
return s_sharedCxMaskIntf;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CxMaskIntf::call(std::string fname, cc::ValueVector params, const DataCallback& callback)
|
||||||
|
{
|
||||||
|
if (fname == "createMask")
|
||||||
|
{
|
||||||
|
std::string name = params.at(0).asString();
|
||||||
|
float rectX = params.at(1).asFloat();
|
||||||
|
float rectY = params.at(2).asFloat();
|
||||||
|
float rectW = params.at(3).asFloat();
|
||||||
|
float rectH = params.at(4).asFloat();
|
||||||
|
|
||||||
|
if (getMaskView(name))
|
||||||
|
return "";
|
||||||
|
|
||||||
|
CxMaskView* maskView = [[CxMaskView alloc] initWithFrame:CGRectMake(rectX, rectY, rectW, rectH)];
|
||||||
|
//maskView.contentView.backgroundColor = [UIColor colorWithRed:100 green:0 blue:0 alpha:0.4];
|
||||||
|
[[AppController ins] addView:maskView];
|
||||||
|
|
||||||
|
m_maskViewList.emplace(name, maskView);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (fname == "setMaskVisible")
|
||||||
|
{
|
||||||
|
std::string name = params.at(0).asString();
|
||||||
|
bool visible = params.at(1).asBool();
|
||||||
|
|
||||||
|
auto maskView = getMaskView(name);
|
||||||
|
if (maskView)
|
||||||
|
[maskView setHidden:!visible];
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (fname == "setMaskSize")
|
||||||
|
{
|
||||||
|
std::string name = params.at(0).asString();
|
||||||
|
float rectW = params.at(1).asFloat();
|
||||||
|
float rectH = params.at(2).asFloat();
|
||||||
|
|
||||||
|
auto maskView = getMaskView(name);
|
||||||
|
if (maskView)
|
||||||
|
maskView.frame = CGRectMake(maskView.frame.origin.x, maskView.frame.origin.y, rectW, rectH);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (fname == "setMaskMask")
|
||||||
|
{
|
||||||
|
std::string name = params.at(0).asString();
|
||||||
|
auto maskView = getMaskView(name);
|
||||||
|
if (maskView)
|
||||||
|
{
|
||||||
|
float maskX = params.at(1).asFloat();
|
||||||
|
float maskY = params.at(2).asFloat();
|
||||||
|
float maskW = params.at(3).asFloat();
|
||||||
|
float maskH = params.at(4).asFloat();
|
||||||
|
float radius = params.at(5).asFloat();
|
||||||
|
UIBezierPath* path = [UIBezierPath bezierPathWithRect:maskView.contentView.bounds];
|
||||||
|
UIBezierPath* round = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(maskX, maskY, maskW, maskH) cornerRadius:radius];
|
||||||
|
CAShapeLayer* maskLayer = [CAShapeLayer layer];
|
||||||
|
[path appendPath:round];
|
||||||
|
maskLayer.path = [path CGPath];
|
||||||
|
maskLayer.fillRule = kCAFillRuleEvenOdd;
|
||||||
|
maskView.contentView.layer.mask = maskLayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (fname == "clearMaskMask")
|
||||||
|
{
|
||||||
|
std::string name = params.at(0).asString();
|
||||||
|
auto maskView = getMaskView(name);
|
||||||
|
if (maskView)
|
||||||
|
maskView.contentView.layer.mask = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (fname == "removeMask")
|
||||||
|
{
|
||||||
|
std::string name = params.at(0).asString();
|
||||||
|
auto maskView = getMaskView(name);
|
||||||
|
if (maskView)
|
||||||
|
{
|
||||||
|
[maskView removeFromSuperview];
|
||||||
|
m_maskViewList.erase(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CxMaskIntf::addNativeView(std::string maskName, void* view)
|
||||||
|
{
|
||||||
|
auto maskView = getMaskView(maskName);
|
||||||
|
if (maskView)
|
||||||
|
[maskView.contentView addSubview:(UIView*)view];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CxMaskIntf::hasNativeView(std::string maskName, void* view)
|
||||||
|
{
|
||||||
|
auto maskView = getMaskView(maskName);
|
||||||
|
if (maskView)
|
||||||
|
{
|
||||||
|
for (UIView* subview in maskView.contentView.subviews)
|
||||||
|
{
|
||||||
|
if (subview == view)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
9
cx-framework3.1/cx-native/cxMask/cxMaskView.h
Normal file
9
cx-framework3.1/cx-native/cxMask/cxMaskView.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface CxMaskView : UIView
|
||||||
|
|
||||||
|
@property (strong, nonatomic) UIView* contentView;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
25
cx-framework3.1/cx-native/cxMask/cxMaskView.mm
Normal file
25
cx-framework3.1/cx-native/cxMask/cxMaskView.mm
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
#import "cxMaskView.h"
|
||||||
|
|
||||||
|
#define pop_height 200
|
||||||
|
#define RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1]
|
||||||
|
|
||||||
|
@implementation CxMaskView
|
||||||
|
|
||||||
|
|
||||||
|
- (id)initWithFrame:(CGRect)frame
|
||||||
|
{
|
||||||
|
self = [super initWithFrame:frame];
|
||||||
|
self.userInteractionEnabled = false;
|
||||||
|
self.clipsToBounds = true;
|
||||||
|
|
||||||
|
CGSize screen = [[UIScreen mainScreen] bounds].size;
|
||||||
|
self.contentView = [[UIView alloc] initWithFrame:CGRectMake(-frame.origin.x, -frame.origin.y, screen.width, screen.height)];
|
||||||
|
self.contentView.userInteractionEnabled = false;
|
||||||
|
[self addSubview:self.contentView];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
23
cx-framework3.1/cx-native/cxSys/cxSysIntf.h
Normal file
23
cx-framework3.1/cx-native/cxSys/cxSysIntf.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "cxDefine.h"
|
||||||
|
#include "cocos/bindings/event/EventDispatcher.h"
|
||||||
|
|
||||||
|
class CxSysIntf : public NativeIntfClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static CxSysIntf* ins();
|
||||||
|
|
||||||
|
virtual std::string call(std::string fname, cc::ValueVector params, const DataCallback& callback) override;
|
||||||
|
|
||||||
|
static DataCallback m_cxSysCallback;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void restartForUpdate(cc::CustomEvent evt);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
70
cx-framework3.1/cx-native/cxSys/cxSysIntf.mm
Normal file
70
cx-framework3.1/cx-native/cxSys/cxSysIntf.mm
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
#include "cxSysIntf.h"
|
||||||
|
|
||||||
|
#include "AppController.h"
|
||||||
|
#include "platform/Application.h"
|
||||||
|
#include "cocos/bindings/event/CustomEventTypes.h"
|
||||||
|
|
||||||
|
DataCallback CxSysIntf::m_cxSysCallback = NULL;
|
||||||
|
|
||||||
|
static CxSysIntf* s_sharedCxSysIntf = nullptr;
|
||||||
|
CxSysIntf* CxSysIntf::ins()
|
||||||
|
{
|
||||||
|
if (!s_sharedCxSysIntf)
|
||||||
|
s_sharedCxSysIntf = new CxSysIntf();
|
||||||
|
return s_sharedCxSysIntf;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CxSysIntf::call(std::string fname, cc::ValueVector params, const DataCallback& callback)
|
||||||
|
{
|
||||||
|
if (fname == "getStoragePath")
|
||||||
|
{
|
||||||
|
#if (CC_PLATFORM == CC_PLATFORM_MAC_IOS)
|
||||||
|
return "";
|
||||||
|
#endif
|
||||||
|
return call("getPackageName", params, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fname == "getPackageName")
|
||||||
|
{
|
||||||
|
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
|
||||||
|
NSString* packageName = [infoDictionary objectForKey:@"CFBundleIdentifier"];
|
||||||
|
return [packageName UTF8String];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fname == "getVersionCode")
|
||||||
|
{
|
||||||
|
return [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] UTF8String];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fname == "getVersionName")
|
||||||
|
{
|
||||||
|
return [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] UTF8String];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (fname == "removeLaunchImage")
|
||||||
|
{
|
||||||
|
[[AppController ins] removeLaunchImage];
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//只供在main.js中,且是ios时调用这个方法
|
||||||
|
if (fname == "restartForUpdate")
|
||||||
|
{
|
||||||
|
//ios弹出网络授权时,应用会进入后台,点击后回到前台,侦听回到前台时重启
|
||||||
|
cc::EventDispatcher::addCustomEventListener(EVENT_COME_TO_FOREGROUND, CC_CALLBACK_1(CxSysIntf::restartForUpdate, this));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CxSysIntf::restartForUpdate(cc::CustomEvent evt)
|
||||||
|
{
|
||||||
|
if (evt.name == EVENT_COME_TO_FOREGROUND)
|
||||||
|
{
|
||||||
|
cc::EventDispatcher::removeAllCustomEventListeners(EVENT_COME_TO_FOREGROUND);
|
||||||
|
cc::Application::getInstance()->restart();
|
||||||
|
}
|
||||||
|
}
|
187
cx-framework3.1/cx-native/jsb_module_register.cpp
Normal file
187
cx-framework3.1/cx-native/jsb_module_register.cpp
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
Copyright (c) 2017-2021 Xiamen Yaji Software Co., Ltd.
|
||||||
|
|
||||||
|
http://www.cocos.com
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated engine source code (the "Software"), a limited,
|
||||||
|
worldwide, royalty-free, non-assignable, revocable and non-exclusive license
|
||||||
|
to use Cocos Creator solely to develop games on your target platforms. You shall
|
||||||
|
not use Cocos Creator software for developing other software or tools that's
|
||||||
|
used for developing games. You are not granted to publish, distribute,
|
||||||
|
sublicense, and/or sell copies of Cocos Creator.
|
||||||
|
|
||||||
|
The software or tools in this License Agreement are licensed, not sold.
|
||||||
|
Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "cocos/bindings/jswrapper/SeApi.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_module_register.h"
|
||||||
|
#include "cocos/bindings/auto/jsb_cocos_auto.h"
|
||||||
|
#include "cocos/base/AutoreleasePool.h"
|
||||||
|
#include "cocos/bindings/dop/jsb_dop.h"
|
||||||
|
#include "cocos/bindings/auto/jsb_extension_auto.h"
|
||||||
|
#include "cocos/bindings/auto/jsb_network_auto.h"
|
||||||
|
#include "cocos/bindings/auto/jsb_gfx_auto.h"
|
||||||
|
#include "cocos/bindings/auto/jsb_pipeline_auto.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_pipeline_manual.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_cocos_manual.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_network_manual.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_conversions.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_gfx_manual.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_global.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_platform.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_xmlhttprequest.h"
|
||||||
|
|
||||||
|
#if USE_GFX_RENDERER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_SOCKET
|
||||||
|
#include "cocos/bindings/manual/jsb_socketio.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_websocket.h"
|
||||||
|
#endif // USE_SOCKET
|
||||||
|
|
||||||
|
#if USE_AUDIO
|
||||||
|
#include "cocos/bindings/auto/jsb_audio_auto.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (CC_PLATFORM == CC_PLATFORM_MAC_IOS || CC_PLATFORM == CC_PLATFORM_MAC_OSX)
|
||||||
|
#include "cocos/bindings/manual/JavaScriptObjCBridge.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
|
||||||
|
#include "cocos/bindings/manual/JavaScriptJavaBridge.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (CC_PLATFORM == CC_PLATFORM_MAC_IOS || CC_PLATFORM == CC_PLATFORM_ANDROID)
|
||||||
|
|
||||||
|
#if USE_VIDEO
|
||||||
|
#include "cocos/bindings/auto/jsb_video_auto.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_WEBVIEW
|
||||||
|
#include "cocos/bindings/auto/jsb_webview_auto.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // (CC_PLATFORM == CC_PLATFORM_MAC_IOS || CC_PLATFORM == CC_PLATFORM_ANDROID)
|
||||||
|
|
||||||
|
#if USE_SOCKET && USE_WEBSOCKET_SERVER
|
||||||
|
#include "cocos/bindings/manual/jsb_websocket_server.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_MIDDLEWARE
|
||||||
|
#include "cocos/bindings/auto/jsb_editor_support_auto.h"
|
||||||
|
|
||||||
|
#if USE_SPINE
|
||||||
|
#include "cocos/bindings/auto/jsb_spine_auto.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_spine_manual.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_DRAGONBONES
|
||||||
|
#include "cocos/bindings/auto/jsb_dragonbones_auto.h"
|
||||||
|
#include "cocos/bindings/manual/jsb_dragonbones_manual.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // USE_MIDDLEWARE
|
||||||
|
|
||||||
|
#if USE_PHYSICS_PHYSX
|
||||||
|
#include "cocos/bindings/auto/jsb_physics_auto.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace cc;
|
||||||
|
|
||||||
|
bool jsb_register_all_modules() {
|
||||||
|
se::ScriptEngine *se = se::ScriptEngine::getInstance();
|
||||||
|
|
||||||
|
se->addBeforeInitHook([]() {
|
||||||
|
JSBClassType::init();
|
||||||
|
});
|
||||||
|
|
||||||
|
se->addBeforeCleanupHook([se]() {
|
||||||
|
se->garbageCollect();
|
||||||
|
PoolManager::getInstance()->getCurrentPool()->clear();
|
||||||
|
se->garbageCollect();
|
||||||
|
PoolManager::getInstance()->getCurrentPool()->clear();
|
||||||
|
});
|
||||||
|
|
||||||
|
se->addRegisterCallback(jsb_register_global_variables);
|
||||||
|
se->addRegisterCallback(register_all_engine);
|
||||||
|
se->addRegisterCallback(register_all_cocos_manual);
|
||||||
|
se->addRegisterCallback(register_platform_bindings);
|
||||||
|
se->addRegisterCallback(register_all_gfx);
|
||||||
|
se->addRegisterCallback(register_all_gfx_manual);
|
||||||
|
|
||||||
|
se->addRegisterCallback(register_all_network);
|
||||||
|
se->addRegisterCallback(register_all_network_manual);
|
||||||
|
se->addRegisterCallback(register_all_xmlhttprequest);
|
||||||
|
// extension depend on network
|
||||||
|
se->addRegisterCallback(register_all_extension);
|
||||||
|
se->addRegisterCallback(register_all_dop_bindings);
|
||||||
|
se->addRegisterCallback(register_all_pipeline);
|
||||||
|
se->addRegisterCallback(register_all_pipeline_manual);
|
||||||
|
|
||||||
|
#if (CC_PLATFORM == CC_PLATFORM_MAC_IOS || CC_PLATFORM == CC_PLATFORM_MAC_OSX)
|
||||||
|
se->addRegisterCallback(register_javascript_objc_bridge);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (CC_PLATFORM == CC_PLATFORM_ANDROID)
|
||||||
|
se->addRegisterCallback(register_javascript_java_bridge);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_AUDIO
|
||||||
|
se->addRegisterCallback(register_all_audio);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_SOCKET
|
||||||
|
se->addRegisterCallback(register_all_websocket);
|
||||||
|
se->addRegisterCallback(register_all_socketio);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_MIDDLEWARE
|
||||||
|
se->addRegisterCallback(register_all_editor_support);
|
||||||
|
|
||||||
|
#if USE_SPINE
|
||||||
|
se->addRegisterCallback(register_all_spine);
|
||||||
|
se->addRegisterCallback(register_all_spine_manual);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_DRAGONBONES
|
||||||
|
se->addRegisterCallback(register_all_dragonbones);
|
||||||
|
se->addRegisterCallback(register_all_dragonbones_manual);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // USE_MIDDLEWARE
|
||||||
|
|
||||||
|
#if USE_PHYSICS_PHYSX
|
||||||
|
se->addRegisterCallback(register_all_physics);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (CC_PLATFORM == CC_PLATFORM_MAC_IOS || CC_PLATFORM == CC_PLATFORM_ANDROID)
|
||||||
|
|
||||||
|
#if USE_VIDEO
|
||||||
|
se->addRegisterCallback(register_all_video);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_WEBVIEW
|
||||||
|
se->addRegisterCallback(register_all_webview);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // (CC_PLATFORM == CC_PLATFORM_MAC_IOS || CC_PLATFORM == CC_PLATFORM_ANDROID)
|
||||||
|
|
||||||
|
#if USE_SOCKET && USE_WEBSOCKET_SERVER
|
||||||
|
se->addRegisterCallback(register_all_websocket_server);
|
||||||
|
#endif
|
||||||
|
se->addAfterCleanupHook([]() {
|
||||||
|
PoolManager::getInstance()->getCurrentPool()->clear();
|
||||||
|
JSBClassType::destroy();
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user