From cfc71b845d7189893e981b1560ffae5f86dedb06 Mon Sep 17 00:00:00 2001 From: gnembon Date: Tue, 14 Jan 2020 01:26:46 -0400 Subject: [PATCH] system key-value storage --- .../carpet/script/CarpetScriptServer.java | 1 + src/main/java/carpet/script/Expression.java | 37 +++++++++++++++++++ src/main/java/carpet/script/ScriptHost.java | 4 ++ 3 files changed, 42 insertions(+) diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index c7bb9516..0364945e 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -48,6 +48,7 @@ public class CarpetScriptServer public CarpetScriptServer() { + ScriptHost.systemGlobals.clear(); events = new CarpetEventServer(); modules = new HashMap<>(); tickStart = 0L; diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index 9bcc34e5..b6be4cbf 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -2681,6 +2681,7 @@ public class Expression *

task_completed(task)

*

Returns true if task has completed, or false otherwise.

* + *
*

Auxiliary functions

* *

lower(expr), upper(expr), title(expr)

@@ -2795,6 +2796,20 @@ public class Expression * /script run count_blocks(player()) * * + *
+ *

System key-value storage

+ *

Scarpet runs apps in isolation. The can share code via use of shared libraries, but each library that is imported + * to each app is specific to that app. Apps can store and fetch state from disk, but its restricted to specific locations + * meaning apps cannot interact via disk either. To facilitate communication for interappperability, scarpet hosts its own + * key-value storage that is shared between all apps currently running on the host, providing methods for getting + * an associated value with optional setting it if not present, and an operation of modifying a content of a system global + * value.

+ *

system_variable_get(key, default_value ?)

+ *

Returns the variable from the system shared key-value storage keyed with a key value, optionally + * if value is not present, and default expression is provided, sets a new value to be associated with that key

+ *

system_variable_set(key, new_value)

+ *

Returns the variable from the system shared key-value storage keyed with a key value, and sets + * a new mapping for the key

* */ public void SystemFunctions() @@ -3103,6 +3118,28 @@ public class Expression return new NumericValue(((ThreadValue) v).isFinished()); }); + addLazyFunction("system_variable_get", -1, (c, t, lv) -> + { + if (lv.size() == 0) throw new InternalExpressionException("'system_variable_get' expects at least a key to be fetched"); + Value key = lv.get(0).evalValue(c); + if (lv.size() > 1) + { + ScriptHost.systemGlobals.computeIfAbsent(key, k -> lv.get(1).evalValue(c)); + } + Value res = ScriptHost.systemGlobals.get(key); + if (res!=null) return (cc, tt) -> res; + return (cc, tt) -> Value.NULL; + }); + + addLazyFunction("system_variable_set", 2, (c, t, lv) -> + { + Value key = lv.get(0).evalValue(c); + Value value = lv.get(1).evalValue(c); + Value res = ScriptHost.systemGlobals.put(key, value); + if (res!=null) return (cc, tt) -> res; + return (cc, tt) -> Value.NULL; + }); + } diff --git a/src/main/java/carpet/script/ScriptHost.java b/src/main/java/carpet/script/ScriptHost.java index 840070b6..ad2ba58f 100644 --- a/src/main/java/carpet/script/ScriptHost.java +++ b/src/main/java/carpet/script/ScriptHost.java @@ -9,11 +9,15 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; import java.util.stream.Stream; public abstract class ScriptHost { + public static Map systemGlobals = new ConcurrentHashMap<>(); + + public static class ModuleData { Module parent;