Files
ShrinkModFramework/Runtime/Core/ShrinkModContext.cs
T
cneicy 78ccae3e07
Publish UPM package / publish (push) Failing after 1s
chore: initialize standalone UPM package
2026-08-26 02:50:31 +08:00

99 lines
4.5 KiB
C#

using System;
using System.Collections.Generic;
using ShrinkContext;
using UnityEngine;
namespace ShrinkModFramework
{
public sealed class ShrinkModContext
{
private readonly ShrinkModRegistryManager _registryManager;
private readonly IReadOnlyDictionary<string, ShrinkModHandle> _loadedMods;
private readonly bool _verboseLogging;
private readonly ShrinkCtx _effectContext;
internal ShrinkModContext(ShrinkModInfo modInfo, ShrinkModRegistryManager registryManager,
IReadOnlyDictionary<string, ShrinkModHandle> loadedMods, bool verboseLogging,
ShrinkCtx effectContext = null)
{
ModInfo = modInfo;
_registryManager = registryManager;
_loadedMods = loadedMods;
_verboseLogging = verboseLogging;
_effectContext = effectContext;
}
public ShrinkModInfo ModInfo { get; }
public IReadOnlyDictionary<string, ShrinkModHandle> LoadedMods => _loadedMods;
public bool IsContextManaged => _effectContext != null;
public IReadOnlyShrinkModRegistry<T> GetRegistry<T>(string name) =>
_registryManager.GetOrCreateRegistry<T>(name);
public bool TryGetRegistry<T>(string name, out IReadOnlyShrinkModRegistry<T> registry)
=> _registryManager.TryGetRegistry(name, out registry);
/// <summary>用当前 ModId 作为 namespace 注册内容,并返回最终完整键。</summary>
public string RegisterContent<T>(string registryName, string localKey, T value) =>
_registryManager.GetOrCreateMutableRegistry<T>(registryName)
.RegisterNamespaced(ModInfo.ModId, localKey, value);
/// <summary>以当前模组为 owner 覆盖已有内容;同目标、同优先级冲突会直接失败。</summary>
public void OverrideContent<T>(string registryName, string targetKey, int priority, T value) =>
_registryManager.GetOrCreateMutableRegistry<T>(registryName)
.RegisterOverride(ModInfo.ModId, targetKey, priority, value);
public bool IsModLoaded(string modId) => !string.IsNullOrWhiteSpace(modId) && _loadedMods.ContainsKey(modId);
public bool TryGetLoadedMod(string modId, out ShrinkModHandle handle)
{
if (!string.IsNullOrWhiteSpace(modId))
return _loadedMods.TryGetValue(modId, out handle);
handle = null;
return false;
}
/// <summary>
/// 在模组组件上下文中执行前向动作并就地登记逆操作。逆操作随 fiber 卸载按 LIFO 执行。
/// 旧 ShrinkModLoader 路径没有可逆上下文,调用本 API 会明确失败而不是静默丢失 cleanup。
/// </summary>
public void Effect(Action forward, Action inverse)
{
if (_effectContext == null)
throw new InvalidOperationException(
"ShrinkModContext.Effect requires ShrinkModContextHost. The legacy ShrinkModLoader cannot track inverses.");
_effectContext.Effect(forward, inverse);
}
/// <summary>为已完成的前向动作登记同步逆操作。</summary>
public void EffectInverse(Action inverse)
{
if (inverse == null)
throw new ArgumentNullException(nameof(inverse));
Effect(() => { }, inverse);
}
public void Log(string message)
{
if (_verboseLogging)
Debug.Log($"[ShrinkMod:{ModInfo.ModId}] {message}");
}
public void RegisterNetworkHandler<T>(string channel, System.Action<ShrinkModNetworkMessageContext, T> handler)
=> ShrinkModNetworkManager.RegisterHandler(ModInfo.ModId, channel, handler);
public void SendToServer<T>(string channel, T payload, string senderPeerId = null)
=> ShrinkModNetworkManager.SendToServer(ModInfo.ModId, channel, payload, senderPeerId);
public void SendToAllClients<T>(string channel, T payload, string senderPeerId = null)
=> ShrinkModNetworkManager.SendToAllClients(ModInfo.ModId, channel, payload, senderPeerId);
public void SendToClient<T>(string channel, T payload, string targetPeerId, string senderPeerId = null)
=> ShrinkModNetworkManager.SendToClient(ModInfo.ModId, channel, payload, targetPeerId, senderPeerId);
public void LogWarning(string message) => Debug.LogWarning($"[ShrinkMod:{ModInfo.ModId}] {message}");
public void LogError(string message) => Debug.LogError($"[ShrinkMod:{ModInfo.ModId}] {message}");
}
}