Fix method signatures for apple machines

This commit is contained in:
Michal Pikulski
2025-11-25 15:48:18 +01:00
parent 83fcf24f52
commit a02b70e1f7
12 changed files with 1077 additions and 78 deletions

View File

@@ -0,0 +1,399 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Core;
using UnityEngine;
using SDev;
namespace Minigames.StatueDressup.Utils
{
/// <summary>
/// Manages statue photo capture, storage, and retrieval.
/// Supports area-limited screenshots, persistent file storage (mobile + PC),
/// and optimized gallery loading with pagination.
/// </summary>
public static class StatuePhotoManager
{
private const string PHOTO_FOLDER = "StatuePhotos";
private const string PHOTO_PREFIX = "MrCementStatue_";
private const string METADATA_KEY_PREFIX = "StatuePhoto_Meta_";
private const string PHOTO_INDEX_KEY = "StatuePhoto_Index";
/// <summary>
/// Photo metadata stored in PlayerPrefs
/// </summary>
[System.Serializable]
public class PhotoMetadata
{
public string photoId;
public string timestamp;
public int decorationCount;
public long fileSizeBytes;
}
#region Capture
/// <summary>
/// Capture a specific area of the screen using Screenshot Helper
/// </summary>
/// <param name="captureArea">RectTransform defining the capture region</param>
/// <param name="onComplete">Callback with captured Texture2D</param>
/// <param name="mainCamera">Camera used for coordinate conversion (null = Camera.main)</param>
public static void CaptureAreaPhoto(RectTransform captureArea, Action<Texture2D> onComplete, Camera mainCamera = null)
{
if (captureArea == null)
{
Logging.Error("[StatuePhotoManager] CaptureArea RectTransform is null!");
onComplete?.Invoke(null);
return;
}
if (mainCamera == null) mainCamera = Camera.main;
// Get screen rect from RectTransform
Rect screenRect = GetScreenRectFromRectTransform(captureArea, mainCamera);
Logging.Debug($"[StatuePhotoManager] Capturing area: pos={screenRect.position}, size={screenRect.size}");
// Use Screenshot Helper's Capture method
ScreenshotHelper.Instance.Capture(
screenRect.position,
screenRect.size,
(Texture2D texture) =>
{
if (texture != null)
{
Logging.Debug($"[StatuePhotoManager] Photo captured: {texture.width}x{texture.height}");
onComplete?.Invoke(texture);
}
else
{
Logging.Error("[StatuePhotoManager] Screenshot Helper returned null texture!");
onComplete?.Invoke(null);
}
}
);
}
/// <summary>
/// Convert RectTransform world corners to screen space rect
/// </summary>
private static Rect GetScreenRectFromRectTransform(RectTransform rectTransform, Camera camera)
{
Vector3[] corners = new Vector3[4];
rectTransform.GetWorldCorners(corners);
Vector2 min = RectTransformUtility.WorldToScreenPoint(camera, corners[0]);
Vector2 max = RectTransformUtility.WorldToScreenPoint(camera, corners[2]);
// Ensure positive dimensions
float width = Mathf.Abs(max.x - min.x);
float height = Mathf.Abs(max.y - min.y);
return new Rect(min.x, min.y, width, height);
}
#endregion
#region Save/Load
/// <summary>
/// Save photo to persistent storage with metadata
/// </summary>
/// <param name="photo">Texture2D to save</param>
/// <param name="decorationCount">Number of decorations placed (for metadata)</param>
/// <returns>Photo ID if successful, null if failed</returns>
public static string SavePhoto(Texture2D photo, int decorationCount = 0)
{
if (photo == null)
{
Logging.Error("[StatuePhotoManager] Cannot save null photo");
return null;
}
try
{
// Generate unique photo ID
string photoId = $"{PHOTO_PREFIX}{DateTime.Now.Ticks}";
// Save texture using FileSaveUtil
string savedPath = FileSaveUtil.Instance.SaveTextureAsPNG(
photo,
FileSaveUtil.AppPath.PersistentDataPath,
PHOTO_FOLDER,
photoId
);
// Calculate file size
FileInfo fileInfo = new FileInfo(savedPath);
long fileSize = fileInfo.Exists ? fileInfo.Length : 0;
// Save metadata
PhotoMetadata metadata = new PhotoMetadata
{
photoId = photoId,
timestamp = DateTime.Now.ToString("o"),
decorationCount = decorationCount,
fileSizeBytes = fileSize
};
SaveMetadata(metadata);
AddToPhotoIndex(photoId);
Logging.Debug($"[StatuePhotoManager] Photo saved: {savedPath} ({fileSize} bytes)");
return photoId;
}
catch (Exception e)
{
Logging.Error($"[StatuePhotoManager] Failed to save photo: {e.Message}");
return null;
}
}
/// <summary>
/// Load photo texture from storage
/// </summary>
public static Texture2D LoadPhoto(string photoId)
{
if (string.IsNullOrEmpty(photoId))
{
Logging.Warning("[StatuePhotoManager] PhotoId is null or empty");
return null;
}
try
{
string filePath = GetPhotoFilePath(photoId);
if (!File.Exists(filePath))
{
Logging.Warning($"[StatuePhotoManager] Photo not found: {filePath}");
return null;
}
byte[] fileData = File.ReadAllBytes(filePath);
Texture2D texture = new Texture2D(2, 2, TextureFormat.RGBA32, false);
if (texture.LoadImage(fileData))
{
Logging.Debug($"[StatuePhotoManager] Photo loaded: {photoId} ({texture.width}x{texture.height})");
return texture;
}
else
{
Logging.Error($"[StatuePhotoManager] Failed to decode image: {photoId}");
UnityEngine.Object.Destroy(texture);
return null;
}
}
catch (Exception e)
{
Logging.Error($"[StatuePhotoManager] Failed to load photo {photoId}: {e.Message}");
return null;
}
}
/// <summary>
/// Delete photo and its metadata
/// </summary>
public static bool DeletePhoto(string photoId)
{
if (string.IsNullOrEmpty(photoId)) return false;
try
{
string filePath = GetPhotoFilePath(photoId);
if (File.Exists(filePath))
{
File.Delete(filePath);
}
DeleteMetadata(photoId);
RemoveFromPhotoIndex(photoId);
Logging.Debug($"[StatuePhotoManager] Photo deleted: {photoId}");
return true;
}
catch (Exception e)
{
Logging.Error($"[StatuePhotoManager] Failed to delete photo {photoId}: {e.Message}");
return false;
}
}
#endregion
#region Gallery Support
/// <summary>
/// Get all photo IDs sorted by timestamp (newest first)
/// </summary>
public static List<string> GetAllPhotoIds()
{
string indexJson = PlayerPrefs.GetString(PHOTO_INDEX_KEY, "[]");
List<string> photoIds = JsonUtility.FromJson<PhotoIdList>(WrapJsonArray(indexJson))?.ids ?? new List<string>();
// Sort by timestamp descending (newest first)
photoIds.Sort((a, b) =>
{
PhotoMetadata metaA = LoadMetadata(a);
PhotoMetadata metaB = LoadMetadata(b);
DateTime dateA = DateTime.Parse(metaA?.timestamp ?? DateTime.MinValue.ToString("o"));
DateTime dateB = DateTime.Parse(metaB?.timestamp ?? DateTime.MinValue.ToString("o"));
return dateB.CompareTo(dateA);
});
return photoIds;
}
/// <summary>
/// Get paginated photo IDs for optimized gallery loading
/// </summary>
/// <param name="page">Page number (0-indexed)</param>
/// <param name="pageSize">Number of items per page</param>
public static List<string> GetPhotoIdsPage(int page, int pageSize)
{
List<string> allIds = GetAllPhotoIds();
int startIndex = page * pageSize;
if (startIndex >= allIds.Count) return new List<string>();
int count = Mathf.Min(pageSize, allIds.Count - startIndex);
return allIds.GetRange(startIndex, count);
}
/// <summary>
/// Get total number of saved photos
/// </summary>
public static int GetPhotoCount()
{
return GetAllPhotoIds().Count;
}
/// <summary>
/// Get latest photo ID (most recent)
/// </summary>
public static string GetLatestPhotoId()
{
List<string> allIds = GetAllPhotoIds();
return allIds.Count > 0 ? allIds[0] : null;
}
/// <summary>
/// Load photo metadata
/// </summary>
public static PhotoMetadata GetPhotoMetadata(string photoId)
{
return LoadMetadata(photoId);
}
/// <summary>
/// Create thumbnail from full-size photo (for gallery preview)
/// </summary>
public static Texture2D CreateThumbnail(Texture2D fullSizePhoto, int maxSize = 256)
{
if (fullSizePhoto == null) return null;
int width = fullSizePhoto.width;
int height = fullSizePhoto.height;
// Calculate thumbnail size maintaining aspect ratio
float scale = Mathf.Min((float)maxSize / width, (float)maxSize / height);
int thumbWidth = Mathf.RoundToInt(width * scale);
int thumbHeight = Mathf.RoundToInt(height * scale);
// Create thumbnail using bilinear filtering
RenderTexture rt = RenderTexture.GetTemporary(thumbWidth, thumbHeight, 0, RenderTextureFormat.ARGB32);
RenderTexture.active = rt;
Graphics.Blit(fullSizePhoto, rt);
Texture2D thumbnail = new Texture2D(thumbWidth, thumbHeight, TextureFormat.RGB24, false);
thumbnail.ReadPixels(new Rect(0, 0, thumbWidth, thumbHeight), 0, 0);
thumbnail.Apply();
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(rt);
return thumbnail;
}
#endregion
#region Internal Helpers
public static string GetPhotoDirectory()
{
return Path.Combine(Application.persistentDataPath, PHOTO_FOLDER);
}
private static string GetPhotoFilePath(string photoId)
{
return Path.Combine(GetPhotoDirectory(), $"{photoId}.png");
}
private static void SaveMetadata(PhotoMetadata metadata)
{
string json = JsonUtility.ToJson(metadata);
PlayerPrefs.SetString(METADATA_KEY_PREFIX + metadata.photoId, json);
PlayerPrefs.Save();
}
private static PhotoMetadata LoadMetadata(string photoId)
{
string json = PlayerPrefs.GetString(METADATA_KEY_PREFIX + photoId, null);
return string.IsNullOrEmpty(json) ? null : JsonUtility.FromJson<PhotoMetadata>(json);
}
private static void DeleteMetadata(string photoId)
{
PlayerPrefs.DeleteKey(METADATA_KEY_PREFIX + photoId);
PlayerPrefs.Save();
}
private static void AddToPhotoIndex(string photoId)
{
List<string> photoIds = GetAllPhotoIds();
if (!photoIds.Contains(photoId))
{
photoIds.Add(photoId);
SavePhotoIndex(photoIds);
}
}
private static void RemoveFromPhotoIndex(string photoId)
{
List<string> photoIds = GetAllPhotoIds();
if (photoIds.Remove(photoId))
{
SavePhotoIndex(photoIds);
}
}
private static void SavePhotoIndex(List<string> photoIds)
{
string json = JsonUtility.ToJson(new PhotoIdList { ids = photoIds });
PlayerPrefs.SetString(PHOTO_INDEX_KEY, json);
PlayerPrefs.Save();
}
private static string WrapJsonArray(string json)
{
if (json.StartsWith("[")) return "{\"ids\":" + json + "}";
return json;
}
[System.Serializable]
private class PhotoIdList
{
public List<string> ids = new List<string>();
}
#endregion
}
}