riversong code showcase
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public class EntityCache : IEntityCache
|
||||
{
|
||||
private Dictionary<int, Cache> _caches = new();
|
||||
|
||||
public void CreateCache<T>(int key, Predicate<T> filter) where T : Entity
|
||||
{
|
||||
if (!_caches.TryGetValue(key, out var cache))
|
||||
{
|
||||
cache = new Cache<T>();
|
||||
_caches.Add(key, cache);
|
||||
}
|
||||
((Cache<T>)cache).Filter = filter;
|
||||
}
|
||||
|
||||
public List<T> Get<T>(int key) where T : Entity
|
||||
{
|
||||
if (!_caches.TryGetValue(key, out var cache))
|
||||
{
|
||||
cache = new Cache<T>();
|
||||
_caches.Add(key, cache);
|
||||
}
|
||||
return ((Cache<T>)cache).Entities;
|
||||
}
|
||||
|
||||
public void OnAdded(Entity entity)
|
||||
{
|
||||
foreach (var cache in _caches.Values) cache.TryAdd(entity);
|
||||
}
|
||||
|
||||
public void OnRemoved(Entity entity)
|
||||
{
|
||||
foreach (var cache in _caches.Values) cache.TryRemove(entity);
|
||||
}
|
||||
|
||||
private abstract class Cache
|
||||
{
|
||||
public void TryAdd(Entity entity)
|
||||
{
|
||||
if (FilterEntity(entity)) Add(entity);
|
||||
}
|
||||
|
||||
public void TryRemove(Entity entity)
|
||||
{
|
||||
if (FilterEntity(entity)) Remove(entity);
|
||||
}
|
||||
|
||||
protected abstract bool FilterEntity(Entity entity);
|
||||
|
||||
protected abstract void Add(Entity entity);
|
||||
|
||||
protected abstract void Remove(Entity entity);
|
||||
}
|
||||
|
||||
private class Cache<T> : Cache where T : Entity
|
||||
{
|
||||
public Predicate<T> Filter { get; set; }
|
||||
|
||||
public List<T> Entities { get; } = new();
|
||||
|
||||
protected override bool FilterEntity(Entity entity)
|
||||
{
|
||||
return entity is T typedEntity && Filter.Invoke(typedEntity);
|
||||
}
|
||||
|
||||
protected override void Add(Entity entity)
|
||||
{
|
||||
Entities.Add((T)entity);
|
||||
}
|
||||
|
||||
protected override void Remove(Entity entity)
|
||||
{
|
||||
Entities.Remove((T)entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public static class EntityCacheExtensions
|
||||
{
|
||||
public static List<Building> GetHarvesterBuildings(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Building>((int)EntityCacheKeys.HarvesterBuildings);
|
||||
}
|
||||
|
||||
public static List<Building> GetHunterBuildings(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Building>((int)EntityCacheKeys.HunterBuildings);
|
||||
}
|
||||
|
||||
public static List<Building> GetFarmBuildings(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Building>((int)EntityCacheKeys.FarmBuildings);
|
||||
}
|
||||
|
||||
public static List<Building> GetProducers(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Building>((int)EntityCacheKeys.ProducerBuildings);
|
||||
}
|
||||
|
||||
public static List<Building> GetProviders(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Building>((int)EntityCacheKeys.ProviderBuildings);
|
||||
}
|
||||
|
||||
public static List<Building> GetBuildingsWithWorkers(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Building>((int)EntityCacheKeys.BuildingsWithWorkers);
|
||||
}
|
||||
|
||||
public static List<Building> GetHouses(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Building>((int)EntityCacheKeys.HouseBuildings);
|
||||
}
|
||||
|
||||
public static List<Building> GetTentBuildings(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Building>((int)EntityCacheKeys.TentBuildings);
|
||||
}
|
||||
|
||||
public static List<Building> GetStorageBuildings(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Building>((int)EntityCacheKeys.StorageBuildings);
|
||||
}
|
||||
|
||||
public static List<Building> GetStorageRequestBuildings(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Building>((int)EntityCacheKeys.StorageRequestBuildings);
|
||||
}
|
||||
|
||||
public static List<Agent> GetHunterAgents(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Agent>((int)EntityCacheKeys.HunterAgents);
|
||||
}
|
||||
|
||||
public static List<Agent> GetCritterAgents(this IEntityCache entityCache)
|
||||
{
|
||||
return entityCache.Get<Agent>((int)EntityCacheKeys.CritterAgents);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public enum EntityCacheKeys
|
||||
{
|
||||
Invalid,
|
||||
|
||||
#region Buildings
|
||||
|
||||
HarvesterBuildings,
|
||||
|
||||
HunterBuildings,
|
||||
|
||||
FarmBuildings,
|
||||
|
||||
ProducerBuildings,
|
||||
|
||||
ProviderBuildings,
|
||||
|
||||
BuildingsWithWorkers,
|
||||
|
||||
HouseBuildings,
|
||||
|
||||
StorageBuildings,
|
||||
|
||||
StorageRequestBuildings,
|
||||
|
||||
TentBuildings,
|
||||
|
||||
#endregion
|
||||
|
||||
#region Agents
|
||||
|
||||
HunterAgents,
|
||||
|
||||
CritterAgents
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
[GameSystemGroup(typeof(EarlyGameSystemGroup))]
|
||||
[InitializeAfter(typeof(PreLoadAssetsSystem))]
|
||||
public class EntityCacheSystem : GameSystem, IInitializable, IDisposable
|
||||
{
|
||||
[InjectService]
|
||||
private IEntityCollection _entityCollection;
|
||||
|
||||
[InjectService]
|
||||
private IEntityCache _entityCache;
|
||||
|
||||
[InjectService]
|
||||
private GameConfig _config;
|
||||
|
||||
public EntityCacheSystem(IServiceLocator serviceLocator) : base(serviceLocator)
|
||||
{
|
||||
}
|
||||
|
||||
public UniTask InitializeAsync()
|
||||
{
|
||||
CreateCaches();
|
||||
|
||||
foreach (var entity in _entityCollection.GetInternalEntityList(typeof(Entity))) _entityCache.OnAdded(entity);
|
||||
|
||||
var callbacks = _entityCollection.On<Entity>();
|
||||
callbacks.Added += _entityCache.OnAdded;
|
||||
callbacks.Removed += _entityCache.OnRemoved;
|
||||
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
private void CreateCaches()
|
||||
{
|
||||
_entityCache.CreateCache<Building>((int)EntityCacheKeys.HarvesterBuildings, b => b.Definition.HarvestedResource);
|
||||
_entityCache.CreateCache<Building>((int)EntityCacheKeys.HunterBuildings, b => b.Definition.TargetCritter);
|
||||
_entityCache.CreateCache<Building>((int)EntityCacheKeys.FarmBuildings, b => b.Definition.IsFarm);
|
||||
_entityCache.CreateCache<Building>((int)EntityCacheKeys.ProducerBuildings, b => b.Definition.Recipe);
|
||||
_entityCache.CreateCache<Building>((int)EntityCacheKeys.ProviderBuildings, b => b.Definition.ProvidedProducts.Count > 0);
|
||||
_entityCache.CreateCache<Building>((int)EntityCacheKeys.BuildingsWithWorkers, b => b.Definition.WorkerCount > 0);
|
||||
_entityCache.CreateCache<Building>((int)EntityCacheKeys.HouseBuildings, b => b.Definition.IsHouse);
|
||||
_entityCache.CreateCache<Building>((int)EntityCacheKeys.StorageBuildings, b => b.Definition.IsStorage);
|
||||
_entityCache.CreateCache<Building>((int)EntityCacheKeys.StorageRequestBuildings, b => b.Definition.IsStorage);
|
||||
_entityCache.CreateCache<Building>((int)EntityCacheKeys.TentBuildings, b => b.Definition == _config.Population.TentBuilding.Asset);
|
||||
_entityCache.CreateCache<Agent>(
|
||||
(int)EntityCacheKeys.HunterAgents,
|
||||
a =>
|
||||
{
|
||||
ref var jobState = ref a.GetJobStateRW();
|
||||
return jobState.Job == AgentJob.Hunter;
|
||||
});
|
||||
_entityCache.CreateCache<Agent>(
|
||||
(int)EntityCacheKeys.CritterAgents,
|
||||
a =>
|
||||
{
|
||||
ref var critterState = ref a.GetCritterStateRW();
|
||||
return critterState.IsCritter;
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
var callbacks = _entityCollection.On<Entity>();
|
||||
callbacks.Added -= _entityCache.OnAdded;
|
||||
callbacks.Removed -= _entityCache.OnRemoved;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public interface IEntityCache
|
||||
{
|
||||
void CreateCache<T>(int key, Predicate<T> filter) where T : Entity;
|
||||
|
||||
List<T> Get<T>(int key) where T : Entity;
|
||||
|
||||
void OnAdded(Entity entity);
|
||||
|
||||
void OnRemoved(Entity entity);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user