{"id":15672866,"url":"https://github.com/sof3/actionapi","last_synced_at":"2025-05-06T22:07:16.361Z","repository":{"id":95880631,"uuid":"359087159","full_name":"SOF3/ActionApi","owner":"SOF3","description":"Generalized user interface framework for PocketMine plugins.","archived":false,"fork":false,"pushed_at":"2021-04-21T06:20:46.000Z","size":26,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-05-06T22:02:55.351Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SOF3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-18T08:30:44.000Z","updated_at":"2024-11-04T04:19:31.000Z","dependencies_parsed_at":"2023-03-12T16:30:58.418Z","dependency_job_id":null,"html_url":"https://github.com/SOF3/ActionApi","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SOF3%2FActionApi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SOF3%2FActionApi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SOF3%2FActionApi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SOF3%2FActionApi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SOF3","download_url":"https://codeload.github.com/SOF3/ActionApi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252776579,"owners_count":21802467,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T15:32:58.131Z","updated_at":"2025-05-06T22:07:16.324Z","avatar_url":"https://github.com/SOF3.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ActionApi\n\nGeneralized user interface framework for PocketMine plugins.\n\n## How does this work?\nActionApi introduces the following concepts:\n\n### Action\n`Action` is an interface implemented by plugins\nto represent something that a user can do.\n\nEach action type implements a new subclass of `Action`.\nA new instance of `Action` is created for every execution.\nAn `Action` subclass holds the arguments required for the action.\n\n### Arg\n`Arg` is an argument that the user provides to customize the action.\nThey can be inferred from the `Hook` (action trigger),\nor separately requested from the user.\n\nImplementations provided by `ActionApi`:\n\n| Type | Command line support | Form UI support | Inference from `Hook` |\n| :---: | :---: | :---: | :---: |\n| `StringArg` | Yes (single argument or space implosion) | Yes (`CustomForm` `Input`) | None |\n| `StringEnumArg` | Yes (single argument) | Yes (`CustomForm` `Dropdown`, or `CustomForm` `StepSlider`, or `MenuForm`) | None |\n| `StringEnumSetArg` | Yes (last argument only, or if delimiter is provided) | Yes (`CustomForm` `Toggle`s) | None |\n| `IntArg` | Yes | Yes (`CustomForm` `Slider`, or `CustomForm` `Input`) | None |\n| `FloatArg` | Yes | Yes (`CustomForm` `Slider`, or `CustomForm` `Input`) | None |\n| `BoolArg` | Yes | Yes (`CustomForm` `Toggle`, or `ModalForm`) | None |\n| `GenericListArg` | Yes if element type supports (rearranged as last argument, variadic) | Yes if element type supports (interactive loop) | If element type is inferrable, singleton list |\n| `PlayerArg` (online players only) | Yes (by name prefix or full name) | Yes (`CustomForm` `Dropdown`, or `MenuForm`) | If hook is clicking on a player |\n| `PlayerSetArg` (online players only) | Yes (comma-separated) | Yes (`CustomForm` `Toggle`s) | None |\n| `EntityArg` | No | Yes (click on entity in world) | If hook is clicking on an entity |\n| `BlockTypeArg` | Yes (by name, with variant colon-separated) | Yes (interactive selector with search button) | If hook is clicking on a block |\n| `ItemArg` | Yes (by name, with damage and count colon-separated) | Yes (interactive selector with search button) | If hook is clicking on air, a block or entity (default value is currently held item) |\n| `ItemTypeArg` | Yes (by name, with damage colon-separated) | Yes (interactive selector with search button) | If hook is clicking on air, a block or entity (default value is currently held item) |\n| `PositionArg` | Yes (by typing x y z world-name) | Yes (`CustomForm` `Dropdown` to select current position, `CustomForm` `Input`, current crosshair target or next-click position) | If hook is clicking on a block or entity (otherwise) |\n| `WorldArg` | Yes (world name) | Yes (`CustomForm` `Dropdown`, or `MenuForm`) | None (default value is player current world) |\n| `WorldSetArg` | Yes (last argument only) | Yes (`CustomForm` `Toggle`s) | None |\n| `YawArg` | Yes (in degrees, not recommended) | Yes (`CustomForm` `Slider`) | Player current orientation |\n| `PitchArg` | Yes (in degrees, not recommended) | Yes (`CustomForm` `Slider`) | Player current orientation |\n| `DateTimeArg` | Yes (ISO 8601, or `+` + duration) | Yes (`CustomForm` `Slider`s for YMDhmsZ) | None |\n| `DurationArg` | Yes (single argument, e.g. `1w2d3h4m5s`) | Yes (interactive loop with `CustomForm` `Input` + `Dropdown` for unit) | None |\n\nInference from `Hook` may be suppressed as the default value instead of silently selected\nby an extra flag from the constructor call in the `Action` implementation.\n\n### Hook\n`Hook` is the method that the user used to trigger the initiation of this action.\nIt stores data related to the trigger.\n\nImplementations provided by `ActionApi`:\n\n- command\n- block click\n- air click\n- entity click\n- item selection\n- hotbar switch\n- action menu (a navigation index for actions defined in config.yml)\n\n### Example `Action` implementation\n```php\nfinal class AddWarpAction implements Action {\n\tprivate DataProvider $db;\n\n\tprivate ?string $name = null;\n\tprivate ?Position $pos = null;\n\tprivate ?bool $open = null;\n\n\tpublic function __construct(DataProvider $db) {\n\t\t$this-\u003edb = $db;\n\t}\n\n\tpublic function isMissingArg() : bool {\n\t\treturn $this-\u003ename === null || $this-\u003epos === null || $this-\u003eopen === null;\n\t}\n\n\tpublic function getArguments() : iterable {\n\t\tyield StringArg::new(\"Warp name\", $this-\u003ename);\n\t\tyield PositionArg::new(\"Warp position\", $this-\u003epos);\n\t\tyield BoolArg::new(\"Open to public?\", $this-\u003eopen)-\u003edefault(true);\n\t}\n\n\tpublic function run(CommandSender $sender) : void {\n\t\t$this-\u003edb-\u003eaddWarp($this-\u003ename, $this-\u003epos-\u003egetX(), $this-\u003epos-\u003egetY(), $this-\u003epos-\u003egetZ(),\n\t\t\t\t$this-\u003epos-\u003egetWorld()-\u003egetFolderName(), $this-\u003eopen);\n\t\t$sender-\u003esendMessage(\"Warp \\\"$this-\u003ename\\\" created at $this-\u003epos\");\n\t}\n}\n```\n\n### Implementing `Arg` and `Hook`\nIf the existing arguments are not sufficient, other plugins can implement additional `Arg` types.\nPlugins that want to trigger actions from other methods can also implement their own `Hook` types.\n\nEach `Arg` supports command line and form UI interface.\nHowever, if an `Arg` additionally infers arguments from a `Hook`,\nthe logic is implemented under a separate `Inferrer` interface.\nPlugins may register an `Inferrer` instance that supports a specific type of `Arg` and a specific type of `Hook`.\nAn example implementation for inferring `EntityArg` from an `EntityClickHook`:\n\n```php\nfinal class EntityClickItemInferrer implements Inferrer {\n\tpublic function infer(Hook $hook) {\n\t\tassert($hook instanceof EntityClickHook); // this is true if you registered the inferrer for the correct class\n\t\treturn $hook-\u003egetClickedEntity();\n\t}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsof3%2Factionapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsof3%2Factionapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsof3%2Factionapi/lists"}