keytops-game-framework 1.0.21 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/module/view/IView.d.ts +1 -0
- package/dist/index.js +1730 -1728
- package/dist/view/CCPViewLoader.d.ts +1 -2
- package/dist/view/View.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6832,2007 +6832,2013 @@ class Task extends EventDispatcher {
|
|
|
6832
6832
|
}
|
|
6833
6833
|
Task.Event = Event$1;
|
|
6834
6834
|
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
/**
|
|
6847
|
-
* 视图管理类
|
|
6848
|
-
*/
|
|
6849
|
-
class ViewManager {
|
|
6850
|
-
/**
|
|
6851
|
-
* 注册视图上报事件的视图名称,一般为中文方便数据分辨
|
|
6852
|
-
* @param viewClass
|
|
6853
|
-
* @param analyticsName 可选参数,默认为view的name,可以指定为上报的中文名称
|
|
6854
|
-
* @param group 分组,可选参数,默认为default,方便分类统计
|
|
6855
|
-
*/
|
|
6856
|
-
registerAnalytics(viewClass, analyticsName, group = "default") {
|
|
6857
|
-
let config = this._getViewConfig(viewClass);
|
|
6858
|
-
if (config) {
|
|
6859
|
-
this._viewAnalyticsMap.set(config.name, { name: analyticsName || config.name, group });
|
|
6860
|
-
}
|
|
6861
|
-
else {
|
|
6862
|
-
throw new Error(`未获取到视图${viewClass}的配置`);
|
|
6835
|
+
class EffectAudioSourceProxy {
|
|
6836
|
+
constructor() {
|
|
6837
|
+
this._audioNode = null;
|
|
6838
|
+
this._audioSource = null;
|
|
6839
|
+
this._onFinishCallBack = null;
|
|
6840
|
+
this._audioNode = cc.find("__audioNode__");
|
|
6841
|
+
if (!this._audioNode) {
|
|
6842
|
+
this._audioNode = new cc.Node();
|
|
6843
|
+
this._audioNode.name = '__audioNode__';
|
|
6844
|
+
cc.director.getScene().addChild(this._audioNode);
|
|
6845
|
+
cc.director.addPersistRootNode(this._audioNode);
|
|
6863
6846
|
}
|
|
6847
|
+
this._audioSource = this._audioNode.addComponent(cc.AudioSource);
|
|
6864
6848
|
}
|
|
6865
6849
|
/**
|
|
6866
|
-
*
|
|
6867
|
-
* @param viewName 视图名称
|
|
6868
|
-
* @param config 视图配置
|
|
6850
|
+
* 声音大小
|
|
6869
6851
|
*/
|
|
6870
|
-
|
|
6871
|
-
if (this.
|
|
6872
|
-
|
|
6852
|
+
set volume(value) {
|
|
6853
|
+
if (!this._audioNode || !this._audioSource) {
|
|
6854
|
+
return;
|
|
6873
6855
|
}
|
|
6874
|
-
this.
|
|
6856
|
+
this._audioSource.volume = value;
|
|
6875
6857
|
}
|
|
6876
6858
|
/**
|
|
6877
|
-
*
|
|
6878
|
-
* @param config 视图配置|Class|名称
|
|
6859
|
+
* 声音大小
|
|
6879
6860
|
*/
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
throw new Error(`未获取到默认遮罩视图${config}的配置`);
|
|
6861
|
+
get volume() {
|
|
6862
|
+
if (!this._audioNode || !this._audioSource) {
|
|
6863
|
+
return 1;
|
|
6884
6864
|
}
|
|
6885
|
-
this.
|
|
6886
|
-
}
|
|
6887
|
-
getViewConfig(config) {
|
|
6888
|
-
return Object.assign({}, this._getViewConfig(config));
|
|
6865
|
+
return this._audioSource.volume;
|
|
6889
6866
|
}
|
|
6890
6867
|
/**
|
|
6891
|
-
*
|
|
6892
|
-
* @param
|
|
6868
|
+
* 渐进式播放
|
|
6869
|
+
* @param clip
|
|
6870
|
+
* @param volume
|
|
6871
|
+
* @param loop
|
|
6872
|
+
* @param onFinishCallBack
|
|
6893
6873
|
* @returns
|
|
6894
6874
|
*/
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
return null;
|
|
6899
|
-
}
|
|
6900
|
-
if (typeof config == "string") {
|
|
6901
|
-
if (!this._viewConfigMap.has(config)) {
|
|
6902
|
-
console.error(`[view]${config}视图配置未注册`);
|
|
6903
|
-
return null;
|
|
6904
|
-
}
|
|
6905
|
-
return this._viewConfigMap.get(config);
|
|
6906
|
-
}
|
|
6907
|
-
if ("path" in config) {
|
|
6908
|
-
return config;
|
|
6909
|
-
}
|
|
6910
|
-
let values = this._viewConfigMap.values();
|
|
6911
|
-
while (true) {
|
|
6912
|
-
let item = values.next();
|
|
6913
|
-
if (!item || item.done) {
|
|
6914
|
-
return null;
|
|
6915
|
-
}
|
|
6916
|
-
if (item.value['viewClass'] == config) {
|
|
6917
|
-
return item.value;
|
|
6918
|
-
}
|
|
6919
|
-
}
|
|
6875
|
+
playfade(clip, volume, loop = false, onFinishCallBack) {
|
|
6876
|
+
this.play(clip, volume, loop, onFinishCallBack);
|
|
6877
|
+
return this.fadeIn();
|
|
6920
6878
|
}
|
|
6921
|
-
|
|
6922
|
-
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6879
|
+
/**
|
|
6880
|
+
* 播放
|
|
6881
|
+
* @param clip
|
|
6882
|
+
* @param volume
|
|
6883
|
+
* @param loop
|
|
6884
|
+
* @param onFinishCallBack
|
|
6885
|
+
* @returns
|
|
6886
|
+
*/
|
|
6887
|
+
play(clip, volume, loop = false, onFinishCallBack) {
|
|
6888
|
+
this._audioSource.clip = clip;
|
|
6889
|
+
this._audioSource.loop = loop;
|
|
6890
|
+
this._audioSource.volume = volume;
|
|
6891
|
+
this._audioSource.playOnAwake = false;
|
|
6892
|
+
this._onFinishCallBack = onFinishCallBack;
|
|
6893
|
+
this._audioNode.on(cc.AudioSource.EventType.ENDED, this._onAudioEnded, this);
|
|
6894
|
+
this._audioSource.play();
|
|
6895
|
+
return this;
|
|
6931
6896
|
}
|
|
6932
6897
|
/**
|
|
6933
|
-
*
|
|
6934
|
-
* @
|
|
6898
|
+
* 渐进
|
|
6899
|
+
* @returns
|
|
6935
6900
|
*/
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6901
|
+
fadeIn() {
|
|
6902
|
+
return new Promise((resolve) => {
|
|
6903
|
+
const targetVolume = this.volume;
|
|
6904
|
+
cc.tween(this).set({ volume: 0 }).to(0.2, { volume: targetVolume }).call(() => {
|
|
6905
|
+
resolve(this);
|
|
6906
|
+
}).start();
|
|
6941
6907
|
});
|
|
6942
|
-
this._viewCache.clear();
|
|
6943
|
-
this._currentStack.length = 0;
|
|
6944
|
-
this.event("open", root);
|
|
6945
|
-
this.reportViewAnalytics("open", root);
|
|
6946
|
-
this._scene = root;
|
|
6947
|
-
this._currentView = null;
|
|
6948
|
-
businessCenter && businessCenter.start(RewardVideoMaskBusiness);
|
|
6949
6908
|
}
|
|
6950
6909
|
/**
|
|
6951
|
-
*
|
|
6952
|
-
* @param
|
|
6953
|
-
* @param data
|
|
6910
|
+
* 渐出
|
|
6911
|
+
* @param stop
|
|
6954
6912
|
* @returns
|
|
6955
6913
|
*/
|
|
6956
|
-
|
|
6957
|
-
return
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
|
|
6962
|
-
}
|
|
6963
|
-
else {
|
|
6964
|
-
view = yield this._switchViewByConfig(config, ...data);
|
|
6965
|
-
}
|
|
6966
|
-
// this.cacheView(view);
|
|
6967
|
-
// this._currentStack.push(config);
|
|
6968
|
-
return view;
|
|
6914
|
+
fedeOut(stop = true) {
|
|
6915
|
+
return new Promise((resolve) => {
|
|
6916
|
+
cc.tween(this).to(0.2, { volume: 0 }).call(() => {
|
|
6917
|
+
stop && this.stop();
|
|
6918
|
+
resolve(this);
|
|
6919
|
+
}).start();
|
|
6969
6920
|
});
|
|
6970
6921
|
}
|
|
6971
6922
|
/**
|
|
6972
|
-
*
|
|
6923
|
+
* 暂停
|
|
6973
6924
|
* @returns
|
|
6974
6925
|
*/
|
|
6975
|
-
|
|
6976
|
-
|
|
6926
|
+
pause() {
|
|
6927
|
+
if (!this._audioNode || !this._audioSource) {
|
|
6928
|
+
return;
|
|
6929
|
+
}
|
|
6930
|
+
this._audioSource.pause();
|
|
6977
6931
|
}
|
|
6978
6932
|
/**
|
|
6979
|
-
*
|
|
6980
|
-
* @
|
|
6933
|
+
* 恢复
|
|
6934
|
+
* @returns
|
|
6981
6935
|
*/
|
|
6982
|
-
|
|
6983
|
-
if (
|
|
6984
|
-
|
|
6985
|
-
}
|
|
6986
|
-
else {
|
|
6987
|
-
this._touchLocks.clear();
|
|
6936
|
+
resume() {
|
|
6937
|
+
if (!this._audioNode || !this._audioSource) {
|
|
6938
|
+
return;
|
|
6988
6939
|
}
|
|
6989
|
-
this.
|
|
6940
|
+
this._audioSource.play();
|
|
6990
6941
|
}
|
|
6991
6942
|
/**
|
|
6992
|
-
*
|
|
6993
|
-
* @
|
|
6994
|
-
* @param maskViewConfig 可选参数,默认为空白,要显示的遮罩试图。
|
|
6995
|
-
* @returns 当前触摸锁令牌,可传给openTouch精确释放本次锁。
|
|
6943
|
+
* 渐进停止
|
|
6944
|
+
* @returns
|
|
6996
6945
|
*/
|
|
6997
|
-
|
|
6998
|
-
return
|
|
6999
|
-
const token = this._lockTouch();
|
|
7000
|
-
let config = maskViewConfig == null ? this._defaultMaskViewConfig : this._getViewConfig(maskViewConfig);
|
|
7001
|
-
if (!config) {
|
|
7002
|
-
return token;
|
|
7003
|
-
}
|
|
7004
|
-
if (delay <= 0) {
|
|
7005
|
-
yield this._showMaskView(config, token);
|
|
7006
|
-
return token;
|
|
7007
|
-
}
|
|
7008
|
-
timer.once(delay, this, this._showMaskView, [config, token]);
|
|
7009
|
-
return token;
|
|
7010
|
-
});
|
|
7011
|
-
}
|
|
7012
|
-
_lockTouch() {
|
|
7013
|
-
const token = Symbol("touch-lock");
|
|
7014
|
-
this._touchLocks.add(token);
|
|
7015
|
-
this._applyTouchState();
|
|
7016
|
-
return token;
|
|
6946
|
+
stopFade() {
|
|
6947
|
+
return this.fedeOut(true).then(() => { });
|
|
7017
6948
|
}
|
|
7018
|
-
|
|
7019
|
-
|
|
7020
|
-
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
}
|
|
6949
|
+
/**
|
|
6950
|
+
* 停止
|
|
6951
|
+
* @returns
|
|
6952
|
+
*/
|
|
6953
|
+
stop() {
|
|
6954
|
+
if (!this._audioNode || !this._audioSource) {
|
|
6955
|
+
return;
|
|
7026
6956
|
}
|
|
7027
|
-
|
|
7028
|
-
|
|
6957
|
+
this._audioSource.stop();
|
|
6958
|
+
this._audioNode.off(cc.AudioSource.EventType.ENDED, this._onAudioEnded, this);
|
|
6959
|
+
}
|
|
6960
|
+
_onAudioEnded(audioSource) {
|
|
6961
|
+
if (audioSource == this._audioSource) {
|
|
6962
|
+
this._onFinishCallBack && this._onFinishCallBack();
|
|
6963
|
+
this._audioNode.off(cc.AudioSource.EventType.ENDED, this._onAudioEnded, this);
|
|
7029
6964
|
}
|
|
7030
6965
|
}
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
|
|
7034
|
-
|
|
7035
|
-
|
|
7036
|
-
let view = this.getCacheView(maskViewConfig);
|
|
7037
|
-
if (view) {
|
|
7038
|
-
view = yield this._addView(view, this._scene);
|
|
7039
|
-
}
|
|
7040
|
-
else {
|
|
7041
|
-
view = yield this._loadViewByConfig(maskViewConfig, this._scene, "显示遮罩视图错误");
|
|
7042
|
-
this.cacheView(view);
|
|
7043
|
-
}
|
|
7044
|
-
if (!this._touchLocks.has(token)) {
|
|
7045
|
-
view.removeFromParent(true);
|
|
7046
|
-
return;
|
|
7047
|
-
}
|
|
7048
|
-
this._currentMaskView = view;
|
|
7049
|
-
timer.frameNext(this, () => {
|
|
7050
|
-
if (this._currentMaskView == view && this._touchLocks.has(token)) {
|
|
7051
|
-
view.setData();
|
|
7052
|
-
}
|
|
7053
|
-
});
|
|
7054
|
-
});
|
|
6966
|
+
/**
|
|
6967
|
+
* 是否循环
|
|
6968
|
+
*/
|
|
6969
|
+
get loop() {
|
|
6970
|
+
return this._audioSource ? this._audioSource.loop : false;
|
|
7055
6971
|
}
|
|
7056
6972
|
/**
|
|
7057
|
-
*
|
|
7058
|
-
* @returns
|
|
6973
|
+
* 是否播放中
|
|
7059
6974
|
*/
|
|
7060
|
-
|
|
7061
|
-
return this.
|
|
6975
|
+
get playing() {
|
|
6976
|
+
return this._audioSource ? this._audioSource.playing : false;
|
|
6977
|
+
}
|
|
6978
|
+
reset() {
|
|
6979
|
+
this.stop();
|
|
6980
|
+
cc.Tween.stopAllByTarget(this);
|
|
6981
|
+
this._onFinishCallBack = null;
|
|
6982
|
+
}
|
|
6983
|
+
destroy() {
|
|
6984
|
+
this._audioSource.destroy();
|
|
6985
|
+
this._audioSource = null;
|
|
6986
|
+
this._audioNode = null;
|
|
6987
|
+
this._onFinishCallBack = null;
|
|
6988
|
+
}
|
|
6989
|
+
}
|
|
6990
|
+
class AudioManager {
|
|
6991
|
+
constructor() {
|
|
6992
|
+
this._musicVolume = null;
|
|
6993
|
+
this._effectVolume = null;
|
|
6994
|
+
this._effectPool = new Pool(EffectAudioSourceProxy); //cc.AudioSource.maxAudioChannel - 1);
|
|
7062
6995
|
}
|
|
7063
6996
|
/**
|
|
7064
|
-
*
|
|
7065
|
-
* @param target 目标视图的配置|Class|名称
|
|
7066
|
-
* @param datas 目标视图初始化参数
|
|
6997
|
+
* 音效音量大小
|
|
7067
6998
|
*/
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
}
|
|
7074
|
-
let view = this.getCacheView(config);
|
|
7075
|
-
if (view) {
|
|
7076
|
-
view = yield this._switchView(view, ...data);
|
|
7077
|
-
}
|
|
7078
|
-
else {
|
|
7079
|
-
view = yield this._switchViewByConfig(config, ...data);
|
|
7080
|
-
}
|
|
7081
|
-
this.cacheView(view);
|
|
7082
|
-
this._currentStack.push(config);
|
|
7083
|
-
return view;
|
|
7084
|
-
});
|
|
6999
|
+
get effectVolume() {
|
|
7000
|
+
if (this._effectVolume == null) {
|
|
7001
|
+
this._effectVolume = storage.effectsVolume;
|
|
7002
|
+
}
|
|
7003
|
+
return this._effectVolume;
|
|
7085
7004
|
}
|
|
7086
7005
|
/**
|
|
7087
|
-
*
|
|
7088
|
-
* @param data
|
|
7089
|
-
* @returns
|
|
7006
|
+
* 音效音量大小
|
|
7090
7007
|
*/
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
7095
|
-
|
|
7096
|
-
|
|
7097
|
-
|
|
7098
|
-
|
|
7099
|
-
//获取之前视图config
|
|
7100
|
-
let lastViewConfig = this._currentStack.pop();
|
|
7101
|
-
if (!lastViewConfig) {
|
|
7102
|
-
console.warn("上个主视图为空,");
|
|
7103
|
-
return null;
|
|
7104
|
-
}
|
|
7105
|
-
return yield this.switchTo(lastViewConfig, ...data);
|
|
7106
|
-
});
|
|
7008
|
+
set effectVolume(value) {
|
|
7009
|
+
storage.effectsVolume = this._effectVolume = value;
|
|
7010
|
+
let usingEffect = this._effectPool['_usingArray'];
|
|
7011
|
+
usingEffect = usingEffect.concat();
|
|
7012
|
+
for (let i = 0; i < usingEffect.length; i++) {
|
|
7013
|
+
const effectProxy = usingEffect[i];
|
|
7014
|
+
effectProxy.volume = value;
|
|
7015
|
+
}
|
|
7107
7016
|
}
|
|
7108
|
-
|
|
7109
|
-
|
|
7110
|
-
|
|
7111
|
-
|
|
7112
|
-
|
|
7113
|
-
this.
|
|
7114
|
-
|
|
7115
|
-
|
|
7116
|
-
});
|
|
7017
|
+
/**
|
|
7018
|
+
* BGM音量大小
|
|
7019
|
+
*/
|
|
7020
|
+
get musicVolume() {
|
|
7021
|
+
if (this._musicVolume == null) {
|
|
7022
|
+
this._musicVolume = storage.musicVolume;
|
|
7023
|
+
}
|
|
7024
|
+
return this._musicVolume;
|
|
7117
7025
|
}
|
|
7118
|
-
|
|
7119
|
-
|
|
7120
|
-
|
|
7121
|
-
|
|
7122
|
-
|
|
7123
|
-
|
|
7124
|
-
}
|
|
7125
|
-
catch (error) {
|
|
7126
|
-
this.openTouch(touchToken);
|
|
7127
|
-
console.error(`切换视图错误 code:${error.code}, msg:${error.msg || error.message}`);
|
|
7128
|
-
throw new Error(`切换视图错误 code:${error.code}, msg:${error.msg || error.message}`);
|
|
7129
|
-
}
|
|
7130
|
-
let name = viewConfig.name || viewConfig.path.substring(viewConfig.path.lastIndexOf("/") + 1);
|
|
7131
|
-
this._currentView && this._currentView.removeFromParent(!this._currentView.config.cache);
|
|
7132
|
-
this._currentView = null;
|
|
7133
|
-
let view = loader.initView(name, true);
|
|
7134
|
-
view.name = name;
|
|
7135
|
-
view.config = viewConfig;
|
|
7136
|
-
view.analyticsInfo = this._viewAnalyticsMap.get(viewConfig.name);
|
|
7137
|
-
if (view['addToBG']) {
|
|
7138
|
-
this.setRoot(view);
|
|
7139
|
-
}
|
|
7140
|
-
else {
|
|
7141
|
-
this._currentView = view;
|
|
7142
|
-
this._scene.addView(view, viewConfig.zIndex);
|
|
7143
|
-
}
|
|
7144
|
-
timer.frameNext(this, () => {
|
|
7145
|
-
this.openTouch(touchToken);
|
|
7146
|
-
view.setData(...datas);
|
|
7147
|
-
});
|
|
7148
|
-
return view;
|
|
7149
|
-
});
|
|
7026
|
+
/**
|
|
7027
|
+
* BGM音量大小
|
|
7028
|
+
*/
|
|
7029
|
+
set musicVolume(value) {
|
|
7030
|
+
storage.musicVolume = this._musicVolume = value;
|
|
7031
|
+
this._music && (this._music.volume = value);
|
|
7150
7032
|
}
|
|
7151
7033
|
/**
|
|
7152
|
-
*
|
|
7153
|
-
* @param
|
|
7154
|
-
* @param
|
|
7155
|
-
* @param
|
|
7034
|
+
* 播放音效
|
|
7035
|
+
* @param clip
|
|
7036
|
+
* @param loop 是否循环,默认为false。传入true,需要手动调用recoverEffect进行回收
|
|
7037
|
+
* @param onFinishCallBack 播放完回调
|
|
7038
|
+
* @param volume 当此播放的声音大小,默认为统一effect的大小
|
|
7156
7039
|
*/
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
throw new Error("当前View不存在, 且未传入父级视图");
|
|
7163
|
-
}
|
|
7164
|
-
let view = this.getCacheView(config);
|
|
7165
|
-
if (view) {
|
|
7166
|
-
view = yield this._addView(view, parent, ...datas);
|
|
7040
|
+
playEffect(clip, loop = false, onFinishCallBack, volume = null) {
|
|
7041
|
+
const effectProxy = this._effectPool.allocate();
|
|
7042
|
+
effectProxy.play(clip, volume == null ? this.effectVolume : volume, loop, () => {
|
|
7043
|
+
if (!loop) {
|
|
7044
|
+
this.recoverEffect(effectProxy);
|
|
7167
7045
|
}
|
|
7168
7046
|
else {
|
|
7169
|
-
|
|
7170
|
-
}
|
|
7171
|
-
this.cacheView(view);
|
|
7172
|
-
return view;
|
|
7173
|
-
});
|
|
7174
|
-
}
|
|
7175
|
-
_addView(view, parent, ...datas) {
|
|
7176
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
7177
|
-
parent.addView(view, view.config.zIndex);
|
|
7178
|
-
view.setData(...datas);
|
|
7179
|
-
return view;
|
|
7180
|
-
});
|
|
7181
|
-
}
|
|
7182
|
-
_addViewbyConfig(config, parent, ...datas) {
|
|
7183
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
7184
|
-
const touchToken = this._lockTouch();
|
|
7185
|
-
let view;
|
|
7186
|
-
try {
|
|
7187
|
-
view = yield this._loadViewByConfig(config, parent, "添加视图错误");
|
|
7188
|
-
}
|
|
7189
|
-
catch (error) {
|
|
7190
|
-
this.openTouch(touchToken);
|
|
7191
|
-
throw error;
|
|
7192
|
-
}
|
|
7193
|
-
timer.frameNext(this, () => {
|
|
7194
|
-
this.openTouch(touchToken);
|
|
7195
|
-
view.setData(...datas);
|
|
7196
|
-
});
|
|
7197
|
-
return view;
|
|
7198
|
-
});
|
|
7199
|
-
}
|
|
7200
|
-
_loadViewByConfig(config, parent, errorPrefix) {
|
|
7201
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
7202
|
-
let loader;
|
|
7203
|
-
try {
|
|
7204
|
-
loader = yield this.loadView(config);
|
|
7205
|
-
}
|
|
7206
|
-
catch (error) {
|
|
7207
|
-
console.error(`${errorPrefix} code:${error.code}, msg:${error.msg || error.message}`);
|
|
7208
|
-
throw new Error(`${errorPrefix} code:${error.code}, msg:${error.msg || error.message}`);
|
|
7047
|
+
console.warn("需要手动回收音效播放器");
|
|
7209
7048
|
}
|
|
7210
|
-
|
|
7211
|
-
let view = loader.initView(name, true);
|
|
7212
|
-
view.name = name;
|
|
7213
|
-
view.config = config;
|
|
7214
|
-
view.analyticsInfo = this._viewAnalyticsMap.get(config.name);
|
|
7215
|
-
parent.addView(view, config.zIndex);
|
|
7216
|
-
return view;
|
|
7049
|
+
onFinishCallBack && onFinishCallBack();
|
|
7217
7050
|
});
|
|
7051
|
+
return effectProxy;
|
|
7218
7052
|
}
|
|
7219
7053
|
/**
|
|
7220
|
-
*
|
|
7221
|
-
* @param
|
|
7222
|
-
* @param task 任务载体
|
|
7054
|
+
* 回收音效播放器,用于effect多次复用后的回收
|
|
7055
|
+
* @param proxy
|
|
7223
7056
|
*/
|
|
7224
|
-
|
|
7225
|
-
|
|
7226
|
-
config = this._getViewConfig(config);
|
|
7227
|
-
let loader = this.impl.getLoader(config).init(config);
|
|
7228
|
-
task = task || new Task();
|
|
7229
|
-
task.once(Task.Event.COMPLETE, this, () => {
|
|
7230
|
-
resolve(loader);
|
|
7231
|
-
});
|
|
7232
|
-
task.once(Task.Event.ERROR, this, (type, task, reason) => {
|
|
7233
|
-
reject(reason);
|
|
7234
|
-
});
|
|
7235
|
-
loader.load(task);
|
|
7236
|
-
});
|
|
7057
|
+
recoverEffect(proxy) {
|
|
7058
|
+
this._effectPool.recover(proxy);
|
|
7237
7059
|
}
|
|
7238
7060
|
/**
|
|
7239
|
-
*
|
|
7240
|
-
* @param config
|
|
7241
|
-
* @returns
|
|
7061
|
+
* 停止所有音效
|
|
7242
7062
|
*/
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
if (!view.inStage) {
|
|
7251
|
-
return view;
|
|
7252
|
-
}
|
|
7063
|
+
stopAllEffect() {
|
|
7064
|
+
let usingEffect = this._effectPool['_usingArray'];
|
|
7065
|
+
usingEffect = usingEffect.concat();
|
|
7066
|
+
for (let i = 0; i < usingEffect.length; i++) {
|
|
7067
|
+
const effectProxy = usingEffect[i];
|
|
7068
|
+
effectProxy.stop();
|
|
7069
|
+
this.recoverEffect(effectProxy);
|
|
7253
7070
|
}
|
|
7254
|
-
return null;
|
|
7255
7071
|
}
|
|
7256
7072
|
/**
|
|
7257
|
-
*
|
|
7258
|
-
* @param
|
|
7259
|
-
* @param
|
|
7260
|
-
* @
|
|
7073
|
+
* 播放背景音乐
|
|
7074
|
+
* @param clip
|
|
7075
|
+
* @param fade 是否渐进式播放,默认为true
|
|
7076
|
+
* @param loop 是否循环,默认为true
|
|
7077
|
+
* @param onFinishCallBack 播放完回调
|
|
7078
|
+
* @param volume 当此播放的声音大小,默认为统一music的大小
|
|
7261
7079
|
*/
|
|
7262
|
-
|
|
7263
|
-
if (!
|
|
7264
|
-
|
|
7265
|
-
}
|
|
7266
|
-
let views = this._viewCache.get(view.config.path);
|
|
7267
|
-
if (!views) {
|
|
7268
|
-
views = [view];
|
|
7269
|
-
this._viewCache.set(view.config.path, views);
|
|
7270
|
-
return true;
|
|
7271
|
-
}
|
|
7272
|
-
else if (!views.includes(view)) {
|
|
7273
|
-
views.push(view);
|
|
7274
|
-
return true;
|
|
7080
|
+
playMusic(clip, fade = true, loop = true, onFinishCallBack, volume = null) {
|
|
7081
|
+
if (!this._music) {
|
|
7082
|
+
this._music = new EffectAudioSourceProxy();
|
|
7275
7083
|
}
|
|
7276
|
-
|
|
7084
|
+
this._music.playing && this._music.stop();
|
|
7085
|
+
volume = volume == null ? this.musicVolume : volume;
|
|
7086
|
+
fade ? this._music.playfade(clip, volume, loop, onFinishCallBack) : this._music.play(clip, volume, loop, onFinishCallBack);
|
|
7277
7087
|
}
|
|
7278
7088
|
/**
|
|
7279
|
-
*
|
|
7280
|
-
* @param view
|
|
7089
|
+
* 暂停播放背景音乐
|
|
7281
7090
|
* @returns
|
|
7282
7091
|
*/
|
|
7283
|
-
|
|
7284
|
-
if (!
|
|
7285
|
-
return
|
|
7286
|
-
}
|
|
7287
|
-
let views = this._viewCache.get(view.config.path);
|
|
7288
|
-
if (!views || views.length == 0) {
|
|
7289
|
-
return false;
|
|
7290
|
-
}
|
|
7291
|
-
const index = views.indexOf(view);
|
|
7292
|
-
if (index != -1) {
|
|
7293
|
-
views.splice(index, 1);
|
|
7294
|
-
return true;
|
|
7092
|
+
pauseMusic() {
|
|
7093
|
+
if (!this._music) {
|
|
7094
|
+
return;
|
|
7295
7095
|
}
|
|
7296
|
-
|
|
7297
|
-
}
|
|
7298
|
-
/**
|
|
7299
|
-
* [快捷方式]增加视图打开的事件监听
|
|
7300
|
-
* @param targetView 目标视图Class|名称
|
|
7301
|
-
* @param listener 响应回调
|
|
7302
|
-
* @param caller 回调this
|
|
7303
|
-
* @param once 是否只监听对应视图打开一次。
|
|
7304
|
-
* @param args 其他参数
|
|
7305
|
-
*/
|
|
7306
|
-
onViewOpen(targetView, caller, listener, once = false, ...args) {
|
|
7307
|
-
this._viewOpenEventMap = this._viewOpenEventMap || new Map();
|
|
7308
|
-
this._viewOpenEventMap.set(listener, { event: "open", viewConfig: this._getViewConfig(targetView), caller, listener, once, args });
|
|
7309
|
-
this.offViewEvent("open", this, this._onViewOpen);
|
|
7310
|
-
this.onViewEvent("open", this, this._onViewOpen);
|
|
7311
|
-
}
|
|
7312
|
-
_onViewOpen(viewName, ...args) {
|
|
7313
|
-
this._viewOpenEventMap.forEach((value, key) => {
|
|
7314
|
-
if (value.viewConfig.name == viewName) {
|
|
7315
|
-
value.listener.apply(value.caller, value.args);
|
|
7316
|
-
value.once && this._viewOpenEventMap.delete(key);
|
|
7317
|
-
}
|
|
7318
|
-
});
|
|
7096
|
+
this._music.pause();
|
|
7319
7097
|
}
|
|
7320
7098
|
/**
|
|
7321
|
-
*
|
|
7322
|
-
* @param listener
|
|
7099
|
+
* 恢复播放背景音乐
|
|
7323
7100
|
* @returns
|
|
7324
7101
|
*/
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
* @param targetView 目标视图Class|名称
|
|
7331
|
-
* @param listener 响应回调
|
|
7332
|
-
* @param caller 回调this
|
|
7333
|
-
* @param once 是否只监听对应视图关闭一次。
|
|
7334
|
-
* @param args 其他参数
|
|
7335
|
-
*/
|
|
7336
|
-
onViewClose(targetView, caller, listener, once = false, ...args) {
|
|
7337
|
-
this._viewCloseEventMap = this._viewCloseEventMap || new Map();
|
|
7338
|
-
this._viewCloseEventMap.set(listener, { event: "close", viewConfig: this._getViewConfig(targetView), caller, listener, once, args });
|
|
7339
|
-
this.offViewEvent("close", this, this._onViewClose);
|
|
7340
|
-
this.onViewEvent("close", this, this._onViewClose);
|
|
7102
|
+
resumeMusic() {
|
|
7103
|
+
if (!this._music) {
|
|
7104
|
+
return;
|
|
7105
|
+
}
|
|
7106
|
+
this._music.resume();
|
|
7341
7107
|
}
|
|
7342
7108
|
/**
|
|
7343
|
-
*
|
|
7344
|
-
* @param
|
|
7109
|
+
* 停止背景音乐
|
|
7110
|
+
* @param fade 是否渐出
|
|
7345
7111
|
* @returns
|
|
7346
7112
|
*/
|
|
7347
|
-
|
|
7348
|
-
return this
|
|
7349
|
-
|
|
7350
|
-
|
|
7351
|
-
this._viewCloseEventMap.forEach((value, key) => {
|
|
7352
|
-
if (value.viewConfig.name == viewName) {
|
|
7353
|
-
value.listener.apply(value.caller, value.args.concat(args));
|
|
7354
|
-
value.once && this._viewCloseEventMap.delete(key);
|
|
7113
|
+
stopMusic(fade = true) {
|
|
7114
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7115
|
+
if (!this._music) {
|
|
7116
|
+
return;
|
|
7355
7117
|
}
|
|
7118
|
+
return fade ? yield this._music.stopFade() : this._music.stop();
|
|
7356
7119
|
});
|
|
7357
7120
|
}
|
|
7358
|
-
/**
|
|
7359
|
-
* 增加视图事件监听
|
|
7360
|
-
* @param event 视图事件名称
|
|
7361
|
-
* @param caller 回调this
|
|
7362
|
-
* @param listener 响应回调
|
|
7363
|
-
* @param once 是否只监听对应视图关闭一次。
|
|
7364
|
-
* @param args 其他参数
|
|
7365
|
-
*/
|
|
7366
|
-
onViewEvent(event, caller, listener, once = false, ...args) {
|
|
7367
|
-
if (!this._viewEvent) {
|
|
7368
|
-
this._viewEvent = new EventDispatcher();
|
|
7369
|
-
}
|
|
7370
|
-
if (once) {
|
|
7371
|
-
this._viewEvent.once(event, caller, listener, args);
|
|
7372
|
-
}
|
|
7373
|
-
else {
|
|
7374
|
-
this._viewEvent.on(event, caller, listener, args);
|
|
7375
|
-
}
|
|
7376
|
-
}
|
|
7377
|
-
/**
|
|
7378
|
-
* 移除视图事件监听
|
|
7379
|
-
* @param event 事件类型
|
|
7380
|
-
* @param caller 事件侦听函数的执行域。
|
|
7381
|
-
* @param listener 事件侦听函数。
|
|
7382
|
-
* @returns
|
|
7383
|
-
*/
|
|
7384
|
-
offViewEvent(event, caller, listener) {
|
|
7385
|
-
if (!this._viewEvent) {
|
|
7386
|
-
return;
|
|
7387
|
-
}
|
|
7388
|
-
this._viewEvent.off(event, caller, listener);
|
|
7389
|
-
}
|
|
7390
|
-
/**
|
|
7391
|
-
* 广播视图事件
|
|
7392
|
-
* @param event 视图事件
|
|
7393
|
-
* @param view 视图
|
|
7394
|
-
*/
|
|
7395
|
-
event(event, view, ...args) {
|
|
7396
|
-
if (this._viewEvent) {
|
|
7397
|
-
args.unshift(view.name);
|
|
7398
|
-
this._viewEvent.event(event, args);
|
|
7399
|
-
}
|
|
7400
|
-
}
|
|
7401
|
-
/**
|
|
7402
|
-
* 上报视图统计数据(open\close\...)
|
|
7403
|
-
* @param event 事件
|
|
7404
|
-
* @param view 视图
|
|
7405
|
-
* @param data 上报附带信息
|
|
7406
|
-
*/
|
|
7407
|
-
reportViewAnalytics(event, view, data) {
|
|
7408
|
-
let maskViewconfig = this._currentMaskView && this._currentMaskView.config;
|
|
7409
|
-
if (maskViewconfig && view.name == maskViewconfig.name) {
|
|
7410
|
-
return;
|
|
7411
|
-
}
|
|
7412
|
-
let analyticsInfo = this._viewAnalyticsMap.get(view.name);
|
|
7413
|
-
if (analyticsInfo) {
|
|
7414
|
-
data = data || (view.getAnalyticsDataOnViewEvent && view.getAnalyticsDataOnViewEvent(event)) || {};
|
|
7415
|
-
data.action = event;
|
|
7416
|
-
data.name = analyticsInfo.name;
|
|
7417
|
-
data.group = analyticsInfo.group || "default";
|
|
7418
|
-
//open:进入时刻, close:停留时长
|
|
7419
|
-
data.stay = Math.floor((App.durationOfLaunch - (analyticsInfo.lastOpenTime || 0)) / 1000);
|
|
7420
|
-
analytics.base.report("view", data);
|
|
7421
|
-
analyticsInfo.lastOpenTime = event == "open" ? App.durationOfLaunch : 0;
|
|
7422
|
-
}
|
|
7423
|
-
}
|
|
7424
|
-
get impl() {
|
|
7425
|
-
if (this._impl == null) {
|
|
7426
|
-
this._impl = Injector.getInject(ViewManager.KEY);
|
|
7427
|
-
}
|
|
7428
|
-
if (this._impl == null) {
|
|
7429
|
-
throw new Error(ViewManager.KEY + "未注入!");
|
|
7430
|
-
}
|
|
7431
|
-
return this._impl;
|
|
7432
|
-
}
|
|
7433
7121
|
}
|
|
7434
|
-
ViewManager.KEY = "ViewManager";
|
|
7435
|
-
ViewManager.created = false;
|
|
7436
7122
|
/**
|
|
7437
|
-
*
|
|
7123
|
+
* 音效管理
|
|
7438
7124
|
*/
|
|
7439
|
-
const
|
|
7125
|
+
const audio = new AudioManager();
|
|
7440
7126
|
|
|
7441
|
-
|
|
7127
|
+
const GC_CD = 60 * 1000;
|
|
7128
|
+
/**
|
|
7129
|
+
* 资源管理
|
|
7130
|
+
*/
|
|
7131
|
+
class ResourceManager {
|
|
7442
7132
|
constructor() {
|
|
7443
|
-
this.
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
this.
|
|
7133
|
+
this._loadPromiseMap = new Map();
|
|
7134
|
+
this._loadBunldePromiseMap = new Map();
|
|
7135
|
+
this._waitToReleaseBundles = new Map();
|
|
7136
|
+
this._startedGC = false;
|
|
7447
7137
|
}
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7138
|
+
preload(path, task) {
|
|
7139
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7140
|
+
let paths = typeof path === "string" ? [path] : path;
|
|
7141
|
+
let pathInfoList = paths.map((value) => {
|
|
7142
|
+
return this.parsePath(value);
|
|
7143
|
+
});
|
|
7144
|
+
let loadPromiseList = pathInfoList.map((info) => {
|
|
7145
|
+
return !info.isRemote ? this._preLoadFromBundle(info, task) : this._preLoadFromRemote(info, task);
|
|
7146
|
+
});
|
|
7147
|
+
return Promise.all(loadPromiseList).then((value) => {
|
|
7148
|
+
return value.length == 1 ? value[0] : value;
|
|
7149
|
+
});
|
|
7150
|
+
});
|
|
7461
7151
|
}
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7152
|
+
preLoadScene(path, task) {
|
|
7153
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7154
|
+
let paths = typeof path === "string" ? [path] : path;
|
|
7155
|
+
let pathInfoList = paths.map((value) => {
|
|
7156
|
+
let result = this.parsePath(value);
|
|
7157
|
+
if (result.isRemote) {
|
|
7158
|
+
throw new Error(`不支持从远程预加载场景${value}`);
|
|
7159
|
+
}
|
|
7160
|
+
return result;
|
|
7161
|
+
});
|
|
7162
|
+
let loadPromiseList = pathInfoList.map((info) => __awaiter(this, void 0, void 0, function* () {
|
|
7163
|
+
let bundle = yield this.getBundle(info.bundle);
|
|
7164
|
+
return new Promise((resolve) => {
|
|
7165
|
+
if (!bundle) {
|
|
7166
|
+
resolve(null);
|
|
7167
|
+
task && task.onError("preLoadScene", `加载${info.fullPath}时 bundle${info.bundle}加载失败`);
|
|
7168
|
+
}
|
|
7169
|
+
bundle.preloadScene(info.path, (error) => {
|
|
7170
|
+
if (error) {
|
|
7171
|
+
resolve(null);
|
|
7172
|
+
task && task.onError(error.name, error.message);
|
|
7173
|
+
}
|
|
7174
|
+
resolve(info.fullPath);
|
|
7175
|
+
task && task.onComplete();
|
|
7176
|
+
});
|
|
7177
|
+
});
|
|
7178
|
+
}));
|
|
7179
|
+
return Promise.all(loadPromiseList).then((value) => {
|
|
7180
|
+
return value.length > 0 ? (value.length == 1 ? value[0] : value) : null;
|
|
7181
|
+
});
|
|
7182
|
+
});
|
|
7183
|
+
}
|
|
7184
|
+
_preLoadFromRemote(info, task) {
|
|
7185
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7186
|
+
if (!info.isRemote) {
|
|
7187
|
+
throw new Error(`${info.fullPath}不是远程资源地址`);
|
|
7188
|
+
}
|
|
7189
|
+
if (info.isDir) {
|
|
7190
|
+
throw new Error(`不支持对远程Dir的加载`);
|
|
7191
|
+
}
|
|
7192
|
+
return new Promise((resolve, reject) => {
|
|
7193
|
+
cc.assetManager.loadRemote(info.fullPath, (error, asset) => {
|
|
7194
|
+
if (error) {
|
|
7195
|
+
resolve(null);
|
|
7196
|
+
task && task.onError(error.name, error.message);
|
|
7197
|
+
}
|
|
7198
|
+
else {
|
|
7199
|
+
resolve(info.fullPath);
|
|
7200
|
+
task && task.onComplete();
|
|
7201
|
+
}
|
|
7202
|
+
});
|
|
7203
|
+
});
|
|
7204
|
+
});
|
|
7205
|
+
}
|
|
7206
|
+
_preLoadFromBundle(info, task) {
|
|
7207
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7208
|
+
let bundle = yield this.getBundle(info.bundle);
|
|
7209
|
+
if (!bundle) {
|
|
7210
|
+
task && task.onError("_preLoadFromBundle", `加载${info.fullPath}时 bundle${info.bundle}加载失败`);
|
|
7211
|
+
return null;
|
|
7212
|
+
}
|
|
7213
|
+
return new Promise((resolve) => {
|
|
7214
|
+
let onProgress = (finish, total) => {
|
|
7215
|
+
task && task.onProgress(finish / total);
|
|
7216
|
+
};
|
|
7217
|
+
let onComplete = (error) => {
|
|
7218
|
+
if (error) {
|
|
7219
|
+
resolve(null);
|
|
7220
|
+
task && task.onError(error.name, error.message);
|
|
7221
|
+
}
|
|
7222
|
+
else {
|
|
7223
|
+
resolve(info.fullPath);
|
|
7224
|
+
task && task.onComplete();
|
|
7225
|
+
}
|
|
7226
|
+
};
|
|
7227
|
+
if (info.path == "") {
|
|
7228
|
+
onComplete(null);
|
|
7229
|
+
}
|
|
7230
|
+
else if (!info.isDir) {
|
|
7231
|
+
bundle.preload(info.path, onProgress, onComplete);
|
|
7232
|
+
}
|
|
7233
|
+
else {
|
|
7234
|
+
bundle.preloadDir(info.path, onProgress, onComplete);
|
|
7235
|
+
}
|
|
7236
|
+
});
|
|
7237
|
+
});
|
|
7238
|
+
}
|
|
7239
|
+
load(path, assetType, task) {
|
|
7240
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7241
|
+
let paths = typeof path === "string" ? [path] : path;
|
|
7242
|
+
let pathInfoList = paths.map((value) => {
|
|
7243
|
+
return this.parsePath(value);
|
|
7244
|
+
});
|
|
7245
|
+
let result = [];
|
|
7246
|
+
for (const info of pathInfoList) {
|
|
7247
|
+
if (!info.isRemote) {
|
|
7248
|
+
let assets = yield this._loadFromBundle(info, assetType, task);
|
|
7249
|
+
if (assets instanceof cc.Asset) {
|
|
7250
|
+
result.push(assets);
|
|
7251
|
+
}
|
|
7252
|
+
else {
|
|
7253
|
+
result.push(...assets);
|
|
7254
|
+
}
|
|
7255
|
+
continue;
|
|
7256
|
+
}
|
|
7257
|
+
let asset = yield this._loadfromRemote(info, task);
|
|
7258
|
+
if (assetType === cc.SpriteFrame) {
|
|
7259
|
+
asset = cc.SpriteFrame.createWithImage(asset);
|
|
7260
|
+
}
|
|
7261
|
+
result.push(asset);
|
|
7262
|
+
}
|
|
7263
|
+
return typeof path === "string" ? result[0] : result;
|
|
7264
|
+
});
|
|
7265
|
+
}
|
|
7266
|
+
_loadFromBundle(info, type, task) {
|
|
7267
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7268
|
+
let bundle = yield this.getBundle(info.bundle);
|
|
7269
|
+
if (!bundle) {
|
|
7270
|
+
task && task.onError("_loadFromBundle", `加载${info.fullPath}时 bundle${info.bundle}加载失败`);
|
|
7271
|
+
return null;
|
|
7272
|
+
}
|
|
7273
|
+
if (this._loadPromiseMap.has(info.fullPath)) {
|
|
7274
|
+
return this._loadPromiseMap.get(info.fullPath).then((value) => {
|
|
7275
|
+
task && task.onComplete();
|
|
7276
|
+
return value;
|
|
7277
|
+
});
|
|
7278
|
+
}
|
|
7279
|
+
let promise = new Promise((resolve) => {
|
|
7280
|
+
let onProgress = (finish, total) => {
|
|
7281
|
+
task && task.onProgress(finish / total);
|
|
7282
|
+
};
|
|
7283
|
+
let onComplete = (error, assets) => {
|
|
7284
|
+
if (error) {
|
|
7285
|
+
console.error("加载资源发生错误", info, error);
|
|
7286
|
+
resolve(null);
|
|
7287
|
+
task && task.onError(error.name, error.message);
|
|
7288
|
+
}
|
|
7289
|
+
else {
|
|
7290
|
+
resolve(assets);
|
|
7291
|
+
task && task.onComplete();
|
|
7292
|
+
}
|
|
7293
|
+
};
|
|
7294
|
+
if (info.path == "") {
|
|
7295
|
+
onComplete(null, null);
|
|
7296
|
+
}
|
|
7297
|
+
else if (!info.isDir) {
|
|
7298
|
+
bundle.load(info.path, type, onProgress, onComplete);
|
|
7299
|
+
}
|
|
7300
|
+
else {
|
|
7301
|
+
bundle.loadDir(info.path, type, onProgress, onComplete);
|
|
7302
|
+
}
|
|
7303
|
+
});
|
|
7304
|
+
this._loadPromiseMap.set(info.fullPath, promise);
|
|
7305
|
+
return promise;
|
|
7306
|
+
});
|
|
7307
|
+
}
|
|
7308
|
+
_loadfromRemote(info, task) {
|
|
7309
|
+
if (!info.isRemote) {
|
|
7310
|
+
throw new Error(`${info.fullPath}不是远程资源地址`);
|
|
7474
7311
|
}
|
|
7475
|
-
if (
|
|
7476
|
-
|
|
7477
|
-
console.log("callWithReturnType:", className, methodName, argsSig, args.join(","));
|
|
7478
|
-
return cc.native.reflection.callStaticMethod(className, methodName, argsSig, ...args);
|
|
7312
|
+
if (info.isDir) {
|
|
7313
|
+
throw new Error(`不支持对远程Dir的加载`);
|
|
7479
7314
|
}
|
|
7480
|
-
|
|
7315
|
+
if (this._loadPromiseMap.has(info.fullPath)) {
|
|
7316
|
+
return this._loadPromiseMap.get(info.fullPath);
|
|
7317
|
+
}
|
|
7318
|
+
let promise = new Promise((resolve) => {
|
|
7319
|
+
cc.assetManager.loadRemote(info.fullPath, (error, asset) => {
|
|
7320
|
+
if (error) {
|
|
7321
|
+
resolve(null);
|
|
7322
|
+
task && task.onError(error.name, error.message);
|
|
7323
|
+
}
|
|
7324
|
+
else {
|
|
7325
|
+
resolve(asset);
|
|
7326
|
+
task && task.onComplete();
|
|
7327
|
+
}
|
|
7328
|
+
});
|
|
7329
|
+
});
|
|
7330
|
+
this._loadPromiseMap.set(info.fullPath, promise);
|
|
7331
|
+
return promise;
|
|
7481
7332
|
}
|
|
7482
|
-
|
|
7483
|
-
|
|
7484
|
-
|
|
7485
|
-
|
|
7486
|
-
|
|
7333
|
+
/**
|
|
7334
|
+
* 解析资源路径成PathInfo
|
|
7335
|
+
* @param fullPath - 资源路径应该符合bundle://cc.path/to/resource格式
|
|
7336
|
+
* @returns - `PathInfo` 资源信息
|
|
7337
|
+
*/
|
|
7338
|
+
parsePath(fullPath) {
|
|
7339
|
+
let tempPath = fullPath.split("://");
|
|
7340
|
+
if (tempPath.length != 2) {
|
|
7341
|
+
throw new Error(`资源地址${fullPath}格式错误,应该符合bundle://cc.path/to/resource格式`); //.suffix
|
|
7487
7342
|
}
|
|
7488
|
-
|
|
7489
|
-
|
|
7343
|
+
let isDir = fullPath.charAt(fullPath.length - 1) == "/";
|
|
7344
|
+
let bundle = tempPath[0];
|
|
7345
|
+
let isRemote = bundle === "https" || bundle === "http";
|
|
7346
|
+
let suffix = cc.path.extname(fullPath).toLowerCase();
|
|
7347
|
+
let simplePath = suffix == "" ? tempPath[1] : tempPath[1].replace(suffix, "");
|
|
7348
|
+
return { bundle, path: simplePath, isRemote, isDir, fullPath };
|
|
7490
7349
|
}
|
|
7491
|
-
|
|
7492
|
-
|
|
7493
|
-
|
|
7350
|
+
/**
|
|
7351
|
+
* 获取目标bundle的资源的完整路径
|
|
7352
|
+
* @param bundleName - 资源所在bundle名称
|
|
7353
|
+
* @param subPath - 可选参数, 相对子路径
|
|
7354
|
+
* @returns
|
|
7355
|
+
*/
|
|
7356
|
+
getPath(bundleName, subPath = "") {
|
|
7357
|
+
if (subPath.includes("://")) {
|
|
7358
|
+
return subPath;
|
|
7494
7359
|
}
|
|
7495
|
-
|
|
7496
|
-
|
|
7497
|
-
|
|
7498
|
-
|
|
7360
|
+
return `${bundleName}://${subPath}`;
|
|
7361
|
+
}
|
|
7362
|
+
/**
|
|
7363
|
+
* 获取主包下资源的完整路径
|
|
7364
|
+
* @param subPath 资源子路径
|
|
7365
|
+
* @returns
|
|
7366
|
+
*/
|
|
7367
|
+
getPathInMain(subPath) {
|
|
7368
|
+
return this.getPath("main", subPath);
|
|
7369
|
+
}
|
|
7370
|
+
/**
|
|
7371
|
+
* 获取动态包下资源的完整路径
|
|
7372
|
+
* @param subPath 资源子路径
|
|
7373
|
+
* @returns
|
|
7374
|
+
*/
|
|
7375
|
+
getPathInResources(subPath) {
|
|
7376
|
+
return this.getPath("resources", subPath);
|
|
7377
|
+
}
|
|
7378
|
+
/**
|
|
7379
|
+
* 加载Bundle
|
|
7380
|
+
* @param bundleName Bundle名称
|
|
7381
|
+
* @returns `Promise<cc.AssetManager.Bundle>`
|
|
7382
|
+
*/
|
|
7383
|
+
getBundle(bundleName) {
|
|
7384
|
+
this._removeBundleFromReleaseMap(bundleName);
|
|
7385
|
+
this._startGC();
|
|
7386
|
+
if (this._loadBunldePromiseMap.has(bundleName)) {
|
|
7387
|
+
return this._loadBunldePromiseMap.get(bundleName);
|
|
7388
|
+
}
|
|
7389
|
+
let promise = new Promise((resolve) => {
|
|
7390
|
+
let bundle = cc.assetManager.getBundle(bundleName);
|
|
7391
|
+
if (!!bundle) {
|
|
7392
|
+
resolve(bundle);
|
|
7393
|
+
return;
|
|
7499
7394
|
}
|
|
7500
|
-
|
|
7501
|
-
|
|
7395
|
+
let version = this._getBundleVersion(bundleName);
|
|
7396
|
+
cc.assetManager.loadBundle(bundleName, version ? { version: version } : null, (error, bundle) => {
|
|
7397
|
+
if (error) {
|
|
7398
|
+
console.error(`LoadBundle ${bundleName} Error:`, error);
|
|
7399
|
+
resolve(null);
|
|
7400
|
+
}
|
|
7401
|
+
else {
|
|
7402
|
+
resolve(bundle);
|
|
7403
|
+
}
|
|
7404
|
+
});
|
|
7405
|
+
});
|
|
7406
|
+
this._loadBunldePromiseMap.set(bundleName, promise);
|
|
7407
|
+
return promise;
|
|
7408
|
+
}
|
|
7409
|
+
/**
|
|
7410
|
+
* bundle是否被加载过,且有效
|
|
7411
|
+
* @param bundleName
|
|
7412
|
+
* @returns
|
|
7413
|
+
*/
|
|
7414
|
+
isBundleValid(bundleName) {
|
|
7415
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7416
|
+
if (this._loadBunldePromiseMap.has(bundleName)) {
|
|
7417
|
+
let bundle = yield this._loadBunldePromiseMap.get(bundleName);
|
|
7418
|
+
return bundle && cc.isValid(bundle);
|
|
7502
7419
|
}
|
|
7503
|
-
|
|
7504
|
-
|
|
7505
|
-
|
|
7506
|
-
|
|
7507
|
-
|
|
7508
|
-
|
|
7420
|
+
return false;
|
|
7421
|
+
});
|
|
7422
|
+
}
|
|
7423
|
+
/**
|
|
7424
|
+
* 移除并销毁bundle,以及bundle下所有资源。
|
|
7425
|
+
* @param bundleName bundle名称
|
|
7426
|
+
* @param delay 是否延后销毁,默认为true
|
|
7427
|
+
* @returns
|
|
7428
|
+
*/
|
|
7429
|
+
removeBundle(bundleName, delay = true) {
|
|
7430
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7431
|
+
if (this.isBundleValid(bundleName)) {
|
|
7432
|
+
let bundle = yield this._loadBunldePromiseMap.get(bundleName);
|
|
7433
|
+
if (delay) {
|
|
7434
|
+
this._pushBundleToReleaseMap(bundle);
|
|
7435
|
+
return true;
|
|
7436
|
+
}
|
|
7437
|
+
return this._onRemoveBundle(bundle);
|
|
7438
|
+
}
|
|
7439
|
+
return false;
|
|
7440
|
+
});
|
|
7441
|
+
}
|
|
7442
|
+
/**
|
|
7443
|
+
* 推送bundle到GC队列
|
|
7444
|
+
* @param bundle
|
|
7445
|
+
*/
|
|
7446
|
+
_pushBundleToReleaseMap(bundle) {
|
|
7447
|
+
if (bundle && cc.isValid(bundle)) {
|
|
7448
|
+
console.log(`[GCBundle] Pre Remove Bundle:${bundle.name}`);
|
|
7449
|
+
this._waitToReleaseBundles.set(bundle.name, bundle);
|
|
7509
7450
|
}
|
|
7510
7451
|
}
|
|
7511
|
-
|
|
7512
|
-
|
|
7513
|
-
|
|
7514
|
-
*
|
|
7515
|
-
|
|
7516
|
-
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
/*
|
|
7522
|
-
* Configurable variables. You may need to tweak these to be compatible with
|
|
7523
|
-
* the server-side, but the defaults work in most cases.
|
|
7524
|
-
*/
|
|
7525
|
-
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
|
|
7526
|
-
/*
|
|
7527
|
-
* These are the functions you'll usually want to call
|
|
7528
|
-
* They take string arguments and return either hex or base-64 encoded strings
|
|
7529
|
-
*/
|
|
7530
|
-
function hex_md5(s) { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }
|
|
7531
|
-
/*
|
|
7532
|
-
* Calculate the MD5 of a raw string
|
|
7533
|
-
*/
|
|
7534
|
-
function rstr_md5(s) {
|
|
7535
|
-
return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
|
|
7536
|
-
}
|
|
7537
|
-
/*
|
|
7538
|
-
* Convert a raw string to a hex string
|
|
7539
|
-
*/
|
|
7540
|
-
function rstr2hex(input) {
|
|
7541
|
-
try {
|
|
7542
|
-
hexcase;
|
|
7452
|
+
/**
|
|
7453
|
+
* 删除等待销毁的bundle,如果有
|
|
7454
|
+
* @param bundleName
|
|
7455
|
+
* @returns
|
|
7456
|
+
*/
|
|
7457
|
+
_removeBundleFromReleaseMap(bundleName) {
|
|
7458
|
+
if (this._waitToReleaseBundles.has(bundleName)) {
|
|
7459
|
+
console.log(`[GCBundle] Cancel Pre Remove Bundle:${bundleName}`);
|
|
7460
|
+
}
|
|
7461
|
+
return this._waitToReleaseBundles.delete(bundleName);
|
|
7543
7462
|
}
|
|
7544
|
-
|
|
7545
|
-
|
|
7463
|
+
/**
|
|
7464
|
+
* 真正移除bundle
|
|
7465
|
+
* @param bundle 目标bundle
|
|
7466
|
+
* @returns
|
|
7467
|
+
*/
|
|
7468
|
+
_onRemoveBundle(bundle) {
|
|
7469
|
+
if (bundle && bundle.name) {
|
|
7470
|
+
//删除bundle的加载promise
|
|
7471
|
+
this._loadBunldePromiseMap.delete(bundle.name);
|
|
7472
|
+
//删除bundle对应的资源缓存
|
|
7473
|
+
this._loadPromiseMap.forEach((value, fullPath) => {
|
|
7474
|
+
if (this.parsePath(fullPath).bundle == bundle.name) {
|
|
7475
|
+
this._loadPromiseMap.delete(fullPath);
|
|
7476
|
+
}
|
|
7477
|
+
});
|
|
7478
|
+
if (cc.isValid(bundle)) {
|
|
7479
|
+
bundle.releaseAll();
|
|
7480
|
+
cc.assetManager.removeBundle(bundle);
|
|
7481
|
+
}
|
|
7482
|
+
//删除等待移除的bundle
|
|
7483
|
+
this._waitToReleaseBundles.delete(bundle.name);
|
|
7484
|
+
return true;
|
|
7485
|
+
}
|
|
7486
|
+
return false;
|
|
7546
7487
|
}
|
|
7547
|
-
|
|
7548
|
-
|
|
7549
|
-
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
|
|
7488
|
+
/**
|
|
7489
|
+
* 开始Bundle GC,只执行一次
|
|
7490
|
+
* @returns
|
|
7491
|
+
*/
|
|
7492
|
+
_startGC() {
|
|
7493
|
+
if (this._startedGC) {
|
|
7494
|
+
return;
|
|
7495
|
+
}
|
|
7496
|
+
this._startedGC = true;
|
|
7497
|
+
timer.loop(GC_CD, this, this._onGC);
|
|
7554
7498
|
}
|
|
7555
|
-
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
var i = -1;
|
|
7564
|
-
var x, y;
|
|
7565
|
-
while (++i < input.length) {
|
|
7566
|
-
/* Decode utf-16 surrogate pairs */
|
|
7567
|
-
x = input.charCodeAt(i);
|
|
7568
|
-
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
|
|
7569
|
-
if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
|
|
7570
|
-
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
|
|
7571
|
-
i++;
|
|
7499
|
+
/**
|
|
7500
|
+
* GC Bundle
|
|
7501
|
+
* @returns
|
|
7502
|
+
*/
|
|
7503
|
+
_onGC() {
|
|
7504
|
+
const count = this._waitToReleaseBundles.size;
|
|
7505
|
+
if (count == 0) {
|
|
7506
|
+
return;
|
|
7572
7507
|
}
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
else if (x <= 0x1FFFFF)
|
|
7581
|
-
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F));
|
|
7508
|
+
const now = Date.now();
|
|
7509
|
+
this._waitToReleaseBundles.forEach((bundle) => {
|
|
7510
|
+
console.log(`[GCBundle] Remove Bundle:${bundle.name}`);
|
|
7511
|
+
this._onRemoveBundle(bundle);
|
|
7512
|
+
});
|
|
7513
|
+
this._waitToReleaseBundles.clear();
|
|
7514
|
+
console.log(`[GCBundle] [${count}] cost:${Date.now() - now} milliseconds`);
|
|
7582
7515
|
}
|
|
7583
|
-
|
|
7584
|
-
|
|
7585
|
-
|
|
7586
|
-
|
|
7587
|
-
|
|
7588
|
-
|
|
7589
|
-
|
|
7590
|
-
|
|
7591
|
-
|
|
7592
|
-
|
|
7593
|
-
|
|
7594
|
-
|
|
7595
|
-
|
|
7596
|
-
|
|
7597
|
-
|
|
7598
|
-
|
|
7599
|
-
|
|
7600
|
-
function binl2rstr(input) {
|
|
7601
|
-
var output = "";
|
|
7602
|
-
for (var i = 0; i < input.length * 32; i += 8)
|
|
7603
|
-
output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
|
|
7604
|
-
return output;
|
|
7605
|
-
}
|
|
7606
|
-
/*
|
|
7607
|
-
* Calculate the MD5 of an array of little-endian words, and a bit length.
|
|
7608
|
-
*/
|
|
7609
|
-
function binl_md5(x, len) {
|
|
7610
|
-
/* append padding */
|
|
7611
|
-
x[len >> 5] |= 0x80 << ((len) % 32);
|
|
7612
|
-
x[(((len + 64) >>> 9) << 4) + 14] = len;
|
|
7613
|
-
var a = 1732584193;
|
|
7614
|
-
var b = -271733879;
|
|
7615
|
-
var c = -1732584194;
|
|
7616
|
-
var d = 271733878;
|
|
7617
|
-
for (var i = 0; i < x.length; i += 16) {
|
|
7618
|
-
var olda = a;
|
|
7619
|
-
var oldb = b;
|
|
7620
|
-
var oldc = c;
|
|
7621
|
-
var oldd = d;
|
|
7622
|
-
a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
|
|
7623
|
-
d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
|
|
7624
|
-
c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
|
|
7625
|
-
b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
|
|
7626
|
-
a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
|
|
7627
|
-
d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
|
|
7628
|
-
c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
|
|
7629
|
-
b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
|
|
7630
|
-
a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
|
|
7631
|
-
d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
|
|
7632
|
-
c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
|
|
7633
|
-
b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
|
|
7634
|
-
a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
|
|
7635
|
-
d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
|
|
7636
|
-
c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
|
|
7637
|
-
b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
|
|
7638
|
-
a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
|
|
7639
|
-
d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
|
|
7640
|
-
c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
|
|
7641
|
-
b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
|
|
7642
|
-
a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
|
|
7643
|
-
d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
|
|
7644
|
-
c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
|
|
7645
|
-
b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
|
|
7646
|
-
a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
|
|
7647
|
-
d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
|
|
7648
|
-
c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
|
|
7649
|
-
b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
|
|
7650
|
-
a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
|
|
7651
|
-
d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
|
|
7652
|
-
c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
|
|
7653
|
-
b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
|
|
7654
|
-
a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
|
|
7655
|
-
d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
|
|
7656
|
-
c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
|
|
7657
|
-
b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
|
|
7658
|
-
a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
|
|
7659
|
-
d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
|
|
7660
|
-
c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
|
|
7661
|
-
b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
|
|
7662
|
-
a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
|
|
7663
|
-
d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
|
|
7664
|
-
c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
|
|
7665
|
-
b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
|
|
7666
|
-
a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
|
|
7667
|
-
d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
|
|
7668
|
-
c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
|
|
7669
|
-
b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
|
|
7670
|
-
a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
|
|
7671
|
-
d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
|
|
7672
|
-
c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
|
|
7673
|
-
b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
|
|
7674
|
-
a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
|
|
7675
|
-
d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
|
|
7676
|
-
c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
|
|
7677
|
-
b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
|
|
7678
|
-
a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
|
|
7679
|
-
d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
|
|
7680
|
-
c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
|
|
7681
|
-
b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
|
|
7682
|
-
a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
|
|
7683
|
-
d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
|
|
7684
|
-
c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
|
|
7685
|
-
b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
|
|
7686
|
-
a = safe_add(a, olda);
|
|
7687
|
-
b = safe_add(b, oldb);
|
|
7688
|
-
c = safe_add(c, oldc);
|
|
7689
|
-
d = safe_add(d, oldd);
|
|
7516
|
+
/**
|
|
7517
|
+
* 手动设置bundle的版本,可新增可以覆盖。
|
|
7518
|
+
* @param map
|
|
7519
|
+
*/
|
|
7520
|
+
setBundleVersion(map) {
|
|
7521
|
+
this._bundleVersionMap = this._bundleVersionMap || new Map();
|
|
7522
|
+
map.forEach((value, key) => {
|
|
7523
|
+
this._bundleVersionMap.set(value, key);
|
|
7524
|
+
});
|
|
7525
|
+
}
|
|
7526
|
+
/**
|
|
7527
|
+
* 获取bundle的版本
|
|
7528
|
+
* @param bundleName
|
|
7529
|
+
* @returns
|
|
7530
|
+
*/
|
|
7531
|
+
_getBundleVersion(bundleName) {
|
|
7532
|
+
return this._bundleVersionMap && this._bundleVersionMap.get(bundleName);
|
|
7690
7533
|
}
|
|
7691
|
-
return Array(a, b, c, d);
|
|
7692
|
-
}
|
|
7693
|
-
/*
|
|
7694
|
-
* These functions implement the four basic operations the algorithm uses.
|
|
7695
|
-
*/
|
|
7696
|
-
function md5_cmn(q, a, b, x, s, t) {
|
|
7697
|
-
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
|
|
7698
|
-
}
|
|
7699
|
-
function md5_ff(a, b, c, d, x, s, t) {
|
|
7700
|
-
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
|
7701
|
-
}
|
|
7702
|
-
function md5_gg(a, b, c, d, x, s, t) {
|
|
7703
|
-
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
|
7704
|
-
}
|
|
7705
|
-
function md5_hh(a, b, c, d, x, s, t) {
|
|
7706
|
-
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
|
|
7707
|
-
}
|
|
7708
|
-
function md5_ii(a, b, c, d, x, s, t) {
|
|
7709
|
-
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
|
|
7710
|
-
}
|
|
7711
|
-
/*
|
|
7712
|
-
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
|
|
7713
|
-
* to work around bugs in some JS interpreters.
|
|
7714
|
-
*/
|
|
7715
|
-
function safe_add(x, y) {
|
|
7716
|
-
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
|
|
7717
|
-
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
|
7718
|
-
return (msw << 16) | (lsw & 0xFFFF);
|
|
7719
|
-
}
|
|
7720
|
-
/*
|
|
7721
|
-
* Bitwise rotate a 32-bit number to the left.
|
|
7722
|
-
*/
|
|
7723
|
-
function bit_rol(num, cnt) {
|
|
7724
|
-
return (num << cnt) | (num >>> (32 - cnt));
|
|
7725
7534
|
}
|
|
7726
|
-
const md5 = hex_md5;
|
|
7727
|
-
|
|
7728
7535
|
/**
|
|
7729
|
-
* cocos
|
|
7536
|
+
* cocos资源加载和管理
|
|
7730
7537
|
*/
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7538
|
+
const res = new ResourceManager();
|
|
7539
|
+
|
|
7540
|
+
var View_1;
|
|
7541
|
+
const { ccclass: ccclass$2, property: property$2, menu: menu$2 } = cc._decorator;
|
|
7542
|
+
var ViewLevel;
|
|
7543
|
+
(function (ViewLevel) {
|
|
7544
|
+
ViewLevel[ViewLevel["TOPUP"] = 500] = "TOPUP";
|
|
7545
|
+
ViewLevel[ViewLevel["NET"] = 400] = "NET";
|
|
7546
|
+
ViewLevel[ViewLevel["TUTORIAL"] = 300] = "TUTORIAL";
|
|
7547
|
+
ViewLevel[ViewLevel["ALERT"] = 200] = "ALERT";
|
|
7548
|
+
ViewLevel[ViewLevel["UI"] = 100] = "UI";
|
|
7549
|
+
ViewLevel[ViewLevel["BG"] = 1] = "BG";
|
|
7550
|
+
})(ViewLevel || (ViewLevel = {}));
|
|
7551
|
+
let View = View_1 = class View extends cc.Component {
|
|
7552
|
+
constructor() {
|
|
7553
|
+
super(...arguments);
|
|
7554
|
+
/**
|
|
7555
|
+
* 是否可以交互
|
|
7556
|
+
*/
|
|
7557
|
+
this._touchEnabled = true;
|
|
7737
7558
|
}
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7559
|
+
/**
|
|
7560
|
+
* 是否在舞台中显示着
|
|
7561
|
+
*/
|
|
7562
|
+
get inStage() {
|
|
7563
|
+
return cc.isValid(this.node) && this.node.activeInHierarchy;
|
|
7564
|
+
}
|
|
7565
|
+
/**
|
|
7566
|
+
* 视图是否响应交互
|
|
7567
|
+
*/
|
|
7568
|
+
get touchEnabled() {
|
|
7569
|
+
return this._touchEnabled;
|
|
7570
|
+
}
|
|
7571
|
+
/**
|
|
7572
|
+
* 视图是否响应交互
|
|
7573
|
+
*/
|
|
7574
|
+
set touchEnabled(value) {
|
|
7575
|
+
this._touchEnabled = value;
|
|
7576
|
+
if (value && !this._mask) {
|
|
7577
|
+
return;
|
|
7744
7578
|
}
|
|
7745
|
-
|
|
7746
|
-
|
|
7579
|
+
if (!this._mask) {
|
|
7580
|
+
this._mask = new cc.Node();
|
|
7581
|
+
this._mask.name = "mask";
|
|
7582
|
+
let transform = this._mask.addComponent(cc.UITransform);
|
|
7583
|
+
const viewSize = cc.view.getVisibleSize();
|
|
7584
|
+
transform.setContentSize(viewSize.width, viewSize.height);
|
|
7585
|
+
this._mask.addComponent(cc.BlockInputEvents);
|
|
7586
|
+
// this.node.addChild(this.mask);
|
|
7587
|
+
this.node.addChild(this._mask);
|
|
7588
|
+
transform.priority = ViewLevel.TOPUP;
|
|
7589
|
+
this._mask.layer = this.node.layer;
|
|
7747
7590
|
}
|
|
7591
|
+
this._mask.active = !value;
|
|
7748
7592
|
}
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7593
|
+
/**
|
|
7594
|
+
* 添加其他视图
|
|
7595
|
+
* @param view 其他视图
|
|
7596
|
+
* @param index 视图索引
|
|
7597
|
+
*/
|
|
7598
|
+
addView(view, index) {
|
|
7599
|
+
view.setControl(this._control);
|
|
7600
|
+
view.node.parent = this.node;
|
|
7601
|
+
(view.node.getComponent(cc.UITransform) || view.node.addComponent(cc.UITransform)).priority = index;
|
|
7602
|
+
viewManager.event("open", view);
|
|
7603
|
+
viewManager.reportViewAnalytics("open", view);
|
|
7604
|
+
analytics.session.updateSessionDuration();
|
|
7605
|
+
}
|
|
7606
|
+
/**
|
|
7607
|
+
* 移除子视图
|
|
7608
|
+
* @param view 子视图
|
|
7609
|
+
* @param destroy 是否销毁,默认为true
|
|
7610
|
+
* @param closeEventParams 视图close事件的参数
|
|
7611
|
+
*/
|
|
7612
|
+
removeView(view, destroy = true, ...closeEventParams) {
|
|
7613
|
+
if (view.parentView == this) {
|
|
7614
|
+
destroy && view.node.destroyAllChildren();
|
|
7615
|
+
view.node.removeFromParent();
|
|
7616
|
+
viewManager.event("close", view, ...closeEventParams);
|
|
7617
|
+
viewManager.reportViewAnalytics("close", view);
|
|
7618
|
+
analytics.session.updateSessionDuration();
|
|
7752
7619
|
}
|
|
7753
|
-
return sys.localStorage.getItem(key);
|
|
7754
7620
|
}
|
|
7755
|
-
|
|
7756
|
-
|
|
7621
|
+
/**
|
|
7622
|
+
* 设置主场景所创建的Control
|
|
7623
|
+
* @param control
|
|
7624
|
+
*/
|
|
7625
|
+
setControl(control) {
|
|
7626
|
+
this._control = control;
|
|
7757
7627
|
}
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
/**
|
|
7761
|
-
* 任务队列
|
|
7762
|
-
*/
|
|
7763
|
-
class TaskSequence extends Task {
|
|
7764
|
-
constructor() {
|
|
7765
|
-
super();
|
|
7766
|
-
this._taskMap = new Map();
|
|
7767
|
-
this._index = 0;
|
|
7628
|
+
control() {
|
|
7629
|
+
return this._control;
|
|
7768
7630
|
}
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
|
|
7773
|
-
|
|
7774
|
-
};
|
|
7775
|
-
this.addTask(task);
|
|
7776
|
-
return task;
|
|
7631
|
+
/**
|
|
7632
|
+
* 实例化后显示到舞台之后调用,缓存视图重新显示时也会调用。
|
|
7633
|
+
* @param data
|
|
7634
|
+
*/
|
|
7635
|
+
setData(...data) {
|
|
7777
7636
|
}
|
|
7778
|
-
|
|
7779
|
-
|
|
7780
|
-
|
|
7781
|
-
|
|
7782
|
-
|
|
7637
|
+
/**
|
|
7638
|
+
* 上报当前视图统计数据
|
|
7639
|
+
* @param event open和close以外的统计名称,名称必须为全小写,无下划线之外的其他特殊字符。
|
|
7640
|
+
* @param data 上报附带信息,可选参数,为空时会尝试从getAnalyticsDataOnViewEvent获取附带信息。
|
|
7641
|
+
*/
|
|
7642
|
+
_report(event, data) {
|
|
7643
|
+
if (event == "open" || event == "close")
|
|
7644
|
+
return;
|
|
7645
|
+
viewManager.reportViewAnalytics(event, this, data);
|
|
7783
7646
|
}
|
|
7784
|
-
|
|
7785
|
-
|
|
7647
|
+
/**
|
|
7648
|
+
* 播放BG音乐
|
|
7649
|
+
* @param path 路径 - `bundleName://path/to/asset` 目标音频地址。
|
|
7650
|
+
* @param fade 是否渐进式播放,默认为true
|
|
7651
|
+
* @param loop 是否循环 默认为true
|
|
7652
|
+
* @param onFinishCallBack 单次播放结束后的回调箭头函数(cocos的锅)
|
|
7653
|
+
* @returns 背景音乐的audioId
|
|
7654
|
+
*
|
|
7655
|
+
* @example
|
|
7656
|
+
* _playBG("https://server.com/game/music.mp3")
|
|
7657
|
+
* _playBG("main://path/to/music")
|
|
7658
|
+
* _playBG("resources://path/to/music")
|
|
7659
|
+
*/
|
|
7660
|
+
playBG(path, fade = true, loop = true, onFinishCallBack, volume = null) {
|
|
7661
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7662
|
+
let clip = yield res.load(path);
|
|
7663
|
+
if (clip) {
|
|
7664
|
+
audio.playMusic(clip, fade, loop, onFinishCallBack, volume);
|
|
7665
|
+
}
|
|
7666
|
+
});
|
|
7786
7667
|
}
|
|
7787
|
-
|
|
7788
|
-
|
|
7789
|
-
|
|
7790
|
-
|
|
7668
|
+
/**
|
|
7669
|
+
* 播放音效
|
|
7670
|
+
* @param path 路径 - `bundleName://path/to/asset` 目标音频地址。
|
|
7671
|
+
* @param onFinishCallBack 单次播放结束后的回调箭头函数(cocos的锅)
|
|
7672
|
+
* @returns 音效的audioId
|
|
7673
|
+
*/
|
|
7674
|
+
playEffect(path, onFinishCallBack, volume = null) {
|
|
7675
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7676
|
+
let clip = yield res.load(path);
|
|
7677
|
+
return new Promise((reslove) => {
|
|
7678
|
+
if (clip) {
|
|
7679
|
+
audio.playEffect(clip, false, () => {
|
|
7680
|
+
onFinishCallBack && onFinishCallBack();
|
|
7681
|
+
reslove();
|
|
7682
|
+
}, volume);
|
|
7683
|
+
}
|
|
7684
|
+
});
|
|
7685
|
+
});
|
|
7791
7686
|
}
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7687
|
+
/**
|
|
7688
|
+
* 播放激励视频的快捷方式。
|
|
7689
|
+
* @param from 可选参数,可以附带广告行为的来源,以及其他需要统计的信息
|
|
7690
|
+
* @param stopRecorder 可选参数,是否暂停录屏, 默认为true
|
|
7691
|
+
*/
|
|
7692
|
+
showRewardVideo(from, stopRecorder = true) {
|
|
7693
|
+
return new Promise((resolve) => {
|
|
7694
|
+
stopRecorder && publisher.record && publisher.record.pauseRecord();
|
|
7695
|
+
viewManager.closeTouch();
|
|
7696
|
+
//解决部分平台(tt)拉起视频时,最小化视频播放不出来的bug。
|
|
7697
|
+
const openTouch = () => {
|
|
7698
|
+
viewManager.openTouch();
|
|
7699
|
+
App.offShow(openTouch);
|
|
7700
|
+
};
|
|
7701
|
+
App.onShow(openTouch);
|
|
7702
|
+
from = from || {};
|
|
7703
|
+
// from.name = this.analyticsInfo ? this.analyticsInfo.name : this.name;
|
|
7704
|
+
publisher.ad.showRewardVideo(from).then((result) => {
|
|
7705
|
+
openTouch();
|
|
7706
|
+
stopRecorder && publisher.record && publisher.record.resumeRecord();
|
|
7707
|
+
resolve(result);
|
|
7708
|
+
}).catch(() => {
|
|
7709
|
+
openTouch();
|
|
7710
|
+
stopRecorder && publisher.record && publisher.record.resumeRecord();
|
|
7711
|
+
resolve(false);
|
|
7712
|
+
});
|
|
7713
|
+
});
|
|
7714
|
+
}
|
|
7715
|
+
/**
|
|
7716
|
+
* 分享录屏视频
|
|
7717
|
+
* @param analyticsName 玩法发起分享的动作来源,用于统计。
|
|
7718
|
+
* @param title 视频标题
|
|
7719
|
+
* @param topics 视频话题列表
|
|
7720
|
+
*/
|
|
7721
|
+
shareRecord(analyticsName, title, topics) {
|
|
7722
|
+
let path = publisher.record.videoPath;
|
|
7723
|
+
if (path) {
|
|
7724
|
+
return publisher.share.shareVideo(analyticsName, { "video_title": title, "videoTopics": topics, "videoPath": path });
|
|
7800
7725
|
}
|
|
7801
7726
|
else {
|
|
7802
|
-
|
|
7803
|
-
this.onComplete();
|
|
7727
|
+
return new Promise((resolve) => { resolve(false); });
|
|
7804
7728
|
}
|
|
7805
7729
|
}
|
|
7806
|
-
|
|
7807
|
-
|
|
7808
|
-
|
|
7809
|
-
|
|
7730
|
+
/**
|
|
7731
|
+
* 子项重写时,必须要调用super.onDestroy()。
|
|
7732
|
+
*
|
|
7733
|
+
*/
|
|
7734
|
+
onDestroy() {
|
|
7735
|
+
this.config.cache && viewManager.cancelCache(this);
|
|
7736
|
+
}
|
|
7737
|
+
/**
|
|
7738
|
+
* 父级视图
|
|
7739
|
+
*/
|
|
7740
|
+
get parentView() {
|
|
7741
|
+
if (this.node.parent) {
|
|
7742
|
+
return this.node.parent.getComponent(View_1);
|
|
7810
7743
|
}
|
|
7811
|
-
|
|
7812
|
-
|
|
7813
|
-
|
|
7814
|
-
|
|
7815
|
-
|
|
7816
|
-
|
|
7744
|
+
return null;
|
|
7745
|
+
}
|
|
7746
|
+
/**
|
|
7747
|
+
* 关闭视图,根据视图是否缓存选择是否销毁视图
|
|
7748
|
+
* @param closeEventParams 视图close事件的参数
|
|
7749
|
+
*/
|
|
7750
|
+
close(...closeEventParams) {
|
|
7751
|
+
this.removeFromParent(!this.config.cache, ...closeEventParams);
|
|
7752
|
+
}
|
|
7753
|
+
onClose(caller, listener, once = true, ...args) {
|
|
7754
|
+
const targetView = this.config.viewClassName || this.config.viewClass || View_1.type;
|
|
7755
|
+
viewManager.onViewClose(targetView, caller, listener, once, ...args);
|
|
7756
|
+
}
|
|
7757
|
+
/**
|
|
7758
|
+
* 从父级移除视图
|
|
7759
|
+
* @param destroy 是否销毁,默认为true
|
|
7760
|
+
* @param closeEventParams 视图close事件的参数
|
|
7761
|
+
*/
|
|
7762
|
+
removeFromParent(destroy = true, ...closeEventParams) {
|
|
7763
|
+
if (this.parentView) {
|
|
7764
|
+
this.parentView.removeView(this, destroy, ...closeEventParams);
|
|
7817
7765
|
}
|
|
7818
7766
|
}
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
7823
|
-
|
|
7824
|
-
|
|
7825
|
-
|
|
7826
|
-
|
|
7767
|
+
/**
|
|
7768
|
+
* 直接销毁
|
|
7769
|
+
*/
|
|
7770
|
+
allDestroy() {
|
|
7771
|
+
if (this.node && cc.isValid(this.node)) {
|
|
7772
|
+
this.node.parent = null;
|
|
7773
|
+
this.node.destroy();
|
|
7774
|
+
}
|
|
7827
7775
|
}
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
this._taskMap.forEach((data, task) => {
|
|
7831
|
-
task.reset();
|
|
7832
|
-
});
|
|
7833
|
-
this._taskMap.clear();
|
|
7834
|
-
this._keys = null;
|
|
7835
|
-
this._index = 0;
|
|
7776
|
+
getAnalyticsDataOnViewEvent(event) {
|
|
7777
|
+
return {};
|
|
7836
7778
|
}
|
|
7837
|
-
}
|
|
7779
|
+
};
|
|
7780
|
+
/**
|
|
7781
|
+
* View类的Class名称
|
|
7782
|
+
*/
|
|
7783
|
+
View.type = "View";
|
|
7784
|
+
View = View_1 = __decorate([
|
|
7785
|
+
ccclass$2("View"),
|
|
7786
|
+
menu$2("基础视图/View")
|
|
7787
|
+
/**
|
|
7788
|
+
* cocos引擎下的视图管理类
|
|
7789
|
+
*/
|
|
7790
|
+
], View);
|
|
7838
7791
|
|
|
7839
7792
|
/**
|
|
7840
|
-
*
|
|
7793
|
+
* 注册进入视图时,上报的事件名称,不注册则上报视图配置的name属性
|
|
7794
|
+
* @param analyticsName 可选参数,默认为view的name,可以指定为上报的中文名称
|
|
7795
|
+
* @param group 分组,默认为default,方便分类统计
|
|
7796
|
+
* @returns
|
|
7841
7797
|
*/
|
|
7842
|
-
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7846
|
-
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
|
|
7850
|
-
|
|
7851
|
-
|
|
7798
|
+
function viewAnalytics(analyticsName, group = "default") {
|
|
7799
|
+
return function (target, propertyKey) {
|
|
7800
|
+
viewManager.registerAnalytics(target, analyticsName, group);
|
|
7801
|
+
};
|
|
7802
|
+
}
|
|
7803
|
+
/**
|
|
7804
|
+
* 视图管理类
|
|
7805
|
+
*/
|
|
7806
|
+
class ViewManager {
|
|
7807
|
+
/**
|
|
7808
|
+
* 注册视图上报事件的视图名称,一般为中文方便数据分辨
|
|
7809
|
+
* @param viewClass
|
|
7810
|
+
* @param analyticsName 可选参数,默认为view的name,可以指定为上报的中文名称
|
|
7811
|
+
* @param group 分组,可选参数,默认为default,方便分类统计
|
|
7812
|
+
*/
|
|
7813
|
+
registerAnalytics(viewClass, analyticsName, group = "default") {
|
|
7814
|
+
let config = this._getViewConfig(viewClass);
|
|
7815
|
+
if (config) {
|
|
7816
|
+
this._viewAnalyticsMap.set(config.name, { name: analyticsName || config.name, group });
|
|
7852
7817
|
}
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
task.onError(error.code, error.msg);
|
|
7856
|
-
});
|
|
7857
|
-
this._initializer.on(Task.Event.PROGRESS, this, (type, a, percent) => {
|
|
7858
|
-
task.onProgress(percent);
|
|
7859
|
-
});
|
|
7818
|
+
else {
|
|
7819
|
+
throw new Error(`未获取到视图${viewClass}的配置`);
|
|
7860
7820
|
}
|
|
7861
|
-
this._initializer.once(Task.Event.COMPLETE, this, () => {
|
|
7862
|
-
this._initializer.reset();
|
|
7863
|
-
task && task.onComplete();
|
|
7864
|
-
});
|
|
7865
|
-
this._initializer.start();
|
|
7866
7821
|
}
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7822
|
+
/**
|
|
7823
|
+
* 注册视图类对应的视图配置
|
|
7824
|
+
* @param viewName 视图名称
|
|
7825
|
+
* @param config 视图配置
|
|
7826
|
+
*/
|
|
7827
|
+
registerView(viewName, config) {
|
|
7828
|
+
if (this._viewConfigMap.has(viewName)) {
|
|
7829
|
+
throw new Error(`已经存在名称为${viewName}的View`);
|
|
7830
|
+
}
|
|
7831
|
+
this._viewConfigMap.set(viewName, config);
|
|
7873
7832
|
}
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7833
|
+
/**
|
|
7834
|
+
* 注册closeTouch默认遮罩视图
|
|
7835
|
+
* @param config 视图配置|Class|名称
|
|
7836
|
+
*/
|
|
7837
|
+
registerMaskView(config) {
|
|
7838
|
+
let viewConfig = this._getViewConfig(config);
|
|
7839
|
+
if (!viewConfig) {
|
|
7840
|
+
throw new Error(`未获取到默认遮罩视图${config}的配置`);
|
|
7841
|
+
}
|
|
7842
|
+
viewConfig.cache = true;
|
|
7843
|
+
viewConfig.zIndex = ViewLevel.TOPUP;
|
|
7844
|
+
this._defaultMaskViewConfig = viewConfig;
|
|
7878
7845
|
}
|
|
7879
|
-
|
|
7880
|
-
this.
|
|
7846
|
+
getViewConfig(config) {
|
|
7847
|
+
return Object.assign({}, this._getViewConfig(config));
|
|
7848
|
+
}
|
|
7849
|
+
/**
|
|
7850
|
+
* [内部直接获取]获取视图配置
|
|
7851
|
+
* @param config
|
|
7852
|
+
* @returns
|
|
7853
|
+
*/
|
|
7854
|
+
_getViewConfig(config) {
|
|
7855
|
+
if (config == null) {
|
|
7856
|
+
console.error(`[view] 获取视图配置,参数不能为空`);
|
|
7857
|
+
return null;
|
|
7858
|
+
}
|
|
7859
|
+
if (typeof config == "string") {
|
|
7860
|
+
if (!this._viewConfigMap.has(config)) {
|
|
7861
|
+
console.error(`[view]${config}视图配置未注册`);
|
|
7862
|
+
return null;
|
|
7863
|
+
}
|
|
7864
|
+
return this._viewConfigMap.get(config);
|
|
7865
|
+
}
|
|
7866
|
+
if ("path" in config) {
|
|
7867
|
+
return config;
|
|
7868
|
+
}
|
|
7869
|
+
let values = this._viewConfigMap.values();
|
|
7870
|
+
while (true) {
|
|
7871
|
+
let item = values.next();
|
|
7872
|
+
if (!item || item.done) {
|
|
7873
|
+
return null;
|
|
7874
|
+
}
|
|
7875
|
+
if (item.value['viewClass'] == config) {
|
|
7876
|
+
return item.value;
|
|
7877
|
+
}
|
|
7878
|
+
}
|
|
7881
7879
|
}
|
|
7882
|
-
}
|
|
7883
|
-
|
|
7884
|
-
const GC_CD = 60 * 1000;
|
|
7885
|
-
/**
|
|
7886
|
-
* 资源管理
|
|
7887
|
-
*/
|
|
7888
|
-
class ResourceManager {
|
|
7889
7880
|
constructor() {
|
|
7890
|
-
this.
|
|
7891
|
-
this.
|
|
7892
|
-
this.
|
|
7893
|
-
this.
|
|
7881
|
+
this._viewConfigMap = new Map();
|
|
7882
|
+
this._viewAnalyticsMap = new Map();
|
|
7883
|
+
this._currentStack = [];
|
|
7884
|
+
this._viewCache = new Map();
|
|
7885
|
+
this._touchLocks = new Set();
|
|
7886
|
+
if (ViewManager.created) {
|
|
7887
|
+
throw new Error("ViewManager 是单例");
|
|
7888
|
+
}
|
|
7889
|
+
ViewManager.created = true;
|
|
7894
7890
|
}
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
}
|
|
7904
|
-
return Promise.all(loadPromiseList).then((value) => {
|
|
7905
|
-
return value.length == 1 ? value[0] : value;
|
|
7906
|
-
});
|
|
7891
|
+
/**
|
|
7892
|
+
* 场景启动后设置场景,不建议手动调用
|
|
7893
|
+
* @param root
|
|
7894
|
+
*/
|
|
7895
|
+
setRoot(root) {
|
|
7896
|
+
this._viewCache.forEach((views) => {
|
|
7897
|
+
for (const view of views) {
|
|
7898
|
+
view.allDestroy();
|
|
7899
|
+
}
|
|
7907
7900
|
});
|
|
7901
|
+
this._viewCache.clear();
|
|
7902
|
+
this._currentStack.length = 0;
|
|
7903
|
+
this.event("open", root);
|
|
7904
|
+
this.reportViewAnalytics("open", root);
|
|
7905
|
+
this._scene = root;
|
|
7906
|
+
this._currentView = null;
|
|
7907
|
+
businessCenter && businessCenter.start(RewardVideoMaskBusiness);
|
|
7908
7908
|
}
|
|
7909
|
-
|
|
7909
|
+
/**
|
|
7910
|
+
* 切换场景
|
|
7911
|
+
* @param config 目标场景的配置|Class|名称
|
|
7912
|
+
* @param data
|
|
7913
|
+
* @returns
|
|
7914
|
+
*/
|
|
7915
|
+
switchScene(config, ...data) {
|
|
7910
7916
|
return __awaiter(this, void 0, void 0, function* () {
|
|
7911
|
-
|
|
7912
|
-
let
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
}
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
if (!bundle) {
|
|
7923
|
-
resolve(null);
|
|
7924
|
-
task && task.onError("preLoadScene", `加载${info.fullPath}时 bundle${info.bundle}加载失败`);
|
|
7925
|
-
}
|
|
7926
|
-
bundle.preloadScene(info.path, (error) => {
|
|
7927
|
-
if (error) {
|
|
7928
|
-
resolve(null);
|
|
7929
|
-
task && task.onError(error.name, error.message);
|
|
7930
|
-
}
|
|
7931
|
-
resolve(info.fullPath);
|
|
7932
|
-
task && task.onComplete();
|
|
7933
|
-
});
|
|
7934
|
-
});
|
|
7935
|
-
}));
|
|
7936
|
-
return Promise.all(loadPromiseList).then((value) => {
|
|
7937
|
-
return value.length > 0 ? (value.length == 1 ? value[0] : value) : null;
|
|
7938
|
-
});
|
|
7917
|
+
config = this._getViewConfig(config);
|
|
7918
|
+
let view = this.getCacheView(config);
|
|
7919
|
+
if (view) {
|
|
7920
|
+
view = yield this._switchView(view, ...data);
|
|
7921
|
+
}
|
|
7922
|
+
else {
|
|
7923
|
+
view = yield this._switchViewByConfig(config, ...data);
|
|
7924
|
+
}
|
|
7925
|
+
// this.cacheView(view);
|
|
7926
|
+
// this._currentStack.push(config);
|
|
7927
|
+
return view;
|
|
7939
7928
|
});
|
|
7940
7929
|
}
|
|
7941
|
-
|
|
7930
|
+
/**
|
|
7931
|
+
* 当前场景
|
|
7932
|
+
* @returns
|
|
7933
|
+
*/
|
|
7934
|
+
scene() {
|
|
7935
|
+
return this._scene;
|
|
7936
|
+
}
|
|
7937
|
+
/**
|
|
7938
|
+
* 开启当前场景的可交互性
|
|
7939
|
+
* @param token closeTouch返回的触摸锁令牌。传入时仅释放该锁,所有锁释放后才会真正开启触摸;不传则清空全部触摸锁并开启触摸。
|
|
7940
|
+
*/
|
|
7941
|
+
openTouch(token) {
|
|
7942
|
+
if (token) {
|
|
7943
|
+
this._touchLocks.delete(token);
|
|
7944
|
+
}
|
|
7945
|
+
else {
|
|
7946
|
+
this._touchLocks.clear();
|
|
7947
|
+
}
|
|
7948
|
+
this._applyTouchState();
|
|
7949
|
+
}
|
|
7950
|
+
/**
|
|
7951
|
+
* 关闭当前场景的可交互性
|
|
7952
|
+
* @param delay 可选参数,默认200毫秒,显示maskView的延迟时间。
|
|
7953
|
+
* @param maskViewConfig 可选参数,默认为空白,要显示的遮罩试图。
|
|
7954
|
+
* @returns 当前触摸锁令牌,可传给openTouch精确释放本次锁。
|
|
7955
|
+
*/
|
|
7956
|
+
closeTouch(delay = 200, maskViewConfig = null) {
|
|
7942
7957
|
return __awaiter(this, void 0, void 0, function* () {
|
|
7943
|
-
|
|
7944
|
-
|
|
7958
|
+
const token = this._lockTouch();
|
|
7959
|
+
let config = maskViewConfig == null ? this._defaultMaskViewConfig : this._getViewConfig(maskViewConfig);
|
|
7960
|
+
if (!config) {
|
|
7961
|
+
return token;
|
|
7945
7962
|
}
|
|
7946
|
-
if (
|
|
7947
|
-
|
|
7963
|
+
if (delay <= 0) {
|
|
7964
|
+
yield this._showMaskView(config, token);
|
|
7965
|
+
return token;
|
|
7948
7966
|
}
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
if (error) {
|
|
7952
|
-
resolve(null);
|
|
7953
|
-
task && task.onError(error.name, error.message);
|
|
7954
|
-
}
|
|
7955
|
-
else {
|
|
7956
|
-
resolve(info.fullPath);
|
|
7957
|
-
task && task.onComplete();
|
|
7958
|
-
}
|
|
7959
|
-
});
|
|
7960
|
-
});
|
|
7967
|
+
timer.once(delay, this, this._showMaskView, [config, token]);
|
|
7968
|
+
return token;
|
|
7961
7969
|
});
|
|
7962
7970
|
}
|
|
7963
|
-
|
|
7971
|
+
_lockTouch() {
|
|
7972
|
+
const token = Symbol("touch-lock");
|
|
7973
|
+
this._touchLocks.add(token);
|
|
7974
|
+
this._applyTouchState();
|
|
7975
|
+
return token;
|
|
7976
|
+
}
|
|
7977
|
+
_applyTouchState() {
|
|
7978
|
+
const locked = this._touchLocks.size > 0;
|
|
7979
|
+
if (!locked) {
|
|
7980
|
+
timer.clear(this, this._showMaskView);
|
|
7981
|
+
if (this._currentMaskView) {
|
|
7982
|
+
this._currentMaskView.removeFromParent(true);
|
|
7983
|
+
this._currentMaskView = null;
|
|
7984
|
+
}
|
|
7985
|
+
}
|
|
7986
|
+
if (this._scene) {
|
|
7987
|
+
this._scene.touchEnabled = !locked;
|
|
7988
|
+
}
|
|
7989
|
+
}
|
|
7990
|
+
_showMaskView(maskViewConfig, token) {
|
|
7964
7991
|
return __awaiter(this, void 0, void 0, function* () {
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
task && task.onError("_preLoadFromBundle", `加载${info.fullPath}时 bundle${info.bundle}加载失败`);
|
|
7968
|
-
return null;
|
|
7992
|
+
if (!this._scene || !this._touchLocks.has(token) || this._currentMaskView) {
|
|
7993
|
+
return;
|
|
7969
7994
|
}
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7973
|
-
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7978
|
-
|
|
7979
|
-
|
|
7980
|
-
|
|
7981
|
-
|
|
7982
|
-
|
|
7983
|
-
|
|
7984
|
-
if (
|
|
7985
|
-
|
|
7986
|
-
}
|
|
7987
|
-
else if (!info.isDir) {
|
|
7988
|
-
bundle.preload(info.path, onProgress, onComplete);
|
|
7989
|
-
}
|
|
7990
|
-
else {
|
|
7991
|
-
bundle.preloadDir(info.path, onProgress, onComplete);
|
|
7995
|
+
let view = this.getCacheView(maskViewConfig);
|
|
7996
|
+
if (view) {
|
|
7997
|
+
view = yield this._addView(view, this._scene);
|
|
7998
|
+
}
|
|
7999
|
+
else {
|
|
8000
|
+
view = yield this._loadViewByConfig(maskViewConfig, this._scene, "显示遮罩视图错误");
|
|
8001
|
+
this.cacheView(view);
|
|
8002
|
+
}
|
|
8003
|
+
if (!this._touchLocks.has(token)) {
|
|
8004
|
+
view.removeFromParent(true);
|
|
8005
|
+
return;
|
|
8006
|
+
}
|
|
8007
|
+
this._currentMaskView = view;
|
|
8008
|
+
timer.frameNext(this, () => {
|
|
8009
|
+
if (this._currentMaskView == view && this._touchLocks.has(token)) {
|
|
8010
|
+
view.setData();
|
|
7992
8011
|
}
|
|
7993
8012
|
});
|
|
7994
8013
|
});
|
|
7995
8014
|
}
|
|
7996
|
-
|
|
8015
|
+
/**
|
|
8016
|
+
* 当前主视图
|
|
8017
|
+
* @returns
|
|
8018
|
+
*/
|
|
8019
|
+
view() {
|
|
8020
|
+
return this._currentView;
|
|
8021
|
+
}
|
|
8022
|
+
/**
|
|
8023
|
+
* 切换主视图到目标视图
|
|
8024
|
+
* @param target 目标视图的配置|Class|名称
|
|
8025
|
+
* @param datas 目标视图初始化参数
|
|
8026
|
+
*/
|
|
8027
|
+
switchTo(config, ...data) {
|
|
7997
8028
|
return __awaiter(this, void 0, void 0, function* () {
|
|
7998
|
-
|
|
7999
|
-
|
|
8000
|
-
|
|
8001
|
-
});
|
|
8002
|
-
let result = [];
|
|
8003
|
-
for (const info of pathInfoList) {
|
|
8004
|
-
if (!info.isRemote) {
|
|
8005
|
-
let assets = yield this._loadFromBundle(info, assetType, task);
|
|
8006
|
-
if (assets instanceof cc.Asset) {
|
|
8007
|
-
result.push(assets);
|
|
8008
|
-
}
|
|
8009
|
-
else {
|
|
8010
|
-
result.push(...assets);
|
|
8011
|
-
}
|
|
8012
|
-
continue;
|
|
8013
|
-
}
|
|
8014
|
-
let asset = yield this._loadfromRemote(info, task);
|
|
8015
|
-
if (assetType === cc.SpriteFrame) {
|
|
8016
|
-
asset = cc.SpriteFrame.createWithImage(asset);
|
|
8017
|
-
}
|
|
8018
|
-
result.push(asset);
|
|
8029
|
+
config = this._getViewConfig(config);
|
|
8030
|
+
if (!this._scene) {
|
|
8031
|
+
throw new Error("根View不存在");
|
|
8019
8032
|
}
|
|
8020
|
-
|
|
8033
|
+
let view = this.getCacheView(config);
|
|
8034
|
+
if (view) {
|
|
8035
|
+
view = yield this._switchView(view, ...data);
|
|
8036
|
+
}
|
|
8037
|
+
else {
|
|
8038
|
+
view = yield this._switchViewByConfig(config, ...data);
|
|
8039
|
+
}
|
|
8040
|
+
this.cacheView(view);
|
|
8041
|
+
this._currentStack.push(config);
|
|
8042
|
+
return view;
|
|
8021
8043
|
});
|
|
8022
8044
|
}
|
|
8023
|
-
|
|
8045
|
+
/**
|
|
8046
|
+
* 切回当前主视图到上一个主视图。
|
|
8047
|
+
* @param data
|
|
8048
|
+
* @returns
|
|
8049
|
+
*/
|
|
8050
|
+
switchBack(...data) {
|
|
8024
8051
|
return __awaiter(this, void 0, void 0, function* () {
|
|
8025
|
-
|
|
8026
|
-
|
|
8027
|
-
task && task.onError("_loadFromBundle", `加载${info.fullPath}时 bundle${info.bundle}加载失败`);
|
|
8052
|
+
if (this._currentStack.length == 0) {
|
|
8053
|
+
console.warn("上一个视图不存在");
|
|
8028
8054
|
return null;
|
|
8029
8055
|
}
|
|
8030
|
-
|
|
8031
|
-
|
|
8032
|
-
|
|
8033
|
-
|
|
8034
|
-
|
|
8056
|
+
//移除当前视图config
|
|
8057
|
+
this._currentStack.pop();
|
|
8058
|
+
//获取之前视图config
|
|
8059
|
+
let lastViewConfig = this._currentStack.pop();
|
|
8060
|
+
if (!lastViewConfig) {
|
|
8061
|
+
console.warn("上个主视图为空,");
|
|
8062
|
+
return null;
|
|
8035
8063
|
}
|
|
8036
|
-
|
|
8037
|
-
let onProgress = (finish, total) => {
|
|
8038
|
-
task && task.onProgress(finish / total);
|
|
8039
|
-
};
|
|
8040
|
-
let onComplete = (error, assets) => {
|
|
8041
|
-
if (error) {
|
|
8042
|
-
console.error("加载资源发生错误", info, error);
|
|
8043
|
-
resolve(null);
|
|
8044
|
-
task && task.onError(error.name, error.message);
|
|
8045
|
-
}
|
|
8046
|
-
else {
|
|
8047
|
-
resolve(assets);
|
|
8048
|
-
task && task.onComplete();
|
|
8049
|
-
}
|
|
8050
|
-
};
|
|
8051
|
-
if (info.path == "") {
|
|
8052
|
-
onComplete(null, null);
|
|
8053
|
-
}
|
|
8054
|
-
else if (!info.isDir) {
|
|
8055
|
-
bundle.load(info.path, type, onProgress, onComplete);
|
|
8056
|
-
}
|
|
8057
|
-
else {
|
|
8058
|
-
bundle.loadDir(info.path, type, onProgress, onComplete);
|
|
8059
|
-
}
|
|
8060
|
-
});
|
|
8061
|
-
this._loadPromiseMap.set(info.fullPath, promise);
|
|
8062
|
-
return promise;
|
|
8064
|
+
return yield this.switchTo(lastViewConfig, ...data);
|
|
8063
8065
|
});
|
|
8064
8066
|
}
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
|
|
8080
|
-
|
|
8081
|
-
|
|
8082
|
-
|
|
8083
|
-
|
|
8084
|
-
}
|
|
8067
|
+
_switchView(view, ...datas) {
|
|
8068
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8069
|
+
this._currentView && this._currentView.removeFromParent(!this._currentView.config.cache);
|
|
8070
|
+
this._currentView = null;
|
|
8071
|
+
this._currentView = view;
|
|
8072
|
+
this._scene.addView(this._currentView, view.config.zIndex);
|
|
8073
|
+
this._currentView.setData(...datas);
|
|
8074
|
+
return this._currentView;
|
|
8075
|
+
});
|
|
8076
|
+
}
|
|
8077
|
+
_switchViewByConfig(viewConfig, ...datas) {
|
|
8078
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8079
|
+
const touchToken = this._lockTouch();
|
|
8080
|
+
let loader;
|
|
8081
|
+
try {
|
|
8082
|
+
loader = yield this.loadView(viewConfig);
|
|
8083
|
+
}
|
|
8084
|
+
catch (error) {
|
|
8085
|
+
this.openTouch(touchToken);
|
|
8086
|
+
console.error(`切换视图错误 code:${error.code}, msg:${error.msg || error.message}`);
|
|
8087
|
+
throw new Error(`切换视图错误 code:${error.code}, msg:${error.msg || error.message}`);
|
|
8088
|
+
}
|
|
8089
|
+
let name = viewConfig.name || viewConfig.path.substring(viewConfig.path.lastIndexOf("/") + 1);
|
|
8090
|
+
this._currentView && this._currentView.removeFromParent(!this._currentView.config.cache);
|
|
8091
|
+
this._currentView = null;
|
|
8092
|
+
let view = loader.initView(name, true);
|
|
8093
|
+
view.name = name;
|
|
8094
|
+
view.config = viewConfig;
|
|
8095
|
+
view.analyticsInfo = this._viewAnalyticsMap.get(viewConfig.name);
|
|
8096
|
+
if (view['addToBG']) {
|
|
8097
|
+
this.setRoot(view);
|
|
8098
|
+
}
|
|
8099
|
+
else {
|
|
8100
|
+
this._currentView = view;
|
|
8101
|
+
this._scene.addView(view, viewConfig.zIndex);
|
|
8102
|
+
}
|
|
8103
|
+
timer.frameNext(this, () => {
|
|
8104
|
+
this.openTouch(touchToken);
|
|
8105
|
+
view.setData(...datas);
|
|
8085
8106
|
});
|
|
8107
|
+
return view;
|
|
8086
8108
|
});
|
|
8087
|
-
this._loadPromiseMap.set(info.fullPath, promise);
|
|
8088
|
-
return promise;
|
|
8089
|
-
}
|
|
8090
|
-
/**
|
|
8091
|
-
* 解析资源路径成PathInfo
|
|
8092
|
-
* @param fullPath - 资源路径应该符合bundle://cc.path/to/resource格式
|
|
8093
|
-
* @returns - `PathInfo` 资源信息
|
|
8094
|
-
*/
|
|
8095
|
-
parsePath(fullPath) {
|
|
8096
|
-
let tempPath = fullPath.split("://");
|
|
8097
|
-
if (tempPath.length != 2) {
|
|
8098
|
-
throw new Error(`资源地址${fullPath}格式错误,应该符合bundle://cc.path/to/resource格式`); //.suffix
|
|
8099
|
-
}
|
|
8100
|
-
let isDir = fullPath.charAt(fullPath.length - 1) == "/";
|
|
8101
|
-
let bundle = tempPath[0];
|
|
8102
|
-
let isRemote = bundle === "https" || bundle === "http";
|
|
8103
|
-
let suffix = cc.path.extname(fullPath).toLowerCase();
|
|
8104
|
-
let simplePath = suffix == "" ? tempPath[1] : tempPath[1].replace(suffix, "");
|
|
8105
|
-
return { bundle, path: simplePath, isRemote, isDir, fullPath };
|
|
8106
|
-
}
|
|
8107
|
-
/**
|
|
8108
|
-
* 获取目标bundle的资源的完整路径
|
|
8109
|
-
* @param bundleName - 资源所在bundle名称
|
|
8110
|
-
* @param subPath - 可选参数, 相对子路径
|
|
8111
|
-
* @returns
|
|
8112
|
-
*/
|
|
8113
|
-
getPath(bundleName, subPath = "") {
|
|
8114
|
-
if (subPath.includes("://")) {
|
|
8115
|
-
return subPath;
|
|
8116
|
-
}
|
|
8117
|
-
return `${bundleName}://${subPath}`;
|
|
8118
8109
|
}
|
|
8119
8110
|
/**
|
|
8120
|
-
*
|
|
8121
|
-
* @param
|
|
8122
|
-
* @
|
|
8111
|
+
* 通过视图配置添加视图
|
|
8112
|
+
* @param viewConfig 要添加的视图配置|Class|名称
|
|
8113
|
+
* @param parent 父级视图,默认为当前主视图,即viewMananger.current()
|
|
8114
|
+
* @param datas 传入setData的数据
|
|
8123
8115
|
*/
|
|
8124
|
-
|
|
8125
|
-
return this
|
|
8116
|
+
addView(config, parent, ...datas) {
|
|
8117
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8118
|
+
config = this._getViewConfig(config);
|
|
8119
|
+
parent = parent || this._currentView;
|
|
8120
|
+
if (!parent) {
|
|
8121
|
+
throw new Error("当前View不存在, 且未传入父级视图");
|
|
8122
|
+
}
|
|
8123
|
+
let view = this.getCacheView(config);
|
|
8124
|
+
if (view) {
|
|
8125
|
+
view = yield this._addView(view, parent, ...datas);
|
|
8126
|
+
}
|
|
8127
|
+
else {
|
|
8128
|
+
view = yield this._addViewbyConfig(config, parent, ...datas);
|
|
8129
|
+
}
|
|
8130
|
+
this.cacheView(view);
|
|
8131
|
+
return view;
|
|
8132
|
+
});
|
|
8126
8133
|
}
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
return this.getPath("resources", subPath);
|
|
8134
|
+
_addView(view, parent, ...datas) {
|
|
8135
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8136
|
+
parent.addView(view, view.config.zIndex);
|
|
8137
|
+
view.setData(...datas);
|
|
8138
|
+
return view;
|
|
8139
|
+
});
|
|
8134
8140
|
}
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
this._removeBundleFromReleaseMap(bundleName);
|
|
8142
|
-
this._startGC();
|
|
8143
|
-
if (this._loadBunldePromiseMap.has(bundleName)) {
|
|
8144
|
-
return this._loadBunldePromiseMap.get(bundleName);
|
|
8145
|
-
}
|
|
8146
|
-
let promise = new Promise((resolve) => {
|
|
8147
|
-
let bundle = cc.assetManager.getBundle(bundleName);
|
|
8148
|
-
if (!!bundle) {
|
|
8149
|
-
resolve(bundle);
|
|
8150
|
-
return;
|
|
8141
|
+
_addViewbyConfig(config, parent, ...datas) {
|
|
8142
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
8143
|
+
const touchToken = this._lockTouch();
|
|
8144
|
+
let view;
|
|
8145
|
+
try {
|
|
8146
|
+
view = yield this._loadViewByConfig(config, parent, "添加视图错误");
|
|
8151
8147
|
}
|
|
8152
|
-
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
|
|
8156
|
-
|
|
8157
|
-
|
|
8158
|
-
|
|
8159
|
-
resolve(bundle);
|
|
8160
|
-
}
|
|
8148
|
+
catch (error) {
|
|
8149
|
+
this.openTouch(touchToken);
|
|
8150
|
+
throw error;
|
|
8151
|
+
}
|
|
8152
|
+
timer.frameNext(this, () => {
|
|
8153
|
+
this.openTouch(touchToken);
|
|
8154
|
+
view.setData(...datas);
|
|
8161
8155
|
});
|
|
8156
|
+
return view;
|
|
8162
8157
|
});
|
|
8163
|
-
this._loadBunldePromiseMap.set(bundleName, promise);
|
|
8164
|
-
return promise;
|
|
8165
8158
|
}
|
|
8166
|
-
|
|
8167
|
-
* bundle是否被加载过,且有效
|
|
8168
|
-
* @param bundleName
|
|
8169
|
-
* @returns
|
|
8170
|
-
*/
|
|
8171
|
-
isBundleValid(bundleName) {
|
|
8159
|
+
_loadViewByConfig(config, parent, errorPrefix) {
|
|
8172
8160
|
return __awaiter(this, void 0, void 0, function* () {
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8161
|
+
let loader;
|
|
8162
|
+
try {
|
|
8163
|
+
loader = yield this.loadView(config);
|
|
8176
8164
|
}
|
|
8177
|
-
|
|
8165
|
+
catch (error) {
|
|
8166
|
+
console.error(`${errorPrefix} code:${error.code}, msg:${error.msg || error.message}`);
|
|
8167
|
+
throw new Error(`${errorPrefix} code:${error.code}, msg:${error.msg || error.message}`);
|
|
8168
|
+
}
|
|
8169
|
+
let name = config.name || config.path.substring(config.path.lastIndexOf("/") + 1);
|
|
8170
|
+
let view = loader.initView(name, true);
|
|
8171
|
+
view.name = name;
|
|
8172
|
+
view.config = config;
|
|
8173
|
+
view.analyticsInfo = this._viewAnalyticsMap.get(config.name);
|
|
8174
|
+
parent.addView(view, config.zIndex);
|
|
8175
|
+
return view;
|
|
8178
8176
|
});
|
|
8179
8177
|
}
|
|
8180
8178
|
/**
|
|
8181
|
-
*
|
|
8182
|
-
* @param
|
|
8183
|
-
* @param
|
|
8184
|
-
* @returns
|
|
8179
|
+
* 加载视图到内存,之后还需要调用loader.initView接口获取view
|
|
8180
|
+
* @param config 要加载的视图配置|Class|名称
|
|
8181
|
+
* @param task 任务载体
|
|
8185
8182
|
*/
|
|
8186
|
-
|
|
8187
|
-
return
|
|
8188
|
-
|
|
8189
|
-
|
|
8190
|
-
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8183
|
+
loadView(config, task) {
|
|
8184
|
+
return new Promise((resolve, reject) => {
|
|
8185
|
+
config = this._getViewConfig(config);
|
|
8186
|
+
let loader = this.impl.getLoader(config).init(config);
|
|
8187
|
+
task = task || new Task();
|
|
8188
|
+
task.once(Task.Event.COMPLETE, this, () => {
|
|
8189
|
+
resolve(loader);
|
|
8190
|
+
});
|
|
8191
|
+
task.once(Task.Event.ERROR, this, (type, task, reason) => {
|
|
8192
|
+
reject(reason);
|
|
8193
|
+
});
|
|
8194
|
+
loader.load(task);
|
|
8197
8195
|
});
|
|
8198
8196
|
}
|
|
8199
8197
|
/**
|
|
8200
|
-
*
|
|
8201
|
-
* @param
|
|
8198
|
+
* 获取缓存视图
|
|
8199
|
+
* @param config
|
|
8200
|
+
* @returns
|
|
8202
8201
|
*/
|
|
8203
|
-
|
|
8204
|
-
|
|
8205
|
-
|
|
8206
|
-
|
|
8202
|
+
getCacheView(config) {
|
|
8203
|
+
config = this._getViewConfig(config);
|
|
8204
|
+
let views = this._viewCache.get(config.path);
|
|
8205
|
+
if (!views || views.length == 0) {
|
|
8206
|
+
return null;
|
|
8207
|
+
}
|
|
8208
|
+
for (const view of views) {
|
|
8209
|
+
if (!view.inStage) {
|
|
8210
|
+
return view;
|
|
8211
|
+
}
|
|
8207
8212
|
}
|
|
8213
|
+
return null;
|
|
8208
8214
|
}
|
|
8209
8215
|
/**
|
|
8210
|
-
*
|
|
8211
|
-
* @param
|
|
8216
|
+
* 缓存视图
|
|
8217
|
+
* @param view
|
|
8218
|
+
* @param force 默认为false,不考虑view.config.cache的值,强制增加到缓存
|
|
8212
8219
|
* @returns
|
|
8213
8220
|
*/
|
|
8214
|
-
|
|
8215
|
-
if (
|
|
8216
|
-
|
|
8221
|
+
cacheView(view, force = false) {
|
|
8222
|
+
if (!view || !view.config || (!view.config.cache && !force)) {
|
|
8223
|
+
return false;
|
|
8217
8224
|
}
|
|
8218
|
-
|
|
8225
|
+
let views = this._viewCache.get(view.config.path);
|
|
8226
|
+
if (!views) {
|
|
8227
|
+
views = [view];
|
|
8228
|
+
this._viewCache.set(view.config.path, views);
|
|
8229
|
+
return true;
|
|
8230
|
+
}
|
|
8231
|
+
else if (!views.includes(view)) {
|
|
8232
|
+
views.push(view);
|
|
8233
|
+
return true;
|
|
8234
|
+
}
|
|
8235
|
+
return false;
|
|
8219
8236
|
}
|
|
8220
8237
|
/**
|
|
8221
|
-
*
|
|
8222
|
-
* @param
|
|
8238
|
+
* 从缓存列表中移除视图。
|
|
8239
|
+
* @param view
|
|
8223
8240
|
* @returns
|
|
8224
8241
|
*/
|
|
8225
|
-
|
|
8226
|
-
if (
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
bundle.releaseAll();
|
|
8237
|
-
cc.assetManager.removeBundle(bundle);
|
|
8238
|
-
}
|
|
8239
|
-
//删除等待移除的bundle
|
|
8240
|
-
this._waitToReleaseBundles.delete(bundle.name);
|
|
8242
|
+
cancelCache(view) {
|
|
8243
|
+
if (!view || !view.config || !view.config.path) {
|
|
8244
|
+
return false;
|
|
8245
|
+
}
|
|
8246
|
+
let views = this._viewCache.get(view.config.path);
|
|
8247
|
+
if (!views || views.length == 0) {
|
|
8248
|
+
return false;
|
|
8249
|
+
}
|
|
8250
|
+
const index = views.indexOf(view);
|
|
8251
|
+
if (index != -1) {
|
|
8252
|
+
views.splice(index, 1);
|
|
8241
8253
|
return true;
|
|
8242
8254
|
}
|
|
8243
8255
|
return false;
|
|
8244
8256
|
}
|
|
8245
8257
|
/**
|
|
8246
|
-
*
|
|
8247
|
-
* @
|
|
8258
|
+
* [快捷方式]增加视图打开的事件监听
|
|
8259
|
+
* @param targetView 目标视图Class|名称
|
|
8260
|
+
* @param listener 响应回调
|
|
8261
|
+
* @param caller 回调this
|
|
8262
|
+
* @param once 是否只监听对应视图打开一次。
|
|
8263
|
+
* @param args 其他参数
|
|
8248
8264
|
*/
|
|
8249
|
-
|
|
8250
|
-
|
|
8251
|
-
|
|
8252
|
-
|
|
8253
|
-
this.
|
|
8254
|
-
|
|
8265
|
+
onViewOpen(targetView, caller, listener, once = false, ...args) {
|
|
8266
|
+
this._viewOpenEventMap = this._viewOpenEventMap || new Map();
|
|
8267
|
+
this._viewOpenEventMap.set(listener, { event: "open", viewConfig: this._getViewConfig(targetView), caller, listener, once, args });
|
|
8268
|
+
this.offViewEvent("open", this, this._onViewOpen);
|
|
8269
|
+
this.onViewEvent("open", this, this._onViewOpen);
|
|
8270
|
+
}
|
|
8271
|
+
_onViewOpen(viewName, ...args) {
|
|
8272
|
+
this._viewOpenEventMap.forEach((value, key) => {
|
|
8273
|
+
if (value.viewConfig.name == viewName) {
|
|
8274
|
+
value.listener.apply(value.caller, value.args);
|
|
8275
|
+
value.once && this._viewOpenEventMap.delete(key);
|
|
8276
|
+
}
|
|
8277
|
+
});
|
|
8255
8278
|
}
|
|
8256
8279
|
/**
|
|
8257
|
-
*
|
|
8280
|
+
* [快捷方式]移除视图打开的事件监听
|
|
8281
|
+
* @param listener
|
|
8258
8282
|
* @returns
|
|
8259
8283
|
*/
|
|
8260
|
-
|
|
8261
|
-
|
|
8262
|
-
if (count == 0) {
|
|
8263
|
-
return;
|
|
8264
|
-
}
|
|
8265
|
-
const now = Date.now();
|
|
8266
|
-
this._waitToReleaseBundles.forEach((bundle) => {
|
|
8267
|
-
console.log(`[GCBundle] Remove Bundle:${bundle.name}`);
|
|
8268
|
-
this._onRemoveBundle(bundle);
|
|
8269
|
-
});
|
|
8270
|
-
this._waitToReleaseBundles.clear();
|
|
8271
|
-
console.log(`[GCBundle] [${count}] cost:${Date.now() - now} milliseconds`);
|
|
8284
|
+
offViewOpen(listener) {
|
|
8285
|
+
return this._viewOpenEventMap && this._viewOpenEventMap.delete(listener);
|
|
8272
8286
|
}
|
|
8273
8287
|
/**
|
|
8274
|
-
*
|
|
8275
|
-
* @param
|
|
8288
|
+
* [快捷方式]增加视图关闭的事件监听
|
|
8289
|
+
* @param targetView 目标视图Class|名称
|
|
8290
|
+
* @param listener 响应回调
|
|
8291
|
+
* @param caller 回调this
|
|
8292
|
+
* @param once 是否只监听对应视图关闭一次。
|
|
8293
|
+
* @param args 其他参数
|
|
8276
8294
|
*/
|
|
8277
|
-
|
|
8278
|
-
this.
|
|
8279
|
-
|
|
8280
|
-
|
|
8281
|
-
|
|
8295
|
+
onViewClose(targetView, caller, listener, once = false, ...args) {
|
|
8296
|
+
this._viewCloseEventMap = this._viewCloseEventMap || new Map();
|
|
8297
|
+
this._viewCloseEventMap.set(listener, { event: "close", viewConfig: this._getViewConfig(targetView), caller, listener, once, args });
|
|
8298
|
+
this.offViewEvent("close", this, this._onViewClose);
|
|
8299
|
+
this.onViewEvent("close", this, this._onViewClose);
|
|
8282
8300
|
}
|
|
8283
8301
|
/**
|
|
8284
|
-
*
|
|
8285
|
-
* @param
|
|
8302
|
+
* [快捷方式]移除视图关闭的事件监听
|
|
8303
|
+
* @param listener
|
|
8286
8304
|
* @returns
|
|
8287
8305
|
*/
|
|
8288
|
-
|
|
8289
|
-
return this.
|
|
8306
|
+
offViewClose(listener) {
|
|
8307
|
+
return this._viewCloseEventMap && this._viewCloseEventMap.delete(listener);
|
|
8290
8308
|
}
|
|
8291
|
-
|
|
8292
|
-
|
|
8293
|
-
|
|
8294
|
-
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
constructor() {
|
|
8299
|
-
this._audioNode = null;
|
|
8300
|
-
this._audioSource = null;
|
|
8301
|
-
this._onFinishCallBack = null;
|
|
8302
|
-
this._audioNode = cc.find("__audioNode__");
|
|
8303
|
-
if (!this._audioNode) {
|
|
8304
|
-
this._audioNode = new cc.Node();
|
|
8305
|
-
this._audioNode.name = '__audioNode__';
|
|
8306
|
-
cc.director.getScene().addChild(this._audioNode);
|
|
8307
|
-
cc.director.addPersistRootNode(this._audioNode);
|
|
8308
|
-
}
|
|
8309
|
-
this._audioSource = this._audioNode.addComponent(cc.AudioSource);
|
|
8309
|
+
_onViewClose(viewName, ...args) {
|
|
8310
|
+
this._viewCloseEventMap.forEach((value, key) => {
|
|
8311
|
+
if (value.viewConfig.name == viewName) {
|
|
8312
|
+
value.listener.apply(value.caller, value.args.concat(args));
|
|
8313
|
+
value.once && this._viewCloseEventMap.delete(key);
|
|
8314
|
+
}
|
|
8315
|
+
});
|
|
8310
8316
|
}
|
|
8311
8317
|
/**
|
|
8312
|
-
*
|
|
8318
|
+
* 增加视图事件监听
|
|
8319
|
+
* @param event 视图事件名称
|
|
8320
|
+
* @param caller 回调this
|
|
8321
|
+
* @param listener 响应回调
|
|
8322
|
+
* @param once 是否只监听对应视图关闭一次。
|
|
8323
|
+
* @param args 其他参数
|
|
8313
8324
|
*/
|
|
8314
|
-
|
|
8315
|
-
if (!this.
|
|
8316
|
-
|
|
8325
|
+
onViewEvent(event, caller, listener, once = true, ...args) {
|
|
8326
|
+
if (!this._viewEvent) {
|
|
8327
|
+
this._viewEvent = new EventDispatcher();
|
|
8317
8328
|
}
|
|
8318
|
-
|
|
8319
|
-
|
|
8320
|
-
|
|
8321
|
-
|
|
8322
|
-
|
|
8323
|
-
get volume() {
|
|
8324
|
-
if (!this._audioNode || !this._audioSource) {
|
|
8325
|
-
return 1;
|
|
8329
|
+
if (once) {
|
|
8330
|
+
this._viewEvent.once(event, caller, listener, args);
|
|
8331
|
+
}
|
|
8332
|
+
else {
|
|
8333
|
+
this._viewEvent.on(event, caller, listener, args);
|
|
8326
8334
|
}
|
|
8327
|
-
return this._audioSource.volume;
|
|
8328
8335
|
}
|
|
8329
8336
|
/**
|
|
8330
|
-
*
|
|
8331
|
-
* @param
|
|
8332
|
-
* @param
|
|
8333
|
-
* @param
|
|
8334
|
-
* @param onFinishCallBack
|
|
8337
|
+
* 移除视图事件监听
|
|
8338
|
+
* @param event 事件类型
|
|
8339
|
+
* @param caller 事件侦听函数的执行域。
|
|
8340
|
+
* @param listener 事件侦听函数。
|
|
8335
8341
|
* @returns
|
|
8336
8342
|
*/
|
|
8337
|
-
|
|
8338
|
-
this.
|
|
8339
|
-
|
|
8343
|
+
offViewEvent(event, caller, listener) {
|
|
8344
|
+
if (!this._viewEvent) {
|
|
8345
|
+
return;
|
|
8346
|
+
}
|
|
8347
|
+
this._viewEvent.off(event, caller, listener);
|
|
8340
8348
|
}
|
|
8341
8349
|
/**
|
|
8342
|
-
*
|
|
8343
|
-
* @param
|
|
8344
|
-
* @param
|
|
8345
|
-
* @param loop
|
|
8346
|
-
* @param onFinishCallBack
|
|
8347
|
-
* @returns
|
|
8350
|
+
* 广播视图事件
|
|
8351
|
+
* @param event 视图事件
|
|
8352
|
+
* @param view 视图
|
|
8348
8353
|
*/
|
|
8349
|
-
|
|
8350
|
-
this.
|
|
8351
|
-
|
|
8352
|
-
|
|
8353
|
-
|
|
8354
|
-
this._onFinishCallBack = onFinishCallBack;
|
|
8355
|
-
this._audioNode.on(cc.AudioSource.EventType.ENDED, this._onAudioEnded, this);
|
|
8356
|
-
this._audioSource.play();
|
|
8357
|
-
return this;
|
|
8354
|
+
event(event, view, ...args) {
|
|
8355
|
+
if (this._viewEvent) {
|
|
8356
|
+
args.unshift(view.name);
|
|
8357
|
+
this._viewEvent.event(event, args);
|
|
8358
|
+
}
|
|
8358
8359
|
}
|
|
8359
8360
|
/**
|
|
8360
|
-
*
|
|
8361
|
-
* @
|
|
8361
|
+
* 上报视图统计数据(open\close\...)
|
|
8362
|
+
* @param event 事件
|
|
8363
|
+
* @param view 视图
|
|
8364
|
+
* @param data 上报附带信息
|
|
8362
8365
|
*/
|
|
8363
|
-
|
|
8364
|
-
|
|
8365
|
-
|
|
8366
|
-
|
|
8367
|
-
|
|
8368
|
-
|
|
8369
|
-
|
|
8366
|
+
reportViewAnalytics(event, view, data) {
|
|
8367
|
+
let maskViewconfig = this._currentMaskView && this._currentMaskView.config;
|
|
8368
|
+
if (maskViewconfig && view.name == maskViewconfig.name) {
|
|
8369
|
+
return;
|
|
8370
|
+
}
|
|
8371
|
+
let analyticsInfo = this._viewAnalyticsMap.get(view.name);
|
|
8372
|
+
if (analyticsInfo) {
|
|
8373
|
+
data = data || (view.getAnalyticsDataOnViewEvent && view.getAnalyticsDataOnViewEvent(event)) || {};
|
|
8374
|
+
data.action = event;
|
|
8375
|
+
data.name = analyticsInfo.name;
|
|
8376
|
+
data.group = analyticsInfo.group || "default";
|
|
8377
|
+
//open:进入时刻, close:停留时长
|
|
8378
|
+
data.stay = Math.floor((App.durationOfLaunch - (analyticsInfo.lastOpenTime || 0)) / 1000);
|
|
8379
|
+
analytics.base.report("view", data);
|
|
8380
|
+
analyticsInfo.lastOpenTime = event == "open" ? App.durationOfLaunch : 0;
|
|
8381
|
+
}
|
|
8370
8382
|
}
|
|
8371
|
-
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
stop && this.stop();
|
|
8380
|
-
resolve(this);
|
|
8381
|
-
}).start();
|
|
8382
|
-
});
|
|
8383
|
+
get impl() {
|
|
8384
|
+
if (this._impl == null) {
|
|
8385
|
+
this._impl = Injector.getInject(ViewManager.KEY);
|
|
8386
|
+
}
|
|
8387
|
+
if (this._impl == null) {
|
|
8388
|
+
throw new Error(ViewManager.KEY + "未注入!");
|
|
8389
|
+
}
|
|
8390
|
+
return this._impl;
|
|
8383
8391
|
}
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8392
|
+
}
|
|
8393
|
+
ViewManager.KEY = "ViewManager";
|
|
8394
|
+
ViewManager.created = false;
|
|
8395
|
+
/**
|
|
8396
|
+
* 视图管理器
|
|
8397
|
+
*/
|
|
8398
|
+
const viewManager = new ViewManager();
|
|
8399
|
+
|
|
8400
|
+
class INativeHelper {
|
|
8401
|
+
constructor() {
|
|
8402
|
+
this._callbackCount = 0;
|
|
8403
|
+
}
|
|
8404
|
+
call(className, methodName, ...args) {
|
|
8405
|
+
this.callWithReturnType(className, methodName, null, ...args);
|
|
8406
|
+
}
|
|
8407
|
+
registerCallback(caller, method, times, ...args) {
|
|
8408
|
+
if (caller == null || method == null) {
|
|
8409
|
+
return "";
|
|
8410
|
+
}
|
|
8411
|
+
++this._callbackCount;
|
|
8412
|
+
let callbackName = 'NativeHelper.callback' + this._callbackCount;
|
|
8413
|
+
window[callbackName] = () => {
|
|
8414
|
+
method.apply(caller, args);
|
|
8415
|
+
if (--times <= 0) {
|
|
8416
|
+
window[callbackName] = null;
|
|
8417
|
+
}
|
|
8418
|
+
};
|
|
8419
|
+
return `window['${callbackName}']()`;
|
|
8420
|
+
}
|
|
8421
|
+
}
|
|
8422
|
+
|
|
8423
|
+
/**
|
|
8424
|
+
@name: NativeHelper
|
|
8425
|
+
@desc: cocos 2.4.x 下nativeHelper
|
|
8426
|
+
@author: timoo
|
|
8427
|
+
@date: 2022/12/02
|
|
8428
|
+
*/
|
|
8429
|
+
class CocosNativeHelper extends INativeHelper {
|
|
8430
|
+
callWithReturnType(className, methodName, returnType, ...args) {
|
|
8431
|
+
if (!className) {
|
|
8390
8432
|
return;
|
|
8391
8433
|
}
|
|
8392
|
-
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8396
|
-
* @returns
|
|
8397
|
-
*/
|
|
8398
|
-
resume() {
|
|
8399
|
-
if (!this._audioNode || !this._audioSource) {
|
|
8400
|
-
return;
|
|
8434
|
+
if (cc.sys.os == cc.sys.OS.ANDROID) {
|
|
8435
|
+
let argsSig = this.getArgsSig(args, returnType);
|
|
8436
|
+
console.log("callWithReturnType:", className, methodName, argsSig, args.join(","));
|
|
8437
|
+
return cc.native.reflection.callStaticMethod(className, methodName, argsSig, ...args);
|
|
8401
8438
|
}
|
|
8402
|
-
|
|
8403
|
-
}
|
|
8404
|
-
/**
|
|
8405
|
-
* 渐进停止
|
|
8406
|
-
* @returns
|
|
8407
|
-
*/
|
|
8408
|
-
stopFade() {
|
|
8409
|
-
return this.fedeOut(true).then(() => { });
|
|
8439
|
+
else if (cc.sys.os == cc.sys.OS.IOS) ;
|
|
8410
8440
|
}
|
|
8411
|
-
|
|
8412
|
-
|
|
8413
|
-
|
|
8414
|
-
|
|
8415
|
-
|
|
8416
|
-
if (!this._audioNode || !this._audioSource) {
|
|
8417
|
-
return;
|
|
8441
|
+
getArgsSig(args, returnType) {
|
|
8442
|
+
let sig = ["("];
|
|
8443
|
+
for (let i = 0; i < args.length; i++) {
|
|
8444
|
+
const element = args[i];
|
|
8445
|
+
sig.push(this.getValueTypeStr(element));
|
|
8418
8446
|
}
|
|
8419
|
-
this.
|
|
8420
|
-
|
|
8447
|
+
sig.push(")", this.getValueTypeStr(returnType));
|
|
8448
|
+
return sig.join("");
|
|
8421
8449
|
}
|
|
8422
|
-
|
|
8423
|
-
if (
|
|
8424
|
-
|
|
8425
|
-
|
|
8450
|
+
getValueTypeStr(value) {
|
|
8451
|
+
if (value == null || value == undefined) {
|
|
8452
|
+
return "V";
|
|
8453
|
+
}
|
|
8454
|
+
let typeStr = typeof value;
|
|
8455
|
+
if (typeStr == "number") {
|
|
8456
|
+
if (value % 1 != 0) { //float
|
|
8457
|
+
return "F";
|
|
8458
|
+
}
|
|
8459
|
+
else {
|
|
8460
|
+
return "I";
|
|
8461
|
+
}
|
|
8462
|
+
}
|
|
8463
|
+
else if (typeStr == "boolean") {
|
|
8464
|
+
return "Z";
|
|
8465
|
+
}
|
|
8466
|
+
else if (typeStr == "string") {
|
|
8467
|
+
return "Ljava/lang/String;";
|
|
8426
8468
|
}
|
|
8427
8469
|
}
|
|
8428
|
-
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
|
|
8432
|
-
|
|
8470
|
+
}
|
|
8471
|
+
|
|
8472
|
+
/*
|
|
8473
|
+
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
|
|
8474
|
+
* Digest Algorithm, as defined in RFC 1321.
|
|
8475
|
+
* Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
|
|
8476
|
+
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
|
|
8477
|
+
* Distributed under the BSD License
|
|
8478
|
+
* See http://pajhome.org.uk/crypt/md5 for more info.
|
|
8479
|
+
*/
|
|
8480
|
+
/*
|
|
8481
|
+
* Configurable variables. You may need to tweak these to be compatible with
|
|
8482
|
+
* the server-side, but the defaults work in most cases.
|
|
8483
|
+
*/
|
|
8484
|
+
var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
|
|
8485
|
+
/*
|
|
8486
|
+
* These are the functions you'll usually want to call
|
|
8487
|
+
* They take string arguments and return either hex or base-64 encoded strings
|
|
8488
|
+
*/
|
|
8489
|
+
function hex_md5(s) { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }
|
|
8490
|
+
/*
|
|
8491
|
+
* Calculate the MD5 of a raw string
|
|
8492
|
+
*/
|
|
8493
|
+
function rstr_md5(s) {
|
|
8494
|
+
return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
|
|
8495
|
+
}
|
|
8496
|
+
/*
|
|
8497
|
+
* Convert a raw string to a hex string
|
|
8498
|
+
*/
|
|
8499
|
+
function rstr2hex(input) {
|
|
8500
|
+
try {
|
|
8501
|
+
hexcase;
|
|
8433
8502
|
}
|
|
8434
|
-
|
|
8435
|
-
|
|
8436
|
-
*/
|
|
8437
|
-
get playing() {
|
|
8438
|
-
return this._audioSource ? this._audioSource.playing : false;
|
|
8503
|
+
catch (e) {
|
|
8504
|
+
hexcase = 0;
|
|
8439
8505
|
}
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
|
|
8506
|
+
var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
|
|
8507
|
+
var output = "";
|
|
8508
|
+
var x;
|
|
8509
|
+
for (var i = 0; i < input.length; i++) {
|
|
8510
|
+
x = input.charCodeAt(i);
|
|
8511
|
+
output += hex_tab.charAt((x >>> 4) & 0x0F)
|
|
8512
|
+
+ hex_tab.charAt(x & 0x0F);
|
|
8444
8513
|
}
|
|
8445
|
-
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
|
|
8514
|
+
return output;
|
|
8515
|
+
}
|
|
8516
|
+
/*
|
|
8517
|
+
* Encode a string as utf-8.
|
|
8518
|
+
* For efficiency, this assumes the input is valid utf-16.
|
|
8519
|
+
*/
|
|
8520
|
+
function str2rstr_utf8(input) {
|
|
8521
|
+
var output = "";
|
|
8522
|
+
var i = -1;
|
|
8523
|
+
var x, y;
|
|
8524
|
+
while (++i < input.length) {
|
|
8525
|
+
/* Decode utf-16 surrogate pairs */
|
|
8526
|
+
x = input.charCodeAt(i);
|
|
8527
|
+
y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
|
|
8528
|
+
if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
|
|
8529
|
+
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
|
|
8530
|
+
i++;
|
|
8531
|
+
}
|
|
8532
|
+
/* Encode output as utf-8 */
|
|
8533
|
+
if (x <= 0x7F)
|
|
8534
|
+
output += String.fromCharCode(x);
|
|
8535
|
+
else if (x <= 0x7FF)
|
|
8536
|
+
output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F), 0x80 | (x & 0x3F));
|
|
8537
|
+
else if (x <= 0xFFFF)
|
|
8538
|
+
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F));
|
|
8539
|
+
else if (x <= 0x1FFFFF)
|
|
8540
|
+
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F));
|
|
8541
|
+
}
|
|
8542
|
+
return output;
|
|
8543
|
+
}
|
|
8544
|
+
/*
|
|
8545
|
+
* Convert a raw string to an array of little-endian words
|
|
8546
|
+
* Characters >255 have their high-byte silently ignored.
|
|
8547
|
+
*/
|
|
8548
|
+
function rstr2binl(input) {
|
|
8549
|
+
var output = Array(input.length >> 2);
|
|
8550
|
+
for (var i = 0; i < output.length; i++)
|
|
8551
|
+
output[i] = 0;
|
|
8552
|
+
for (var i = 0; i < input.length * 8; i += 8)
|
|
8553
|
+
output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
|
|
8554
|
+
return output;
|
|
8555
|
+
}
|
|
8556
|
+
/*
|
|
8557
|
+
* Convert an array of little-endian words to a string
|
|
8558
|
+
*/
|
|
8559
|
+
function binl2rstr(input) {
|
|
8560
|
+
var output = "";
|
|
8561
|
+
for (var i = 0; i < input.length * 32; i += 8)
|
|
8562
|
+
output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
|
|
8563
|
+
return output;
|
|
8564
|
+
}
|
|
8565
|
+
/*
|
|
8566
|
+
* Calculate the MD5 of an array of little-endian words, and a bit length.
|
|
8567
|
+
*/
|
|
8568
|
+
function binl_md5(x, len) {
|
|
8569
|
+
/* append padding */
|
|
8570
|
+
x[len >> 5] |= 0x80 << ((len) % 32);
|
|
8571
|
+
x[(((len + 64) >>> 9) << 4) + 14] = len;
|
|
8572
|
+
var a = 1732584193;
|
|
8573
|
+
var b = -271733879;
|
|
8574
|
+
var c = -1732584194;
|
|
8575
|
+
var d = 271733878;
|
|
8576
|
+
for (var i = 0; i < x.length; i += 16) {
|
|
8577
|
+
var olda = a;
|
|
8578
|
+
var oldb = b;
|
|
8579
|
+
var oldc = c;
|
|
8580
|
+
var oldd = d;
|
|
8581
|
+
a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
|
|
8582
|
+
d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
|
|
8583
|
+
c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
|
|
8584
|
+
b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
|
|
8585
|
+
a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
|
|
8586
|
+
d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
|
|
8587
|
+
c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
|
|
8588
|
+
b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
|
|
8589
|
+
a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
|
|
8590
|
+
d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
|
|
8591
|
+
c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
|
|
8592
|
+
b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
|
|
8593
|
+
a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
|
|
8594
|
+
d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
|
|
8595
|
+
c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
|
|
8596
|
+
b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
|
|
8597
|
+
a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
|
|
8598
|
+
d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
|
|
8599
|
+
c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
|
|
8600
|
+
b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
|
|
8601
|
+
a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
|
|
8602
|
+
d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
|
|
8603
|
+
c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
|
|
8604
|
+
b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
|
|
8605
|
+
a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
|
|
8606
|
+
d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
|
|
8607
|
+
c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
|
|
8608
|
+
b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
|
|
8609
|
+
a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
|
|
8610
|
+
d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
|
|
8611
|
+
c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
|
|
8612
|
+
b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
|
|
8613
|
+
a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
|
|
8614
|
+
d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
|
|
8615
|
+
c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
|
|
8616
|
+
b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
|
|
8617
|
+
a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
|
|
8618
|
+
d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
|
|
8619
|
+
c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
|
|
8620
|
+
b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
|
|
8621
|
+
a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
|
|
8622
|
+
d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
|
|
8623
|
+
c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
|
|
8624
|
+
b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
|
|
8625
|
+
a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
|
|
8626
|
+
d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
|
|
8627
|
+
c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
|
|
8628
|
+
b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
|
|
8629
|
+
a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
|
|
8630
|
+
d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
|
|
8631
|
+
c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
|
|
8632
|
+
b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
|
|
8633
|
+
a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
|
|
8634
|
+
d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
|
|
8635
|
+
c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
|
|
8636
|
+
b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
|
|
8637
|
+
a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
|
|
8638
|
+
d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
|
|
8639
|
+
c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
|
|
8640
|
+
b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
|
|
8641
|
+
a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
|
|
8642
|
+
d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
|
|
8643
|
+
c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
|
|
8644
|
+
b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
|
|
8645
|
+
a = safe_add(a, olda);
|
|
8646
|
+
b = safe_add(b, oldb);
|
|
8647
|
+
c = safe_add(c, oldc);
|
|
8648
|
+
d = safe_add(d, oldd);
|
|
8450
8649
|
}
|
|
8650
|
+
return Array(a, b, c, d);
|
|
8451
8651
|
}
|
|
8452
|
-
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
|
|
8461
|
-
|
|
8462
|
-
|
|
8463
|
-
|
|
8464
|
-
|
|
8465
|
-
|
|
8466
|
-
|
|
8467
|
-
|
|
8468
|
-
|
|
8469
|
-
|
|
8470
|
-
|
|
8471
|
-
|
|
8472
|
-
|
|
8473
|
-
|
|
8474
|
-
|
|
8475
|
-
|
|
8476
|
-
|
|
8477
|
-
|
|
8478
|
-
|
|
8479
|
-
|
|
8480
|
-
|
|
8481
|
-
|
|
8482
|
-
|
|
8483
|
-
|
|
8484
|
-
|
|
8652
|
+
/*
|
|
8653
|
+
* These functions implement the four basic operations the algorithm uses.
|
|
8654
|
+
*/
|
|
8655
|
+
function md5_cmn(q, a, b, x, s, t) {
|
|
8656
|
+
return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
|
|
8657
|
+
}
|
|
8658
|
+
function md5_ff(a, b, c, d, x, s, t) {
|
|
8659
|
+
return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
|
8660
|
+
}
|
|
8661
|
+
function md5_gg(a, b, c, d, x, s, t) {
|
|
8662
|
+
return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
|
8663
|
+
}
|
|
8664
|
+
function md5_hh(a, b, c, d, x, s, t) {
|
|
8665
|
+
return md5_cmn(b ^ c ^ d, a, b, x, s, t);
|
|
8666
|
+
}
|
|
8667
|
+
function md5_ii(a, b, c, d, x, s, t) {
|
|
8668
|
+
return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
|
|
8669
|
+
}
|
|
8670
|
+
/*
|
|
8671
|
+
* Add integers, wrapping at 2^32. This uses 16-bit operations internally
|
|
8672
|
+
* to work around bugs in some JS interpreters.
|
|
8673
|
+
*/
|
|
8674
|
+
function safe_add(x, y) {
|
|
8675
|
+
var lsw = (x & 0xFFFF) + (y & 0xFFFF);
|
|
8676
|
+
var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
|
8677
|
+
return (msw << 16) | (lsw & 0xFFFF);
|
|
8678
|
+
}
|
|
8679
|
+
/*
|
|
8680
|
+
* Bitwise rotate a 32-bit number to the left.
|
|
8681
|
+
*/
|
|
8682
|
+
function bit_rol(num, cnt) {
|
|
8683
|
+
return (num << cnt) | (num >>> (32 - cnt));
|
|
8684
|
+
}
|
|
8685
|
+
const md5 = hex_md5;
|
|
8686
|
+
|
|
8687
|
+
/**
|
|
8688
|
+
* cocos下的本地持久化实现类
|
|
8689
|
+
*/
|
|
8690
|
+
class CocosStorageUtils {
|
|
8691
|
+
removeValue(key) {
|
|
8692
|
+
if (!window['CC_DEBUG']) {
|
|
8693
|
+
key = md5(key);
|
|
8485
8694
|
}
|
|
8486
|
-
|
|
8487
|
-
}
|
|
8488
|
-
/**
|
|
8489
|
-
* BGM音量大小
|
|
8490
|
-
*/
|
|
8491
|
-
set musicVolume(value) {
|
|
8492
|
-
storage.musicVolume = this._musicVolume = value;
|
|
8493
|
-
this._music && (this._music.volume = value);
|
|
8494
|
-
}
|
|
8495
|
-
/**
|
|
8496
|
-
* 播放音效
|
|
8497
|
-
* @param clip
|
|
8498
|
-
* @param loop 是否循环,默认为false。传入true,需要手动调用recoverEffect进行回收
|
|
8499
|
-
* @param onFinishCallBack 播放完回调
|
|
8500
|
-
* @param volume 当此播放的声音大小,默认为统一effect的大小
|
|
8501
|
-
*/
|
|
8502
|
-
playEffect(clip, loop = false, onFinishCallBack, volume = null) {
|
|
8503
|
-
const effectProxy = this._effectPool.allocate();
|
|
8504
|
-
effectProxy.play(clip, volume == null ? this.effectVolume : volume, loop, () => {
|
|
8505
|
-
if (!loop) {
|
|
8506
|
-
this.recoverEffect(effectProxy);
|
|
8507
|
-
}
|
|
8508
|
-
else {
|
|
8509
|
-
console.warn("需要手动回收音效播放器");
|
|
8510
|
-
}
|
|
8511
|
-
onFinishCallBack && onFinishCallBack();
|
|
8512
|
-
});
|
|
8513
|
-
return effectProxy;
|
|
8514
|
-
}
|
|
8515
|
-
/**
|
|
8516
|
-
* 回收音效播放器,用于effect多次复用后的回收
|
|
8517
|
-
* @param proxy
|
|
8518
|
-
*/
|
|
8519
|
-
recoverEffect(proxy) {
|
|
8520
|
-
this._effectPool.recover(proxy);
|
|
8695
|
+
sys.localStorage.removeItem(key);
|
|
8521
8696
|
}
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
stopAllEffect() {
|
|
8526
|
-
let usingEffect = this._effectPool['_usingArray'];
|
|
8527
|
-
usingEffect = usingEffect.concat();
|
|
8528
|
-
for (let i = 0; i < usingEffect.length; i++) {
|
|
8529
|
-
const effectProxy = usingEffect[i];
|
|
8530
|
-
effectProxy.stop();
|
|
8531
|
-
this.recoverEffect(effectProxy);
|
|
8697
|
+
setValue(key, value) {
|
|
8698
|
+
if (!window['CC_DEBUG']) {
|
|
8699
|
+
key = md5(key);
|
|
8532
8700
|
}
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
* 播放背景音乐
|
|
8536
|
-
* @param clip
|
|
8537
|
-
* @param fade 是否渐进式播放,默认为true
|
|
8538
|
-
* @param loop 是否循环,默认为true
|
|
8539
|
-
* @param onFinishCallBack 播放完回调
|
|
8540
|
-
* @param volume 当此播放的声音大小,默认为统一music的大小
|
|
8541
|
-
*/
|
|
8542
|
-
playMusic(clip, fade = true, loop = true, onFinishCallBack, volume = null) {
|
|
8543
|
-
if (!this._music) {
|
|
8544
|
-
this._music = new EffectAudioSourceProxy();
|
|
8701
|
+
try {
|
|
8702
|
+
sys.localStorage.setItem(key, value);
|
|
8545
8703
|
}
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
fade ? this._music.playfade(clip, volume, loop, onFinishCallBack) : this._music.play(clip, volume, loop, onFinishCallBack);
|
|
8549
|
-
}
|
|
8550
|
-
/**
|
|
8551
|
-
* 暂停播放背景音乐
|
|
8552
|
-
* @returns
|
|
8553
|
-
*/
|
|
8554
|
-
pauseMusic() {
|
|
8555
|
-
if (!this._music) {
|
|
8556
|
-
return;
|
|
8704
|
+
catch (error) {
|
|
8705
|
+
console.error('Failed to set storage value:', "key:", key, "value:", value, "length:", String(value).length, "error:", error);
|
|
8557
8706
|
}
|
|
8558
|
-
this._music.pause();
|
|
8559
8707
|
}
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
*/
|
|
8564
|
-
resumeMusic() {
|
|
8565
|
-
if (!this._music) {
|
|
8566
|
-
return;
|
|
8708
|
+
getValue(key) {
|
|
8709
|
+
if (!window['CC_DEBUG']) {
|
|
8710
|
+
key = md5(key);
|
|
8567
8711
|
}
|
|
8568
|
-
|
|
8712
|
+
return sys.localStorage.getItem(key);
|
|
8569
8713
|
}
|
|
8570
|
-
|
|
8571
|
-
|
|
8572
|
-
* @param fade 是否渐出
|
|
8573
|
-
* @returns
|
|
8574
|
-
*/
|
|
8575
|
-
stopMusic(fade = true) {
|
|
8576
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
8577
|
-
if (!this._music) {
|
|
8578
|
-
return;
|
|
8579
|
-
}
|
|
8580
|
-
return fade ? yield this._music.stopFade() : this._music.stop();
|
|
8581
|
-
});
|
|
8714
|
+
clear() {
|
|
8715
|
+
sys.localStorage.clear();
|
|
8582
8716
|
}
|
|
8583
8717
|
}
|
|
8718
|
+
|
|
8584
8719
|
/**
|
|
8585
|
-
*
|
|
8720
|
+
* 任务队列
|
|
8586
8721
|
*/
|
|
8587
|
-
|
|
8588
|
-
|
|
8589
|
-
var View_1;
|
|
8590
|
-
const { ccclass: ccclass$2, property: property$2, menu: menu$2 } = cc._decorator;
|
|
8591
|
-
var ViewLevel;
|
|
8592
|
-
(function (ViewLevel) {
|
|
8593
|
-
ViewLevel[ViewLevel["TOPUP"] = 500] = "TOPUP";
|
|
8594
|
-
ViewLevel[ViewLevel["NET"] = 400] = "NET";
|
|
8595
|
-
ViewLevel[ViewLevel["TUTORIAL"] = 300] = "TUTORIAL";
|
|
8596
|
-
ViewLevel[ViewLevel["ALERT"] = 200] = "ALERT";
|
|
8597
|
-
ViewLevel[ViewLevel["UI"] = 100] = "UI";
|
|
8598
|
-
ViewLevel[ViewLevel["BG"] = 1] = "BG";
|
|
8599
|
-
})(ViewLevel || (ViewLevel = {}));
|
|
8600
|
-
let View = View_1 = class View extends cc.Component {
|
|
8722
|
+
class TaskSequence extends Task {
|
|
8601
8723
|
constructor() {
|
|
8602
|
-
super(
|
|
8603
|
-
|
|
8604
|
-
|
|
8605
|
-
*/
|
|
8606
|
-
this._touchEnabled = true;
|
|
8607
|
-
}
|
|
8608
|
-
/**
|
|
8609
|
-
* 是否在舞台中显示着
|
|
8610
|
-
*/
|
|
8611
|
-
get inStage() {
|
|
8612
|
-
return cc.isValid(this.node) && this.node.activeInHierarchy;
|
|
8613
|
-
}
|
|
8614
|
-
/**
|
|
8615
|
-
* 视图是否响应交互
|
|
8616
|
-
*/
|
|
8617
|
-
get touchEnabled() {
|
|
8618
|
-
return this._touchEnabled;
|
|
8619
|
-
}
|
|
8620
|
-
/**
|
|
8621
|
-
* 视图是否响应交互
|
|
8622
|
-
*/
|
|
8623
|
-
set touchEnabled(value) {
|
|
8624
|
-
this._touchEnabled = value;
|
|
8625
|
-
if (value && !this._mask) {
|
|
8626
|
-
return;
|
|
8627
|
-
}
|
|
8628
|
-
if (!this._mask) {
|
|
8629
|
-
this._mask = new cc.Node();
|
|
8630
|
-
this._mask.name = "mask";
|
|
8631
|
-
let transform = this._mask.addComponent(cc.UITransform);
|
|
8632
|
-
const viewSize = cc.view.getVisibleSize();
|
|
8633
|
-
transform.setContentSize(viewSize.width, viewSize.height);
|
|
8634
|
-
this._mask.addComponent(cc.BlockInputEvents);
|
|
8635
|
-
// this.node.addChild(this.mask);
|
|
8636
|
-
this.node.addChild(this._mask);
|
|
8637
|
-
transform.priority = ViewLevel.TOPUP;
|
|
8638
|
-
this._mask.layer = this.node.layer;
|
|
8639
|
-
}
|
|
8640
|
-
this._mask.active = !value;
|
|
8724
|
+
super();
|
|
8725
|
+
this._taskMap = new Map();
|
|
8726
|
+
this._index = 0;
|
|
8641
8727
|
}
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
|
|
8646
|
-
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
|
|
8650
|
-
(view.node.getComponent(cc.UITransform) || view.node.addComponent(cc.UITransform)).priority = index;
|
|
8651
|
-
viewManager.event("open", view);
|
|
8652
|
-
viewManager.reportViewAnalytics("open", view);
|
|
8653
|
-
analytics.session.updateSessionDuration();
|
|
8728
|
+
addQuickly(taskCaller, taskFun, ...taskData) {
|
|
8729
|
+
let task = new Task();
|
|
8730
|
+
taskData.unshift(task);
|
|
8731
|
+
task.start = (data) => {
|
|
8732
|
+
taskFun.apply(taskCaller, taskData);
|
|
8733
|
+
};
|
|
8734
|
+
this.addTask(task);
|
|
8735
|
+
return task;
|
|
8654
8736
|
}
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
* @param destroy 是否销毁,默认为true
|
|
8659
|
-
* @param closeEventParams 视图close事件的参数
|
|
8660
|
-
*/
|
|
8661
|
-
removeView(view, destroy = true, ...closeEventParams) {
|
|
8662
|
-
if (view.parentView == this) {
|
|
8663
|
-
destroy && view.node.destroyAllChildren();
|
|
8664
|
-
view.node.removeFromParent();
|
|
8665
|
-
viewManager.event("close", view, ...closeEventParams);
|
|
8666
|
-
viewManager.reportViewAnalytics("close", view);
|
|
8667
|
-
analytics.session.updateSessionDuration();
|
|
8737
|
+
addTask(value, ...data) {
|
|
8738
|
+
if (this._taskMap.has(value)) {
|
|
8739
|
+
throw new Error("重复添加!");
|
|
8668
8740
|
}
|
|
8741
|
+
this._taskMap.set(value, data);
|
|
8669
8742
|
}
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
* @param control
|
|
8673
|
-
*/
|
|
8674
|
-
setControl(control) {
|
|
8675
|
-
this._control = control;
|
|
8743
|
+
removeTask(value) {
|
|
8744
|
+
return this._taskMap.delete(value);
|
|
8676
8745
|
}
|
|
8677
|
-
|
|
8678
|
-
|
|
8746
|
+
start(...data) {
|
|
8747
|
+
this._keys = this._taskMap.keys();
|
|
8748
|
+
this._index = 0;
|
|
8749
|
+
this._tryNext();
|
|
8679
8750
|
}
|
|
8680
|
-
|
|
8681
|
-
|
|
8682
|
-
|
|
8683
|
-
|
|
8684
|
-
|
|
8751
|
+
_tryNext() {
|
|
8752
|
+
let next = this._keys.next();
|
|
8753
|
+
if (!next.done) {
|
|
8754
|
+
let task = next.value;
|
|
8755
|
+
task.on(Task.Event.COMPLETE, this, this._subTaskEventHandler);
|
|
8756
|
+
task.on(Task.Event.PROGRESS, this, this._subTaskEventHandler);
|
|
8757
|
+
task.on(Task.Event.ERROR, this, this._subTaskEventHandler);
|
|
8758
|
+
task.start(this._taskMap.get(task));
|
|
8759
|
+
}
|
|
8760
|
+
else {
|
|
8761
|
+
//结束
|
|
8762
|
+
this.onComplete();
|
|
8763
|
+
}
|
|
8685
8764
|
}
|
|
8686
|
-
|
|
8687
|
-
|
|
8688
|
-
|
|
8689
|
-
* @param data 上报附带信息,可选参数,为空时会尝试从getAnalyticsDataOnViewEvent获取附带信息。
|
|
8690
|
-
*/
|
|
8691
|
-
_report(event, data) {
|
|
8692
|
-
if (event == "open" || event == "close")
|
|
8765
|
+
_subTaskEventHandler(key, target, data) {
|
|
8766
|
+
if (key == Task.Event.ERROR) {
|
|
8767
|
+
this.onError(data.code, data.msg);
|
|
8693
8768
|
return;
|
|
8694
|
-
|
|
8769
|
+
}
|
|
8770
|
+
if (key == Task.Event.COMPLETE) {
|
|
8771
|
+
target.offAllEvent();
|
|
8772
|
+
target.destroy();
|
|
8773
|
+
this._index++;
|
|
8774
|
+
this.onProgress(this._index / this._taskMap.size);
|
|
8775
|
+
this._tryNext();
|
|
8776
|
+
}
|
|
8695
8777
|
}
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
|
|
8699
|
-
|
|
8700
|
-
* @param loop 是否循环 默认为true
|
|
8701
|
-
* @param onFinishCallBack 单次播放结束后的回调箭头函数(cocos的锅)
|
|
8702
|
-
* @returns 背景音乐的audioId
|
|
8703
|
-
*
|
|
8704
|
-
* @example
|
|
8705
|
-
* _playBG("https://server.com/game/music.mp3")
|
|
8706
|
-
* _playBG("main://path/to/music")
|
|
8707
|
-
* _playBG("resources://path/to/music")
|
|
8708
|
-
*/
|
|
8709
|
-
playBG(path, fade = true, loop = true, onFinishCallBack, volume = null) {
|
|
8710
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
8711
|
-
let clip = yield res.load(path);
|
|
8712
|
-
if (clip) {
|
|
8713
|
-
audio.playMusic(clip, fade, loop, onFinishCallBack, volume);
|
|
8714
|
-
}
|
|
8778
|
+
reset() {
|
|
8779
|
+
this.offAllEvent();
|
|
8780
|
+
this._taskMap.forEach((data, task) => {
|
|
8781
|
+
task.reset();
|
|
8715
8782
|
});
|
|
8783
|
+
this._taskMap.clear();
|
|
8784
|
+
this._keys = null;
|
|
8785
|
+
this._index = 0;
|
|
8716
8786
|
}
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
|
|
8721
|
-
* @returns 音效的audioId
|
|
8722
|
-
*/
|
|
8723
|
-
playEffect(path, onFinishCallBack, volume = null) {
|
|
8724
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
8725
|
-
let clip = yield res.load(path);
|
|
8726
|
-
return new Promise((reslove) => {
|
|
8727
|
-
if (clip) {
|
|
8728
|
-
audio.playEffect(clip, false, () => {
|
|
8729
|
-
onFinishCallBack && onFinishCallBack();
|
|
8730
|
-
reslove();
|
|
8731
|
-
}, volume);
|
|
8732
|
-
}
|
|
8733
|
-
});
|
|
8787
|
+
destroy() {
|
|
8788
|
+
super.destroy();
|
|
8789
|
+
this._taskMap.forEach((data, task) => {
|
|
8790
|
+
task.reset();
|
|
8734
8791
|
});
|
|
8792
|
+
this._taskMap.clear();
|
|
8793
|
+
this._keys = null;
|
|
8794
|
+
this._index = 0;
|
|
8735
8795
|
}
|
|
8736
|
-
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
|
|
8742
|
-
|
|
8743
|
-
|
|
8744
|
-
|
|
8745
|
-
|
|
8746
|
-
const openTouch = () => {
|
|
8747
|
-
viewManager.openTouch();
|
|
8748
|
-
App.offShow(openTouch);
|
|
8749
|
-
};
|
|
8750
|
-
App.onShow(openTouch);
|
|
8751
|
-
from = from || {};
|
|
8752
|
-
// from.name = this.analyticsInfo ? this.analyticsInfo.name : this.name;
|
|
8753
|
-
publisher.ad.showRewardVideo(from).then((result) => {
|
|
8754
|
-
openTouch();
|
|
8755
|
-
stopRecorder && publisher.record && publisher.record.resumeRecord();
|
|
8756
|
-
resolve(result);
|
|
8757
|
-
}).catch(() => {
|
|
8758
|
-
openTouch();
|
|
8759
|
-
stopRecorder && publisher.record && publisher.record.resumeRecord();
|
|
8760
|
-
resolve(false);
|
|
8761
|
-
});
|
|
8762
|
-
});
|
|
8796
|
+
}
|
|
8797
|
+
|
|
8798
|
+
/**
|
|
8799
|
+
* 视图加载器
|
|
8800
|
+
*/
|
|
8801
|
+
class IViewLoader extends EventDispatcher {
|
|
8802
|
+
constructor(pool) {
|
|
8803
|
+
super();
|
|
8804
|
+
this._initializer = new TaskSequence();
|
|
8805
|
+
this._pool = pool;
|
|
8763
8806
|
}
|
|
8764
|
-
|
|
8765
|
-
|
|
8766
|
-
|
|
8767
|
-
|
|
8768
|
-
* @param topics 视频话题列表
|
|
8769
|
-
*/
|
|
8770
|
-
shareRecord(analyticsName, title, topics) {
|
|
8771
|
-
let path = publisher.record.videoPath;
|
|
8772
|
-
if (path) {
|
|
8773
|
-
return publisher.share.shareVideo(analyticsName, { "video_title": title, "videoTopics": topics, "videoPath": path });
|
|
8774
|
-
}
|
|
8775
|
-
else {
|
|
8776
|
-
return new Promise((resolve) => { resolve(false); });
|
|
8807
|
+
load(task) {
|
|
8808
|
+
if (this._asset) {
|
|
8809
|
+
task && task.onComplete();
|
|
8810
|
+
return;
|
|
8777
8811
|
}
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
|
|
8782
|
-
|
|
8783
|
-
|
|
8784
|
-
|
|
8785
|
-
}
|
|
8786
|
-
/**
|
|
8787
|
-
* 父级视图
|
|
8788
|
-
*/
|
|
8789
|
-
get parentView() {
|
|
8790
|
-
if (this.node.parent) {
|
|
8791
|
-
return this.node.parent.getComponent(View_1);
|
|
8812
|
+
if (task) {
|
|
8813
|
+
this._initializer.once(Task.Event.ERROR, this, (type, a, error) => {
|
|
8814
|
+
task.onError(error.code, error.msg);
|
|
8815
|
+
});
|
|
8816
|
+
this._initializer.on(Task.Event.PROGRESS, this, (type, a, percent) => {
|
|
8817
|
+
task.onProgress(percent);
|
|
8818
|
+
});
|
|
8792
8819
|
}
|
|
8793
|
-
|
|
8794
|
-
|
|
8795
|
-
|
|
8796
|
-
|
|
8797
|
-
|
|
8798
|
-
*/
|
|
8799
|
-
close(...closeEventParams) {
|
|
8800
|
-
this.removeFromParent(!this.config.cache, ...closeEventParams);
|
|
8820
|
+
this._initializer.once(Task.Event.COMPLETE, this, () => {
|
|
8821
|
+
this._initializer.reset();
|
|
8822
|
+
task && task.onComplete();
|
|
8823
|
+
});
|
|
8824
|
+
this._initializer.start();
|
|
8801
8825
|
}
|
|
8802
|
-
|
|
8803
|
-
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
if (this.parentView) {
|
|
8809
|
-
this.parentView.removeView(this, destroy, ...closeEventParams);
|
|
8810
|
-
}
|
|
8826
|
+
destroy() {
|
|
8827
|
+
this.offAll();
|
|
8828
|
+
this._initializer.reset();
|
|
8829
|
+
this._initializer = null;
|
|
8830
|
+
this._asset = null;
|
|
8831
|
+
this._pool = null;
|
|
8811
8832
|
}
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
if (this.node && cc.isValid(this.node)) {
|
|
8817
|
-
this.node.parent = null;
|
|
8818
|
-
this.node.destroy();
|
|
8819
|
-
}
|
|
8833
|
+
reset() {
|
|
8834
|
+
this._initializer.reset();
|
|
8835
|
+
this.offAll();
|
|
8836
|
+
this._asset = null;
|
|
8820
8837
|
}
|
|
8821
|
-
|
|
8822
|
-
|
|
8838
|
+
recover() {
|
|
8839
|
+
this._pool.recover(this);
|
|
8823
8840
|
}
|
|
8824
|
-
}
|
|
8825
|
-
/**
|
|
8826
|
-
* View类的Class名称
|
|
8827
|
-
*/
|
|
8828
|
-
View.type = "View";
|
|
8829
|
-
View = View_1 = __decorate([
|
|
8830
|
-
ccclass$2("View"),
|
|
8831
|
-
menu$2("基础视图/View")
|
|
8832
|
-
/**
|
|
8833
|
-
* cocos引擎下的视图管理类
|
|
8834
|
-
*/
|
|
8835
|
-
], View);
|
|
8841
|
+
}
|
|
8836
8842
|
|
|
8837
8843
|
/**
|
|
8838
8844
|
* 注册View配置的装饰器(CCPViewLoader)
|
|
@@ -8878,14 +8884,10 @@ function viewClass(data) {
|
|
|
8878
8884
|
}
|
|
8879
8885
|
/**
|
|
8880
8886
|
* 注册closeTouch默认遮罩视图
|
|
8881
|
-
* @param data 视图配置
|
|
8882
8887
|
*/
|
|
8883
|
-
function maskView(
|
|
8888
|
+
function maskView() {
|
|
8884
8889
|
return function (target, propertyKey) {
|
|
8885
|
-
|
|
8886
|
-
data.zIndex = ViewLevel.TOPUP;
|
|
8887
|
-
viewClass(data)(target, propertyKey);
|
|
8888
|
-
viewManager.registerMaskView(data);
|
|
8890
|
+
viewManager.registerMaskView(target);
|
|
8889
8891
|
};
|
|
8890
8892
|
}
|
|
8891
8893
|
/**
|