Private
Public Access
1
0

try to decrease allocations

This commit is contained in:
2026-03-21 04:18:11 +01:00
parent 734970a6ff
commit e9e4fec229
5 changed files with 84 additions and 68 deletions

View File

@@ -1,5 +1,5 @@
{ {
"total": 592730, "total": 602351,
"sessions": [ "sessions": [
{ {
"begin": "2026-01-09T17:26:02+01:00", "begin": "2026-01-09T17:26:02+01:00",
@@ -1355,6 +1355,11 @@
"begin": "2026-03-21T01:18:07+01:00", "begin": "2026-03-21T01:18:07+01:00",
"end": "2026-03-21T01:43:24+01:00", "end": "2026-03-21T01:43:24+01:00",
"duration": 1517 "duration": 1517
},
{
"begin": "2026-03-21T01:43:25+01:00",
"end": "2026-03-21T04:23:47+01:00",
"duration": 9621
} }
] ]
} }

View File

@@ -24,13 +24,7 @@ public interface IPlantPositionRegistry
) )
GetPlantCountsNearPosition(BlockPos hivePos, int radius); GetPlantCountsNearPosition(BlockPos hivePos, int radius);
( (float InitialScanProgress, float RescanProgress) GetPlantsNearPosition(BlockPos hivePos, int radius, List<StructVec3i> flowerPositionsBuffer, List<StructVec3i> cropPositionsBuffer);
IEnumerable<BlockPos> Flowers,
IEnumerable<BlockPos> Crops,
float InitialScanProgress,
float RescanProgress
)
GetPlantsNearPosition(BlockPos hivePos, int radius);
void RegisterBeehive(BlockPos pos, int radius); void RegisterBeehive(BlockPos pos, int radius);

View File

