Clone API event parameters to reduce listener contamination

This commit is contained in:
James Seibel
2024-07-12 19:22:20 -05:00
parent 6bb832a488
commit cab9f7c830
12 changed files with 154 additions and 20 deletions
@@ -0,0 +1,18 @@
package com.seibel.distanthorizons.api.interfaces.util;
/**
* Used for objects that need deep clones. <br>
* Replacement for {@link Cloneable}.
*
* @see Cloneable
*
* @author James Seibel
* @version 2024-7-12
* @since API 3.0.0
*/
public interface IDhApiCopyable
{
/** Returns a deep clone of all parameters whenever possible. */
IDhApiCopyable copy();
}
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.api.methods.events.abstractEvents;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
import com.seibel.distanthorizons.api.objects.math.DhApiVec3f;
@@ -52,7 +53,7 @@ public abstract class DhApiBeforeBufferRenderEvent implements IDhApiEvent<DhApiB
// parameter object //
//==================//
public static class EventParam extends DhApiRenderParam
public static class EventParam extends DhApiRenderParam implements IDhApiEventParam
{
/**
* Measured in blocks.
@@ -66,6 +67,15 @@ public abstract class DhApiBeforeBufferRenderEvent implements IDhApiEvent<DhApiB
super(parent);
this.modelPos = modelPos;
}
@Override
public EventParam copy()
{
return new EventParam(
this, this.modelPos.copy()
);
}
}
}
@@ -22,6 +22,7 @@ package com.seibel.distanthorizons.api.methods.events.abstractEvents;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiRenderableBoxGroup;
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiCancelableEvent;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiCancelableEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiRenderParam;
@@ -51,12 +52,13 @@ public abstract class DhApiBeforeGenericObjectRenderEvent implements IDhApiCance
// parameter object //
//==================//
public static class EventParam extends DhApiRenderParam
public static class EventParam extends DhApiRenderParam implements IDhApiEventParam
{
public final long boxGroupId;
public final String resourceLocationNamespace;
public final String resourceLocationPath;
public EventParam(
DhApiRenderParam renderParam,
IDhApiRenderableBoxGroup boxGroup
@@ -68,7 +70,28 @@ public abstract class DhApiBeforeGenericObjectRenderEvent implements IDhApiCance
this.resourceLocationNamespace = boxGroup.getResourceLocationNamespace();
this.resourceLocationPath = boxGroup.getResourceLocationPath();
}
public EventParam(
DhApiRenderParam renderParam,
long boxGroupId, String resourceLocationNamespace, String resourceLocationPath
)
{
super(renderParam);
this.boxGroupId = boxGroupId;
this.resourceLocationNamespace = resourceLocationNamespace;
this.resourceLocationPath = resourceLocationPath;
}
@Override
public EventParam copy()
{
return new EventParam(
this,
this.boxGroupId, this.resourceLocationNamespace, this.resourceLocationPath
);
}
}
}
@@ -22,6 +22,7 @@ package com.seibel.distanthorizons.api.methods.events.abstractEvents;
import com.seibel.distanthorizons.api.interfaces.data.IDhApiTerrainDataRepo;
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
/**
@@ -53,7 +54,7 @@ public abstract class DhApiChunkModifiedEvent implements IDhApiEvent<DhApiChunkM
// parameter object //
//==================//
public static class EventParam
public static class EventParam implements IDhApiEventParam
{
/** The saved level. */
public final IDhApiLevelWrapper levelWrapper;
@@ -71,6 +72,15 @@ public abstract class DhApiChunkModifiedEvent implements IDhApiEvent<DhApiChunkM
this.chunkZ = chunkZ;
}
@Override
public EventParam copy()
{
return new EventParam(
this.levelWrapper,
this.chunkX, this.chunkZ
);
}
}
}
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.api.methods.events.abstractEvents;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
/**
@@ -48,7 +49,7 @@ public abstract class DhApiColorDepthTextureCreatedEvent implements IDhApiEvent<
// parameter object //
//==================//
public static class EventParam
public static class EventParam implements IDhApiEventParam
{
/** Measured in pixels */
public final int previousWidth;
@@ -72,6 +73,16 @@ public abstract class DhApiColorDepthTextureCreatedEvent implements IDhApiEvent<
this.newHeight = newHeight;
}
@Override
public EventParam copy()
{
return new EventParam(
this.previousWidth, this.previousHeight,
this.newWidth, this.newHeight
);
}
}
}
@@ -21,6 +21,7 @@ package com.seibel.distanthorizons.api.methods.events.abstractEvents;
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
/**
@@ -49,13 +50,16 @@ public abstract class DhApiLevelLoadEvent implements IDhApiEvent<DhApiLevelLoadE
// parameter object //
//==================//
public static class EventParam
public static class EventParam implements IDhApiEventParam
{
/** The newly loaded level. */
public final IDhApiLevelWrapper levelWrapper;
public EventParam(IDhApiLevelWrapper newLevelWrapper) { this.levelWrapper = newLevelWrapper; }
@Override
public EventParam copy() { return new EventParam(this.levelWrapper); }
}
}
@@ -19,9 +19,9 @@
package com.seibel.distanthorizons.api.methods.events.abstractEvents;
import com.seibel.distanthorizons.api.DhApi;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.distanthorizons.api.interfaces.world.IDhApiLevelWrapper;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
/**
@@ -49,13 +49,16 @@ public abstract class DhApiLevelUnloadEvent implements IDhApiEvent<DhApiLevelUnl
// parameter object //
//==================//
public static class EventParam
public static class EventParam implements IDhApiEventParam
{
/** The recently unloaded level. */
public final IDhApiLevelWrapper levelWrapper;
public EventParam(IDhApiLevelWrapper newLevelWrapper) { this.levelWrapper = newLevelWrapper; }
@Override
public EventParam copy() { return new EventParam(this.levelWrapper); }
}
}
@@ -0,0 +1,13 @@
package com.seibel.distanthorizons.api.methods.events.interfaces;
import com.seibel.distanthorizons.api.interfaces.util.IDhApiCopyable;
/**
* @author James Seibel
* @version 2024-7-12
* @since API 3.0.0
*/
public interface IDhApiEventParam extends IDhApiCopyable
{
}
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.api.methods.events.sharedParameterObjects;
import com.seibel.distanthorizons.api.enums.rendering.EDhApiRenderPass;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
/**
@@ -29,7 +30,7 @@ import com.seibel.distanthorizons.api.objects.math.DhApiMat4f;
* @version 2024-1-31
* @since API 1.0.0
*/
public class DhApiRenderParam
public class DhApiRenderParam implements IDhApiEventParam
{
/** Indicates what render pass DH is currently rendering */
public final EDhApiRenderPass renderPass;
@@ -66,18 +67,18 @@ public class DhApiRenderParam
// constructors //
//==============//
public DhApiRenderParam(DhApiRenderParam parent)
{
this(
parent.renderPass,
parent.partialTicks,
parent.nearClipPlane, parent.farClipPlane,
parent.mcProjectionMatrix, parent.mcModelViewMatrix,
parent.dhProjectionMatrix, parent.dhModelViewMatrix,
parent.worldYOffset
);
parent.renderPass,
parent.partialTicks,
parent.nearClipPlane, parent.farClipPlane,
parent.mcProjectionMatrix.copy(), parent.mcModelViewMatrix.copy(),
parent.dhProjectionMatrix.copy(), parent.dhModelViewMatrix.copy(),
parent.worldYOffset
);
}
public DhApiRenderParam(
EDhApiRenderPass renderPass,
float newPartialTicks,
@@ -104,4 +105,16 @@ public class DhApiRenderParam
}
//================//
// base overrides //
//================//
@Override
public DhApiRenderParam copy()
{
return new DhApiRenderParam(this);
}
}
@@ -19,6 +19,8 @@
package com.seibel.distanthorizons.api.objects.math;
import com.seibel.distanthorizons.api.interfaces.util.IDhApiCopyable;
/**
* An (almost) exact copy of Minecraft's 1.16.5
* implementation of a 4x4 float matrix. <br><br>
@@ -33,7 +35,7 @@ package com.seibel.distanthorizons.api.objects.math;
* @author James Seibel
* @version 2024-6-30
*/
public class DhApiMat4f
public class DhApiMat4f implements IDhApiCopyable
{
public float m00;
public float m01;
@@ -277,7 +279,6 @@ public class DhApiMat4f
this.m33 *= scalar;
}
public DhApiMat4f copy() { return new DhApiMat4f(this); }
@@ -384,4 +385,7 @@ public class DhApiMat4f
this.m30 + " " + this.m31 + " " + this.m32 + " " + this.m33 + "\n";
}
@Override
public DhApiMat4f copy() { return new DhApiMat4f(this); }
}
@@ -19,6 +19,8 @@
package com.seibel.distanthorizons.api.objects.math;
import com.seibel.distanthorizons.api.interfaces.util.IDhApiCopyable;
/**
* Often used to store block positions or any other
* position in 3D space.
@@ -27,7 +29,7 @@ package com.seibel.distanthorizons.api.objects.math;
* @version 2024-6-3
* @since API 2.2.0
*/
public class DhApiVec3f
public class DhApiVec3f implements IDhApiCopyable
{
public float x;
public float y;
@@ -90,4 +92,7 @@ public class DhApiVec3f
@Override
public String toString() { return "[" + this.x + ", " + this.y + ", " + this.z + "]"; }
@Override
public DhApiVec3f copy() { return new DhApiVec3f(this.x, this.y, this.z); }
}
@@ -22,6 +22,7 @@ package com.seibel.distanthorizons.coreapi.DependencyInjection;
import com.seibel.distanthorizons.api.interfaces.events.IDhApiEventInjector;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiCancelableEvent;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEvent;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiEventParam;
import com.seibel.distanthorizons.api.methods.events.interfaces.IDhApiOneTimeEvent;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiCancelableEventParam;
import com.seibel.distanthorizons.api.methods.events.sharedParameterObjects.DhApiEventParam;
@@ -140,7 +141,26 @@ public class ApiEventInjector extends DependencyInjector<IDhApiEvent> implements
// fire each event and record if any of them
// request to cancel the event.
DhApiEventParam<T> eventParam = createEventParamWrapper(event, eventInput);
// attempt to clone the event input if possible
// this is done to reduce the likely hood that one event listener
// will make change the event parameter for other listeners
T input = eventInput;
if (eventInput instanceof IDhApiEventParam)
{
try
{
//noinspection unchecked
input = (T) ((IDhApiEventParam) eventInput).copy();
}
catch (Exception e)
{
LOGGER.error("Unable to clone event parameter ["+eventInput.getClass().getSimpleName()+"], error: ["+e.getMessage()+"].", e);
}
}
DhApiEventParam<T> eventParam = createEventParamWrapper(event, input);
event.fireEvent(eventParam);
if (eventParam instanceof DhApiCancelableEventParam)