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
Branches
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