Add some info and prev. value for setters
This commit is contained in:
parent
b53dff5d12
commit
15485481a2
3 changed files with 25 additions and 4 deletions
|
@ -137,6 +137,16 @@ namespace GamecraftModdingAPI
|
|||
{typeof(Timer), new[] {CommonExclusiveGroups.BUILD_TIMER_BLOCK_GROUP}}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of T with the given ID and group using dynamically created delegates.
|
||||
/// It's equivalent to new T(EGID) with a minimal overhead thanks to caching the created delegates.
|
||||
/// </summary>
|
||||
/// <param name="id">The block ID</param>
|
||||
/// <param name="group">The block group</param>
|
||||
/// <typeparam name="T">The block's type or Block itself</typeparam>
|
||||
/// <returns>An instance of the provided type</returns>
|
||||
/// <exception cref="BlockTypeException">The block group doesn't match or cannot be found</exception>
|
||||
/// <exception cref="MissingMethodException">The block class doesn't have the needed constructor</exception>
|
||||
private static T New<T>(uint id, ExclusiveGroupStruct? group = null) where T : Block
|
||||
{
|
||||
var type = typeof(T);
|
||||
|
@ -175,8 +185,8 @@ namespace GamecraftModdingAPI
|
|||
il.DeclareLocal(type);
|
||||
il.Emit(OpCodes.Ldarg_0); //Load EGID and pass to constructor
|
||||
il.Emit(OpCodes.Newobj, ctor); //Call constructor
|
||||
il.Emit(OpCodes.Stloc_0);
|
||||
il.Emit(OpCodes.Ldloc_0);
|
||||
//il.Emit(OpCodes.Stloc_0); - doesn't seem like we need these
|
||||
//il.Emit(OpCodes.Ldloc_0);
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
func = (Func<EGID, T>) dynamic.CreateDelegate(typeof(Func<EGID, T>));
|
||||
|
@ -188,6 +198,9 @@ namespace GamecraftModdingAPI
|
|||
public Block(EGID id)
|
||||
{
|
||||
Id = id;
|
||||
if (typeToGroup.TryGetValue(GetType(), out var groups) && groups.All(gr => gr != id.groupID))
|
||||
throw new BlockTypeException("The block has the wrong group! The type is " + GetType() +
|
||||
" while the group is " + id.groupID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -328,6 +341,7 @@ namespace GamecraftModdingAPI
|
|||
|
||||
/// <summary>
|
||||
/// Whether the block exists. The other properties will return a default value if the block doesn't exist.
|
||||
/// If the block was just placed, then this will also return false but the properties will work correctly.
|
||||
/// </summary>
|
||||
public bool Exists => BlockEngine.BlockExists(Id);
|
||||
|
||||
|
|
|
@ -85,10 +85,11 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
if (entitiesDB.Exists<T>(block.Id))
|
||||
setter(ref entitiesDB.QueryEntity<T>(block.Id), value);
|
||||
if (block.InitData.Group != null)
|
||||
else if (block.InitData.Group != null)
|
||||
{
|
||||
var initializer = new EntityComponentInitializer(block.Id, block.InitData.Group);
|
||||
ref T structRef = ref (new T[1])[0]; //A reference for a default value for struct
|
||||
T component = initializer.Has<T>() ? initializer.Get<T>() : default;
|
||||
ref T structRef = ref component;
|
||||
setter(ref structRef, value);
|
||||
initializer.Init(structRef);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ namespace GamecraftModdingAPI.Blocks
|
|||
{
|
||||
public partial class BlockEngine
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds information needed to construct a component initializer
|
||||
/// </summary>
|
||||
internal struct BlockInitData
|
||||
{
|
||||
public FasterDictionary<RefWrapper<Type>, ITypeSafeDictionary> Group;
|
||||
|
@ -17,6 +20,9 @@ namespace GamecraftModdingAPI.Blocks
|
|||
internal delegate FasterDictionary<RefWrapper<Type>, ITypeSafeDictionary> GetInitGroup(
|
||||
EntityComponentInitializer initializer);
|
||||
|
||||
/// <summary>
|
||||
/// Accesses the group field of the initializer
|
||||
/// </summary>
|
||||
internal GetInitGroup InitGroup = CreateAccessor<GetInitGroup>("_group");
|
||||
|
||||
//https://stackoverflow.com/questions/55878525/unit-testing-ref-structs-with-private-fields-via-reflection
|
||||
|
|
Loading…
Reference in a new issue