Fix remaining errors, add support for managed entity DB
This commit is contained in:
parent
d238c97906
commit
858a5c9b5c
14 changed files with 282 additions and 233 deletions
|
@ -322,13 +322,9 @@ namespace TechbloxModdingAPI
|
||||||
get => BlockEngine.GetBlockInfo<ScalingEntityStruct>(this).scale.x < 0;
|
get => BlockEngine.GetBlockInfo<ScalingEntityStruct>(this).scale.x < 0;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ScalingEntityStruct st, bool val) =>
|
var st = BlockEngine.GetBlockInfo<ScalingEntityStruct>(this);
|
||||||
st.scale.x = math.abs(st.scale.x) * (val ? -1 : 1), value);
|
st.scale.x = math.abs(st.scale.x) * (value ? -1 : 1);
|
||||||
BlockEngine.SetBlockInfo(this, (ref GFXPrefabEntityStructGPUI st, bool val) =>
|
BlockEngine.UpdatePrefab(this, (ushort) Type, (byte) Material, value);
|
||||||
{
|
|
||||||
uint prefabId = PrefabsID.GetOrCreatePrefabID((ushort) Type, (byte) Material, 0, value);
|
|
||||||
st.prefabID = prefabId;
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,7 +335,8 @@ namespace TechbloxModdingAPI
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (DBEntityStruct st) => (BlockIDs) st.DBID, BlockIDs.Invalid);
|
var opt = BlockEngine.GetBlockInfoOptional<DBEntityStruct>(this);
|
||||||
|
return opt ? (BlockIDs) opt.Get().DBID : BlockIDs.Invalid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,18 +347,16 @@ namespace TechbloxModdingAPI
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
byte index = BlockEngine.GetBlockInfo(this, (ColourParameterEntityStruct st) => st.indexInPalette,
|
var opt = BlockEngine.GetBlockInfoOptional<ColourParameterEntityStruct>(this);
|
||||||
byte.MaxValue);
|
return new BlockColor(opt ? opt.Get().indexInPalette : byte.MaxValue);
|
||||||
return new BlockColor(index);
|
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, BlockColor val) =>
|
//TODO: Check if setting to 255 works
|
||||||
{ //TODO: Check if setting to 255 works
|
var color = BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(this);
|
||||||
color.indexInPalette = val.Index;
|
color.indexInPalette = value.Index;
|
||||||
color.hasNetworkChange = true;
|
color.hasNetworkChange = true;
|
||||||
color.paletteColour = BlockEngine.ConvertBlockColor(color.indexInPalette);
|
color.paletteColour = BlockEngine.ConvertBlockColor(color.indexInPalette);
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,11 +368,9 @@ namespace TechbloxModdingAPI
|
||||||
get => BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(this).paletteColour;
|
get => BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(this).paletteColour;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ColourParameterEntityStruct color, float4 val) =>
|
ref var color = ref BlockEngine.GetBlockInfo<ColourParameterEntityStruct>(this);
|
||||||
{
|
color.paletteColour = value;
|
||||||
color.paletteColour = val;
|
color.hasNetworkChange = true;
|
||||||
color.hasNetworkChange = true;
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,9 +379,16 @@ namespace TechbloxModdingAPI
|
||||||
*/
|
*/
|
||||||
public BlockMaterial Material
|
public BlockMaterial Material
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo(this, (CubeMaterialStruct cmst) => (BlockMaterial) cmst.materialId, BlockMaterial.Default);
|
get
|
||||||
set => BlockEngine.SetBlockInfo(this,
|
{
|
||||||
(ref CubeMaterialStruct cmst, BlockMaterial val) => cmst.materialId = (byte) val, value);
|
var opt = BlockEngine.GetBlockInfoOptional<CubeMaterialStruct>(this);
|
||||||
|
return opt ? (BlockMaterial) opt.Get().materialId : BlockMaterial.Default;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
BlockEngine.GetBlockInfo<CubeMaterialStruct>(this).materialId = (byte) value;
|
||||||
|
BlockEngine.UpdatePrefab(this, (ushort) Type, (byte) value, Flipped); //TODO: Test default
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -397,13 +397,11 @@ namespace TechbloxModdingAPI
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Label
|
public string Label
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfoViewStruct(this, (TextLabelEntityViewStruct st) => st.textLabelComponent?.text);
|
get => BlockEngine.GetBlockInfoViewComponent<TextLabelEntityViewStruct>(this).textLabelComponent?.text;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfoViewStruct(this, (ref TextLabelEntityViewStruct text, string val) =>
|
var comp = BlockEngine.GetBlockInfoViewComponent<TextLabelEntityViewStruct>(this).textLabelComponent;
|
||||||
{
|
if (comp != null) comp.text = value;
|
||||||
if (text.textLabelComponent != null) text.textLabelComponent.text = val;
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,9 +419,8 @@ namespace TechbloxModdingAPI
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (blockGroup != null) return blockGroup;
|
if (blockGroup != null) return blockGroup;
|
||||||
return blockGroup = BlockEngine.GetBlockInfo(this,
|
var bgec = BlockEngine.GetBlockInfo<BlockGroupEntityComponent>(this);
|
||||||
(BlockGroupEntityComponent bgec) =>
|
return blockGroup = bgec.currentBlockGroup == -1 ? null : new BlockGroup(bgec.currentBlockGroup, this);
|
||||||
bgec.currentBlockGroup == -1 ? null : new BlockGroup(bgec.currentBlockGroup, this));
|
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
@ -434,9 +431,7 @@ namespace TechbloxModdingAPI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
blockGroup?.RemoveInternal(this);
|
blockGroup?.RemoveInternal(this);
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<BlockGroupEntityComponent>(this).currentBlockGroup = value?.Id ?? -1;
|
||||||
(ref BlockGroupEntityComponent bgec, BlockGroup val) => bgec.currentBlockGroup = val?.Id ?? -1,
|
|
||||||
value);
|
|
||||||
value?.AddInternal(this);
|
value?.AddInternal(this);
|
||||||
blockGroup = value;
|
blockGroup = value;
|
||||||
}
|
}
|
||||||
|
@ -466,10 +461,10 @@ namespace TechbloxModdingAPI
|
||||||
/// <returns>The SimBody of the chunk or null if the block doesn't exist or not in simulation mode.</returns>
|
/// <returns>The SimBody of the chunk or null if the block doesn't exist or not in simulation mode.</returns>
|
||||||
public SimBody GetSimBody()
|
public SimBody GetSimBody()
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this,
|
var st = BlockEngine.GetBlockInfo<GridConnectionsEntityStruct>(this);
|
||||||
(GridConnectionsEntityStruct st) => st.machineRigidBodyId != uint.MaxValue
|
return st.machineRigidBodyId != uint.MaxValue
|
||||||
? new SimBody(st.machineRigidBodyId, st.clusterId)
|
? new SimBody(st.machineRigidBodyId, st.clusterId)
|
||||||
: null);
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -555,7 +550,7 @@ namespace TechbloxModdingAPI
|
||||||
|
|
||||||
//Lets improve that using delegates
|
//Lets improve that using delegates
|
||||||
var block = New<T>(Id.entityID, Id.groupID);
|
var block = New<T>(Id.entityID, Id.groupID);
|
||||||
if (this.InitData.Group != null)
|
if (this.InitData.Valid)
|
||||||
{
|
{
|
||||||
block.InitData = this.InitData;
|
block.InitData = this.InitData;
|
||||||
Placed += block.OnPlacedInit; //Reset InitData of new object
|
Placed += block.OnPlacedInit; //Reset InitData of new object
|
||||||
|
|
|
@ -80,6 +80,16 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
return ref entitiesDB.QueryEntityOrDefault<T>(block);
|
return ref entitiesDB.QueryEntityOrDefault<T>(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal ref T GetBlockInfo<T>(EcsObjectBase obj) where T : unmanaged, IEntityComponent
|
||||||
|
{
|
||||||
|
return ref entitiesDB.QueryEntityOrDefault<T>(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref T GetBlockInfoViewComponent<T>(Block block) where T : struct, IEntityViewComponent
|
||||||
|
{
|
||||||
|
return ref entitiesDB.QueryEntityOrDefault<T>(block);
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateDisplayedBlock(EGID id)
|
public void UpdateDisplayedBlock(EGID id)
|
||||||
{
|
{
|
||||||
if (!BlockExists(id)) return;
|
if (!BlockExists(id)) return;
|
||||||
|
|
|
@ -21,8 +21,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).springFrequency;
|
get => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).springFrequency;
|
||||||
|
|
||||||
set => BlockEngine.SetBlockInfo(this,
|
set => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).springFrequency = value;
|
||||||
(ref DampedSpringReadOnlyStruct dsrs, float val) => dsrs.springFrequency = val, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -41,8 +40,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).springDamping;
|
get => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).springDamping;
|
||||||
|
|
||||||
set => BlockEngine.SetBlockInfo(this,
|
set => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).springDamping = value;
|
||||||
(ref DampedSpringReadOnlyStruct ljf, float val) => ljf.springDamping = val, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -52,8 +50,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).maxExtent;
|
get => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).maxExtent;
|
||||||
|
|
||||||
set => BlockEngine.SetBlockInfo(this,
|
set => BlockEngine.GetBlockInfo<DampedSpringReadOnlyStruct>(this).maxExtent = value;
|
||||||
(ref DampedSpringReadOnlyStruct ljf, float val) => ljf.maxExtent = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -33,8 +33,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).trackIndx = value;
|
||||||
(ref MusicBlockDataEntityStruct msdes, byte val) => msdes.trackIndx = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,24 +41,22 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this,
|
var msdes = BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this);
|
||||||
(MusicBlockDataEntityStruct msdes) => msdes.fmod2DEventPaths.Get<Guid>(msdes.trackIndx));
|
return msdes.fmod2DEventPaths.Get<Guid>(msdes.trackIndx);
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref MusicBlockDataEntityStruct msdes, Guid val) =>
|
ref var msdes = ref BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this);
|
||||||
|
for (byte i = 0; i < msdes.fmod2DEventPaths.Count<Guid>(); i++)
|
||||||
{
|
{
|
||||||
for (byte i = 0; i < msdes.fmod2DEventPaths.Count<Guid>(); i++)
|
Guid track = msdes.fmod2DEventPaths.Get<Guid>(i);
|
||||||
|
if (track == value)
|
||||||
{
|
{
|
||||||
Guid track = msdes.fmod2DEventPaths.Get<Guid>(i);
|
msdes.trackIndx = i;
|
||||||
if (track == val)
|
break;
|
||||||
{
|
|
||||||
msdes.trackIndx = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, value);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,15 +64,13 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (MusicBlockDataEntityStruct msdes) =>
|
var msdes = BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this);
|
||||||
|
Guid[] tracks = new Guid[msdes.fmod2DEventPaths.Count<Guid>()];
|
||||||
|
for (byte i = 0; i < tracks.Length; i++)
|
||||||
{
|
{
|
||||||
Guid[] tracks = new Guid[msdes.fmod2DEventPaths.Count<Guid>()];
|
tracks[i] = msdes.fmod2DEventPaths.Get<Guid>(i);
|
||||||
for (byte i = 0; i < tracks.Length; i++)
|
}
|
||||||
{
|
return tracks;
|
||||||
tracks[i] = msdes.fmod2DEventPaths.Get<Guid>(i);
|
|
||||||
}
|
|
||||||
return tracks;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,8 +83,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).tweakableVolume = value;
|
||||||
(ref MusicBlockDataEntityStruct msdes, float val) => msdes.tweakableVolume = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,14 +92,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
//Assert.Log("Block exists: " + Exists);
|
//Assert.Log("Block exists: " + Exists);
|
||||||
return BlockEngine.GetBlockInfo(this,
|
return (ChannelType) BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).channelType;
|
||||||
(MusicBlockDataEntityStruct msdes) => (ChannelType) msdes.channelType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).channelType = (byte) value;
|
||||||
(ref MusicBlockDataEntityStruct msdes, ChannelType val) => msdes.channelType = (byte) val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,33 +105,31 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this,
|
return BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this).isPlaying;
|
||||||
(MusicBlockDataEntityStruct msdes) => msdes.isPlaying);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref MusicBlockDataEntityStruct msdes, bool val) =>
|
ref var msdes = ref BlockEngine.GetBlockInfo<MusicBlockDataEntityStruct>(this);
|
||||||
|
if (msdes.isPlaying == value) return;
|
||||||
|
if (value)
|
||||||
{
|
{
|
||||||
if (msdes.isPlaying == val) return;
|
// start playing
|
||||||
if (val)
|
EventInstance inst = RuntimeManager.CreateInstance(msdes.fmod2DEventPaths.Get<Guid>(msdes.trackIndx));
|
||||||
{
|
inst.setVolume(msdes.tweakableVolume / 100f);
|
||||||
// start playing
|
inst.start();
|
||||||
EventInstance inst = RuntimeManager.CreateInstance(msdes.fmod2DEventPaths.Get<Guid>(msdes.trackIndx));
|
msdes.eventHandle = inst.handle;
|
||||||
inst.setVolume(msdes.tweakableVolume / 100f);
|
}
|
||||||
inst.start();
|
else
|
||||||
msdes.eventHandle = inst.handle;
|
{
|
||||||
}
|
// stop playing
|
||||||
else
|
EventInstance inst = default(EventInstance);
|
||||||
{
|
inst.handle = msdes.eventHandle;
|
||||||
// stop playing
|
inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
|
||||||
EventInstance inst = default(EventInstance);
|
inst.release();
|
||||||
inst.handle = msdes.eventHandle;
|
}
|
||||||
inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
|
|
||||||
inst.release();
|
msdes.isPlaying = value;
|
||||||
}
|
|
||||||
msdes.isPlaying = val;
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,14 +16,11 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
public char Identifier
|
public char Identifier
|
||||||
{
|
{
|
||||||
get => (char) BlockEngine.GetBlockInfo<ObjectIdEntityStruct>(this).objectId + 'A';
|
get => (char) (BlockEngine.GetBlockInfo<ObjectIdEntityStruct>(this).objectId + 'A');
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref ObjectIdEntityStruct st, char val) =>
|
BlockEngine.GetBlockInfo<ObjectIdEntityStruct>(this).objectId = (byte) (value - 'A');
|
||||||
{
|
Label = value + ""; //The label isn't updated automatically
|
||||||
st.objectId = (byte) (val - 'A');
|
|
||||||
Label = val + ""; //The label isn't updated automatically
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).tweakableVolume = value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, float val) => obj.tweakableVolume = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +40,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).tweakablePitch = value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, float val) => obj.tweakablePitch = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,8 +53,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).is3D = value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, bool val) => obj.is3D = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,13 +61,12 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) => (ChannelType)obj.channelType);
|
return (ChannelType) BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).channelType;
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).channelType = (byte) value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, ChannelType val) => obj.tweakableVolume = (byte) val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,8 +79,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).soundEffectIndex = value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, byte val) => obj.soundEffectIndex = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,35 +88,36 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this,
|
var obj = BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this);
|
||||||
(SoundSfxBlockDataEntityStruct obj) => obj.is3D ? obj.fmod3DEventPaths.Get<Guid>(obj.soundEffectIndex) : obj.fmod2DEventPaths.Get<Guid>(obj.soundEffectIndex));
|
return obj.is3D
|
||||||
|
? obj.fmod3DEventPaths.Get<Guid>(obj.soundEffectIndex)
|
||||||
|
: obj.fmod2DEventPaths.Get<Guid>(obj.soundEffectIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref SoundSfxBlockDataEntityStruct obj, Guid val) =>
|
var obj = BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this);
|
||||||
|
for (byte i = 0; i < obj.fmod2DEventPaths.Count<Guid>(); i++)
|
||||||
{
|
{
|
||||||
for (byte i = 0; i < obj.fmod2DEventPaths.Count<Guid>(); i++)
|
Guid track = obj.fmod2DEventPaths.Get<Guid>(i);
|
||||||
|
if (track == value)
|
||||||
{
|
{
|
||||||
Guid track = obj.fmod2DEventPaths.Get<Guid>(i);
|
obj.soundEffectIndex = i;
|
||||||
if (track == val)
|
obj.is3D = false;
|
||||||
{
|
return;
|
||||||
obj.soundEffectIndex = i;
|
|
||||||
obj.is3D = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (byte i = 0; i < obj.fmod3DEventPaths.Count<Guid>(); i++)
|
}
|
||||||
|
|
||||||
|
for (byte i = 0; i < obj.fmod3DEventPaths.Count<Guid>(); i++)
|
||||||
|
{
|
||||||
|
Guid track = obj.fmod3DEventPaths.Get<Guid>(i);
|
||||||
|
if (track == value)
|
||||||
{
|
{
|
||||||
Guid track = obj.fmod3DEventPaths.Get<Guid>(i);
|
obj.soundEffectIndex = i;
|
||||||
if (track == val)
|
obj.is3D = true;
|
||||||
{
|
return;
|
||||||
obj.soundEffectIndex = i;
|
|
||||||
obj.is3D = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, value);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,15 +126,14 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) =>
|
var obj = BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this);
|
||||||
|
Guid[] tracks = new Guid[obj.fmod2DEventPaths.Count<Guid>()];
|
||||||
|
for (byte i = 0; i < tracks.Length; i++)
|
||||||
{
|
{
|
||||||
Guid[] tracks = new Guid[obj.fmod2DEventPaths.Count<Guid>()];
|
tracks[i] = obj.fmod2DEventPaths.Get<Guid>(i);
|
||||||
for (byte i = 0; i < tracks.Length; i++)
|
}
|
||||||
{
|
|
||||||
tracks[i] = obj.fmod2DEventPaths.Get<Guid>(i);
|
return tracks;
|
||||||
}
|
|
||||||
return tracks;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,15 +141,14 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this, (SoundSfxBlockDataEntityStruct obj) =>
|
var obj = BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this);
|
||||||
|
Guid[] tracks = new Guid[obj.fmod3DEventPaths.Count<Guid>()];
|
||||||
|
for (byte i = 0; i < tracks.Length; i++)
|
||||||
{
|
{
|
||||||
Guid[] tracks = new Guid[obj.fmod3DEventPaths.Count<Guid>()];
|
tracks[i] = obj.fmod2DEventPaths.Get<Guid>(i);
|
||||||
for (byte i = 0; i < tracks.Length; i++)
|
}
|
||||||
{
|
|
||||||
tracks[i] = obj.fmod2DEventPaths.Get<Guid>(i);
|
return tracks;
|
||||||
}
|
|
||||||
return tracks;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,8 +161,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this,
|
BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).isLoopedBlock = value;
|
||||||
(ref SoundSfxBlockDataEntityStruct obj, bool val) => obj.isLoopedBlock = val, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,33 +169,33 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return BlockEngine.GetBlockInfo(this,
|
return BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this).isPlaying;
|
||||||
(SoundSfxBlockDataEntityStruct obj) => obj.isPlaying);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
BlockEngine.SetBlockInfo(this, (ref SoundSfxBlockDataEntityStruct obj, bool val) =>
|
var obj = BlockEngine.GetBlockInfo<SoundSfxBlockDataEntityStruct>(this);
|
||||||
|
if (obj.isPlaying == value) return;
|
||||||
|
if (value)
|
||||||
{
|
{
|
||||||
if (obj.isPlaying == val) return;
|
// start playing
|
||||||
if (val)
|
EventInstance inst = RuntimeManager.CreateInstance(obj.is3D
|
||||||
{
|
? obj.fmod3DEventPaths.Get<Guid>(obj.soundEffectIndex)
|
||||||
// start playing
|
: obj.fmod2DEventPaths.Get<Guid>(obj.soundEffectIndex));
|
||||||
EventInstance inst = RuntimeManager.CreateInstance(obj.is3D ? obj.fmod3DEventPaths.Get<Guid>(obj.soundEffectIndex) : obj.fmod2DEventPaths.Get<Guid>(obj.soundEffectIndex));
|
inst.setVolume(obj.tweakableVolume / 100f);
|
||||||
inst.setVolume(obj.tweakableVolume / 100f);
|
inst.start();
|
||||||
inst.start();
|
obj.eventHandle = inst.handle;
|
||||||
obj.eventHandle = inst.handle;
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
// stop playing
|
||||||
// stop playing
|
EventInstance inst = default(EventInstance);
|
||||||
EventInstance inst = default(EventInstance);
|
inst.handle = obj.eventHandle;
|
||||||
inst.handle = obj.eventHandle;
|
inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
|
||||||
inst.stop(FMOD.Studio.STOP_MODE.ALLOWFADEOUT);
|
inst.release();
|
||||||
inst.release();
|
}
|
||||||
}
|
|
||||||
obj.isPlaying = val;
|
obj.isPlaying = value;
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,6 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
/// <returns>The localized port name.</returns>
|
/// <returns>The localized port name.</returns>
|
||||||
public string PortName(byte port, bool input)
|
public string PortName(byte port, bool input)
|
||||||
{
|
{
|
||||||
BlockPortsStruct bps = BlockEngine.GetBlockInfo(this, (BlockPortsStruct a) => a);
|
|
||||||
PortEntityStruct pes = SignalEngine.GetPortByOffset(this, port, input);
|
PortEntityStruct pes = SignalEngine.GetPortByOffset(this, port, input);
|
||||||
return pes.portNameLocalised;
|
return pes.portNameLocalised;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,11 +32,9 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == null) value = "";
|
if (value == null) value = "";
|
||||||
BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) =>
|
var tbds = BlockEngine.GetBlockInfo<TextBlockDataStruct>(this);
|
||||||
{
|
tbds.textCurrent.Set(value);
|
||||||
tbds.textCurrent.Set(val);
|
tbds.textStored.Set(value, true);
|
||||||
tbds.textStored.Set(val, true);
|
|
||||||
}, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,8 +48,7 @@ namespace TechbloxModdingAPI.Blocks
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == null) value = "";
|
if (value == null) value = "";
|
||||||
BlockEngine.SetBlockInfo(this, (ref TextBlockDataStruct tbds, string val) =>
|
BlockEngine.GetBlockInfo<TextBlockDataStruct>(this).textBlockID.Set(value);
|
||||||
tbds.textBlockID.Set(val), value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ namespace TechbloxModdingAPI
|
||||||
/// Represnts a cluster of blocks in time running mode, meaning blocks that are connected either directly or via joints.
|
/// Represnts a cluster of blocks in time running mode, meaning blocks that are connected either directly or via joints.
|
||||||
/// Only exists if a cluster destruction manager is present. Static blocks like grass and dirt aren't part of a cluster.
|
/// Only exists if a cluster destruction manager is present. Static blocks like grass and dirt aren't part of a cluster.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Cluster
|
public class Cluster : EcsObjectBase
|
||||||
{
|
{
|
||||||
public EGID Id { get; }
|
public override EGID Id { get; }
|
||||||
|
|
||||||
public Cluster(EGID id)
|
public Cluster(EGID id)
|
||||||
{
|
{
|
||||||
|
@ -23,20 +23,20 @@ namespace TechbloxModdingAPI
|
||||||
|
|
||||||
public float InitialHealth
|
public float InitialHealth
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).initialHealth;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).initialHealth = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float CurrentHealth
|
public float CurrentHealth
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).currentHealth;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).currentHealth = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float HealthMultiplier
|
public float HealthMultiplier
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).healthMultiplier;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).healthMultiplier = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
using Techblox.FlyCam;
|
using Techblox.FlyCam;
|
||||||
using TechbloxModdingAPI.Engines;
|
using TechbloxModdingAPI.Engines;
|
||||||
|
using TechbloxModdingAPI.Utility;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Players
|
namespace TechbloxModdingAPI.Players
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,9 +12,9 @@ namespace TechbloxModdingAPI
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A rigid body (like a chunk of connected blocks) during simulation.
|
/// A rigid body (like a chunk of connected blocks) during simulation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class SimBody : IEquatable<SimBody>, IEquatable<EGID>
|
public class SimBody : EcsObjectBase, IEquatable<SimBody>, IEquatable<EGID>
|
||||||
{
|
{
|
||||||
public EGID Id { get; }
|
public override EGID Id { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The cluster this chunk belongs to, or null if no cluster destruction manager present or the chunk doesn't exist.
|
/// The cluster this chunk belongs to, or null if no cluster destruction manager present or the chunk doesn't exist.
|
||||||
|
@ -92,26 +92,26 @@ namespace TechbloxModdingAPI
|
||||||
|
|
||||||
public float InitialHealth
|
public float InitialHealth
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).initialHealth;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).initialHealth = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float CurrentHealth
|
public float CurrentHealth
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).currentHealth;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).currentHealth = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float HealthMultiplier
|
public float HealthMultiplier
|
||||||
{
|
{
|
||||||
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier;
|
get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).healthMultiplier;
|
||||||
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier = value;
|
set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).healthMultiplier = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the body can be moved or static.
|
/// Whether the body can be moved or static.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Static => Block.BlockEngine.GetBlockInfo<MassEntityStruct>(Id).isStatic; //Setting it doesn't have any effect
|
public bool Static => Block.BlockEngine.GetBlockInfo<MassEntityStruct>(this).isStatic; //Setting it doesn't have any effect
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The rigid bodies connected to this one via functional joints (broken ones don't count).
|
/// The rigid bodies connected to this one via functional joints (broken ones don't count).
|
||||||
|
@ -132,7 +132,7 @@ namespace TechbloxModdingAPI
|
||||||
|
|
||||||
private ref RigidBodyEntityStruct GetStruct()
|
private ref RigidBodyEntityStruct GetStruct()
|
||||||
{
|
{
|
||||||
return ref Block.BlockEngine.GetBlockInfo<RigidBodyEntityStruct>(Id);
|
return ref Block.BlockEngine.GetBlockInfo<RigidBodyEntityStruct>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
|
|
55
TechbloxModdingAPI/Utility/ManagedApiExtensions.cs
Normal file
55
TechbloxModdingAPI/Utility/ManagedApiExtensions.cs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
using Svelto.ECS;
|
||||||
|
using Svelto.ECS.Hybrid;
|
||||||
|
using TechbloxModdingAPI.Blocks;
|
||||||
|
|
||||||
|
namespace TechbloxModdingAPI.Utility
|
||||||
|
{
|
||||||
|
public static class ManagedApiExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to query an entity and returns an optional that contains the result if succeeded.
|
||||||
|
/// <b>This overload does not take initializer data into account.</b>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entitiesDB">The entities DB</param>
|
||||||
|
/// <param name="egid">The EGID to query</param>
|
||||||
|
/// <typeparam name="T">The component type to query</typeparam>
|
||||||
|
/// <returns>An optional that contains the result on success or is empty if not found</returns>
|
||||||
|
public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EGID egid)
|
||||||
|
where T : struct, IEntityViewComponent
|
||||||
|
{
|
||||||
|
return entitiesDB.TryQueryEntitiesAndIndex<T>(egid, out uint index, out var array)
|
||||||
|
? new OptionalRef<T>(array, index)
|
||||||
|
: new OptionalRef<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to query an entity and returns the result or a dummy value that can be modified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entitiesDB"></param>
|
||||||
|
/// <param name="obj"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static OptionalRef<T> QueryEntityOptional<T>(this EntitiesDB entitiesDB, EcsObjectBase obj)
|
||||||
|
where T : struct, IEntityViewComponent
|
||||||
|
{
|
||||||
|
var opt = QueryEntityOptional<T>(entitiesDB, obj.Id);
|
||||||
|
return opt ? opt : new OptionalRef<T>(obj, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to query an entity and returns the result or a dummy value that can be modified.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entitiesDB"></param>
|
||||||
|
/// <param name="obj"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ref T QueryEntityOrDefault<T>(this EntitiesDB entitiesDB, EcsObjectBase obj)
|
||||||
|
where T : struct, IEntityViewComponent
|
||||||
|
{
|
||||||
|
var opt = QueryEntityOptional<T>(entitiesDB, obj.Id);
|
||||||
|
if (opt) return ref opt.Get();
|
||||||
|
if (obj.InitData.Valid) return ref obj.InitData.Initializer(obj.Id).GetOrCreate<T>();
|
||||||
|
return ref opt.Get(); //Default value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,10 +3,11 @@ using TechbloxModdingAPI.Blocks;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI.Utility
|
namespace TechbloxModdingAPI.Utility
|
||||||
{
|
{
|
||||||
public static class ApiExtensions
|
public static class NativeApiExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attempts to query an entity and returns an optional that contains the result if succeeded.
|
/// Attempts to query an entity and returns an optional that contains the result if succeeded.
|
||||||
|
/// <b>This overload does not take initializer data into account.</b>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="entitiesDB">The entities DB</param>
|
/// <param name="entitiesDB">The entities DB</param>
|
||||||
/// <param name="egid">The EGID to query</param>
|
/// <param name="egid">The EGID to query</param>
|
||||||
|
@ -31,7 +32,7 @@ namespace TechbloxModdingAPI.Utility
|
||||||
where T : unmanaged, IEntityComponent
|
where T : unmanaged, IEntityComponent
|
||||||
{
|
{
|
||||||
var opt = QueryEntityOptional<T>(entitiesDB, obj.Id);
|
var opt = QueryEntityOptional<T>(entitiesDB, obj.Id);
|
||||||
return opt ? opt : new OptionalRef<T>(obj);
|
return opt ? opt : new OptionalRef<T>(obj, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
|
@ -1,44 +1,53 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Runtime.InteropServices;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using TechbloxModdingAPI.Blocks;
|
|
||||||
using Svelto.DataStructures;
|
using Svelto.DataStructures;
|
||||||
using Svelto.ECS;
|
using Svelto.ECS;
|
||||||
|
|
||||||
namespace TechbloxModdingAPI
|
namespace TechbloxModdingAPI.Utility
|
||||||
{
|
{
|
||||||
public ref struct OptionalRef<T> where T : unmanaged, IEntityComponent
|
[StructLayout(LayoutKind.Explicit)] //Make the array and managedArray fields take up the same space
|
||||||
|
public ref struct OptionalRef<T> where T : struct, IEntityComponent
|
||||||
{
|
{
|
||||||
private bool exists;
|
[FieldOffset(0)] private readonly State state;
|
||||||
private NB<T> array;
|
[FieldOffset(1)] private readonly uint index;
|
||||||
private uint index;
|
[FieldOffset(5)] private NB<T> array;
|
||||||
private EntityInitializer initializer;
|
[FieldOffset(5)] private MB<T> managedArray;
|
||||||
|
[FieldOffset(1)] private readonly EntityInitializer initializer;
|
||||||
|
//The possible fields are: (index && (array || managedArray)) || initializer
|
||||||
|
|
||||||
public OptionalRef(NB<T> array, uint index)
|
public OptionalRef(NB<T> array, uint index)
|
||||||
{
|
{
|
||||||
exists = true;
|
state = State.Native;
|
||||||
this.array = array;
|
this.array = array;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
initializer = default;
|
initializer = default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OptionalRef(MB<T> array, uint index)
|
||||||
|
{
|
||||||
|
state = State.Managed;
|
||||||
|
managedArray = array;
|
||||||
|
this.index = index;
|
||||||
|
initializer = default;
|
||||||
|
this.array = default;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Wraps the initializer data, if present.
|
/// Wraps the initializer data, if present.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="obj">The object with the initializer</param>
|
/// <param name="obj">The object with the initializer</param>
|
||||||
public OptionalRef(EcsObjectBase obj)
|
/// <param name="unmanaged">Whether the struct is unmanaged</param>
|
||||||
|
public OptionalRef(EcsObjectBase obj, bool unmanaged)
|
||||||
{
|
{
|
||||||
if (obj.InitData.Valid)
|
if (obj.InitData.Valid)
|
||||||
{
|
{
|
||||||
initializer = obj.InitData.Initializer(obj.Id);
|
initializer = obj.InitData.Initializer(obj.Id);
|
||||||
exists = true;
|
state = (unmanaged ? State.Native : State.Managed) | State.Initializer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
initializer = default;
|
initializer = default;
|
||||||
exists = false;
|
state = State.Empty;
|
||||||
}
|
}
|
||||||
array = default;
|
array = default;
|
||||||
index = default;
|
index = default;
|
||||||
|
@ -50,31 +59,36 @@ namespace TechbloxModdingAPI
|
||||||
/// <returns>The value or the default value</returns>
|
/// <returns>The value or the default value</returns>
|
||||||
public ref T Get()
|
public ref T Get()
|
||||||
{
|
{
|
||||||
if (!exists) return ref CompRefCache<T>.Default;
|
if (state == State.Empty) return ref CompRefCache.Default;
|
||||||
if (initializer.EGID == EGID.Empty)
|
if ((state & State.Initializer) != State.Empty) return ref initializer.GetOrCreate<T>();
|
||||||
return ref array[index];
|
if ((state & State.Native) != State.Empty) return ref array[index];
|
||||||
return ref initializer.GetOrCreate<T>();
|
return ref managedArray[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Exists => exists;
|
public bool Exists => state != State.Empty;
|
||||||
|
|
||||||
public static implicit operator T(OptionalRef<T> opt) => opt.Get();
|
public static implicit operator T(OptionalRef<T> opt) => opt.Get();
|
||||||
|
|
||||||
public static implicit operator bool(OptionalRef<T> opt) => opt.exists;
|
public static implicit operator bool(OptionalRef<T> opt) => opt.state != State.Empty;
|
||||||
|
|
||||||
/*public delegate ref TR Mapper<TR>(ref T component) where TR : unmanaged;
|
|
||||||
public unsafe delegate TR* PMapper<TR>(T* component) where TR : unmanaged;
|
|
||||||
|
|
||||||
public unsafe OptionalRef<TR> Map<TR>(PMapper<TR> mapper) where TR : unmanaged =>
|
|
||||||
exists ? new OptionalRef<TR>(ref *mapper(pointer)) : new OptionalRef<TR>();*/
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an instance of a struct T that can be referenced.
|
/// Creates an instance of a struct T that can be referenced.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TR">The struct type to cache</typeparam>
|
internal struct CompRefCache
|
||||||
private struct CompRefCache<TR> where TR : unmanaged
|
|
||||||
{
|
{
|
||||||
public static TR Default;
|
public static T Default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A byte that holds state in its bits.
|
||||||
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
|
private enum State : byte
|
||||||
|
{
|
||||||
|
Empty,
|
||||||
|
Native,
|
||||||
|
Managed,
|
||||||
|
Initializer = 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue