Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
yukieiji committed Sep 28, 2024
2 parents 322003c + 784b7b9 commit 64204d1
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 47 deletions.
4 changes: 2 additions & 2 deletions ExtremeRoles/ExtremeRoles.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
<WarningLevel>7</WarningLevel>
<Version>12.0.1.2</Version>
<!--<VersionPrefix>12.0.1</VersionPrefix>-->
<!--<Version>12.0.2</Version>-->
<VersionPrefix>12.0.2</VersionPrefix>
<VersionSuffix>Invitation-AmongUsV2024813</VersionSuffix>
<Description>Extreme Roles for Advanced user</Description>
<Authors>yukieiji</Authors>
Expand Down
142 changes: 142 additions & 0 deletions ExtremeRoles/Module/LruCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using UnityEngine.XR;

namespace ExtremeRoles.Module;

#nullable enable

public class LruCache<TKey, TValue>
where TKey : IEquatable<TKey>
where TValue : UnityEngine.Object
{
public static void Add(TKey key, TValue value)
{
if (instance == null)
{
instance = new LruCache<TKey, TValue>(DEFAULT_CAPACITY);
}
instance.add(key, value);
}
public static bool TryGetValue(TKey key, [NotNullWhen(true)] out TValue? value)
{
if (instance == null)
{
instance = new LruCache<TKey, TValue>(DEFAULT_CAPACITY);
}
return instance.tryGetValue(key, out value);
}


private static LruCache<TKey, TValue>? instance;
private const int DEFAULT_CAPACITY = 10000;

private readonly int capacity;
private readonly Dictionary<TKey, LinkedListNode<CacheItem>> cacheMap;
private readonly LinkedList<CacheItem> lruList;
private readonly ReaderWriterLockSlim @lock = new ReaderWriterLockSlim();

public LruCache(int capacity)
{
this.capacity = capacity;
cacheMap = new Dictionary<TKey, LinkedListNode<CacheItem>>(this.capacity);
lruList = new LinkedList<CacheItem>();
}

~LruCache()
{
@lock.Dispose();
}

private bool tryGetValue(TKey key, [NotNullWhen(true)] out TValue? value)
{
@lock.EnterReadLock(); // 読み取りロック
try
{
if (cacheMap.TryGetValue(key, out var node) &&
node != null &&
node.Value.Value != null)
{
// 読み取りロックを解除してから、書き込みロックを取得して更新操作を行う
@lock.ExitReadLock();
@lock.EnterWriteLock();

try
{
// Accessed node becomes most recently used, so move it to the front of the list
lruList.Remove(node);
lruList.AddFirst(node);
}
finally
{
@lock.ExitWriteLock();
}

value = node.Value.Value;
return true;
}

value = default;
return false;
}
finally
{
if (@lock.IsReadLockHeld)
{
@lock.ExitReadLock(); // 読み取りロック解除
}
}
}

private void add(TKey key, TValue value)
{
@lock.EnterWriteLock();
try
{
if (cacheMap.TryGetValue(key, out var checkNode) &&
(checkNode == null || checkNode.Value.Value == null))
{
cacheMap.Remove(key);
lruList.RemoveLast();
}
else if (cacheMap.ContainsKey(key))
{
throw new ArgumentException();
}
else if (cacheMap.Count >= capacity)
{
// If the cache is full, remove the least recently used item (last in the list)
var lruNode = lruList.Last;
if (lruNode != null)
{
if (cacheMap.TryGetValue(lruNode.Value.Key, out var node) &&
node != null &&
node.Value.Value != null)
{
UnityEngine.Object.Destroy(node.Value.Value);
}
cacheMap.Remove(lruNode.Value.Key);
lruList.RemoveLast();
}
}

// Add new item to the cache and mark it as most recently used
var cacheItem = new CacheItem(key, value);
var newNode = new LinkedListNode<CacheItem>(cacheItem);
lruList.AddFirst(newNode);
Helper.Logging.Debug($"Add CacheItem({typeof(TKey).Name}):{key}");
cacheMap[key] = newNode;
}
finally
{
if (@lock.IsWriteLockHeld)
{
@lock.ExitWriteLock();
}
}
}

private sealed record CacheItem(TKey Key, TValue Value);
}
21 changes: 13 additions & 8 deletions ExtremeRoles/Resources/Loader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using UnityEngine;

using ExtremeRoles.Module;
using ExtremeRoles.Module.CustomMonoBehaviour.UIPart;

using UnityObject = UnityEngine.Object;
Expand Down Expand Up @@ -175,10 +176,8 @@ public static void ResetCache()
bundle.Unload(false);
}
cachedBundle.Clear();
cachedSprite.Clear();
}

private static readonly Dictionary<string, Sprite> cachedSprite = new Dictionary<string, Sprite> ();
private static readonly Dictionary<string, AssetBundle> cachedBundle = new Dictionary<string, AssetBundle>();

public static SimpleButton CreateSimpleButton(Transform parent)
Expand All @@ -197,17 +196,23 @@ public static Sprite LoadSpriteFromResources(
{
string key = $"{path}{pixelsPerUnit}";

if (cachedSprite.TryGetValue(key, out Sprite? sprite) ||
sprite != null) { return sprite; }
if (LruCache<string, Sprite>.TryGetValue(key, out var sprite))
{
return sprite;
}

Texture2D texture = createTextureFromResources(path);
if (!LruCache<string, Texture2D>.TryGetValue(key, out var texture))
{
texture = createTextureFromResources(path);
LruCache<string, Texture2D>.Add(key, texture);
}
sprite = Sprite.Create(
texture,
new Rect(0, 0, texture.width, texture.height),
new Vector2(0.5f, 0.5f), pixelsPerUnit);

sprite.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontSaveInEditor;
cachedSprite.Add(key, sprite);
sprite.hideFlags |= HideFlags.DontSaveInEditor;
LruCache<string, Sprite>.Add(key, sprite);

return sprite;
}
Expand Down Expand Up @@ -350,7 +355,7 @@ private static AssetBundle GetAssetBundleFromAssembly(
private static AssetBundle loadAssetFromByteArray(Il2CppStructArray<byte> byteArray)
{
AssetBundle bundle = AssetBundle.LoadFromMemory(byteArray);
bundle.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontSaveInEditor;
bundle.hideFlags |= HideFlags.DontSaveInEditor;
return bundle;
}

Expand Down
8 changes: 2 additions & 6 deletions ExtremeRoles/Roles/API/FlexibleCombinationRoleManagerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,9 @@ public override void AssignSetUpInit(int curImpNum)

bool isEvil = impOpt.Value;

var spawnOption = cate.GetValueOption<CombinationRoleCommonOption, int>(
int spawnOption = cate.GetValue<CombinationRoleCommonOption, int>(
CombinationRoleCommonOption.ImposterSelectedRate);
isEvil = isEvil &&
(UnityEngine.Random.RandomRange(0, 110) < (int)decimal.Multiply(
spawnOption.Value, spawnOption.Range)) &&
curImpNum < GameOptionsManager.Instance.CurrentGameOptions.GetInt(
Int32OptionNames.NumImpostors);
isEvil = isEvil && spawnOption >= RandomGenerator.Instance.Next(1, 101);

if (isEvil)
{
Expand Down
5 changes: 3 additions & 2 deletions ExtremeRoles/Roles/Combination/DetectiveOffice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -678,10 +678,11 @@ public static void ChangeToDetectiveApprentice(
}

int offset = 2 * ExtremeRoleManager.OptionOffsetPerRole;
var loader = new OptionLoadWrapper(cate, offset);
DetectiveApprentice newRole = new DetectiveApprentice(
prevRole.Loader,
loader,
prevRole.GameControlId,
DetectiveApprenticeOptionHolder.LoadOptions(new OptionLoadWrapper(cate, offset)));
DetectiveApprenticeOptionHolder.LoadOptions(loader));
if (playerId == PlayerControl.LocalPlayer.PlayerId)
{
newRole.CreateAbility();
Expand Down
4 changes: 2 additions & 2 deletions ExtremeSkins/ExtremeSkins.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
<WarningLevel>7</WarningLevel>
<Version>10.0.0.15</Version>
<!--<VersionPrefix>10.0.0</VersionPrefix>-->
<!--<Version>10.0.1.0</Version>-->
<VersionPrefix>10.0.1</VersionPrefix>
<VersionSuffix>AmongUsv20240618</VersionSuffix>
<Description>Extreme Skins for Extreme Roles</Description>
<Authors>yukieiji</Authors>
Expand Down
25 changes: 18 additions & 7 deletions ExtremeSkins/Module/CustomHat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,30 @@ private HatData crateData()
private static Expected<Sprite, Loader.LoadError> loadHatSprite(
string path)
{
var result = Loader.LoadTextureFromDisk(path);
if (!result.HasValue())
if (LruCache<string, Sprite>.TryGetValue(path, out var sprite))
{
return sprite;
}

if (!LruCache<string, Texture2D>.TryGetValue(path, out var texture))
{
return result.Error;
var result = Loader.LoadTextureFromDisk(path);
if (!result.HasValue())
{
return result.Error;
}
texture = result.Value;
texture.hideFlags |= HideFlags.DontUnloadUnusedAsset;

LruCache<string, Texture2D>.Add(path, texture);
}

Texture2D texture = result.Value;
Sprite sprite = Sprite.Create(
sprite = Sprite.Create(
texture, new Rect(0, 0, texture.width, texture.height),
new Vector2(0.53f, 0.575f), texture.width * 0.375f);
sprite.hideFlags |=HideFlags.DontUnloadUnusedAsset;

texture.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontUnloadUnusedAsset;
sprite.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontUnloadUnusedAsset;
LruCache<string, Sprite>.Add(path, sprite);

return sprite;
}
Expand Down
36 changes: 25 additions & 11 deletions ExtremeSkins/Module/CustomNamePlate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,34 @@ public NamePlateData GetData()
private static Expected<Sprite, Loader.LoadError> loadNamePlateSprite(
string path)
{
var result = Loader.LoadTextureFromDisk(path);
if (!result.HasValue())
{
return result.Error;
}

Texture2D texture = result.Value;
Sprite sprite = Sprite.Create(

if (LruCache<string, Sprite>.TryGetValue(path, out var sprite))
{
return sprite;
}

if (!LruCache<string, Texture2D>.TryGetValue(path, out var texture))
{
var result = Loader.LoadTextureFromDisk(path);
if (!result.HasValue())
{
return result.Error;
}
texture = result.Value;
texture.hideFlags |= HideFlags.DontUnloadUnusedAsset;

LruCache<string, Texture2D>.Add(path, texture);
}

sprite = Sprite.Create(
texture,
new Rect(0, 0, texture.width, texture.height),
new Vector2(0.5f, 0.5f), 100f);
texture.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontUnloadUnusedAsset;
sprite.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontUnloadUnusedAsset;
return sprite;
sprite.hideFlags |= HideFlags.DontUnloadUnusedAsset;

LruCache<string, Sprite>.Add(path, sprite);

return sprite;
}
}

Expand Down
30 changes: 22 additions & 8 deletions ExtremeSkins/Module/CustomVisor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,19 +137,33 @@ private VisorViewData loadViewData()
private static Expected<Sprite, Loader.LoadError> loadVisorSprite(
string path)
{
var result = Loader.LoadTextureFromDisk(path);
if (!result.HasValue())

if (LruCache<string, Sprite>.TryGetValue(path, out var sprite))
{
return result.Error;
return sprite;
}

Texture2D texture = result.Value;
Sprite sprite = Sprite.Create(
if (!LruCache<string, Texture2D>.TryGetValue(path, out var texture))
{
var result = Loader.LoadTextureFromDisk(path);
if (!result.HasValue())
{
return result.Error;
}
texture = result.Value;
texture.hideFlags |= HideFlags.DontUnloadUnusedAsset;

LruCache<string, Texture2D>.Add(path, texture);
}

sprite = Sprite.Create(
texture, new Rect(0, 0, texture.width, texture.height),
new Vector2(0.53f, 0.575f), texture.width * 0.375f);
texture.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontUnloadUnusedAsset;
sprite.hideFlags |= HideFlags.HideAndDontSave | HideFlags.DontUnloadUnusedAsset;
return sprite;
sprite.hideFlags |= HideFlags.DontUnloadUnusedAsset;

LruCache<string, Sprite>.Add(path, sprite);

return sprite;
}
}

Expand Down
2 changes: 1 addition & 1 deletion ExtremeVoiceEngine/ExtremeVoiceEngine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>net6.0</TargetFramework>
<LangVersion>latest</LangVersion>
<WarningLevel>7</WarningLevel>
<Version>2.0.0.77</Version>
<Version>2.0.0.78</Version>
<!--<VersionPrefix>2.0.0</VersionPrefix>-->
<!--<VersionSuffix>AmongUsV20230711</VersionSuffix>-->
<Description>Extreme Voice Engine for bridging Extreme Roles and Voice Engine</Description>
Expand Down

0 comments on commit 64204d1

Please sign in to comment.