1
0
mirror of https://github.com/aNNiMON/HotaruFX.git synced 2024-09-19 14:14:21 +03:00

Ability to get and set node properties

This commit is contained in:
Victor 2017-08-30 17:54:19 +03:00
parent 0d2b24f850
commit 40100d8aaa
3 changed files with 61 additions and 23 deletions

View File

@ -1,5 +1,6 @@
package com.annimon.hotarufx.lib;
import com.annimon.hotarufx.exceptions.HotaruRuntimeException;
import com.annimon.hotarufx.exceptions.TypeException;
import com.annimon.hotarufx.visual.Property;
import com.annimon.hotarufx.visual.PropertyBindings;
@ -32,9 +33,32 @@ public class NodeValue implements Value {
return node;
}
@SuppressWarnings("unchecked")
public void fill(MapValue map) {
map.getMap().forEach((key, value) -> {
map.getMap().forEach(this::set);
}
@SuppressWarnings("unchecked")
public Value get(String key) {
if (!bindings.containsKey(key)) {
throw new HotaruRuntimeException("Unable to get property " + key + " from node value");
}
final Property property = bindings.get(key);
val timeline = property.getProperty().get();
val type = property.getType();
switch (type) {
case NUMBER:
return type.<Number>getToHFX().apply(
((PropertyTimeline<Number>) timeline).getProperty().getValue());
case PAINT:
return type.<Paint>getToHFX().apply(
((PropertyTimeline<Paint>) timeline).getProperty().getValue());
default:
throw new TypeException("Unknown type of node property");
}
}
@SuppressWarnings("unchecked")
public void set(String key, Value value) {
if (!bindings.containsKey(key)) return;
final Property property = bindings.get(key);
val timeline = property.getProperty().get();
@ -49,7 +73,6 @@ public class NodeValue implements Value {
type.<Paint>getFromHFX().apply(value));
break;
}
});
}
@Override

View File

@ -5,6 +5,7 @@ import com.annimon.hotarufx.exceptions.TypeException;
import com.annimon.hotarufx.exceptions.VariableNotFoundException;
import com.annimon.hotarufx.lib.Context;
import com.annimon.hotarufx.lib.MapValue;
import com.annimon.hotarufx.lib.NodeValue;
import com.annimon.hotarufx.lib.NumberValue;
import com.annimon.hotarufx.lib.StringValue;
import com.annimon.hotarufx.lib.Types;
@ -102,7 +103,7 @@ public class InterpreterVisitor implements ResultVisitor<Value, Context> {
public Value get(AccessNode node, Context context) {
Value container = node.root.accept(this, context);
return getContainer(node.indices, context, container)
.orElseThrow(() -> new TypeException("Map expected", node.start(), node.end()));
.orElseThrow(() -> new TypeException("Unable to get property from non-accessible type", node.start(), node.end()));
}
@Override
@ -110,14 +111,20 @@ public class InterpreterVisitor implements ResultVisitor<Value, Context> {
Value container = node.root.accept(this, context);
int lastIndex = node.indices.size() - 1;
Supplier<TypeException> exceptionSupplier = () ->
new TypeException("Map expected", node.start(), node.end());
new TypeException("Unable to set property to non-accessible type", node.start(), node.end());
container = getContainer(node.indices.subList(0, lastIndex), context, container)
.orElseThrow(exceptionSupplier);
switch (container.type()) {
case Types.MAP:
case Types.MAP: {
val key = node.indices.get(lastIndex).accept(this, context).asString();
((MapValue) container).getMap().put(key, value);
break;
} break;
case Types.NODE: {
val key = node.indices.get(lastIndex).accept(this, context).asString();
((NodeValue) container).set(key, value);
} break;
default:
throw exceptionSupplier.get();
}
@ -127,10 +134,16 @@ public class InterpreterVisitor implements ResultVisitor<Value, Context> {
private Optional<Value> getContainer(List<Node> nodes, Context context, Value container) {
for (Node index : nodes) {
switch (container.type()) {
case Types.MAP:
case Types.MAP: {
val key = index.accept(this, context).asString();
container = ((MapValue) container).getMap().get(key);
break;
} break;
case Types.NODE: {
val key = index.accept(this, context).asString();
container = ((NodeValue) container).get(key);
} break;
default:
return Optional.empty();
}

View File

@ -7,4 +7,6 @@ A = circle({
fill: "red"
})
A.radius = 10
render(A)