Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

1) Moved id out of event type

2) Moved Input Output to top level
  • Loading branch information...
commit 0e863d5716eabd9316c9f4e5b6d70d04f93b3cb1 1 parent 93692e7
@stampy88 authored
Showing with 128 additions and 120 deletions.
  1. +24 −2 src/main/java/org/matrixlab/octopus/core/{processor → }/Input.java
  2. +12 −3 src/main/java/org/matrixlab/octopus/core/{processor → }/Output.java
  3. +6 −6 src/main/java/org/matrixlab/octopus/core/compiler/esper/EsperCompiler.java
  4. +4 −3 src/main/java/org/matrixlab/octopus/core/compiler/esper/EsperProcessorAdaptor.java
  5. +0 −23 src/main/java/org/matrixlab/octopus/core/compiler/esper/EsperUtils.java
  6. +1 −0  src/main/java/org/matrixlab/octopus/core/event/Event.java
  7. +7 −18 src/main/java/org/matrixlab/octopus/core/event/EventType.java
  8. +3 −1 src/main/java/org/matrixlab/octopus/core/processor/Addition.java
  9. +9 −0 src/main/java/org/matrixlab/octopus/core/processor/CompiledProcessor.java
  10. +5 −4 src/main/java/org/matrixlab/octopus/core/processor/Processor.java
  11. +6 −1 src/main/java/org/matrixlab/octopus/core/processor/Sma.java
  12. +2 −2 src/main/java/org/matrixlab/octopus/core/runtime/ProcessingRuntime.java
  13. +4 −16 src/main/java/org/matrixlab/octopus/core/runtime/esper/EsperRuntime.java
  14. +1 −1  src/main/java/org/matrixlab/octopus/core/sink/Sink.java
  15. +4 −0 src/main/java/org/matrixlab/octopus/core/source/Source.java
  16. +32 −30 src/main/java/org/matrixlab/octopus/core/source/external/SqlQuerySource.java
  17. +8 −10 src/main/java/org/matrixlab/octopus/core/source/external/TestSource.java
View
26 ...trixlab/octopus/core/processor/Input.java → ...ava/org/matrixlab/octopus/core/Input.java
@@ -1,8 +1,8 @@
-package org.matrixlab.octopus.core.processor;
+package org.matrixlab.octopus.core;
-import org.matrixlab.octopus.core.ValidationException;
import org.matrixlab.octopus.core.event.Attribute;
import org.matrixlab.octopus.core.event.EventType;
+import org.matrixlab.octopus.core.processor.ProcessorComponent;
import org.matrixlab.octopus.core.source.Source;
import static com.google.common.base.Preconditions.checkArgument;
@@ -79,6 +79,28 @@ public Source getSource() {
return this;
}
+ public void setSourceAttribute(String attributeName) throws ValidationException {
+ if (this.source == null) {
+ throw new ValidationException("Cannot set the source before setting the source attribute");
+ }
+
+ EventType sourceType = source.getOutputEventType();
+
+ Attribute sourceAttribute = sourceType.getAttributeByName(attributeName);
+
+ if (sourceAttribute == null) {
+ throw new ValidationException(String.format("Source does not contain an attribute named '%s'", attributeName));
+ }
+
+ if (!sourceAttribute.isCompatibleWith(getType())) {
+ throw new ValidationException(
+ String.format("The attribute '%s' is not compatible with the input '%s'", sourceAttribute,
+ getName())
+ );
+ }
+ this.sourceAttribute = sourceAttribute;
+ }
+
public void setSourceAttribute(Attribute sourceAttribute) throws ValidationException {
if (this.source == null) {
throw new ValidationException("Cannot set the source before setting the source attribute");
View
15 ...rixlab/octopus/core/processor/Output.java → ...va/org/matrixlab/octopus/core/Output.java
@@ -1,6 +1,7 @@
-package org.matrixlab.octopus.core.processor;
+package org.matrixlab.octopus.core;
import org.matrixlab.octopus.core.event.Attribute;
+import org.matrixlab.octopus.core.processor.ProcessorComponent;
/**
* @author dave sinclair(david.sinclair@lisa-park.com)
@@ -9,9 +10,16 @@
private final Attribute<T> attribute;
+ //private final EventType eventType;
+
private Output(Builder<T> builder) {
super(builder.id, builder.name, builder.description);
this.attribute = builder.attribute;
+
+// this.eventType = new EventType();
+// if(attribute != null) {
+// this.eventType.addAttribute(attribute);
+// }
}
private Output(Output<T> existingOutput, ReproductionMode mode) {
@@ -19,9 +27,10 @@ private Output(Output<T> existingOutput, ReproductionMode mode) {
if (mode == ReproductionMode.NEW_INSTANCE) {
this.attribute = existingOutput.attribute.newInstance();
-
+ // this.eventType = existingOutput.eventType.newInstance();
} else {
this.attribute = existingOutput.attribute.copyOf();
+ // this.eventType = existingOutput.eventType.copyOf();
}
}
@@ -33,7 +42,7 @@ public String getAttributeName() {
return attribute.getName();
}
- Attribute<T> getAttribute() {
+ public Attribute<T> getAttribute() {
return attribute;
}
View
12 src/main/java/org/matrixlab/octopus/core/compiler/esper/EsperCompiler.java
@@ -2,18 +2,19 @@
import com.espertech.esper.client.*;
import com.google.common.collect.Lists;
+import org.matrixlab.octopus.core.Input;
import org.matrixlab.octopus.core.ProcessingModel;
import org.matrixlab.octopus.core.ValidationException;
import org.matrixlab.octopus.core.event.EventType;
import org.matrixlab.octopus.core.memory.Memory;
import org.matrixlab.octopus.core.memory.heap.HeapMemoryProvider;
import org.matrixlab.octopus.core.processor.CompiledProcessor;
-import org.matrixlab.octopus.core.processor.Input;
import org.matrixlab.octopus.core.processor.Processor;
import org.matrixlab.octopus.core.runtime.ProcessingRuntime;
import org.matrixlab.octopus.core.runtime.esper.EsperRuntime;
import org.matrixlab.octopus.core.source.external.CompiledExternalSource;
import org.matrixlab.octopus.core.source.external.ExternalSource;
+import org.matrixlab.octopus.util.esper.EsperUtils;
import java.util.*;
@@ -43,7 +44,7 @@ void registerEventTypesForModel(Configuration configuration, ProcessingModel mod
EventType eventType = externalSource.getOutputEventType();
configuration.addEventType(
- EsperUtils.getEventNameForEventType(eventType),
+ EsperUtils.getEventNameForSource(externalSource),
eventType.getEventDefinition()
);
}
@@ -54,7 +55,7 @@ void registerEventTypesForModel(Configuration configuration, ProcessingModel mod
EventType eventType = processor.getOutputEventType();
configuration.addEventType(
- EsperUtils.getEventNameForEventType(eventType),
+ EsperUtils.getEventNameForSource(processor),
eventType.getEventDefinition()
);
}
@@ -97,8 +98,7 @@ public ProcessingRuntime compile(ProcessingModel model) {
stmt.setSubscriber(runner);
// todo this is temporary think we want the output to have the id possibly
- EventType outputEventType = processor.getOutputEventType();
- String outputEventName = EsperUtils.getEventNameForEventType(outputEventType);
+ String outputEventName = EsperUtils.getEventNameForSource(processor);
System.out.println("Compiler " + outputEventName);
String debugStmt = String.format("select * from %s", outputEventName);
stmt = admin.createEPL(debugStmt);
@@ -136,7 +136,7 @@ String getStatementForCompiledProcessor(CompiledProcessor<?> compiledProcessor)
fromClause.append(", ");
}
- String inputName = EsperUtils.getEventNameForEventType(input.getSource().getOutputEventType());
+ String inputName = EsperUtils.getEventNameForSource(input.getSource());
String aliasName = "_" + aliasIndex++;
selectClause.append(aliasName).append(".*");
View
7 src/main/java/org/matrixlab/octopus/core/compiler/esper/EsperProcessorAdaptor.java
@@ -2,11 +2,12 @@
import com.espertech.esper.client.EPRuntime;
import com.google.common.collect.Maps;
+import org.matrixlab.octopus.core.Input;
import org.matrixlab.octopus.core.event.Event;
import org.matrixlab.octopus.core.memory.Memory;
import org.matrixlab.octopus.core.processor.CompiledProcessor;
-import org.matrixlab.octopus.core.processor.Input;
import org.matrixlab.octopus.util.Pair;
+import org.matrixlab.octopus.util.esper.EsperUtils;
import java.util.Arrays;
import java.util.Map;
@@ -33,14 +34,14 @@
int index = 0;
for (Input input : processor.getInputs()) {
- String sourceId = EsperUtils.getEventNameForEventType(input.getSource().getOutputEventType());
+ String sourceId = EsperUtils.getEventNameForSource(input.getSource());
Integer inputId = input.getId();
sourceIdToInputId[index++] = Pair.newInstance(sourceId, inputId);
}
if (processor.generatesOutput()) {
outputAttributeName = processor.getOutput().getAttributeName();
- outputEventId = EsperUtils.getEventNameForEventType(processor.getOutputEventType());
+ outputEventId = EsperUtils.getEventNameForSource(processor);
} else {
outputAttributeName = null;
View
23 src/main/java/org/matrixlab/octopus/core/compiler/esper/EsperUtils.java
@@ -1,23 +0,0 @@
-package org.matrixlab.octopus.core.compiler.esper;
-
-import org.matrixlab.octopus.core.event.EventType;
-
-/**
- * @author dave sinclair(david.sinclair@lisa-park.com)
- */
-abstract class EsperUtils {
-
- static String getEventNameForEventType(EventType eventType) {
- StringBuilder eventName = new StringBuilder("_");
-
- String idAsString = eventType.getId().toString();
- for (int i = 0; i < idAsString.length(); ++i) {
- if (idAsString.charAt(i) != '-') {
- eventName.append(idAsString.charAt(i));
- }
- }
-
- return eventName.toString();
- }
-
-}
View
1  src/main/java/org/matrixlab/octopus/core/event/Event.java
@@ -47,6 +47,7 @@ public Float getAttributeAsFloat(String attributeName) {
}
public Double getAttributeAsDouble(String attributeName) {
+ // todo return null??
return ((Number) data.get(attributeName)).doubleValue();
}
View
25 src/main/java/org/matrixlab/octopus/core/event/EventType.java
@@ -8,34 +8,24 @@
import java.util.Collection;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
/**
+ * An {@link EventType} is the definition of an {@link Event} that describes some or all of the attributes a event
+ * will have.
+ *
* @author dave sinclair(david.sinclair@lisa-park.com)
*/
public class EventType implements Reproducible {
- private final UUID id;
private final List<Attribute> attributes = Lists.newLinkedList();
- public EventType(UUID id) {
- this.id = id;
+ public EventType() {
}
private EventType(EventType copyFromEventType) {
- this.id = copyFromEventType.id;
this.attributes.addAll(copyFromEventType.attributes);
}
- private EventType(UUID id, EventType copyFromEventType) {
- this.id = id;
- this.attributes.addAll(copyFromEventType.attributes);
- }
-
- public UUID getId() {
- return id;
- }
-
public EventType unionWith(EventType eventType) {
attributes.addAll(eventType.attributes);
@@ -90,18 +80,17 @@ public boolean containsAttribute(Attribute attribute) {
@Override
public String toString() {
return "EventType{" +
- "id='" + id + '\'' +
- ", attributes=" + attributes +
+ "attributes=" + attributes +
'}';
}
@Override
public EventType newInstance() {
- return new EventType(UUID.randomUUID(), this);
+ return new EventType(this);
}
@Override
- public Reproducible copyOf() {
+ public EventType copyOf() {
return new EventType(this);
}
}
View
4 src/main/java/org/matrixlab/octopus/core/processor/Addition.java
@@ -1,5 +1,7 @@
package org.matrixlab.octopus.core.processor;
+import org.matrixlab.octopus.core.Input;
+import org.matrixlab.octopus.core.Output;
import org.matrixlab.octopus.core.ValidationException;
import org.matrixlab.octopus.core.event.Event;
import org.matrixlab.octopus.core.memory.Memory;
@@ -70,7 +72,7 @@ public Addition copyOf() {
/**
* Returns a new {@link Addition} processor configured with all the appropriate
- * {@link org.matrixlab.octopus.core.processor.parameter.Parameter}s, {@link Input}s and {@link Output}.
+ * {@link org.matrixlab.octopus.core.processor.parameter.Parameter}s, {@link org.matrixlab.octopus.core.Input}s and {@link org.matrixlab.octopus.core.Output}.
*
* @return new {@link Addition}
*/
View
9 src/main/java/org/matrixlab/octopus/core/processor/CompiledProcessor.java
@@ -1,11 +1,14 @@
package org.matrixlab.octopus.core.processor;
+import org.matrixlab.octopus.core.Input;
+import org.matrixlab.octopus.core.Output;
import org.matrixlab.octopus.core.event.Event;
import org.matrixlab.octopus.core.event.EventType;
import org.matrixlab.octopus.core.memory.Memory;
import java.util.List;
import java.util.Map;
+import java.util.UUID;
/**
* @author dave sinclair(david.sinclair@lisa-park.com)
@@ -14,13 +17,19 @@
private final List<Input> inputs;
private final Output output;
private final EventType outputEventType;
+ private final UUID id;
protected CompiledProcessor(Processor<MEMORY_TYPE> processor) {
+ this.id = processor.getId();
this.inputs = processor.getInputs();
this.output = processor.getOutput();
this.outputEventType = processor.getOutputEventType();
}
+ public UUID getId() {
+ return id;
+ }
+
public List<Input> getInputs() {
return inputs;
}
View
9 src/main/java/org/matrixlab/octopus/core/processor/Processor.java
@@ -3,6 +3,8 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import org.matrixlab.octopus.core.AbstractNode;
+import org.matrixlab.octopus.core.Input;
+import org.matrixlab.octopus.core.Output;
import org.matrixlab.octopus.core.ValidationException;
import org.matrixlab.octopus.core.event.EventType;
import org.matrixlab.octopus.core.memory.Memory;
@@ -20,8 +22,8 @@
* that affect the behavior of the processor.
*
* @author dave sinclair(david.sinclair@lisa-park.com)
- * @see org.matrixlab.octopus.core.processor.Input
- * @see org.matrixlab.octopus.core.processor.Output
+ * @see org.matrixlab.octopus.core.Input
+ * @see org.matrixlab.octopus.core.Output
* @see org.matrixlab.octopus.core.processor.parameter.Parameter
*/
public abstract class Processor<MEMORY_TYPE> extends AbstractNode implements Source, Sink {
@@ -102,8 +104,7 @@ protected void setOutput(Output.Builder output) {
protected void setOutput(Output output) {
this.output = output;
- // the event type id is the same as this processor's id
- this.outputEventType = new EventType(getId());
+ this.outputEventType = new EventType();
this.outputEventType.addAttribute(output.getAttribute());
}
View
7 src/main/java/org/matrixlab/octopus/core/processor/Sma.java
@@ -1,5 +1,7 @@
package org.matrixlab.octopus.core.processor;
+import org.matrixlab.octopus.core.Input;
+import org.matrixlab.octopus.core.Output;
import org.matrixlab.octopus.core.ValidationException;
import org.matrixlab.octopus.core.event.Event;
import org.matrixlab.octopus.core.memory.Memory;
@@ -142,8 +144,11 @@ public Object processEvent(Memory<Double> memory, Map<Integer, Event> eventsByIn
// sma only has a single event
Event event = eventsByInputId.get(INPUT_ID);
- double newItem = event.getAttributeAsDouble(inputAttributeName);
+ Double newItem = event.getAttributeAsDouble(inputAttributeName);
+ if (newItem == null) {
+ newItem = 0D;
+ }
memory.add(newItem);
double total = 0;
View
4 src/main/java/org/matrixlab/octopus/core/runtime/ProcessingRuntime.java
@@ -1,7 +1,7 @@
package org.matrixlab.octopus.core.runtime;
import org.matrixlab.octopus.core.event.Event;
-import org.matrixlab.octopus.core.event.EventType;
+import org.matrixlab.octopus.core.source.Source;
/**
* @author dave sinclair(david.sinclair@lisa-park.com)
@@ -9,5 +9,5 @@
public interface ProcessingRuntime {
void start();
- void sendEvent(Event event, EventType eventType);
+ void sendEventFromSource(Event event, Source source);
}
View
20 src/main/java/org/matrixlab/octopus/core/runtime/esper/EsperRuntime.java
@@ -2,9 +2,10 @@
import com.espertech.esper.client.EPServiceProvider;
import org.matrixlab.octopus.core.event.Event;
-import org.matrixlab.octopus.core.event.EventType;
import org.matrixlab.octopus.core.runtime.ProcessingRuntime;
+import org.matrixlab.octopus.core.source.Source;
import org.matrixlab.octopus.core.source.external.CompiledExternalSource;
+import org.matrixlab.octopus.util.esper.EsperUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -83,31 +84,18 @@ public void start() throws IllegalStateException {
}
@Override
- public void sendEvent(Event event, EventType eventType) {
+ public void sendEventFromSource(Event event, Source source) {
readLock.lock();
try {
checkState(currentState == State.RUNNING, "Cannot send an event unless the runtime has been started");
- epService.getEPRuntime().sendEvent(event.getData(), getEventNameForUUID(eventType));
+ epService.getEPRuntime().sendEvent(event.getData(), EsperUtils.getEventNameForSource(source));
} finally {
readLock.unlock();
}
}
- static String getEventNameForUUID(EventType eventType) {
- StringBuilder eventName = new StringBuilder("_");
-
- String idAsString = eventType.getId().toString();
- for (int i = 0; i < idAsString.length(); ++i) {
- if (idAsString.charAt(i) != '-') {
- eventName.append(idAsString.charAt(i));
- }
- }
-
- return eventName.toString();
- }
-
/**
* @author dave sinclair(david.sinclair@lisa-park.com)
*/
View
2  src/main/java/org/matrixlab/octopus/core/sink/Sink.java
@@ -1,7 +1,7 @@
package org.matrixlab.octopus.core.sink;
+import org.matrixlab.octopus.core.Input;
import org.matrixlab.octopus.core.Node;
-import org.matrixlab.octopus.core.processor.Input;
import java.util.Collection;
View
4 src/main/java/org/matrixlab/octopus/core/source/Source.java
@@ -10,6 +10,8 @@
// todo is EventType reproducible?
+ //Output getOutput();
+
/**
* Implementers need to return the type of event this source is creating
*
@@ -17,6 +19,8 @@
*/
EventType getOutputEventType();
+ // Output getOutput();
+
Source newInstance();
Source copyOf();
View
62 src/main/java/org/matrixlab/octopus/core/source/external/SqlQuerySource.java
@@ -46,19 +46,18 @@
private SqlQuerySource(UUID sourceId, String name, String description) {
super(sourceId, name, description);
// the event type id is the same as this source's id
- this.outputEventType = new EventType(sourceId);
+ this.outputEventType = new EventType();
}
private SqlQuerySource(UUID sourceId, SqlQuerySource copyFromSource) {
super(sourceId, copyFromSource);
- // the event type id is the same as this source's id
- this.outputEventType = new EventType(sourceId);
+ this.outputEventType = copyFromSource.outputEventType.newInstance();
}
private SqlQuerySource(SqlQuerySource copyFromSource) {
super(copyFromSource);
- // the event type id is the same as this source's id
- this.outputEventType = new EventType(getId());
+
+ this.outputEventType = copyFromSource.outputEventType.copyOf();
}
@SuppressWarnings("unchecked")
@@ -66,26 +65,46 @@ public void setUrl(String url) {
getParameter(URL_PARAMETER_ID).setValue(url);
}
+ public String getUrl() {
+ return getParameter(URL_PARAMETER_ID).getValueAsString();
+ }
+
@SuppressWarnings("unchecked")
public void setUsername(String username) {
getParameter(USER_NAME_PARAMETER_ID).setValue(username);
}
+ public String getUsername() {
+ return getParameter(USER_NAME_PARAMETER_ID).getValueAsString();
+ }
+
@SuppressWarnings("unchecked")
public void setPassword(String password) {
getParameter(PASSWORD_PARAMETER_ID).setValue(password);
}
+ public String getPassword() {
+ return getParameter(PASSWORD_PARAMETER_ID).getValueAsString();
+ }
+
@SuppressWarnings("unchecked")
public void setDriverClass(String driverClass) {
getParameter(DRIVER_PARAMETER_ID).setValue(driverClass);
}
+ public String getDriverClass() {
+ return getParameter(DRIVER_PARAMETER_ID).getValueAsString();
+ }
+
@SuppressWarnings("unchecked")
public void setQuery(String query) {
getParameter(QUERY_PARAMETER_ID).setValue(query);
}
+ public String getQuery() {
+ return getParameter(QUERY_PARAMETER_ID).getValueAsString();
+ }
+
@Override
public EventType getOutputEventType() {
return outputEventType;
@@ -120,34 +139,16 @@ public static SqlQuerySource newTemplate() {
public CompiledExternalSource compile() throws ValidationException {
validate();
- return new CompiledSqlQuerySource(
- getParameterValueAsString(URL_PARAMETER_ID),
- getParameterValueAsString(USER_NAME_PARAMETER_ID),
- getParameterValueAsString(PASSWORD_PARAMETER_ID),
- getParameterValueAsString(DRIVER_PARAMETER_ID),
- getParameterValueAsString(QUERY_PARAMETER_ID),
- getOutputEventType()
- );
+ return new CompiledSqlQuerySource(this.copyOf());
}
private static class CompiledSqlQuerySource implements CompiledExternalSource {
- private final String url;
- private final String userName;
- private final String password;
- private final String className;
- private final String query;
- private final EventType eventType;
+ private final SqlQuerySource source;
private volatile boolean running;
- public CompiledSqlQuerySource(String url, String userName, String password, String className,
- String query, EventType eventType) {
- this.url = url;
- this.userName = userName;
- this.password = password;
- this.className = className;
- this.query = query;
- this.eventType = eventType;
+ public CompiledSqlQuerySource(SqlQuerySource source) {
+ this.source = source;
}
@Override
@@ -158,13 +159,13 @@ public void startProcessingEvents(ProcessingRuntime runtime) {
running = true;
}
- Connection connection = getConnection(className, url, userName, password);
+ Connection connection = getConnection(source.getDriverClass(), source.getUrl(), source.getUsername(), source.getPassword());
Statement statement = null;
ResultSet rs = null;
try {
statement = connection.createStatement();
- rs = statement.executeQuery(query);
+ rs = statement.executeQuery(source.getQuery());
processResultSet(rs, runtime);
} catch (SQLException e) {
throw new ProcessingException("Problem processing result set from database. Please check your settings.", e);
@@ -178,11 +179,12 @@ public void startProcessingEvents(ProcessingRuntime runtime) {
void processResultSet(ResultSet rs, ProcessingRuntime runtime) throws SQLException {
Thread thread = Thread.currentThread();
+ EventType eventType = source.getOutputEventType();
while (!thread.isInterrupted() && running && rs.next()) {
Event newEvent = createEventFromResultSet(rs, eventType);
- runtime.sendEvent(newEvent, eventType);
+ runtime.sendEventFromSource(newEvent, source);
}
}
View
18 src/main/java/org/matrixlab/octopus/core/source/external/TestSource.java
@@ -8,7 +8,6 @@
import org.matrixlab.octopus.core.runtime.ProcessingRuntime;
import java.util.LinkedList;
-import java.util.List;
import java.util.UUID;
/**
@@ -59,22 +58,20 @@ public TestSource copyOf() {
@Override
public CompiledExternalSource compile() throws ValidationException {
- return new CompiledTestSource(eventType, events);
+ return new CompiledTestSource(copyOf());
}
static class CompiledTestSource implements CompiledExternalSource {
- private final LinkedList<Event> events = Lists.newLinkedList();
- private final EventType eventType;
+ private final TestSource source;
/**
* Running is declared volatile because it may be access my different threads
*/
private volatile boolean running;
- public CompiledTestSource(EventType eventType, List<Event> events) {
- this.eventType = eventType;
- this.events.addAll(events);
+ public CompiledTestSource(TestSource source) {
+ this.source = source;
}
@Override
@@ -82,10 +79,11 @@ public void startProcessingEvents(ProcessingRuntime runtime) {
Thread thread = Thread.currentThread();
running = true;
- while (!thread.isInterrupted() && running && events.size() > 0) {
- Event e = events.pop();
- runtime.sendEvent(e, eventType);
+ while (!thread.isInterrupted() && running && source.events.size() > 0) {
+ Event e = source.events.pop();
+
+ runtime.sendEventFromSource(e, source);
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.