Утечки: картинки глав книги, материал кольца пирамиды, мелочи прилива
- Книга: картинка главы при смене главы не удалялась (~2 МБ за смену) - удаляем сами при смене, у главы без картинки и при закрытии окна. - Пирамида: кольцо зоны создавало новый материал при каждой перезагрузке чанка - теперь один общий. - Прилив: не держать стат игрока после выхода из мира; забывать полосы пересобранного HUD. - SpatialVaultPatch: исправлен устаревший комментарий про очистку кэша. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
75e122b6a4
commit
7fd0d405cc
@@ -60,6 +60,7 @@ namespace NecromancerTome
|
|||||||
_origHoldType = -1;
|
_origHoldType = -1;
|
||||||
Heart(false);
|
Heart(false);
|
||||||
Patch_XUiC_HUDStatBar_Update_BloodTide.Forget();
|
Patch_XUiC_HUDStatBar_Update_BloodTide.Forget();
|
||||||
|
Patch_Stat_Tick_BloodTide.Next = null; // не держать стат (а через него игрока) после выхода из мира
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool tide = SnakeMode.IsBloodTide();
|
bool tide = SnakeMode.IsBloodTide();
|
||||||
@@ -293,7 +294,11 @@ namespace NecromancerTome
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!_bars.TryGetValue(__instance, out var e))
|
if (_bars.TryGetValue(__instance, out var e) && e.bar.UiTransform == null)
|
||||||
|
{
|
||||||
|
_bars.Remove(__instance); // окно пересобрано - старая полоса удалена
|
||||||
|
}
|
||||||
|
if (!_bars.TryGetValue(__instance, out e))
|
||||||
{
|
{
|
||||||
if (!BloodTide.Armed || !(__instance.GetChildById("BarContent")?.ViewComponent is XUiV_Sprite s))
|
if (!BloodTide.Armed || !(__instance.GetChildById("BarContent")?.ViewComponent is XUiV_Sprite s))
|
||||||
{
|
{
|
||||||
|
|||||||
+28
-1
@@ -281,6 +281,24 @@ namespace NecromancerTome
|
|||||||
/// <summary>Показать картинку или видео справа (или убрать обе). Видео задаётся только здесь,
|
/// <summary>Показать картинку или видео справа (или убрать обе). Видео задаётся только здесь,
|
||||||
/// а не в вёрстке: XUiV_Video сам запускает ролик при открытии окна, и в оглавлении он играл
|
/// а не в вёрстке: XUiV_Video сам запускает ролик при открытии окна, и в оглавлении он играл
|
||||||
/// бы невидимым. Пустой uri - XUiV_Video.startVideo сам освобождает свою текстуру.</summary>
|
/// бы невидимым. Пустой uri - XUiV_Video.startVideo сам освобождает свою текстуру.</summary>
|
||||||
|
/// <summary>Путь загруженной картинки (null - не загружена). Свой, а не _img.Path - см. ниже.</summary>
|
||||||
|
string _imgPath;
|
||||||
|
|
||||||
|
void ReleaseImage()
|
||||||
|
{
|
||||||
|
if (_img == null || _imgPath == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Texture t = _img.Texture;
|
||||||
|
_img.Path = null; // TextureUris = пусто, Texture = null - без выгрузки (autounload выключен)
|
||||||
|
if (t != null)
|
||||||
|
{
|
||||||
|
UnityEngine.Object.Destroy(t);
|
||||||
|
}
|
||||||
|
_imgPath = null;
|
||||||
|
}
|
||||||
|
|
||||||
void SetMedia(string _image, string _video, bool _top = false)
|
void SetMedia(string _image, string _video, bool _top = false)
|
||||||
{
|
{
|
||||||
bool img = !string.IsNullOrEmpty(_image), vid = !img && !string.IsNullOrEmpty(_video);
|
bool img = !string.IsNullOrEmpty(_image), vid = !img && !string.IsNullOrEmpty(_video);
|
||||||
@@ -289,9 +307,18 @@ namespace NecromancerTome
|
|||||||
// Без чтения _img.Path: у пустой картинки (в вёрстке texture не задан) его геттер берёт
|
// Без чтения _img.Path: у пустой картинки (в вёрстке texture не задан) его геттер берёт
|
||||||
// textureUris[0] из пустого массива - IndexOutOfRange (тест 09.10). Сеттер сам сравнивает
|
// textureUris[0] из пустого массива - IndexOutOfRange (тест 09.10). Сеттер сам сравнивает
|
||||||
// с текущим путём и не перезагружает тот же файл.
|
// с текущим путём и не перезагружает тот же файл.
|
||||||
if (img)
|
// Утечка (проверка 10.10): картинка из файла мода - новая текстура (XUiV_Texture.FetchWwwTexture, клон),
|
||||||
|
// и при смене пути старая сама не удаляется (autounload в вёрстке не включён - в этом режиме игра на
|
||||||
|
// загрузке стирает путь новой картинки). Каждая смена главы оставляла ~2 МБ. Удаляем сами: при смене
|
||||||
|
// картинки, у главы без картинки и при закрытии окна (SetMedia(null, null)).
|
||||||
|
if (_imgPath != _image)
|
||||||
|
{
|
||||||
|
ReleaseImage();
|
||||||
|
}
|
||||||
|
if (img && _imgPath == null)
|
||||||
{
|
{
|
||||||
_img.Path = _image;
|
_img.Path = _image;
|
||||||
|
_imgPath = _image;
|
||||||
}
|
}
|
||||||
_img.IsVisible = img;
|
_img.IsVisible = img;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -319,6 +319,7 @@ namespace NecromancerTome
|
|||||||
// светящееся фиолетовое кольцо по земле - LineRenderer, точки опущены на рельеф лучом.
|
// светящееся фиолетовое кольцо по земле - LineRenderer, точки опущены на рельеф лучом.
|
||||||
// Дочерний объект модели блока - поэтому сдвиги Origin и выгрузка чанка его не теряют.
|
// Дочерний объект модели блока - поэтому сдвиги Origin и выгрузка чанка его не теряют.
|
||||||
GameObject ring;
|
GameObject ring;
|
||||||
|
static Material _ringMat;
|
||||||
|
|
||||||
public void SpawnZoneRing()
|
public void SpawnZoneRing()
|
||||||
{
|
{
|
||||||
@@ -332,8 +333,13 @@ namespace NecromancerTome
|
|||||||
const int n = 96;
|
const int n = 96;
|
||||||
lr.positionCount = n;
|
lr.positionCount = n;
|
||||||
lr.widthMultiplier = 0.14f;
|
lr.widthMultiplier = 0.14f;
|
||||||
var mat = new Material(Shader.Find("Sprites/Default"));
|
// Один материал на все кольца (проверка утечек 10.10): материал - ассет и с объектом кольца не удаляется,
|
||||||
lr.material = mat;
|
// а кольцо пересоздаётся при каждой перезагрузке чанка (модель блока - новая). Цвет - вершинный (startColor).
|
||||||
|
if (_ringMat == null)
|
||||||
|
{
|
||||||
|
_ringMat = new Material(Shader.Find("Sprites/Default")) { name = "NecroWardRing" };
|
||||||
|
}
|
||||||
|
lr.sharedMaterial = _ringMat;
|
||||||
Color col = new Color(0.75f, 0.25f, 1f, 0.85f);
|
Color col = new Color(0.75f, 0.25f, 1f, 0.85f);
|
||||||
lr.startColor = col; lr.endColor = col;
|
lr.startColor = col; lr.endColor = col;
|
||||||
lr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; lr.receiveShadows = false;
|
lr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; lr.receiveShadows = false;
|
||||||
|
|||||||
@@ -68,8 +68,10 @@ namespace NecromancerTome
|
|||||||
public const float ShoveDistance = 6f;
|
public const float ShoveDistance = 6f;
|
||||||
|
|
||||||
/// <summary>Session cache only - the durable copy lives on disk, see
|
/// <summary>Session cache only - the durable copy lives on disk, see
|
||||||
/// SpatialVaultPersistence.cs. Cleared on WorldShuttingDown so a different save loaded
|
/// SpatialVaultPersistence.cs. NOT cleared on WorldShuttingDown any more (that event fires before
|
||||||
/// afterwards cannot inherit this world's vault through a recycled entityId.</summary>
|
/// the final player save and wiped vaults - see SpatialVaultPersistence.cs); a different save cannot
|
||||||
|
/// inherit this world's vault because ToPlayer overwrites or removes the entry on load. Leftover entries
|
||||||
|
/// are at most one per world loaded in a session - not a growing leak (checked 10.10).</summary>
|
||||||
public static readonly Dictionary<int, Bag> PlayerVaults = new Dictionary<int, Bag>();
|
public static readonly Dictionary<int, Bag> PlayerVaults = new Dictionary<int, Bag>();
|
||||||
|
|
||||||
public static bool Prefix(ItemActionData _actionData, bool _bReleased)
|
public static bool Prefix(ItemActionData _actionData, bool _bReleased)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user