diff --git a/src/main/java/com/vizor/unreal/convert/ClientGenerator.java b/src/main/java/com/vizor/unreal/convert/ClientGenerator.java index e2e8549..8a8fdfe 100644 --- a/src/main/java/com/vizor/unreal/convert/ClientGenerator.java +++ b/src/main/java/com/vizor/unreal/convert/ClientGenerator.java @@ -28,6 +28,7 @@ import com.vizor.unreal.util.Tuple; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -151,19 +152,32 @@ private List> genDelegates() final CppArgument statusArg = new CppArgument(plain("FGrpcStatus", Struct), "Status"); return requestsResponses.entrySet().stream() - .map(e -> { + .flatMap(e -> { final CppArgument responseArg = e.getValue().reduce(($, rsp) -> new CppArgument(rsp.makeRef(), "Response")); + final CppType dynamicEventType = plain(eventTypePrefix + e.getKey() + service.name() + "_Dynamic", Struct); final CppType eventType = plain(eventTypePrefix + e.getKey() + service.name(), Struct); - return Tuple.of( - new CppDelegate(eventType, asList(dispatcherArg, responseArg, statusArg)), - new CppField(eventType, eventPrefix + e.getKey()) - ); + ArrayList> array = new ArrayList<>(); + array.add(Tuple.of( + new CppDelegate(dynamicEventType, asList(dispatcherArg, responseArg, statusArg), true), + new CppField(dynamicEventType, eventPrefix + e.getKey() + "Dynamic") + )); + + CppField field = new CppField(eventType, eventPrefix + e.getKey()); + field.enableAnnotations(false); + array.add(Tuple.of( + new CppDelegate(eventType, asList(dispatcherArg, responseArg, statusArg), false), + field + )); + return array.stream(); }) .peek(t -> { - // should add an UE-specific annotations to these events - t.second().addAnnotation(BlueprintAssignable); - t.second().addAnnotation(Category, rpcResponsesCategory + service.name()); + // should add an UE-specific annotations to these events if it's a dynamic event + if (t.first().isDynamic()) + { + t.second().addAnnotation(BlueprintAssignable); + t.second().addAnnotation(Category, rpcResponsesCategory + service.name()); + } }) .collect(toList()); } @@ -206,25 +220,36 @@ private CppFunction genUpdate() "'{'", " {1} ResponseWithStatus;", " while ({0}.Dequeue(ResponseWithStatus))", + " '{'", " {2}.Broadcast(", " this,", " ResponseWithStatus.Response,", " ResponseWithStatus.Status", " );", + " {3}.Broadcast(", + " this,", + " ResponseWithStatus.Response,", + " ResponseWithStatus.Status", + " );", + " '}'", "'}'" )); final StringBuilder sb = new StringBuilder(supressSuperString(updateFunctionName)); for (int i = 0; i < conduits.size(); i++) { - final Tuple delegate = delegates.get(i); + // Each conduit is "paired" to 2 delegates + final Tuple delegate = delegates.get(i * 2); + final Tuple delegate2 = delegates.get(i * 2 + 1); final CppField conduit = conduits.get(i); final String dequeue = delegate.reduce((d, f) -> { - final List genericParams = conduit.getType().getGenericParams(); - final CppType requestWithContext = genericParams.get(1); - - return format(dequeuePattern, conduit.getName(), requestWithContext.toString(), f.getName()); + return delegate2.reduce((d2, f2) -> { + final List genericParams = conduit.getType().getGenericParams(); + final CppType requestWithContext = genericParams.get(1); + + return format(dequeuePattern, conduit.getName(), requestWithContext.toString(), f2.getName(), f.getName()); + }); }); sb.append(dequeue).append(lineSeparator()).append(lineSeparator()); diff --git a/src/main/java/com/vizor/unreal/tree/CppDelegate.java b/src/main/java/com/vizor/unreal/tree/CppDelegate.java index b1009a5..edf9d4d 100644 --- a/src/main/java/com/vizor/unreal/tree/CppDelegate.java +++ b/src/main/java/com/vizor/unreal/tree/CppDelegate.java @@ -25,11 +25,13 @@ public final class CppDelegate implements CtLeaf { private final CppType type; private final List arguments; + private final boolean dynamic; - public CppDelegate(final CppType type, final List arguments) + public CppDelegate(final CppType type, final List arguments, final boolean dynamic) { this.type = type; this.arguments = unmodifiableList(arguments); + this.dynamic = dynamic; } public String getTense() @@ -61,6 +63,11 @@ public final CppType getType() return type; } + public final boolean isDynamic() + { + return dynamic; + } + @Override public CppPrinter accept(CppPrinter printer) { diff --git a/src/main/java/com/vizor/unreal/writer/CppPrinter.java b/src/main/java/com/vizor/unreal/writer/CppPrinter.java index e15147d..9c9365e 100644 --- a/src/main/java/com/vizor/unreal/writer/CppPrinter.java +++ b/src/main/java/com/vizor/unreal/writer/CppPrinter.java @@ -448,7 +448,15 @@ public void visit(CppNamespace namespace) public void visit(final CppDelegate delegate) { - write("DECLARE_DYNAMIC_MULTICAST_DELEGATE"); + // First we declare a dynamic event + if (delegate.isDynamic()) + { + write("DECLARE_DYNAMIC_MULTICAST_DELEGATE"); + } + else + { + write("DECLARE_MULTICAST_DELEGATE"); + } final String tense = delegate.getTense(); if (!tense.isEmpty()) @@ -469,8 +477,11 @@ public void visit(final CppDelegate delegate) argType.accept(this); - write(", "); - write(a.getName()); + if (delegate.isDynamic()) + { + write(", "); + write(a.getName()); + } } write(");"); }