Skip to content

Commit

Permalink
Using separate Items for JavaScript and Java evaluation
Browse files Browse the repository at this point in the history
  • Loading branch information
jtulach committed May 11, 2020
1 parent 80e9973 commit 27af175
Showing 1 changed file with 103 additions and 74 deletions.
177 changes: 103 additions & 74 deletions generic/src/main/java/org/netbeans/html/presenters/spi/Generic.java
Original file line number Diff line number Diff line change
Expand Up @@ -519,9 +519,42 @@ interface OnReady {
void callbackReady(String name);
}

private class Item implements Runnable {
private abstract class Item {
final int id;
final Item prev;

Item(int id, Item prev) {
this.id = id;
this.prev = prev;
}

abstract void result(String typeof, String res);
abstract void noLongerNeeded();
abstract void inJava();
abstract String inJavaScript(int[] finishedId);
abstract void header(StringBuilder sb, String sep);

final void toString(StringBuilder sb, String sep) {
header(sb, sep);
if (prev != null) {
sb.append(", prev=\n");
prev.toString(sb, " " + sep);
sb.append("\n").append(sep);
}
sb.append("]");
}

@Override
public final String toString() {
synchronized (lock()) {
StringBuilder sb = new StringBuilder();
toString(sb, "");
return sb.toString();
}
}
}

private class JavaItem extends Item implements Runnable {
Boolean done;
boolean resultObtained;

Expand All @@ -530,48 +563,32 @@ private class Item implements Runnable {
final Object[] params;
Object result;

Item(int id, Item prev, Method method, Object thiz, Object[] params) {
this.id = id;
this.prev = prev;
JavaItem(int id, Item prev, Method method, Object thiz, Object[] params) {
super(id, prev);
this.method = method;
this.thiz = thiz;
this.params = adaptParams(method, Arrays.asList(params));
this.toExec = null;
}

@Override
public String toString() {
synchronized (lock()) {
StringBuilder sb = new StringBuilder();
toString(sb, "");
return sb.toString();
}
}

private void toString(StringBuilder sb, String sep) {
sb.append(sep).append("Item[id=").append(id).append(", ");
if (method != null) {
sb.append("method=").append(method.getName());
} else {
sb.append("javascript");
}
if (prev != null) {
sb.append(", prev=\n");
prev.toString(sb, " " + sep);
sb.append("\n").append(sep);
}
sb.append("]");
final void header(StringBuilder sb, String sep) {
sb.append(sep).append("JavaItem[id=").append(id).append(", ");
sb.append("method=").append(method.getName());
}

@Override
protected final String inJavaScript(int[] finished) {
assert Thread.holdsLock(lock());
if (this.method != null) {
return js(finished);
} else {
return sj(finished);
if (Boolean.TRUE.equals(done)) {
StringBuilder sb = new StringBuilder();
encodeObject(result, false, sb, null);
finished[0] = -1;
return sb.toString();
}
return null;
}

@Override
protected final void inJava() {
assert Thread.holdsLock(lock());
if (this.method == null) {
Expand All @@ -591,40 +608,51 @@ protected final void inJava() {
}
}

@Override public void run() {
@Override
public void run() {
synchronized (lock()) {
log(Level.FINE, "run: {0}", this);
inJava();
lock().notifyAll();
}
}


protected String js(int[] finished) {
assert Thread.holdsLock(lock());
if (Boolean.TRUE.equals(done)) {
StringBuilder sb = new StringBuilder();
encodeObject(result, false, sb, null);
finished[0] = -1;
return sb.toString();
}
return null;
@Override
void result(String typeof, String res) {
}

@Override
void noLongerNeeded() {
resultObtained = true;
}
}

private final class JsItem extends Item {
private final String toExec;
private String typeof;
private Boolean done;
private String result;

Item(int id, Item prev, String toExec) {
this.id = id;
this.prev = prev;
JsItem(int id, Item prev, String toExec) {
super(id, prev);
this.toExec = toExec;

this.method = null;
this.params = null;
this.thiz = null;
}

protected String sj(int[] finished) {
@Override
protected final void result(String newType, String newResult) {
assert Thread.holdsLock(lock());
this.typeof = newType;
this.result = newResult;
log(Level.FINE, "result ({0}): {1} for {2}", typeof, result, toExec);
}

@Override
protected final void noLongerNeeded() {
}

@Override
protected final String inJavaScript(int[] finished) {
assert Thread.holdsLock(lock());
assert Thread.holdsLock(lock());
if (Boolean.TRUE.equals(done)) {
return null;
Expand All @@ -633,20 +661,16 @@ protected String sj(int[] finished) {
return "javascript:" + finished[0] + "/" + toExec;
}

protected final void result(String newType, String newResult) {
assert Thread.holdsLock(lock());
if (this.method != null) {
throw new UnsupportedOperationException();
}
this.typeof = newType;
this.result = newResult;
log(Level.FINE, "result ({0}): {1} for {2}", typeof, result, toExec);
@Override
protected final void inJava() {
}

protected final void noLongerNeeded() {
assert Thread.holdsLock(lock());
this.resultObtained = true;
@Override
final void header(StringBuilder sb, String sep) {
sb.append(sep).append("JsItem[id=").append(id).append(", ");
sb.append("javascript");
}

} // end of Item

final void result(String counterId, String typeof, String res) {
Expand All @@ -664,7 +688,7 @@ final void result(String counterId, String typeof, String res) {
return;
}
final int id = Integer.parseInt(counterId);
final Item top = topMostCall();
final Item top = topMostCall(null);
Item my = findCall(id);
if (top == my) {
top.result(typeof, res);
Expand Down Expand Up @@ -701,10 +725,10 @@ final String javacall(
}
params.addAll(Arrays.asList((Object[]) args));
Object[] converted = adaptParams(method, params);
Item top = topMostCall();
Item top = topMostCall(null);
boolean first = top == null;
log(Level.FINE, "jc: {0}@{1}args: {2} is first: {3}, now: {4}", new Object[]{method.getName(), vm, params, first, topMostCall()});
Item newItem = registerCall(new Item(nextCallId(), top, method, vm, converted));
log(Level.FINE, "jc: {0}@{1}args: {2} is first: {3}, now: {4}", new Object[]{method.getName(), vm, params, first, topMostCall(null)});
JavaItem newItem = registerCall(new JavaItem(nextCallId(), top, method, vm, converted));
try {
if (first || synchronous) {
dispatch(newItem);
Expand All @@ -726,7 +750,7 @@ final String javaresult(int reqId) throws IllegalStateException, InterruptedExce
deferred = null;
return ret;
}
final Item top = topMostCall();
final Item top = topMostCall(null);
String jsToExec = top.inJavaScript(finishedId);
log(Level.FINE, "jr: {0} jsToExec: {1} finished: {2}", new Object[]{top, jsToExec, finishedId[0]});
if (jsToExec != null) {
Expand Down Expand Up @@ -760,7 +784,7 @@ public final void loadScript(final Reader reader) throws Exception {

final void deferExec(StringBuilder sb) {
synchronized (lock()) {
log(Level.FINE, "deferExec: {0} empty: {1}, call: {2}", new Object[]{sb, deferred == null, topMostCall()});
log(Level.FINE, "deferExec: {0} empty: {1}, call: {2}", new Object[]{sb, deferred == null, topMostCall(null)});
if (deferred == null) {
deferred = sb;
} else {
Expand Down Expand Up @@ -795,15 +819,15 @@ final Object exec(int id, String fn) {
log(Level.FINE, "Flushing {0}", fn);
}

Item myCall;
JsItem myCall;
boolean load;
final Item top = topMostCall();
final Item top = topMostCall(null);
if (top != null) {
myCall = registerCall(new Item(id, top, fn));
myCall = registerCall(new JsItem(id, top, fn));
load = synchronous;
first = false;
} else {
myCall = registerCall(new Item(id, null, null));
myCall = registerCall(new JsItem(id, null, null));
load = true;
first = true;
}
Expand All @@ -820,7 +844,7 @@ final Object exec(int id, String fn) {
} catch (InterruptedException ex) {
log(Level.SEVERE, null, ex);
}
Item c = topMostCall();
Item c = topMostCall(null);
if (c != null) {
c.inJava();
}
Expand Down Expand Up @@ -1034,9 +1058,14 @@ void register() {
}
}

private Item topMostCall() {
private Item topMostCall(Class<? extends Item> type) {
assert Thread.holdsLock(lock());
return call;
for (Item it = call; it != null; it = it.prev) {
if (type == null || type.isInstance(it)) {
return it;
}
}
return null;
}

private Item findCall(int reqId) {
Expand All @@ -1050,7 +1079,7 @@ private Item findCall(int reqId) {
}
}

private Item registerCall(Item call) {
private <T extends Item> T registerCall(T call) {
assert Thread.holdsLock(lock());
this.call = call;
lock().notifyAll();
Expand Down

0 comments on commit 27af175

Please sign in to comment.