Commit 29110428 authored by René Schöne's avatar René Schöne
Browse files

Continue working on incremental dependencies.

parent 16a91b3e
Pipeline #8673 passed with stages
in 6 minutes and 6 seconds
...@@ -4,4 +4,5 @@ aspect Configuration { ...@@ -4,4 +4,5 @@ aspect Configuration {
public static TypeDecl ASTNode.rootNode; public static TypeDecl ASTNode.rootNode;
public static boolean ASTNode.usesMqtt; public static boolean ASTNode.usesMqtt;
public static boolean ASTNode.usesRest; public static boolean ASTNode.usesRest;
public static boolean ASTNode.incrementalOptionActive;
} }
...@@ -78,7 +78,6 @@ public class Compiler extends AbstractCompiler { ...@@ -78,7 +78,6 @@ public class Compiler extends AbstractCompiler {
printMessage("Writing output files"); printMessage("Writing output files");
final List<String> handlers = new ArrayList<>(); final List<String> handlers = new ArrayList<>();
handlers.add("RagConnectObserver.jadd");
if (ASTNode.usesMqtt) { if (ASTNode.usesMqtt) {
handlers.add("MqttHandler.jadd"); handlers.add("MqttHandler.jadd");
} }
...@@ -224,6 +223,8 @@ public class Compiler extends AbstractCompiler { ...@@ -224,6 +223,8 @@ public class Compiler extends AbstractCompiler {
ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration); ragConnect.additionalRelations().forEach(ragConnectGrammarPart::addDeclaration);
ASTNode.loggingEnabledForReads = optionLogReads.value(); ASTNode.loggingEnabledForReads = optionLogReads.value();
ASTNode.loggingEnabledForWrites = optionLogWrites.value(); ASTNode.loggingEnabledForWrites = optionLogWrites.value();
// reuse "--incremental" option of JastAdd
ASTNode.incrementalOptionActive = getConfiguration().incremental() && getConfiguration().traceFlush();
ASTNode.usesMqtt = optionProtocols.hasValue(OPTION_PROTOCOL_MQTT); ASTNode.usesMqtt = optionProtocols.hasValue(OPTION_PROTOCOL_MQTT);
ASTNode.usesRest = optionProtocols.hasValue(OPTION_PROTOCOL_REST); ASTNode.usesRest = optionProtocols.hasValue(OPTION_PROTOCOL_REST);
return ragConnect; return ragConnect;
......
...@@ -252,7 +252,7 @@ public class MqttHandler { ...@@ -252,7 +252,7 @@ public class MqttHandler {
} }
// register callback // register callback
logger.debug("new connection for {}", topic); 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<>()); callbacks.put(topic, new java.util.ArrayList<>());
// subscribe at broker // 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 { ...@@ -21,3 +21,62 @@ aspect ROS2RAG {
{{> tokenComponent}} {{> tokenComponent}}
{{/TokenComponents}} {{/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; ...@@ -3,6 +3,12 @@ private byte[] {{parentTypeName}}.{{lastValue}} = null;
public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) throws java.io.IOException { public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterName}}, boolean writeCurrentValue) throws java.io.IOException {
{{>handleUri}} {{>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) { switch (scheme) {
{{#usesMqtt}} {{#usesMqtt}}
case "mqtt": case "mqtt":
...@@ -18,35 +24,45 @@ public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterNam ...@@ -18,35 +24,45 @@ public boolean {{parentTypeName}}.{{connectMethod}}(String {{connectParameterNam
if (writeCurrentValue) { if (writeCurrentValue) {
{{writeMethod}}(); {{writeMethod}}();
} }
connectToken = new ConnectToken(uri);
break; break;
{{/usesMqtt}} {{/usesMqtt}}
{{#usesRest}} {{#usesRest}}
case "rest": case "rest":
ConnectToken connectToken = {{restHandlerAttribute}}().newGETConnection(uri, () -> { connectToken = {{restHandlerAttribute}}().newGETConnection(uri, () -> {
{{updateMethod}}(); {{updateMethod}}();
return new String({{lastValue}}); return new String({{lastValue}});
}); });
if (connectToken == null) { if (connectToken == null) {
return false; return false;
} }
connectTokens.computeIfAbsent(this, astNode -> new java.util.HashMap<java.net.URI, ConnectToken>())
.put(uri, connectToken);
break; break;
{{/usesRest}} {{/usesRest}}
default: default:
System.err.println("Unknown protocol '" + scheme + "'."); System.err.println("Unknown protocol '" + scheme + "'.");
return false; 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}}()) { if (this.{{updateMethod}}()) {
this.{{writeMethod}}(); this.{{writeMethod}}();
} }
}); });
{{/incrementalOptionActive}}
return true; return true;
} }
public boolean {{parentTypeName}}.{{disconnectMethod}}(String {{connectParameterName}}) throws java.io.IOException { public boolean {{parentTypeName}}.{{disconnectMethod}}(String {{connectParameterName}}) throws java.io.IOException {
{{>handleUri}} {{>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) { switch (scheme) {
{{#usesMqtt}} {{#usesMqtt}}
case "mqtt": case "mqtt":
...@@ -56,7 +72,7 @@ public boolean {{parentTypeName}}.{{disconnectMethod}}(String {{connectParameter ...@@ -56,7 +72,7 @@ public boolean {{parentTypeName}}.{{disconnectMethod}}(String {{connectParameter
{{/usesMqtt}} {{/usesMqtt}}
{{#usesRest}} {{#usesRest}}
case "rest": case "rest":
{{restHandlerAttribute}}().disconnect(connectTokens.get(this).get(uri)); {{restHandlerAttribute}}().disconnect(connectToken);
break; break;
{{/usesRest}} {{/usesRest}}
default: default:
......
buildscript { buildscript {
repositories.mavenCentral() repositories {
mavenCentral()
maven {
name "gitlab-maven"
url "https://git-st.inf.tu-dresden.de/api/v4/groups/jastadd/-/packages/maven"
}
}
dependencies { dependencies {
classpath 'org.jastadd:jastaddgradle:1.13.3' 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' ...@@ -24,7 +30,6 @@ group = 'de.tudresden.inf.st'
repositories { repositories {
mavenCentral() mavenCentral()
jcenter()
} }
dependencies { dependencies {
...@@ -82,7 +87,9 @@ sourceSets.test.java.srcDir genSrc ...@@ -82,7 +87,9 @@ sourceSets.test.java.srcDir genSrc
idea.module.generatedSourceDirs += genSrc idea.module.generatedSourceDirs += genSrc
clean { 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 --- // --- Test: Example ---
...@@ -332,6 +339,7 @@ task compileTutorialTest(type: RelastTest) { ...@@ -332,6 +339,7 @@ task compileTutorialTest(type: RelastTest) {
moreInputFiles 'src/test/01-input/tutorial/Test.jadd', moreInputFiles 'src/test/01-input/tutorial/Test.jadd',
'src/test/02-after-ragconnect/tutorial/MqttHandler.jadd', 'src/test/02-after-ragconnect/tutorial/MqttHandler.jadd',
'src/test/02-after-ragconnect/tutorial/RagConnect.jadd' 'src/test/02-after-ragconnect/tutorial/RagConnect.jadd'
// extraJastAddOptions "--tracing=cache,flush"
} }
compileTestJava.dependsOn compileTutorialTest compileTestJava.dependsOn compileTutorialTest
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment