package io.gitlab.jfronny.muscript.data; import io.gitlab.jfronny.commons.data.ImmCollection; import io.gitlab.jfronny.muscript.data.dynamic.*; import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal; import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.function.Function; public class Scope implements DObject { private final @Nullable Scope source; private final Map> override = new HashMap<>(); public Scope() { this(null); } public Scope(@Nullable DObject source) { if (source == null) { this.source = null; } else if (source instanceof Scope src) { this.source = src; } else { this.source = new Scope(); source.getValue().forEach(this::set); } } public Scope(@Nullable Scope source) { this.source = source; } @Override public Map> getValue() { if (source == null) return ImmCollection.of(override); var map = new HashMap<>(source.getValue()); map.putAll(override); return ImmCollection.of(map); } /** * @deprecated Using the convenience methods is recommended wherever possible. */ @Deprecated(forRemoval = false) public Scope set(String key, Dynamic value) { if (key.startsWith("$")) { if (!setGlobal(key, value)) override.put(key, value); } else { override.put(key, value); } return this; } private boolean setGlobal(String key, Dynamic value) { if (override.containsKey(key)) { override.put(key, value); return true; } else if (source != null) { return source.setGlobal(key, value); } else { return false; } } public Scope set(String key, boolean value) { return set(key, DFinal.of(value)); } public Scope set(String key, double value) { return set(key, DFinal.of(value)); } public Scope set(String key, String value) { return set(key, DFinal.of(value)); } public Scope set(String key, Map> value) { return set(key, DFinal.of(value)); } public Scope set(String key, List> value) { return set(key, DFinal.of(value)); } public Scope set(String key, Function> value) { return set(key, DFinal.of(value, () -> key)); } public Scope fork() { return new Scope(this); } @Override public String toString() { return Dynamic.serialize(this); } }