Skip to content
Snippets Groups Projects
Commit 29110428 authored by René Schöne's avatar René Schöne
Browse files

Continue working on incremental dependencies.

parent 16a91b3e
No related branches found
No related tags found
1 merge request!5Testing incremental dependency tracking.
Pipeline #8673 passed
File deleted
......@@ -4,4 +4,5 @@ aspect Configuration {
public static TypeDecl ASTNode.rootNode;
public static boolean ASTNode.usesMqtt;
public static boolean ASTNode.usesRest;
public static boolean ASTNode.incrementalOptionActive;
}
......@@ -78,7 +78,6 @@ public class Compiler extends AbstractCompiler {
printMessage("Writing output files");
final List<String> handlers = new ArrayList<>();
handlers.add("RagConnectObserver.jadd");
if (ASTNode.usesMqtt) {
handlers.add("MqttHandler.jadd");
}
......@@ -224,6 +223,8 @@ public class Compiler extends AbstractCompiler {
ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration);
ASTNode.loggingEnabledForReads = optionLogReads.value();
ASTNode.loggingEnabledForWrites = optionLogWrites.value();
// reuse "--incremental" option of JastAdd
ASTNode.incrementalOptionActive = getConfiguration().incremental() && getConfiguration().traceFlush();
ASTNode.usesMqtt = optionProtocols.hasValue(OPTION_PROTOCOL_MQTT);
ASTNode.usesRest = optionProtocols.hasValue(OPTION_PROTOCOL_REST);
return ragConnect;
......
......@@ -252,7 +252,7 @@ public class MqttHandler {
}
// register callback
logger.debug("new connection for {}", topic);
if (callbacks.get(topic) == null) {
if (callbacks.get(topic) == null || callbacks.get(topic).isEmpty()) {
callbacks.put(topic, new java.util.ArrayList<>());
// subscribe at broker
......
aspect RagConnectObserver {
class RagConnectObserver implements ASTState.Trace.Receiver {
ASTState.Trace.Receiver oldReceiver;
class RagConnectObserverEntry {
ASTNode node;
String attributeString;
Runnable attributeCall;
RagConnectObserverEntry(ASTNode node, String attributeString, Runnable attributeCall) {
this.node = node;
this.attributeString = attributeString;
this.attributeCall = attributeCall;
}
}
java.util.List<RagConnectObserverEntry> observedNodes = new java.util.ArrayList<>();
RagConnectObserver(ASTNode node) {
// set the receiver. potentially dangerous because overriding existing receiver!
oldReceiver = node.trace().getReceiver();
node.trace().setReceiver(this);
}
void add(ASTNode node, String attributeString, Runnable attributeCall) {
System.out.println("** observer add " + node + " on " + attributeString);
observedNodes.add(new RagConnectObserverEntry(node, attributeString, attributeCall));
}
void remove(ASTNode node, String attributeString, Runnable attributeCall) {
observedNodes.remove(new RagConnectObserverEntry(node, attributeString, attributeCall));
}
@Override
public void accept(ASTState.Trace.Event event, ASTNode node, String attribute, Object params, Object value) {
oldReceiver.accept(event, node, attribute, params, value);
// ignore all events but INC_FLUSH_ATTR
if (event != ASTState.Trace.Event.INC_FLUSH_ATTR) {
return;
}
System.out.println("** observer check INC_FLUSH_ATTR event");
// iterate through list, if matching pair. could maybe be more efficient.
for (RagConnectObserverEntry entry : observedNodes) {
if (entry.node.equals(node) && entry.attributeString.equals(attribute)) {
// hit. call the attribute/nta-token
System.out.println("** observer hit " + entry.node + " on " + entry.attributeString);
entry.attributeCall.run();
}
}
}
}
private static RagConnectObserver ASTNode._ragConnectObserverInstance;
RagConnectObserver ASTNode._ragConnectObserver() {
if (_ragConnectObserverInstance == null) {
// does not matter, which node is used to create the observer as ASTState/tracing is also static
_ragConnectObserverInstance = new RagConnectObserver(this);
}
return _ragConnectObserverInstance;
}
}
......@@ -21,3 +21,62 @@ aspect ROS2RAG {
{{> tokenComponent}}
{{/TokenComponents}}
}
{{#incrementalOptionActive}}
aspect RagConnectObserver {
class RagConnectObserver implements ASTState.Trace.Receiver {
ASTState.Trace.Receiver oldReceiver;
class RagConnectObserverEntry {
final ConnectToken connectToken;
final ASTNode node;
final String attributeString;
final Runnable attributeCall;
RagConnectObserverEntry(ConnectToken connectToken, ASTNode node, String attributeString, Runnable attributeCall) {
this.connectToken = connectToken;
this.node = node;
this.attributeString = attributeString;
this.attributeCall = attributeCall;
}
}
java.util.List<RagConnectObserverEntry> observedNodes = new java.util.ArrayList<>();
RagConnectObserver(ASTNode node) {
// set the receiver. potentially dangerous because overriding existing receiver!
oldReceiver = node.trace().getReceiver();
node.trace().setReceiver(this);
}
void add(ConnectToken connectToken, ASTNode node, String attributeString, Runnable attributeCall) {
System.out.println("** observer add " + node + " on " + attributeString);
observedNodes.add(new RagConnectObserverEntry(connectToken, node, attributeString, attributeCall));
}
void remove(ConnectToken connectToken) {
observedNodes.removeIf(entry -> entry.connectToken.equals(connectToken));
}
@Override
public void accept(ASTState.Trace.Event event, ASTNode node, String attribute, Object params, Object value) {
oldReceiver.accept(event, node, attribute, params, value);
// ignore all events but INC_FLUSH_ATTR
if (event != ASTState.Trace.Event.INC_FLUSH_ATTR) {
return;
}
System.out.println("** observer check INC_FLUSH_ATTR event");
// iterate through list, if matching pair. could maybe be more efficient.
for (RagConnectObserverEntry entry : observedNodes) {
if (entry.node.equals(node) && entry.attributeString.equals(attribute)) {
// hit. call the attribute/nta-token
System.out.println("** observer hit " + entry.node + " on " + entry.attributeString);
entry.attributeCall.run();
}
}
}
}
private static RagConnectObserver ASTNode._ragConnectObserverInstance;
RagConnectObserver ASTNode._ragConnectObserver() {
if (_ragConnectObserverInstance == null) {
// does not matter, which node is used to create the observer as ASTState/tracing is also static
_ragConnectObserverInstance = new RagConnectObserver(this);
}
return _ragConnectObserverInstance;
}
}
{{/incrementalOptionActive}}
......@@ -3,6 +3,12 @@ private byte[] {{parentTypeName}}.{{lastValue}} = null;
public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) throws java.io.IOException {
{{>handleUri}}
ConnectToken connectToken;
if (connectTokens.computeIfAbsent(this, astNode -> new java.util.HashMap<java.net.URI, ConnectToken>())
.get(uri) != null) {
System.err.println("Already connected for " + uri + " on " + this + "!");
return true;
}
switch (scheme) {
{{#usesMqtt}}
case "mqtt":
......@@ -18,35 +24,45 @@ public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterNam
if (writeCurrentValue) {
{{writeMethod}}();
}
connectToken = new ConnectToken(uri);
break;
{{/usesMqtt}}
{{#usesRest}}
case "rest":
ConnectToken connectToken = {{restHandlerAttribute}}().newGETConnection(uri, () -> {
connectToken = {{restHandlerAttribute}}().newGETConnection(uri, () -> {
{{updateMethod}}();
return new String({{lastValue}});
});
if (connectToken == null) {
return false;
}
connectTokens.computeIfAbsent(this, astNode -> new java.util.HashMap<java.net.URI, ConnectToken>())
.put(uri, connectToken);
break;
{{/usesRest}}
default:
System.err.println("Unknown protocol '" + scheme + "'.");
return false;
}
_ragConnectObserver().add(this, "{{parentTypeName}}.get{{tokenName}}()", () -> {
connectTokens.computeIfAbsent(this, astNode -> new java.util.HashMap<java.net.URI, ConnectToken>())
.put(uri, connectToken);
{{#incrementalOptionActive}}
_ragConnectObserver().add(connectToken, this, "{{parentTypeName}}.get{{tokenName}}()", () -> {
if (this.{{updateMethod}}()) {
this.{{writeMethod}}();
}
});
{{/incrementalOptionActive}}
return true;
}
public boolean {{parentTypeName}}.{{disconnectMethod}}(String {{connectParameterName}}) throws java.io.IOException {
{{>handleUri}}
ConnectToken connectToken = connectTokens.get(this).remove(uri);
if (connectToken == null) {
System.err.println("Disconnect without connect for " + uri + " on " + this + "!");
}
{{#incrementalOptionActive}}
_ragConnectObserver().remove(connectToken);
{{/incrementalOptionActive}}
switch (scheme) {
{{#usesMqtt}}
case "mqtt":
......@@ -56,7 +72,7 @@ public boolean {{parentTypeName}}.{{disconnectMethod}}(String {{connectParameter
{{/usesMqtt}}
{{#usesRest}}
case "rest":
{{restHandlerAttribute}}().disconnect(connectTokens.get(this).get(uri));
{{restHandlerAttribute}}().disconnect(connectToken);
break;
{{/usesRest}}
default:
......
buildscript {
repositories.mavenCentral()
repositories {
mavenCentral()
maven {
name "gitlab-maven"
url "https://git-st.inf.tu-dresden.de/api/v4/groups/jastadd/-/packages/maven"
}
}
dependencies {
classpath 'org.jastadd:jastaddgradle:1.13.3'
classpath fileTree(include: ['buildSrc.jar'], dir: '../libs')
classpath 'org.jastadd.relast:relast-test:0.2.4'
}
}
......@@ -24,7 +30,6 @@ group = 'de.tudresden.inf.st'
repositories {
mavenCentral()
jcenter()
}
dependencies {
......@@ -82,7 +87,9 @@ sourceSets.test.java.srcDir genSrc
idea.module.generatedSourceDirs += genSrc
clean {
delete 'src/test/02-after-ragconnect/*/', 'src/test/03-after-relast/*/', 'src/test/java-gen/*/'
delete fileTree(dir: 'src/test/02-after-ragconnect/', exclude: '.gitignore')
delete fileTree(dir: 'src/test/03-after-relast/', exclude: '.gitignore')
delete fileTree(dir: 'src/test/java-gen/', exclude: '.gitignore')
}
// --- Test: Example ---
......@@ -332,6 +339,7 @@ task compileTutorialTest(type: RelastTest) {
moreInputFiles 'src/test/01-input/tutorial/Test.jadd',
'src/test/02-after-ragconnect/tutorial/MqttHandler.jadd',
'src/test/02-after-ragconnect/tutorial/RagConnect.jadd'
// extraJastAddOptions "--tracing=cache,flush"
}
compileTestJava.dependsOn compileTutorialTest
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment