Interface KeyProviderExpression<T>

All Superinterfaces:
Debuggable, Expression<T>, Loopable<T>, Simplifiable<Expression<? extends T>>, SyntaxElement
All Known Implementing Classes:
ConvertedKeyProviderExpression, Variable

public interface KeyProviderExpression<T> extends Expression<T>
Represents an expression that is able to return a set of keys linked to its values. This can be used to return index-linked values to store in a list variable, using the Changer.ChangeMode.SET Changer or passed to a function argument. An expression can provide a set of keys to use, rather than numerical indices.
Index-linking is not (currently) used with other change modes.

Contract


Advice on Caching

As long as callers are built sensibly and follow API advice, it should be safe to cache a key-list during a values call. E.g. if an expression is returning data from a map, it could request the whole entry-set during Expression.getArray(Event) and return the keys during getArrayKeys(Event) (provided the cache is weak, safe and event-linked). This is not necessary, but it may be helpful for some expressions where the set of keys could potentially change between repeated calls, or is expensive to access.

Caveats

  1. The caller may never ask for getArrayKeys(Event). The cache should be disposed of in a timely manner.
  2. It is (theoretically) possible for two separate calls to occur simultaneously (asking for the value/key sets separately) so it is recommended to link any cache system to the event instance .
Note that the caller may never ask for getArrayKeys(Event) and so the cache should be disposed of in a timely manner.

 Map<Event, Collection<String>> cache = new WeakHashMap<>();

 public Object[] getArray(Event event) {
     Set<Entry<String, T>> entries = something.entrySet();
     cache.put(event, List.copyOf(something.keySet()));
     return something.values().toArray(...);
 }

 public String[] getArrayKeys(Event event) {
     if (!cache.containsKey(event))
         throw new IllegalStateException();
     return cache.remove(event).toArray(new String[0]);
     // this should never be absent/null
 }
 
See Also:
  • Method Details

    • getArrayKeys

      @NotNull @NotNull String @NotNull [] getArrayKeys(org.bukkit.event.Event event) throws IllegalStateException
      A set of keys, matching the length and order of the immediately-previous Expression.getArray(Event) values array.
      This should only be called immediately after a Expression.getArray(Event) invocation, and iff canReturnKeys() returns true. If it is called without a matching values request (or after a delay) then the behaviour is undefined, in which case:
      • the method may throw an error,
      • the method may return keys not matching any previous values,
      • or the method may return nothing at all.
      Parameters:
      event - The event context
      Returns:
      A set of keys, of the same length as Expression.getArray(Event)
      Throws:
      IllegalStateException - If this was not called directly after a Expression.getArray(Event) call or if canReturnKeys() returns false
    • getAllKeys

      @NotNull default @NotNull String @NotNull [] getAllKeys(org.bukkit.event.Event event)
      A set of keys, matching the length and order of the immediately-previous Expression.getAll(Event) values array.
      This should only be called immediately after a Expression.getAll(Event) invocation, and iff canReturnKeys() returns true. If it is called without a matching values request (or after a delay) then the behaviour is undefined, in which case:
      • the method may throw an error,
      • the method may return keys not matching any previous values,
      • or the method may return nothing at all.
      Parameters:
      event - The event context
      Returns:
      A set of keys, of the same length as Expression.getAll(Event)
      Throws:
      IllegalStateException - If this was not called directly after a Expression.getAll(Event) call or if canReturnKeys() returns false
    • keyedIterator

      default Iterator<KeyedValue<T>> keyedIterator(org.bukkit.event.Event event)
      Returns an iterator over the keyed values of this expression.
      This should only be called iff canReturnKeys() returns true.
      Parameters:
      event - The event context
      Returns:
      An iterator over the key-value pairs of this expression
    • isSingle

      default boolean isSingle()
      Keyed expressions should never be single.
      Specified by:
      isSingle in interface Expression<T>
      Returns:
      true if this expression will ever only return one value at most, false if it can return multiple values.
    • canReturnKeys

      default boolean canReturnKeys()
      Returns whether this expression can return keys.
      If this returns false, then getArrayKeys(Event) and getAllKeys(Event) should never be called.
      Returns:
      Whether this expression can return keys
    • areKeysRecommended

      default boolean areKeysRecommended()
      While all keyed expressions may offer their keys, some may prefer that they are not used unless strictly required (e.g. variables).
      Returns:
      Whether the caller is recommended to ask for keys after asking for values
    • isLoopOf

      default boolean isLoopOf(String input)
      Description copied from interface: Loopable
      Checks whether the given 'loop-...' expression should match this loop, e.g. loop-block matches any loops that loop through blocks and loop-argument matches an argument loop.

      You should usually just return false as e.g. loop-block will automatically match the expression if its returnType is Block or a subtype of it.

      Specified by:
      isLoopOf in interface Loopable<T>
      Parameters:
      input - The entered input string (the blank in loop-___)
      Returns:
      Whether this loop matches the given string
    • isIndexLoop

      default boolean isIndexLoop(String input)
      Checks whether the 'loop-...' expression should match this loop's index, e.g. loop-index matches the index of a loop that iterates over a list variable.
      Parameters:
      input - the input to check
      Returns:
      true if the input matches the index loop, false otherwise
    • canReturnKeys

      static boolean canReturnKeys(Expression<?> expression)
      Checks if the given expression can return keys.
      Parameters:
      expression - the expression to check
      Returns:
      true if the expression can return keys, false otherwise
      See Also:
    • areKeysRecommended

      static boolean areKeysRecommended(Expression<?> expression)
      Checks if the given expression can return keys and whether it is recommended to use them.
      Parameters:
      expression - the expression to check
      Returns:
      true if the expression can return keys, and it is recommended to use them, false otherwise
      See Also: