1. The forums will be archived and moved to a read only mode in about 2 weeks (mid march).

[RFC] Variables API

Discussion in 'Development' started by SOFe, Jun 26, 2017.

Tags:
  1. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    We need an API for retrieving data from other plugins.
    This idea originate from a very simple plugins that executes commands upon some events. Obviously, making such commands requires the use of variables. For example, in a config.yml (suppose there is a "/dm <player>" command which sends a raw message to a player):
    Code:
    on-kill: # when killing takes place
      - takemoney ${victim} 1000 # take 1000 dollars from victim
      - givemomey ${killer} 1000
    on-fall: # when a player falls
      - dm ${player} You took ${damage.hearts} hearts of damage (${damage} halfhearts)!
      - ${player.last-hitter}: /wrap spawn # run a command as player.last-hitter, if the player's last hitter can be resolved to a command sender
    
    When I want to retrieve more information about a certain variable, e.g. the damage in terms of hearts, it changes to the syntax damage.hearts.
    This can be further extended by plugins through the event API. Suppose there is an event VariableResolveEvent:
    PHP:
    class VariableResolveEvent extends PluginEvent {
      
    /** @var Variable */
      
    private $baseVar;

      
    /** @var string[] */
      
    private $nest;
      
    // Constructor, getters and setters skipped

      
    public function resolveAs(Variable $subvarint $levels){...}
    }
    The Variable class represents a context, or certain components in the context. The structure is as follows:
    PHP:
    class Variable {
      public 
    $toString;
      
    /** @var Variable [] */
      
    public $children// or an ArrayAccess object that retrieves values on-demand
      
    public $traits;
    }
    The traits are strings identifying the type of the variable. For example, if it can resolve the properties of a player, it should have the "player" trait. This is only for API, so nobody will check if it really has such properties, but declaring it wrongly may cause other plugins to misunderstand the variable.
    It may also be possible to resolve the variable as a string directly. For example, in the example before, ${damage} can be directly resolved as the damage in halfhearts, but it also contains a child called "hearts", which can be resolved as the damage in hearts.

    The resolveAs function is called by plugins handling the event. For example, we want to resolve the variable ${aaa.bbb.ccc.ddd}. "aaa" can be resolved from the base variable directly, but bbb cannot be resolved from aaa. So, we fire a VariableResolveEvent with the nest as ["bbb", "ccc", "ddd"] and baseVar as the resolved aaa Variable. Now, a plugin successfully resolved "bbb" by calling resolveAs($bbbVariable, 1), and we found that the bbb variable contains the ccc child, so we recursively fire a VariableResolveEvent for ["ddd"] with the newly resolved ccc. Repeat this loop until a certain nest level cannot be resolved, or all have been resolved, then we take the $toString value.

    The user doesn't have to know so much complication. They just look at the variable name, e.g. ${victim.last-hitter.economysapi:money}, etc.

    I'm not sure what should happen if a variable cannot be resolved, though. Any comments?
     
  2. TheDiamondYT

    TheDiamondYT Zombie

    Messages:
    298
    GitHub:
    TheDiamondYT1
    Variables should have the ability to be escaped. For example if i wanted to display a message showing the user how to add a variable, i could escape it and it would just be part of the string
     
    SOFe likes this.
  3. SOFe

    SOFe Administrator Staff Member PMMP Team Poggit Admin

    Messages:
    1,968
    GitHub:
    sof3
    This is simple. Just make a "raw" syntax, like this:
    Code:
    ${--raw text here}
    
    or if you want to put } in your raw text, use NOWDOC style:
    Code:
    ${--[END OF RAW TEXT]raw text where any characters like $:{}[]()<>/\ are allowed[END OF RAW TEXT]}
    I'm not using the backslash style because I don't want to force people to make double backslash when they don't know anything about escaping.
     
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.