Browse Source

Add some info and prev. value for setters

tags/v2.2.0
NorbiPeti 4 years ago
parent
commit
3f2139d592
Signed by: NorbiPeti <szatmari.norbert.peter@gmail.com> GPG Key ID: DBA4C4549A927E56
3 changed files with 25 additions and 4 deletions
  1. +16
    -2
      GamecraftModdingAPI/Block.cs
  2. +3
    -2
      GamecraftModdingAPI/Blocks/BlockEngine.cs
  3. +6
    -0
      GamecraftModdingAPI/Blocks/BlockEngineInit.cs

+ 16
- 2
GamecraftModdingAPI/Block.cs View File

@@ -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);



+ 3
- 2
GamecraftModdingAPI/Blocks/BlockEngine.cs View File

@@ -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);
}


+ 6
- 0
GamecraftModdingAPI/Blocks/BlockEngineInit.cs View File

@@ -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…
Cancel
Save