@@ -81,26 +81,33 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry
} }
public ( public (
IEnumerable<BlockPos> Flowers,
IEnumerable<BlockPos> Crops,
float InitialScanProgress, float InitialScanProgress,
float RescanProgress float RescanProgress
) GetPlantsNearPosition(BlockPos hivePos, int radius) ) GetPlantsNearPosition(BlockPos hivePos, int radius, List<StructVec3i> flowerPositionsBuffer, List<StructVec3i> cropPositionsBuffer)
{ {
flowerPositionsBuffer.Clear();
cropPositionsBuffer.Clear();
var key = StructVec3i.FromBlockPos(hivePos); var key = StructVec3i.FromBlockPos(hivePos);
var flowers = flowerPositions foreach (var flowerPos in flowerPositions)
.Where(p => Overlaps.IsWithinSphericalRadius(hivePos, p, radius)) {
.Select(p => new BlockPos(p.X, p.Y, p.Z, hivePos.dimension)); if (!Overlaps.IsWithinSphericalRadius(hivePos, flowerPos, radius))
continue;
flowerPositionsBuffer.Add(flowerPos);
}
var crops = cropPositions foreach (var cropPos in cropPositions)
.Where(p => Overlaps.IsWithinSphericalRadius(hivePos, p, radius)) {
.Select(p => new BlockPos(p.X, p.Y, p.Z, hivePos.dimension)); if (!Overlaps.IsWithinSphericalRadius(hivePos, cropPos, radius))
continue;
cropPositionsBuffer.Add(cropPos);
}
float initialProgress = 1.0f; float initialProgress = 1.0f;
float rescanProgress = 0.0f; float rescanProgress = 0.0f;
if (!beehives.TryGetValue(key, out var cursor)) if (!beehives.TryGetValue(key, out var cursor))
return (flowers, crops, initialProgress, rescanProgress); return (initialProgress, rescanProgress);
var table = offsetTables[cursor.Radius]; var table = offsetTables[cursor.Radius];
if (table.Count > 0) if (table.Count > 0)
@@ -109,13 +116,24 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry
rescanProgress = cursor.GetRescanProgress(offsetTables); rescanProgress = cursor.GetRescanProgress(offsetTables);
} }
return (flowers, crops, initialProgress, rescanProgress); return (initialProgress, rescanProgress);
} }
public (int FlowerCount, int CropCount, float InitialScanProgress, float RescanProgress) GetPlantCountsNearPosition(BlockPos hivePos, int radius) public (int FlowerCount, int CropCount, float InitialScanProgress, float RescanProgress) GetPlantCountsNearPosition(BlockPos hivePos, int radius)
{ {
int flowers = flowerPositions.Count(p => Overlaps.IsWithinSphericalRadius(hivePos, p, radius)); int flowers = 0;
int crops = cropPositions.Count(p => Overlaps.IsWithinSphericalRadius(hivePos, p, radius)); foreach (var flowerPos in flowerPositions)
{
if (Overlaps.IsWithinSphericalRadius(hivePos, flowerPos, radius))
flowers++;
}
int crops = 0;
foreach (var cropPos in cropPositions)
{
if (Overlaps.IsWithinSphericalRadius(hivePos, cropPos, radius))
crops++;
}
float initialProgress = 0.0f; float initialProgress = 0.0f;
float rescanProgress = 0.0f; float rescanProgress = 0.0f;

View File

@@ -36,6 +36,11 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
private float rainfall; private float rainfall;
private float temperature; private float temperature;
private bool initialized; private bool initialized;
private readonly List<StructVec3i> flowerPositions = [];
private readonly List<StructVec3i> cropPositions = [];
private readonly List<Vector3> relativePlantPositions = [];
public const string TARGET_BEE_PARTICLE_COUNT_ATTRIBUTE = "roamingbees_targetBeeParticleCount"; public const string TARGET_BEE_PARTICLE_COUNT_ATTRIBUTE = "roamingbees_targetBeeParticleCount";
public const string RADIUS_ATTRIBUTE = "roamingbees_radius"; public const string RADIUS_ATTRIBUTE = "roamingbees_radius";
public const string NETWORK_CHANNEL_NAME = "bee particle spawns"; public const string NETWORK_CHANNEL_NAME = "bee particle spawns";
@@ -214,14 +219,14 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
TargetParticleCount = Config.Instance.RoamingBeesPerFgcLangstroth; TargetParticleCount = Config.Instance.RoamingBeesPerFgcLangstroth;
if (isFgcCeramic) if (isFgcCeramic)
TargetParticleCount = Config.Instance.RoamingBeesPerFgcCeramic; TargetParticleCount = Config.Instance.RoamingBeesPerFgcCeramic;
var nearbyPlantPositions = Api.Side == EnumAppSide.Server
? GetNearbyPlantPositions()
: [];
Update(dt, nearbyPlantPositions); if (Api.Side == EnumAppSide.Server)
UpdatePlantInfo();
Update(dt);
} }
private void Update(float dt, IEnumerable<Vector3> nearbyPlantPositions) private void Update(float dt)
{ {
if (dt > 10f) if (dt > 10f)
return; return;
@@ -259,15 +264,15 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
TimeSinceLastSpawn += dt; TimeSinceLastSpawn += dt;
if (Api.Side == EnumAppSide.Server) if (Api.Side == EnumAppSide.Server)
TrySpawnNewBee(TargetParticleCount, nearbyPlantPositions); TrySpawnNewBee(TargetParticleCount);
} }
private void TrySpawnNewBee(int targetParticleCount, IEnumerable<Vector3> nearbyPlantPositions) private void TrySpawnNewBee(int targetParticleCount)
{ {
if (TimeSinceLastSpawn < spawn_cooldown_seconds) if (TimeSinceLastSpawn < spawn_cooldown_seconds)
return; return;
if (!nearbyPlantPositions.Any()) if (relativePlantPositions.Count == 0)
return; return;
var cfg = Config.Instance; var cfg = Config.Instance;
@@ -312,7 +317,7 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
var facing = GetFacing(); var facing = GetFacing();
var entrancePos = GetEntrancePosition(facing); var entrancePos = GetEntrancePosition(facing);
var frontDirection = GetFrontDirection(facing); var frontDirection = GetFrontDirection(facing);
var path = BeePathGeneration.GeneratePath(Api.World.BlockAccessor, Blockentity.Pos, entrancePos, frontDirection, nearbyPlantPositions); var path = BeePathGeneration.GeneratePath(Api.World.BlockAccessor, Blockentity.Pos, entrancePos, frontDirection, relativePlantPositions);
if (path is null || path.Length == 0) if (path is null || path.Length == 0)
return; return;
@@ -364,37 +369,35 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
}; };
} }
private Vector3[] GetNearbyPlantPositions() private void UpdatePlantInfo()
{ {
relativePlantPositions.Clear();
int radius = Config.Instance.BeeRoamingRadius; int radius = Config.Instance.BeeRoamingRadius;
if (radius <= 0) if (radius <= 0)
{ {
radius = entityAttributeSnapshot.GetInt(RADIUS_ATTRIBUTE, 10); radius = entityAttributeSnapshot.GetInt(RADIUS_ATTRIBUTE, 10);
if (radius <= 0) if (radius <= 0)
return []; return;
} }
var plantPositions = new List<Vector3>();
var plantRegistry = Api.GetPlantPositionRegistry(); var plantRegistry = Api.GetPlantPositionRegistry();
if (plantRegistry is null) if (plantRegistry is null)
return []; return;
var (flowerCount, cropCount, initialScanProgress, rescanProgress) = plantRegistry.GetPlantCountsNearPosition(Blockentity.Pos, radius); var (initialScanProgress, rescanProgress) = plantRegistry.GetPlantsNearPosition(Blockentity.Pos, radius, flowerPositions, cropPositions);
FlowerCount = flowerCount; FlowerCount = flowerPositions.Count;
CropCount = cropCount; CropCount = cropPositions.Count;
InitialScanProgress = initialScanProgress; InitialScanProgress = initialScanProgress;
RescanProgress = rescanProgress; RescanProgress = rescanProgress;
var (flowers, crops, _, _) = plantRegistry.GetPlantsNearPosition(Blockentity.Pos, radius); foreach (var pos in flowerPositions.Concat(cropPositions))
foreach (var pos in flowers.Concat(crops))
{ {
float relX = pos.X - Blockentity.Pos.X + 0.5f; float relX = pos.X - Blockentity.Pos.X + 0.5f;
float relY = pos.Y - Blockentity.Pos.Y + 0.5f; float relY = pos.Y - Blockentity.Pos.Y + 0.5f;
float relZ = pos.Z - Blockentity.Pos.Z + 0.5f; float relZ = pos.Z - Blockentity.Pos.Z + 0.5f;
plantPositions.Add(new Vector3(relX, relY, relZ)); relativePlantPositions.Add(new Vector3(relX, relY, relZ));
} }
return [.. plantPositions];
} }
private Vector3 GetFrontDirection(string facing) private Vector3 GetFrontDirection(string facing)

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Numerics; using System.Numerics;
using Vintagestory.API.Common; using Vintagestory.API.Common;
using Vintagestory.API.Datastructures; using Vintagestory.API.Datastructures;
@@ -58,7 +57,7 @@ public static class BeePathGeneration
BlockPos hiveWorldPos, BlockPos hiveWorldPos,
Vector3 beehiveEntrancePosition, Vector3 beehiveEntrancePosition,
Vector3 frontDirection, Vector3 frontDirection,
IEnumerable<Vector3> plantPositions) List<Vector3> plantPositions)
{ {
temp_list.Clear(); temp_list.Clear();
temp_plants.Clear(); temp_plants.Clear();
@@ -71,15 +70,13 @@ public static class BeePathGeneration
for (var i = 0; i < plant_count; i++) for (var i = 0; i < plant_count; i++)
{ {
var lastPosition = temp_list.Count > 0 ? temp_list[^1].Position : GetFrontOfEntrance(beehiveEntrancePosition, frontDirection); var lastPosition = temp_list.Count > 0 ? temp_list[^1].Position : GetFrontOfEntrance(beehiveEntrancePosition, frontDirection);
foreach (var plantPathPoint in PickTargetAndGeneratePathPoints(blockAccessor, hiveWorldPos, lastPosition)) PickTargetAndGeneratePathPoints(blockAccessor, hiveWorldPos, lastPosition);
temp_list.Add(plantPathPoint);
} }
if (temp_list.Count == 0) if (temp_list.Count == 0)
return []; return [];
foreach (var returnPathPoint in GetReturnPath(blockAccessor, hiveWorldPos, temp_list.Last().Position, beehiveEntrancePosition, frontDirection)) GetReturnPath(blockAccessor, hiveWorldPos, temp_list[^1].Position, beehiveEntrancePosition, frontDirection);
temp_list.Add(new BeePlannedPathPoint(returnPathPoint, true, false));
temp_list[^1] = temp_list[^1] with { IsSlowdown = true }; temp_list[^1] = temp_list[^1] with { IsSlowdown = true };
temp_list.Add(new BeePlannedPathPoint(beehiveEntrancePosition, false, true)); temp_list.Add(new BeePlannedPathPoint(beehiveEntrancePosition, false, true));
@@ -155,7 +152,7 @@ public static class BeePathGeneration
if (containerSelectionBoxes.Length == 0) if (containerSelectionBoxes.Length == 0)
return false; return false;
Cuboidf containerSelectionBox = containerSelectionBoxes.First(); Cuboidf containerSelectionBox = containerSelectionBoxes[0];
var fillHeight = attributes["fillHeight"]?.AsFloat(0.5f) ?? 0.5f; var fillHeight = attributes["fillHeight"]?.AsFloat(0.5f) ?? 0.5f;
var sitHeight = attributes["sitHeight"]?.AsFloat(Math.Min(0.9f, fillHeight + 0.2f)) ?? Math.Min(0.9f, fillHeight + 0.2f); var sitHeight = attributes["sitHeight"]?.AsFloat(Math.Min(0.9f, fillHeight + 0.2f)) ?? Math.Min(0.9f, fillHeight + 0.2f);
@@ -189,7 +186,7 @@ public static class BeePathGeneration
if (selectionBoxes.Length == 0) if (selectionBoxes.Length == 0)
return false; return false;
Cuboidf selectionBox = selectionBoxes.First(); Cuboidf selectionBox = selectionBoxes[0];
var height = blockPlant.drawnHeight / 32f; var height = blockPlant.drawnHeight / 32f;
var sitHeightAttr = attributes["sitHeight"]; var sitHeightAttr = attributes["sitHeight"];
if (sitHeightAttr != null) if (sitHeightAttr != null)
@@ -203,13 +200,13 @@ public static class BeePathGeneration
return true; return true;
} }
private static IEnumerable<BeePlannedPathPoint> PickTargetAndGeneratePathPoints(IBlockAccessor blockAccessor, BlockPos hiveWorldPos, Vector3 lastPosition) private static void PickTargetAndGeneratePathPoints(IBlockAccessor blockAccessor, BlockPos hiveWorldPos, Vector3 lastPosition)
{ {
for (var i = 0; i < 2; i++) for (var i = 0; i < 2; i++)
{ {
var nearby_only = i == 1; var nearby_only = i == 1;
if (!TryPickPlantPosition(lastPosition, nearby_only, out var blockCenter)) if (!TryPickPlantPosition(lastPosition, nearby_only, out var blockCenter))
yield break; return;
var (plantOffset, plantSize) = GetPlantOffsetAndSize(blockAccessor, blockCenter, hiveWorldPos); var (plantOffset, plantSize) = GetPlantOffsetAndSize(blockAccessor, blockCenter, hiveWorldPos);
if (plantSize is not null && plantOffset is not null) if (plantSize is not null && plantOffset is not null)
@@ -220,10 +217,9 @@ public static class BeePathGeneration
{ {
used_plants.Add(blockCenter); used_plants.Add(blockCenter);
if (waypoint is not null) if (waypoint is not null)
yield return new BeePlannedPathPoint(waypoint.Value, true, false); temp_list.Add(new BeePlannedPathPoint(waypoint.Value, true, false));
foreach (var plantTarget in GetPlantTargets(blockCenter, size, target)) GetPlantTargets(blockCenter, size, target);
yield return new BeePlannedPathPoint(plantTarget, false, false); return;
yield break;
} }
} }
} }
@@ -250,13 +246,13 @@ public static class BeePathGeneration
return valid_count > 0; return valid_count > 0;
} }
private static IEnumerable<Vector3> GetPlantTargets(Vector3 blockCenter, Vector3 plantSize, Vector3 firstTarget) private static void GetPlantTargets(Vector3 blockCenter, Vector3 plantSize, Vector3 firstTarget)
{ {
yield return firstTarget; temp_list.Add(new BeePlannedPathPoint(firstTarget, false, false));
var total_targets = random.Next(3, 10); var total_targets = random.Next(3, 10);
for (var i = 1; i < total_targets; i++) for (var i = 1; i < total_targets; i++)
yield return GetRandomPointInPlantBlock(blockCenter, plantSize); temp_list.Add(new BeePlannedPathPoint(GetRandomPointInPlantBlock(blockCenter, plantSize), false, false));
} }
private static bool TryPickPlantTarget(IBlockAccessor blockAccessor, BlockPos hiveWorldPos, Vector3 lastPosition, Vector3 blockCenter, Vector3 plantSize, out Vector3 target, out Vector3? waypoint, bool biasUpwards = false) private static bool TryPickPlantTarget(IBlockAccessor blockAccessor, BlockPos hiveWorldPos, Vector3 lastPosition, Vector3 blockCenter, Vector3 plantSize, out Vector3 target, out Vector3? waypoint, bool biasUpwards = false)
@@ -402,27 +398,27 @@ public static class BeePathGeneration
return block.CollisionBoxes != null && block.CollisionBoxes.Length > 0; return block.CollisionBoxes != null && block.CollisionBoxes.Length > 0;
} }
private static IEnumerable<Vector3> GetReturnPath(IBlockAccessor blockAccessor, BlockPos hiveWorldPos, Vector3 lastPosition, Vector3 beehiveEntrancePosition, Vector3 frontDirection) private static void GetReturnPath(IBlockAccessor blockAccessor, BlockPos hiveWorldPos, Vector3 lastPosition, Vector3 beehiveEntrancePosition, Vector3 frontDirection)
{ {
var frontOfEntrance = GetFrontOfEntrance(beehiveEntrancePosition, frontDirection); var frontOfEntrance = GetFrontOfEntrance(beehiveEntrancePosition, frontDirection);
var targetPos = frontOfEntrance; var targetPos = frontOfEntrance;
if (HasLineOfSight(blockAccessor, hiveWorldPos, lastPosition, targetPos)) if (HasLineOfSight(blockAccessor, hiveWorldPos, lastPosition, targetPos))
{ {
yield return targetPos; temp_list.Add(new BeePlannedPathPoint(targetPos, true, false));
yield break; return;
} }
if (TryFindWaypoint(blockAccessor, hiveWorldPos, lastPosition, targetPos, out var waypoint)) if (TryFindWaypoint(blockAccessor, hiveWorldPos, lastPosition, targetPos, out var waypoint))
{ {
yield return waypoint; temp_list.Add(new BeePlannedPathPoint(waypoint, true, false));
yield return targetPos; temp_list.Add(new BeePlannedPathPoint(targetPos, true, false));
yield break; return;
} }
foreach (var pathPoint in temp_list.Reverse<BeePlannedPathPoint>()) for (var i = temp_list.Count - 1; i >= 0; i--)
yield return pathPoint.Position; temp_list.Add(new BeePlannedPathPoint(temp_list[i].Position, true, false));
yield return frontOfEntrance; temp_list.Add(new BeePlannedPathPoint(frontOfEntrance, true, false));
} }
internal static Vector3 GetFrontOfEntrance(Vector3 beehiveEntrancePosition, Vector3 frontDirection) internal static Vector3 GetFrontOfEntrance(Vector3 beehiveEntrancePosition, Vector3 frontDirection)