You've already forked Commercialization.topon
feat(topon): 优化主线程调用及增加控制器初始化配置支持
- ToponUnityThread新增初始化方法并封装主线程安全调用接口 - ADListenerAggregator中所有回调改用ToponUnityThread切换至主线程调用 - ToponAdController新增ToponControllerOptions配置支持,支持更多初始化参数 - 实现SDK初始化前后配置的应用,支持设置渠道、区域、经纬度等选项 - 支持初始化时自动检测区域并通过回调通知 - 新增ToponControllerOptions类,实现多种初始化参数来源解析和合并 - ShowAndroidTest方法根据DebuggerKey选择不同调试器UI展示模式 - 记录并公开最近一次区域检测结果及错误信息,方便外部查询和调试
This commit is contained in:
@@ -13,6 +13,8 @@ public class ADListenerAggregator
|
|||||||
|
|
||||||
public void BindAwardVideoListener(IATRewardedVideoAdClient client, ATRewardedVideoListener listener)
|
public void BindAwardVideoListener(IATRewardedVideoAdClient client, ATRewardedVideoListener listener)
|
||||||
{
|
{
|
||||||
|
ToponUnityThread.Initialize();
|
||||||
|
|
||||||
if (this._awardVideoListener == null)
|
if (this._awardVideoListener == null)
|
||||||
{
|
{
|
||||||
client.onRewardEvent += this.onReward;
|
client.onRewardEvent += this.onReward;
|
||||||
@@ -29,6 +31,8 @@ public class ADListenerAggregator
|
|||||||
|
|
||||||
public void BindInterstitialAdListener(IATInterstitialAdClient client, ATInterstitialAdListener listener)
|
public void BindInterstitialAdListener(IATInterstitialAdClient client, ATInterstitialAdListener listener)
|
||||||
{
|
{
|
||||||
|
ToponUnityThread.Initialize();
|
||||||
|
|
||||||
if (this._interstitialListener == null)
|
if (this._interstitialListener == null)
|
||||||
{
|
{
|
||||||
client.onAdLoadEvent += this.onInterstitialAdLoad;
|
client.onAdLoadEvent += this.onInterstitialAdLoad;
|
||||||
@@ -45,7 +49,7 @@ public class ADListenerAggregator
|
|||||||
|
|
||||||
void onRewardedVideoAdLoaded(object sender, ATAdEventArgs callbackInfo)
|
void onRewardedVideoAdLoaded(object sender, ATAdEventArgs callbackInfo)
|
||||||
{
|
{
|
||||||
this._awardVideoListener?.onRewardedVideoAdLoaded(callbackInfo.placementId);
|
ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdLoaded(callbackInfo.placementId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -53,8 +57,8 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
void onRewardedVideoAdLoadFail(object sender, ATAdErrorEventArgs callbackInfo)
|
void onRewardedVideoAdLoadFail(object sender, ATAdErrorEventArgs callbackInfo)
|
||||||
{
|
{
|
||||||
this._awardVideoListener?.onRewardedVideoAdLoadFail(callbackInfo.placementId, callbackInfo.errorCode,
|
ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdLoadFail(callbackInfo.placementId,
|
||||||
callbackInfo.errorMessage);
|
callbackInfo.errorCode, callbackInfo.errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -63,7 +67,8 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
void onRewardedVideoAdPlayEnd(object sender, ATAdEventArgs callbackInfo)
|
void onRewardedVideoAdPlayEnd(object sender, ATAdEventArgs callbackInfo)
|
||||||
{
|
{
|
||||||
this._awardVideoListener?.onRewardedVideoAdPlayEnd(callbackInfo.placementId, callbackInfo.callbackInfo);
|
ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdPlayEnd(callbackInfo.placementId,
|
||||||
|
callbackInfo.callbackInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -73,8 +78,8 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
void onRewardedVideoAdPlayFail(object sender, ATAdErrorEventArgs callbackInfo)
|
void onRewardedVideoAdPlayFail(object sender, ATAdErrorEventArgs callbackInfo)
|
||||||
{
|
{
|
||||||
this._awardVideoListener?.onRewardedVideoAdPlayFail(callbackInfo.placementId, callbackInfo.errorCode,
|
ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdPlayFail(callbackInfo.placementId,
|
||||||
callbackInfo.errorMessage);
|
callbackInfo.errorCode, callbackInfo.errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,8 +88,8 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
void onRewardedVideoAdPlayClosed(object sender, ATAdRewardEventArgs callbackInfo)
|
void onRewardedVideoAdPlayClosed(object sender, ATAdRewardEventArgs callbackInfo)
|
||||||
{
|
{
|
||||||
this._awardVideoListener?.onRewardedVideoAdPlayClosed(callbackInfo.placementId, callbackInfo.isRewarded,
|
ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdPlayClosed(callbackInfo.placementId,
|
||||||
callbackInfo.callbackInfo);
|
callbackInfo.isRewarded, callbackInfo.callbackInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -92,7 +97,8 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
void onRewardedVideoAdPlayClicked(object sender, ATAdEventArgs callbackInfo)
|
void onRewardedVideoAdPlayClicked(object sender, ATAdEventArgs callbackInfo)
|
||||||
{
|
{
|
||||||
this._awardVideoListener?.onRewardedVideoAdPlayClicked(callbackInfo.placementId, callbackInfo.callbackInfo);
|
ToponUnityThread.Post(() => this._awardVideoListener?.onRewardedVideoAdPlayClicked(callbackInfo.placementId,
|
||||||
|
callbackInfo.callbackInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -100,7 +106,8 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
private void onReward(object sender, ATAdEventArgs callbackInfo)
|
private void onReward(object sender, ATAdEventArgs callbackInfo)
|
||||||
{
|
{
|
||||||
this._awardVideoListener?.onReward(callbackInfo.placementId, callbackInfo.callbackInfo);
|
ToponUnityThread.Post(() => this._awardVideoListener?.onReward(callbackInfo.placementId,
|
||||||
|
callbackInfo.callbackInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -110,7 +117,7 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
void onInterstitialAdLoad(object sender, ATAdEventArgs atAdEventArgs)
|
void onInterstitialAdLoad(object sender, ATAdEventArgs atAdEventArgs)
|
||||||
{
|
{
|
||||||
this._interstitialListener?.onInterstitialAdLoad(atAdEventArgs.placementId);
|
ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdLoad(atAdEventArgs.placementId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -121,8 +128,8 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
void onInterstitialAdLoadFail(object sender, ATAdErrorEventArgs atAdErrorEventArgs)
|
void onInterstitialAdLoadFail(object sender, ATAdErrorEventArgs atAdErrorEventArgs)
|
||||||
{
|
{
|
||||||
this._interstitialListener?.onInterstitialAdLoadFail(atAdErrorEventArgs.placementId,
|
ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdLoadFail(atAdErrorEventArgs.placementId,
|
||||||
atAdErrorEventArgs.errorCode, atAdErrorEventArgs.errorMessage);
|
atAdErrorEventArgs.errorCode, atAdErrorEventArgs.errorMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -131,7 +138,8 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
void onInterstitialAdShow(object sender, ATAdEventArgs atAdEventArgs)
|
void onInterstitialAdShow(object sender, ATAdEventArgs atAdEventArgs)
|
||||||
{
|
{
|
||||||
this._interstitialListener?.onInterstitialAdShow(atAdEventArgs.placementId, atAdEventArgs.callbackInfo);
|
ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdShow(atAdEventArgs.placementId,
|
||||||
|
atAdEventArgs.callbackInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -140,7 +148,7 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
void onInterstitialAdFailedToShow(object sender, ATAdErrorEventArgs atAdErrorEventArgs)
|
void onInterstitialAdFailedToShow(object sender, ATAdErrorEventArgs atAdErrorEventArgs)
|
||||||
{
|
{
|
||||||
this._interstitialListener?.onInterstitialAdFailedToShow(atAdErrorEventArgs.placementId);
|
ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdFailedToShow(atAdErrorEventArgs.placementId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -149,7 +157,8 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
void onInterstitialAdClose(object sender, ATAdEventArgs atAdEventArgs)
|
void onInterstitialAdClose(object sender, ATAdEventArgs atAdEventArgs)
|
||||||
{
|
{
|
||||||
this._interstitialListener?.onInterstitialAdClose(atAdEventArgs.placementId, atAdEventArgs.callbackInfo);
|
ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdClose(atAdEventArgs.placementId,
|
||||||
|
atAdEventArgs.callbackInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@@ -158,6 +167,7 @@ public class ADListenerAggregator
|
|||||||
*/
|
*/
|
||||||
void onInterstitialAdClick(object sender, ATAdEventArgs atAdEventArgs)
|
void onInterstitialAdClick(object sender, ATAdEventArgs atAdEventArgs)
|
||||||
{
|
{
|
||||||
this._interstitialListener?.onInterstitialAdClick(atAdEventArgs.placementId, atAdEventArgs.callbackInfo);
|
ToponUnityThread.Post(() => this._interstitialListener?.onInterstitialAdClick(atAdEventArgs.placementId,
|
||||||
|
atAdEventArgs.callbackInfo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,19 +5,28 @@ using UnityEngine;
|
|||||||
|
|
||||||
public class ToponAdController : IAdController
|
public class ToponAdController : IAdController
|
||||||
{
|
{
|
||||||
|
public static string LastDetectedArea { get; private set; }
|
||||||
|
public static string LastAreaError { get; private set; }
|
||||||
|
|
||||||
private Action<bool> _maskAction;
|
private Action<bool> _maskAction;
|
||||||
private Action<string, string> _logEventAction;
|
private Action<string, string> _logEventAction;
|
||||||
|
|
||||||
private ADConfig _adConfig;
|
private ADConfig _adConfig;
|
||||||
|
private ToponControllerOptions _controllerOptions;
|
||||||
|
|
||||||
public void Init(ADConfig adConfig, object[] args)
|
public void Init(ADConfig adConfig, object[] args)
|
||||||
{
|
{
|
||||||
|
ToponUnityThread.Initialize();
|
||||||
|
|
||||||
_adConfig = adConfig;
|
_adConfig = adConfig;
|
||||||
// ATSdkUtil.
|
_controllerOptions = ToponControllerOptions.Resolve(adConfig, args);
|
||||||
ATSDKAPI.setChannel(args[0].ToString());
|
|
||||||
var isDebug = args.Length > 1 && (bool)args[1];
|
ApplyPreInitOptions(_controllerOptions);
|
||||||
|
|
||||||
|
var isDebug = _controllerOptions.Debug ?? false;
|
||||||
ATSDKAPI.setLogDebug(isDebug);
|
ATSDKAPI.setLogDebug(isDebug);
|
||||||
ATSDKAPI.initSDK(adConfig.Id , adConfig.Key);
|
ATSDKAPI.initSDK(adConfig.Id , adConfig.Key);
|
||||||
|
ApplyPostInitOptions(_controllerOptions);
|
||||||
if (isDebug)
|
if (isDebug)
|
||||||
{
|
{
|
||||||
ShowAndroidTest ();
|
ShowAndroidTest ();
|
||||||
@@ -58,7 +67,16 @@ public class ToponAdController : IAdController
|
|||||||
|
|
||||||
private void ShowAndroidTest ()
|
private void ShowAndroidTest ()
|
||||||
{
|
{
|
||||||
ATSDKAPI.showDebuggerUI ();
|
var debuggerKey = _controllerOptions?.DebuggerKey;
|
||||||
|
if (string.IsNullOrWhiteSpace(debuggerKey))
|
||||||
|
{
|
||||||
|
ATSDKAPI.showDebuggerUI();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ATSDKAPI.showDebuggerUI(debuggerKey);
|
||||||
|
}
|
||||||
|
|
||||||
// com.anythink.debug.api.ATDebuggerUITest.showDebuggerUI(this);
|
// com.anythink.debug.api.ATDebuggerUITest.showDebuggerUI(this);
|
||||||
// #if UNITY_EDITOR
|
// #if UNITY_EDITOR
|
||||||
// return;
|
// return;
|
||||||
@@ -77,4 +95,93 @@ public class ToponAdController : IAdController
|
|||||||
// }
|
// }
|
||||||
// #endif
|
// #endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private void ApplyPreInitOptions(ToponControllerOptions options)
|
||||||
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(options.Channel))
|
||||||
|
{
|
||||||
|
ATSDKAPI.setChannel(options.Channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(options.SubChannel))
|
||||||
|
{
|
||||||
|
ATSDKAPI.setSubChannel(options.SubChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.SDKArea.HasValue)
|
||||||
|
{
|
||||||
|
ATSDKAPI.setSDKArea(options.SDKArea.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.Longitude.HasValue && options.Latitude.HasValue)
|
||||||
|
{
|
||||||
|
ATSDKAPI.setLocation(options.Longitude.Value, options.Latitude.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.ExcludeBundleIds != null && options.ExcludeBundleIds.Length > 0)
|
||||||
|
{
|
||||||
|
ATSDKAPI.setExcludeBundleIdArray(options.ExcludeBundleIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyPostInitOptions(ToponControllerOptions options)
|
||||||
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var rewardedPlacementId = _adConfig?.BaseAwardAdKeyValue?.value;
|
||||||
|
if (!string.IsNullOrWhiteSpace(rewardedPlacementId) &&
|
||||||
|
options.RewardedExcludeAdSourceIds != null &&
|
||||||
|
options.RewardedExcludeAdSourceIds.Length > 0)
|
||||||
|
{
|
||||||
|
ATSDKAPI.setExcludeAdSourceIdArrayForPlacementID(rewardedPlacementId, options.RewardedExcludeAdSourceIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.QueryAreaOnInit)
|
||||||
|
{
|
||||||
|
ATSDKAPI.getArea(new ToponAreaListener(this, options));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class ToponAreaListener : ATGetAreaListener
|
||||||
|
{
|
||||||
|
private readonly ToponAdController _controller;
|
||||||
|
private readonly ToponControllerOptions _options;
|
||||||
|
|
||||||
|
public ToponAreaListener(ToponAdController controller, ToponControllerOptions options)
|
||||||
|
{
|
||||||
|
_controller = controller;
|
||||||
|
_options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onArea(string area)
|
||||||
|
{
|
||||||
|
ToponUnityThread.Post(() =>
|
||||||
|
{
|
||||||
|
LastDetectedArea = area;
|
||||||
|
LastAreaError = null;
|
||||||
|
_options?.OnAreaReceived?.Invoke(area);
|
||||||
|
_controller?._logEventAction?.Invoke("topon_area", area);
|
||||||
|
Debug.Log($"[Topon] Area detected: {area}");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onError(string message)
|
||||||
|
{
|
||||||
|
ToponUnityThread.Post(() =>
|
||||||
|
{
|
||||||
|
LastAreaError = message;
|
||||||
|
_options?.OnAreaError?.Invoke(message);
|
||||||
|
_controller?._logEventAction?.Invoke("topon_area_error", message);
|
||||||
|
Debug.LogWarning($"[Topon] Area detect failed: {message}");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
290
Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs
Normal file
290
Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using Runtime.ADAggregator;
|
||||||
|
|
||||||
|
public sealed class ToponControllerOptions
|
||||||
|
{
|
||||||
|
public const string ChannelKey = "topon.channel";
|
||||||
|
public const string SubChannelKey = "topon.sub_channel";
|
||||||
|
public const string DebugKey = "topon.debug";
|
||||||
|
public const string DebuggerKeyKey = "topon.debugger_key";
|
||||||
|
public const string SDKAreaKey = "topon.sdk_area";
|
||||||
|
public const string LongitudeKey = "topon.longitude";
|
||||||
|
public const string LatitudeKey = "topon.latitude";
|
||||||
|
public const string ExcludeBundleIdsKey = "topon.exclude_bundle_ids";
|
||||||
|
public const string RewardedExcludeAdSourceIdsKey = "topon.rewarded_exclude_ad_source_ids";
|
||||||
|
public const string QueryAreaOnInitKey = "topon.query_area_on_init";
|
||||||
|
|
||||||
|
public string Channel { get; set; }
|
||||||
|
public string SubChannel { get; set; }
|
||||||
|
public bool? Debug { get; set; }
|
||||||
|
public string DebuggerKey { get; set; }
|
||||||
|
public int? SDKArea { get; set; }
|
||||||
|
public double? Longitude { get; set; }
|
||||||
|
public double? Latitude { get; set; }
|
||||||
|
public string[] ExcludeBundleIds { get; set; }
|
||||||
|
public string[] RewardedExcludeAdSourceIds { get; set; }
|
||||||
|
public bool QueryAreaOnInit { get; set; }
|
||||||
|
public Action<string> OnAreaReceived { get; set; }
|
||||||
|
public Action<string> OnAreaError { get; set; }
|
||||||
|
|
||||||
|
public static ToponControllerOptions Resolve(ADConfig adConfig, object[] args)
|
||||||
|
{
|
||||||
|
var options = new ToponControllerOptions();
|
||||||
|
|
||||||
|
options.ApplyCommonKeyValues(adConfig?.CommonKeyValues);
|
||||||
|
options.ApplyLegacyArgs(args);
|
||||||
|
|
||||||
|
if (args == null)
|
||||||
|
{
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var arg in args)
|
||||||
|
{
|
||||||
|
switch (arg)
|
||||||
|
{
|
||||||
|
case ToponControllerOptions explicitOptions:
|
||||||
|
options.ApplyExplicitOptions(explicitOptions);
|
||||||
|
break;
|
||||||
|
case IDictionary dictionary:
|
||||||
|
options.ApplyDictionary(dictionary);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyCommonKeyValues(List<AdKeyValue> keyValues)
|
||||||
|
{
|
||||||
|
if (keyValues == null || keyValues.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
foreach (var keyValue in keyValues)
|
||||||
|
{
|
||||||
|
if (keyValue == null || string.IsNullOrWhiteSpace(keyValue.key))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
map[keyValue.key] = keyValue.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Channel = GetString(map, ChannelKey, "channel") ?? Channel;
|
||||||
|
SubChannel = GetString(map, SubChannelKey, "sub_channel") ?? SubChannel;
|
||||||
|
Debug = GetBool(map, DebugKey, "debug") ?? Debug;
|
||||||
|
DebuggerKey = GetString(map, DebuggerKeyKey) ?? DebuggerKey;
|
||||||
|
SDKArea = GetInt(map, SDKAreaKey) ?? SDKArea;
|
||||||
|
Longitude = GetDouble(map, LongitudeKey) ?? Longitude;
|
||||||
|
Latitude = GetDouble(map, LatitudeKey) ?? Latitude;
|
||||||
|
ExcludeBundleIds = GetStringArray(map, ExcludeBundleIdsKey) ?? ExcludeBundleIds;
|
||||||
|
RewardedExcludeAdSourceIds = GetStringArray(map, RewardedExcludeAdSourceIdsKey) ?? RewardedExcludeAdSourceIds;
|
||||||
|
QueryAreaOnInit = GetBool(map, QueryAreaOnInitKey) ?? QueryAreaOnInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyLegacyArgs(object[] args)
|
||||||
|
{
|
||||||
|
if (args == null || args.Length == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Length > 0 && args[0] is string channel)
|
||||||
|
{
|
||||||
|
Channel = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Length > 1 && TryConvertBool(args[1], out var debug))
|
||||||
|
{
|
||||||
|
Debug = debug;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyExplicitOptions(ToponControllerOptions explicitOptions)
|
||||||
|
{
|
||||||
|
if (explicitOptions == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Channel = explicitOptions.Channel ?? Channel;
|
||||||
|
SubChannel = explicitOptions.SubChannel ?? SubChannel;
|
||||||
|
Debug = explicitOptions.Debug ?? Debug;
|
||||||
|
DebuggerKey = explicitOptions.DebuggerKey ?? DebuggerKey;
|
||||||
|
SDKArea = explicitOptions.SDKArea ?? SDKArea;
|
||||||
|
Longitude = explicitOptions.Longitude ?? Longitude;
|
||||||
|
Latitude = explicitOptions.Latitude ?? Latitude;
|
||||||
|
ExcludeBundleIds = explicitOptions.ExcludeBundleIds ?? ExcludeBundleIds;
|
||||||
|
RewardedExcludeAdSourceIds = explicitOptions.RewardedExcludeAdSourceIds ?? RewardedExcludeAdSourceIds;
|
||||||
|
QueryAreaOnInit = explicitOptions.QueryAreaOnInit || QueryAreaOnInit;
|
||||||
|
OnAreaReceived = explicitOptions.OnAreaReceived ?? OnAreaReceived;
|
||||||
|
OnAreaError = explicitOptions.OnAreaError ?? OnAreaError;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyDictionary(IDictionary dictionary)
|
||||||
|
{
|
||||||
|
if (dictionary == null || dictionary.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var map = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
foreach (DictionaryEntry entry in dictionary)
|
||||||
|
{
|
||||||
|
if (entry.Key == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
map[entry.Key.ToString()] = ConvertDictionaryValue(entry.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Channel = GetString(map, ChannelKey, "channel") ?? Channel;
|
||||||
|
SubChannel = GetString(map, SubChannelKey, "sub_channel") ?? SubChannel;
|
||||||
|
Debug = GetBool(map, DebugKey, "debug") ?? Debug;
|
||||||
|
DebuggerKey = GetString(map, DebuggerKeyKey) ?? DebuggerKey;
|
||||||
|
SDKArea = GetInt(map, SDKAreaKey) ?? SDKArea;
|
||||||
|
Longitude = GetDouble(map, LongitudeKey) ?? Longitude;
|
||||||
|
Latitude = GetDouble(map, LatitudeKey) ?? Latitude;
|
||||||
|
ExcludeBundleIds = GetStringArray(map, ExcludeBundleIdsKey) ?? ExcludeBundleIds;
|
||||||
|
RewardedExcludeAdSourceIds = GetStringArray(map, RewardedExcludeAdSourceIdsKey) ?? RewardedExcludeAdSourceIds;
|
||||||
|
QueryAreaOnInit = GetBool(map, QueryAreaOnInitKey) ?? QueryAreaOnInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetString(IDictionary<string, string> map, params string[] keys)
|
||||||
|
{
|
||||||
|
foreach (var key in keys)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrWhiteSpace(key) &&
|
||||||
|
map.TryGetValue(key, out var value) &&
|
||||||
|
!string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
return value.Trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool? GetBool(IDictionary<string, string> map, params string[] keys)
|
||||||
|
{
|
||||||
|
var value = GetString(map, keys);
|
||||||
|
return TryConvertBool(value, out var result) ? result : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int? GetInt(IDictionary<string, string> map, params string[] keys)
|
||||||
|
{
|
||||||
|
var value = GetString(map, keys);
|
||||||
|
if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double? GetDouble(IDictionary<string, string> map, params string[] keys)
|
||||||
|
{
|
||||||
|
var value = GetString(map, keys);
|
||||||
|
if (double.TryParse(value, NumberStyles.Float | NumberStyles.AllowThousands, CultureInfo.InvariantCulture,
|
||||||
|
out var result))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string[] GetStringArray(IDictionary<string, string> map, params string[] keys)
|
||||||
|
{
|
||||||
|
var value = GetString(map, keys);
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var normalized = value.Replace("[", string.Empty)
|
||||||
|
.Replace("]", string.Empty)
|
||||||
|
.Replace("\"", string.Empty)
|
||||||
|
.Replace("'", string.Empty);
|
||||||
|
|
||||||
|
var items = normalized
|
||||||
|
.Split(new[] { ',', ';', '|', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
|
.Select(item => item.Trim())
|
||||||
|
.Where(item => !string.IsNullOrWhiteSpace(item))
|
||||||
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
return items.Length > 0 ? items : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool TryConvertBool(object value, out bool result)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case bool boolValue:
|
||||||
|
result = boolValue;
|
||||||
|
return true;
|
||||||
|
case string stringValue:
|
||||||
|
if (bool.TryParse(stringValue, out result))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.Equals(stringValue, "1", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.Equals(stringValue, "0", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string ConvertDictionaryValue(object value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is string stringValue)
|
||||||
|
{
|
||||||
|
return stringValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value is IEnumerable enumerable)
|
||||||
|
{
|
||||||
|
var items = new List<string>();
|
||||||
|
foreach (var item in enumerable)
|
||||||
|
{
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
items.Add(item.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Join(",", items);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs.meta
Normal file
11
Topon_Adapter/Runtime/Scripts/ToponControllerOptions.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 43bf6f5142e2bbc438fdfcb5d521d6e6
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
55
Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs
Normal file
55
Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
public static class ToponUnityThread
|
||||||
|
{
|
||||||
|
private static readonly object SyncRoot = new object();
|
||||||
|
|
||||||
|
private static SynchronizationContext _unityContext;
|
||||||
|
private static int _mainThreadId = -1;
|
||||||
|
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
if (SynchronizationContext.Current == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (SyncRoot)
|
||||||
|
{
|
||||||
|
_unityContext = SynchronizationContext.Current;
|
||||||
|
_mainThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Post(Action action)
|
||||||
|
{
|
||||||
|
if (action == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var context = _unityContext;
|
||||||
|
var currentThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||||
|
if (context == null || currentThreadId == _mainThreadId)
|
||||||
|
{
|
||||||
|
SafeInvoke(action);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Post(_ => SafeInvoke(action), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SafeInvoke(Action action)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
Debug.LogException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs.meta
Normal file
11
Topon_Adapter/Runtime/Scripts/ToponUnityThread.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 9a72c397bbe840342b1a619ec001f28c
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Reference in New Issue
Block a user