fixes, improvements. firebase
This commit is contained in:
@@ -21,6 +21,8 @@ namespace Darkmatter.Services.Ads
|
||||
[SerializeField] private bool autoReload = true;
|
||||
[Tooltip("Seconds between auto-reload retries on failure.")]
|
||||
[SerializeField, Min(1f)] private float reloadDelaySeconds = 5f;
|
||||
[Tooltip("Max reload attempts before giving up.")]
|
||||
[SerializeField, Min(1)] private int reloadMaxAttempts = 6;
|
||||
|
||||
public bool IsInitialized => _initialized;
|
||||
public event Action<AdFormat, AdLoadState> LoadStateChanged;
|
||||
@@ -495,8 +497,14 @@ namespace Darkmatter.Services.Ads
|
||||
{
|
||||
try
|
||||
{
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(reloadDelaySeconds), cancellationToken: cancellationToken);
|
||||
await LoadAsync(format, cancellationToken);
|
||||
for (int attempt = 0; attempt < reloadMaxAttempts; attempt++)
|
||||
{
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(reloadDelaySeconds), cancellationToken: cancellationToken);
|
||||
if (cancellationToken.IsCancellationRequested) return;
|
||||
if (IsReady(format)) return;
|
||||
if (await LoadAsync(format, cancellationToken)) return;
|
||||
}
|
||||
Debug.LogWarning($"[AdMobAdService] {format} reload gave up after {reloadMaxAttempts} attempts.");
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
}
|
||||
|
||||
@@ -9,9 +9,7 @@ namespace Darkmatter.Services.Analytics
|
||||
{
|
||||
public void Register(IContainerBuilder builder)
|
||||
{
|
||||
#if FIREBASE_ANALYTICS_PRESENT
|
||||
builder.RegisterEntryPoint<FirebaseAnalyticsSystem>();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
#if FIREBASE_ANALYTICS
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Firebase.Crashlytics;
|
||||
@@ -10,7 +9,6 @@ namespace Darkmatter.Services.Analytics
|
||||
{
|
||||
public async UniTask StartAsync(CancellationToken cancellation = new CancellationToken())
|
||||
{
|
||||
#if !UNITY_EDITOR
|
||||
await Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
|
||||
{
|
||||
var dependencyStatus = task.Result;
|
||||
@@ -39,8 +37,6 @@ namespace Darkmatter.Services.Analytics
|
||||
// Firebase Unity SDK is not safe to use here.
|
||||
}
|
||||
}, cancellation);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Darkmatter.Services.Gallery
|
||||
{
|
||||
[Serializable]
|
||||
public struct GalleryConfig
|
||||
{
|
||||
public Texture2D Background { get; }
|
||||
|
||||
public GalleryConfig(Texture2D background)
|
||||
{
|
||||
Background = background;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf2070de4e452444fa248a03c10928a6
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Darkmatter.Core.Contracts.Services.Gallery;
|
||||
@@ -8,36 +10,123 @@ namespace Darkmatter.Services.Gallery
|
||||
{
|
||||
public class GalleryService : IGalleryService
|
||||
{
|
||||
private readonly GalleryConfig _config;
|
||||
|
||||
public GalleryService(GalleryConfig config) => _config = config;
|
||||
|
||||
public async UniTask SaveImageAsync(Texture2D image, string fileName, CancellationToken cancellationToken)
|
||||
{
|
||||
var permission = await NativeGallery.RequestPermissionAsync(NativeGallery.PermissionType.Write,
|
||||
NativeGallery.MediaType.Image);
|
||||
|
||||
if (permission != NativeGallery.Permission.Granted)
|
||||
Texture2D composited = null;
|
||||
Texture2D toSave = image;
|
||||
if (_config.Background != null)
|
||||
{
|
||||
return;
|
||||
composited = CompositeOverBackground(image, _config.Background);
|
||||
toSave = composited;
|
||||
}
|
||||
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
var registration = cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken));
|
||||
var resolvedName = BuildUniqueFileName(fileName);
|
||||
|
||||
NativeGallery.SaveImageToGallery(image, "Colorbook",
|
||||
filename: $"colorbook_{DateTime.UtcNow:yyyyMMdd_HHmmss}.png", callback: (success, path) =>
|
||||
try
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
var bytes = toSave.EncodeToPNG();
|
||||
var dir = Path.Combine(Application.persistentDataPath, "Colorbook-Gallery");
|
||||
Directory.CreateDirectory(dir);
|
||||
var path = Path.Combine(dir, resolvedName);
|
||||
await File.WriteAllBytesAsync(path, bytes, cancellationToken);
|
||||
Debug.Log($"[GalleryService] (Editor) Image saved to: {path}");
|
||||
#else
|
||||
var permission = await NativeGallery.RequestPermissionAsync(NativeGallery.PermissionType.Write,
|
||||
NativeGallery.MediaType.Image);
|
||||
|
||||
if (permission != NativeGallery.Permission.Granted)
|
||||
{
|
||||
registration.Dispose();
|
||||
if (!success)
|
||||
{
|
||||
Debug.LogError("Failed to save image to gallery.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"Image saved to gallery at: {path}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
tcs.TrySetResult();
|
||||
});
|
||||
var tcs = new UniTaskCompletionSource();
|
||||
var registration = cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken));
|
||||
|
||||
await tcs.Task;
|
||||
NativeGallery.SaveImageToGallery(toSave, "Colorbook",
|
||||
filename: resolvedName, callback: (success, path) =>
|
||||
{
|
||||
registration.Dispose();
|
||||
if (!success)
|
||||
{
|
||||
Debug.LogError("Failed to save image to gallery.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"Image saved to gallery at: {path}");
|
||||
}
|
||||
|
||||
tcs.TrySetResult();
|
||||
});
|
||||
|
||||
await tcs.Task;
|
||||
#endif
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (composited != null) UnityEngine.Object.Destroy(composited);
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildUniqueFileName(string baseName)
|
||||
{
|
||||
var prefix = Sanitize(baseName);
|
||||
if (string.IsNullOrEmpty(prefix)) prefix = "drawing";
|
||||
return $"{prefix}_{DateTime.UtcNow:yyyyMMdd_HHmmssfff}.png";
|
||||
}
|
||||
|
||||
private static string Sanitize(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s)) return null;
|
||||
var name = Path.GetFileNameWithoutExtension(s).Trim();
|
||||
var sb = new StringBuilder(name.Length);
|
||||
foreach (var c in name)
|
||||
{
|
||||
if (char.IsLetterOrDigit(c)) sb.Append(c);
|
||||
else if (c == ' ' || c == '-' || c == '_') sb.Append('_');
|
||||
}
|
||||
return sb.Length == 0 ? null : sb.ToString();
|
||||
}
|
||||
|
||||
private static Texture2D CompositeOverBackground(Texture2D captured, Texture2D background)
|
||||
{
|
||||
int bgW = background.width;
|
||||
int bgH = background.height;
|
||||
int cW = captured.width;
|
||||
int cH = captured.height;
|
||||
|
||||
float fit = Mathf.Min(1f, Mathf.Min((float)bgW / cW, (float)bgH / cH));
|
||||
int finalW = Mathf.Max(1, Mathf.RoundToInt(cW * fit));
|
||||
int finalH = Mathf.Max(1, Mathf.RoundToInt(cH * fit));
|
||||
int offsetX = (bgW - finalW) / 2;
|
||||
int offsetY = (bgH - finalH) / 2;
|
||||
|
||||
var rt = RenderTexture.GetTemporary(bgW, bgH, 0, RenderTextureFormat.ARGB32);
|
||||
var prev = RenderTexture.active;
|
||||
try
|
||||
{
|
||||
Graphics.Blit(background, rt);
|
||||
|
||||
RenderTexture.active = rt;
|
||||
GL.PushMatrix();
|
||||
GL.LoadPixelMatrix(0, bgW, bgH, 0);
|
||||
Graphics.DrawTexture(new Rect(offsetX, offsetY, finalW, finalH), captured);
|
||||
GL.PopMatrix();
|
||||
|
||||
var output = new Texture2D(bgW, bgH, TextureFormat.RGBA32, mipChain: false);
|
||||
output.ReadPixels(new Rect(0, 0, bgW, bgH), 0, 0);
|
||||
output.Apply();
|
||||
return output;
|
||||
}
|
||||
finally
|
||||
{
|
||||
RenderTexture.active = prev;
|
||||
RenderTexture.ReleaseTemporary(rt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,11 @@ namespace Darkmatter.Services.Gallery
|
||||
{
|
||||
public class GalleryModule : MonoBehaviour,IModule
|
||||
{
|
||||
[SerializeField] private Texture2D saveBackground;
|
||||
|
||||
public void Register(IContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterInstance(new GalleryConfig(saveBackground));
|
||||
builder.Register<IGalleryService,GalleryService>(Lifetime.Singleton);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user