Add some info and prev. value for setters
This commit is contained in:
parent
16521ab7eb
commit
3f2139d592
3 changed files with 25 additions and 4 deletions
|
@ -137,6 +137,16 @@ namespace GamecraftModdingAPI
|
||||||
{typeof(Timer), new[] {CommonExclusiveGroups.BUILD_TIMER_BLOCK_GROUP}}
|
{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
|
private static T New<T>(uint id, ExclusiveGroupStruct? group = null) where T : Block
|
||||||
{
|
{
|
||||||
var type = typeof(T);
|
var type = typeof(T);
|
||||||
|
@ -175,8 +185,8 @@ namespace GamecraftModdingAPI
|
||||||
il.DeclareLocal(type);
|
il.DeclareLocal(type);
|
||||||
il.Emit(OpCodes.Ldarg_0); //Load EGID and pass to constructor
|
il.Emit(OpCodes.Ldarg_0); //Load EGID and pass to constructor
|
||||||
il.Emit(OpCodes.Newobj, ctor); //Call constructor
|
il.Emit(OpCodes.Newobj, ctor); //Call constructor
|
||||||
il.Emit(OpCodes.Stloc_0);
|
//il.Emit(OpCodes.Stloc_0); - doesn't seem like we need these
|
||||||
il.Emit(OpCodes.Ldloc_0);
|
//il.Emit(OpCodes.Ldloc_0);
|
||||||
il.Emit(OpCodes.Ret);
|
il.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
func = (Func<EGID, T>) dynamic.CreateDelegate(typeof(Func<EGID, T>));
|
func = (Func<EGID, T>) dynamic.CreateDelegate(typeof(Func<EGID, T>));
|
||||||
|
@ -188,6 +198,9 @@ namespace GamecraftModdingAPI
|
||||||
public Block(EGID id)
|
public Block(EGID id)
|
||||||
{
|
{
|
||||||
Id = 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>
|
/// <summary>
|
||||||
|
@ -328,6 +341,7 @@ namespace GamecraftModdingAPI
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the block exists. The other properties will return a default value if the block doesn't exist.
|
/// 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>
|
/// </summary>
|
||||||
public bool Exists => BlockEngine.BlockExists(Id);
|
public bool Exists => BlockEngine.BlockExists(Id);
|
||||||
|
|
||||||
|
|
|
@ -85,10 +85,11 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
if (entitiesDB.Exists<T>(block.Id))
|
if (entitiesDB.Exists<T>(block.Id))
|
||||||
setter(ref entitiesDB.QueryEntity<T>(block.Id), value);
|
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);
|
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);
|
setter(ref structRef, value);
|
||||||
initializer.Init(structRef);
|
initializer.Init(structRef);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,9 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
public partial class BlockEngine
|
public partial class BlockEngine
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Holds information needed to construct a component initializer
|
||||||
|
/// </summary>
|
||||||
internal struct BlockInitData
|
internal struct BlockInitData
|
||||||
{
|
{
|
||||||
public FasterDictionary<RefWrapper<Type>, ITypeSafeDictionary> Group;
|
public FasterDictionary<RefWrapper<Type>, ITypeSafeDictionary> Group;
|
||||||
|
@ -17,6 +20,9 @@ namespace GamecraftModdingAPI.Blocks
|
||||||
internal delegate FasterDictionary<RefWrapper<Type>, ITypeSafeDictionary> GetInitGroup(
|
internal delegate FasterDictionary<RefWrapper<Type>, ITypeSafeDictionary> GetInitGroup(
|
||||||
EntityComponentInitializer initializer);
|
EntityComponentInitializer initializer);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Accesses the group field of the initializer
|
||||||
|
/// </summary>
|
||||||
internal GetInitGroup InitGroup = CreateAccessor<GetInitGroup>("_group");
|
internal GetInitGroup InitGroup = CreateAccessor<GetInitGroup>("_group");
|
||||||
|
|
||||||
//https://stackoverflow.com/questions/55878525/unit-testing-ref-structs-with-private-fields-via-reflection
|
//https://stackoverflow.com/questions/55878525/unit-testing-ref-structs-with-private-fields-via-reflection
|
||||||
|
|
Loading…
Reference in a new issue