Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completely fixed trigger() #488

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -552,8 +552,8 @@ public void setJoinMessage(String message) {
pje.setJoinMessage(message);
}

public static PlayerJoinEvent _instantiate(MCPlayer player, String message) {
return new PlayerJoinEvent(((BukkitMCPlayer) player)._Player(), message);
public static BukkitMCPlayerJoinEvent _instantiate(MCPlayer player, String message) {
return new BukkitMCPlayerJoinEvent(new PlayerJoinEvent(((BukkitMCPlayer) player)._Player(), message));
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package com.laytonsmith.abstraction.events;

import com.laytonsmith.abstraction.MCPlayer;

public interface MCPlayerToggleFlightEvent {
public interface MCPlayerToggleFlightEvent extends MCPlayerEvent {

boolean isFlying();

MCPlayer getPlayer();

void setCancelled(boolean state);

boolean isCancelled();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package com.laytonsmith.abstraction.events;

import com.laytonsmith.abstraction.MCPlayer;

public interface MCPlayerToggleSneakEvent {
public interface MCPlayerToggleSneakEvent extends MCPlayerEvent {

boolean isSneaking();

MCPlayer getPlayer();

void setCancelled(boolean state);

boolean isCancelled();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
package com.laytonsmith.abstraction.events;

import com.laytonsmith.abstraction.MCPlayer;

public interface MCPlayerToggleSprintEvent {
public interface MCPlayerToggleSprintEvent extends MCPlayerEvent {

boolean isSprinting();

MCPlayer getPlayer();

void setCancelled(boolean state);

boolean isCancelled();
Expand Down
54 changes: 10 additions & 44 deletions src/main/java/com/laytonsmith/core/events/EventBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
import com.laytonsmith.PureUtilities.Common.StreamUtils;
import com.laytonsmith.abstraction.Implementation;
import com.laytonsmith.annotations.abstraction;
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.exceptions.CRE.CREPluginInternalException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
Expand All @@ -21,9 +18,9 @@ public final class EventBuilder {
private EventBuilder() {
}

private static final Map<Class<BindableEvent>, Method> methods = new HashMap<Class<BindableEvent>, Method>();
private static final Map<Class<BindableEvent>, Constructor<? extends BindableEvent>> constructors = new HashMap<Class<BindableEvent>, Constructor<? extends BindableEvent>>();
private static final Map<Class<BindableEvent>, Class<BindableEvent>> eventImplementations = new HashMap<Class<BindableEvent>, Class<BindableEvent>>();
private static final Map<Class<BindableEvent>, Method> METHODS = new HashMap<Class<BindableEvent>, Method>();
private static final Map<Class<BindableEvent>, Class<BindableEvent>> EVENT_IMPLEMENTATIONS =
new HashMap<Class<BindableEvent>, Class<BindableEvent>>();

static {
//First, we need to pull all the event implementors
Expand All @@ -38,9 +35,7 @@ private EventBuilder() {
break;
}
}
eventImplementations.put(cinterface, c);
//Also, warm it up
warmup(cinterface);
EVENT_IMPLEMENTATIONS.put(cinterface, c);
}
}
}
Expand All @@ -52,8 +47,8 @@ private EventBuilder() {
* @param clazz
*/
private static void warmup(Class<? extends BindableEvent> clazz) {
if(!methods.containsKey((Class<BindableEvent>) clazz)) {
Class implementor = eventImplementations.get((Class<BindableEvent>) clazz);
if(!METHODS.containsKey((Class<BindableEvent>) clazz)) {
Class implementor = EVENT_IMPLEMENTATIONS.get((Class<BindableEvent>) clazz);
Method method = null;
for(Method m : implementor.getMethods()) {
if(m.getName().equals("_instantiate") && (m.getModifiers() & Modifier.STATIC) != 0) {
Expand All @@ -64,53 +59,24 @@ private static void warmup(Class<? extends BindableEvent> clazz) {
if(method == null) {
StreamUtils.GetSystemErr().println("UNABLE TO CACHE A CONSTRUCTOR FOR " + clazz.getSimpleName()
+ ". Manual triggering will be impossible, and errors will occur"
+ " if an attempt is made. Did you forget to add"
+ " if an attempt is made. Did someone forget to add"
+ " public static <Event> _instantiate(...) to " + clazz.getSimpleName() + "?");
}
methods.put((Class<BindableEvent>) clazz, method);
METHODS.put((Class<BindableEvent>) clazz, method);
}
}

public static <T extends BindableEvent> T instantiate(Class<? extends BindableEvent> clazz, Object... params) {
try {
if(!methods.containsKey((Class<BindableEvent>) clazz)) {
if(!METHODS.containsKey((Class<BindableEvent>) clazz)) {
warmup(clazz);
}
Object o = methods.get((Class<BindableEvent>) clazz).invoke(null, params);
//Now, we have an instance of the underlying object, which the instance
//of the event BindableEvent should know how to handle in a constructor.
if(!constructors.containsKey((Class<BindableEvent>) clazz)) {
Class bindableEvent = eventImplementations.get((Class<BindableEvent>) clazz);
Constructor constructor = null;
for(Constructor c : bindableEvent.getConstructors()) {
if(c.getParameterTypes().length == 1) {
//looks promising
if(c.getParameterTypes()[0].equals(o.getClass())) {
//This is it
constructor = c;
break;
}
}
}
if(constructor == null) {
throw new CREPluginInternalException("Cannot find an acceptable constructor that follows the format:"
+ " public " + bindableEvent.getClass().getSimpleName() + "(" + o.getClass().getSimpleName() + " event)."
+ " Please notify the plugin author of this error.", Target.UNKNOWN);
}
constructors.put((Class<BindableEvent>) clazz, constructor);
}
//Construct a new instance, then return it.
Constructor constructor = constructors.get((Class<BindableEvent>) clazz);
BindableEvent be = (BindableEvent) constructor.newInstance(o);
return (T) be;
return (T) METHODS.get((Class<BindableEvent>) clazz).invoke(null, params);

} catch(Exception e) {
e.printStackTrace();
}
return null;
}

// public static MCPlayerJoinEvent MCPlayerJoinEvent(MCPlayer player, String message){
// return instantiate(MCPlayerJoinEvent.class, player, message);
// }
}
56 changes: 30 additions & 26 deletions src/main/java/com/laytonsmith/core/events/EventUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import com.laytonsmith.core.constructs.Target;
import com.laytonsmith.core.events.BoundEvent.Priority;
import com.laytonsmith.core.exceptions.CRE.CREBindException;
import com.laytonsmith.core.exceptions.CRE.CRECastException;
import com.laytonsmith.core.exceptions.CRE.CREEventException;
import com.laytonsmith.core.exceptions.CRE.CREIllegalArgumentException;
import com.laytonsmith.core.extensions.Extension;
import com.laytonsmith.core.extensions.ExtensionManager;
import com.laytonsmith.core.extensions.ExtensionTracker;
Expand Down Expand Up @@ -140,42 +142,44 @@ public static SortedSet<BoundEvent> GetEvents(Driver type) {
}

public static void ManualTrigger(String eventName, CArray object, Target t, boolean serverWide) {
for(Driver type : event_handles.keySet()) {
// Get the event
Event event = EventList.getEvent(eventName);
if(event == null) {
// Abort if event is not existing
throw new CREIllegalArgumentException("Non existant event is being triggered: " + eventName, t);
}

BindableEvent convertedEvent = null;
try {
// Either an exception will be thrown, or null returned
convertedEvent = event.convert(object, t);
} catch(UnsupportedOperationException ex) {
}
if(convertedEvent == null) {
throw new CREBindException(eventName + " doesn't support the use of trigger() yet.", t);
}

// By Javadoc, if supportsExternal() false there is no use to call it serverwide
if(serverWide && event.supportsExternal()) {
event.manualTrigger(convertedEvent);
} else {
SortedSet<BoundEvent> toRun = new TreeSet<>();
SortedSet<BoundEvent> bounded = GetEvents(type);
Event driver = EventList.getEvent(type, eventName);
if(bounded != null) {
for(BoundEvent b : bounded) {
if(b.getEventName().equalsIgnoreCase(eventName)) {
for(Driver type : event_handles.keySet()) {
for(BoundEvent boundEvent: GetEvents(type)) {
if(boundEvent.getEventName().equalsIgnoreCase(eventName)) {
try {
BindableEvent convertedEvent = null;
try {
convertedEvent = driver.convert(object, t);
} catch(UnsupportedOperationException ex) {
// The event will stay null, and be caught below
}
if(convertedEvent == null) {
throw new CREBindException(eventName + " doesn't support the use of trigger() yet.", t);
} else if(driver.matches(b.getPrefilter(), convertedEvent)) {
toRun.add(b);
if(event.matches(boundEvent.getPrefilter(), convertedEvent)) {
toRun.add(boundEvent);
}
} catch(PrefilterNonMatchException ex) {
//Not running this one
}
}
}
}
//If it's not a serverwide event, or this event doesn't support external events.

if(!toRun.isEmpty()) {
if(!serverWide || !driver.supportsExternal()) {
FireListeners(toRun, driver, driver.convert(object, t));
} else {
//It's serverwide, so we can just trigger it normally with the driver, and it should trickle back down to us
driver.manualTrigger(driver.convert(object, t));
}
} else {
//They have fired a non existant event
ConfigRuntimeException.DoWarning(ConfigRuntimeException.CreateUncatchableException("Non existant event is being triggered: " + eventName, object.getTarget()));
FireListeners(toRun, event, convertedEvent);
}
}
}
Expand Down
21 changes: 14 additions & 7 deletions src/main/java/com/laytonsmith/core/functions/EventBinding.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@
import com.laytonsmith.core.events.EventUtils;
import com.laytonsmith.core.exceptions.CRE.CREBindException;
import com.laytonsmith.core.exceptions.CRE.CRECastException;
import com.laytonsmith.core.exceptions.CRE.CREIllegalArgumentException;
import com.laytonsmith.core.exceptions.CRE.CREInsufficientArgumentsException;
import com.laytonsmith.core.exceptions.CRE.CREThrowable;
import com.laytonsmith.core.exceptions.ConfigCompileException;
import com.laytonsmith.core.exceptions.ConfigRuntimeException;
import com.laytonsmith.core.exceptions.EventException;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
Expand Down Expand Up @@ -456,17 +458,22 @@ public Integer[] numArgs() {

@Override
public String docs() {
return "void {eventName, eventObject, [serverWide]} Manually triggers bound events. The event object passed to this function is "
+ " sent directly as-is to the bound events. Check the documentation for each event to see what is required."
+ " No checks will be done on the data here, but it is not recommended to fail to send all parameters required."
+ " If serverWide is true, the event is triggered directly in the server, unless it is a CommandHelper specific"
+ " event, in which case, serverWide is irrelevant. Defaults to false, which means that only CommandHelper code"
+ " will receive the event.";
return "void {eventName, eventObject, [serverWide]} Manually triggers bound events."
+ " The event object passed to this function is sent directly as-is to the bound events."
+ " Check the documentation for each event to see what is required."
+ " No checks will be done on the data here,"
+ " but it is not recommended to fail to send all parameters required."
+ " If serverWide is true, the event is triggered directly in the server,"
+ " unless it is a CommandHelper specific event, in which case, serverWide is irrelevant."
+ " Defaults to false, which means that only CommandHelper code will receive the event."
+ " Throws a CastException when eventObject is not an array and not null."
+ " Throws a BindException when " + getName() + "() is not yet supported by the given event."
+ " Throws a IllegalArgumentException exception, if the event does not exist.";
}

@Override
public Class<? extends CREThrowable>[] thrown() {
return new Class[]{CRECastException.class};
return new Class[]{CRECastException.class, CREBindException.class, CREIllegalArgumentException.class};
}

@Override
Expand Down