try to decrease allocations
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"total": 592730,
|
||||
"total": 602351,
|
||||
"sessions": [
|
||||
{
|
||||
"begin": "2026-01-09T17:26:02+01:00",
|
||||
@@ -1355,6 +1355,11 @@
|
||||
"begin": "2026-03-21T01:18:07+01:00",
|
||||
"end": "2026-03-21T01:43:24+01:00",
|
||||
"duration": 1517
|
||||
},
|
||||
{
|
||||
"begin": "2026-03-21T01:43:25+01:00",
|
||||
"end": "2026-03-21T04:23:47+01:00",
|
||||
"duration": 9621
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -24,13 +24,7 @@ public interface IPlantPositionRegistry
|
||||
)
|
||||
GetPlantCountsNearPosition(BlockPos hivePos, int radius);
|
||||
|
||||
(
|
||||
IEnumerable<BlockPos> Flowers,
|
||||
IEnumerable<BlockPos> Crops,
|
||||
float InitialScanProgress,
|
||||
float RescanProgress
|
||||
)
|
||||
GetPlantsNearPosition(BlockPos hivePos, int radius);
|
||||
(float InitialScanProgress, float RescanProgress) GetPlantsNearPosition(BlockPos hivePos, int radius, List<StructVec3i> flowerPositionsBuffer, List<StructVec3i> cropPositionsBuffer);
|
||||
|
||||
void RegisterBeehive(BlockPos pos, int radius);
|
||||
|
||||
|
||||
@@ -81,26 +81,33 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry
|
||||
}
|
||||
|
||||
public (
|
||||
IEnumerable<BlockPos> Flowers,
|
||||
IEnumerable<BlockPos> Crops,
|
||||
float InitialScanProgress,
|
||||
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 flowers = flowerPositions
|
||||
.Where(p => Overlaps.IsWithinSphericalRadius(hivePos, p, radius))
|
||||
.Select(p => new BlockPos(p.X, p.Y, p.Z, hivePos.dimension));
|
||||
foreach (var flowerPos in flowerPositions)
|
||||
{
|
||||
if (!Overlaps.IsWithinSphericalRadius(hivePos, flowerPos, radius))
|
||||
continue;
|
||||
flowerPositionsBuffer.Add(flowerPos);
|
||||
}
|
||||
|
||||
var crops = cropPositions
|
||||
.Where(p => Overlaps.IsWithinSphericalRadius(hivePos, p, radius))
|
||||
.Select(p => new BlockPos(p.X, p.Y, p.Z, hivePos.dimension));
|
||||
foreach (var cropPos in cropPositions)
|
||||
{
|
||||
if (!Overlaps.IsWithinSphericalRadius(hivePos, cropPos, radius))
|
||||
continue;
|
||||
cropPositionsBuffer.Add(cropPos);
|
||||
}
|
||||
|
||||
float initialProgress = 1.0f;
|
||||
float rescanProgress = 0.0f;
|
||||
if (!beehives.TryGetValue(key, out var cursor))
|
||||
return (flowers, crops, initialProgress, rescanProgress);
|
||||
return (initialProgress, rescanProgress);
|
||||
|
||||
var table = offsetTables[cursor.Radius];
|
||||
if (table.Count > 0)
|
||||
@@ -109,13 +116,24 @@ public class PlantPositionRegistryModSystem2 : ModSystem, IPlantPositionRegistry
|
||||
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)
|
||||
{
|
||||
int flowers = flowerPositions.Count(p => Overlaps.IsWithinSphericalRadius(hivePos, p, radius));
|
||||
int crops = cropPositions.Count(p => Overlaps.IsWithinSphericalRadius(hivePos, p, radius));
|
||||
int flowers = 0;
|
||||
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 rescanProgress = 0.0f;
|
||||
|
||||
@@ -36,6 +36,11 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
||||
private float rainfall;
|
||||
private float temperature;
|
||||
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 RADIUS_ATTRIBUTE = "roamingbees_radius";
|
||||
public const string NETWORK_CHANNEL_NAME = "bee particle spawns";
|
||||
@@ -214,14 +219,14 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
||||
TargetParticleCount = Config.Instance.RoamingBeesPerFgcLangstroth;
|
||||
if (isFgcCeramic)
|
||||
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)
|
||||
return;
|
||||
@@ -259,15 +264,15 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
||||
|
||||
TimeSinceLastSpawn += dt;
|
||||
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)
|
||||
return;
|
||||
|
||||
if (!nearbyPlantPositions.Any())
|
||||
if (relativePlantPositions.Count == 0)
|
||||
return;
|
||||
|
||||
var cfg = Config.Instance;
|
||||
@@ -312,7 +317,7 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
||||
var facing = GetFacing();
|
||||
var entrancePos = GetEntrancePosition(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)
|
||||
return;
|
||||
|
||||
@@ -364,37 +369,35 @@ public class BlockEntityBehaviorRoamingBees(BlockEntity blockEntity) : BlockEnti
|
||||
};
|
||||
}
|
||||
|
||||
private Vector3[] GetNearbyPlantPositions()
|
||||
private void UpdatePlantInfo()
|
||||
{
|
||||
relativePlantPositions.Clear();
|
||||
|
||||
int radius = Config.Instance.BeeRoamingRadius;
|
||||
if (radius <= 0)
|
||||
{
|
||||
radius = entityAttributeSnapshot.GetInt(RADIUS_ATTRIBUTE, 10);
|
||||
if (radius <= 0)
|
||||
return [];
|
||||
return;
|
||||
}
|
||||
|
||||
var plantPositions = new List<Vector3>();
|
||||
var plantRegistry = Api.GetPlantPositionRegistry();
|
||||
if (plantRegistry is null)
|
||||
return [];
|
||||
return;
|
||||
|
||||
var (flowerCount, cropCount, initialScanProgress, rescanProgress) = plantRegistry.GetPlantCountsNearPosition(Blockentity.Pos, radius);
|
||||
FlowerCount = flowerCount;
|
||||
CropCount = cropCount;
|
||||
var (initialScanProgress, rescanProgress) = plantRegistry.GetPlantsNearPosition(Blockentity.Pos, radius, flowerPositions, cropPositions);
|
||||
FlowerCount = flowerPositions.Count;
|
||||
CropCount = cropPositions.Count;
|
||||
InitialScanProgress = initialScanProgress;
|
||||
RescanProgress = rescanProgress;
|
||||
|
||||
var (flowers, crops, _, _) = plantRegistry.GetPlantsNearPosition(Blockentity.Pos, radius);
|
||||
foreach (var pos in flowers.Concat(crops))
|
||||
foreach (var pos in flowerPositions.Concat(cropPositions))
|
||||
{
|
||||
float relX = pos.X - Blockentity.Pos.X + 0.5f;
|
||||
float relY = pos.Y - Blockentity.Pos.Y + 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)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Vintagestory.API.Common;
|
||||
using Vintagestory.API.Datastructures;
|
||||
@@ -58,7 +57,7 @@ public static class BeePathGeneration
|
||||
BlockPos hiveWorldPos,
|
||||
Vector3 beehiveEntrancePosition,
|
||||
Vector3 frontDirection,
|
||||
IEnumerable<Vector3> plantPositions)
|
||||
List<Vector3> plantPositions)
|
||||
{
|
||||
temp_list.Clear();
|
||||
temp_plants.Clear();
|
||||
@@ -71,15 +70,13 @@ public static class BeePathGeneration
|
||||
for (var i = 0; i < plant_count; i++)
|
||||
{
|
||||
var lastPosition = temp_list.Count > 0 ? temp_list[^1].Position : GetFrontOfEntrance(beehiveEntrancePosition, frontDirection);
|
||||
foreach (var plantPathPoint in PickTargetAndGeneratePathPoints(blockAccessor, hiveWorldPos, lastPosition))
|
||||
temp_list.Add(plantPathPoint);
|
||||
PickTargetAndGeneratePathPoints(blockAccessor, hiveWorldPos, lastPosition);
|
||||
}
|
||||
|
||||
if (temp_list.Count == 0)
|
||||
return [];
|
||||
|
||||
foreach (var returnPathPoint in GetReturnPath(blockAccessor, hiveWorldPos, temp_list.Last().Position, beehiveEntrancePosition, frontDirection))
|
||||
temp_list.Add(new BeePlannedPathPoint(returnPathPoint, true, false));
|
||||
GetReturnPath(blockAccessor, hiveWorldPos, temp_list[^1].Position, beehiveEntrancePosition, frontDirection);
|
||||
|
||||
temp_list[^1] = temp_list[^1] with { IsSlowdown = true };
|
||||
temp_list.Add(new BeePlannedPathPoint(beehiveEntrancePosition, false, true));
|
||||
@@ -155,7 +152,7 @@ public static class BeePathGeneration
|
||||
if (containerSelectionBoxes.Length == 0)
|
||||
return false;
|
||||
|
||||
Cuboidf containerSelectionBox = containerSelectionBoxes.First();
|
||||
Cuboidf containerSelectionBox = containerSelectionBoxes[0];
|
||||
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);
|
||||
|
||||
@@ -189,7 +186,7 @@ public static class BeePathGeneration
|
||||
if (selectionBoxes.Length == 0)
|
||||
return false;
|
||||
|
||||
Cuboidf selectionBox = selectionBoxes.First();
|
||||
Cuboidf selectionBox = selectionBoxes[0];
|
||||
var height = blockPlant.drawnHeight / 32f;
|
||||
var sitHeightAttr = attributes["sitHeight"];
|
||||
if (sitHeightAttr != null)
|
||||
@@ -203,13 +200,13 @@ public static class BeePathGeneration
|
||||
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++)
|
||||
{
|
||||
var nearby_only = i == 1;
|
||||
if (!TryPickPlantPosition(lastPosition, nearby_only, out var blockCenter))
|
||||
yield break;
|
||||
return;
|
||||
|
||||
var (plantOffset, plantSize) = GetPlantOffsetAndSize(blockAccessor, blockCenter, hiveWorldPos);
|
||||
if (plantSize is not null && plantOffset is not null)
|
||||
@@ -220,10 +217,9 @@ public static class BeePathGeneration
|
||||
{
|
||||
used_plants.Add(blockCenter);
|
||||
if (waypoint is not null)
|
||||
yield return new BeePlannedPathPoint(waypoint.Value, true, false);
|
||||
foreach (var plantTarget in GetPlantTargets(blockCenter, size, target))
|
||||
yield return new BeePlannedPathPoint(plantTarget, false, false);
|
||||
yield break;
|
||||
temp_list.Add(new BeePlannedPathPoint(waypoint.Value, true, false));
|
||||
GetPlantTargets(blockCenter, size, target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,13 +246,13 @@ public static class BeePathGeneration
|
||||
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);
|
||||
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)
|
||||
@@ -402,27 +398,27 @@ public static class BeePathGeneration
|
||||
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 targetPos = frontOfEntrance;
|
||||
if (HasLineOfSight(blockAccessor, hiveWorldPos, lastPosition, targetPos))
|
||||
{
|
||||
yield return targetPos;
|
||||
yield break;
|
||||
temp_list.Add(new BeePlannedPathPoint(targetPos, true, false));
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryFindWaypoint(blockAccessor, hiveWorldPos, lastPosition, targetPos, out var waypoint))
|
||||
{
|
||||
yield return waypoint;
|
||||
yield return targetPos;
|
||||
yield break;
|
||||
temp_list.Add(new BeePlannedPathPoint(waypoint, true, false));
|
||||
temp_list.Add(new BeePlannedPathPoint(targetPos, true, false));
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var pathPoint in temp_list.Reverse<BeePlannedPathPoint>())
|
||||
yield return pathPoint.Position;
|
||||
for (var i = temp_list.Count - 1; i >= 0; i--)
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user