[Feature]: Expand JS API functionality to (all?) Macro Functions, deprecate MTScript versions
Feature Request
Currently, the vast majority of Macro Functions are best accessed using a code block like this:
getProperty(property){
return "" + MTScript.evalMacro('[r: getProperty("' + property + '", "' + this.getId() + '")]');
//return this.maptoolToken.getProperty(property);
}
This example is taken from Darinth's maptool.js library, and is the wrapper for the MTScript Macro Function getProperty. In this case, the JS API can be made to mirror the functionality of getProperty() with only a few small tweaks. This would be duplicating the already existing MTScript implementation, requiring twice as much maintenance work in the future. However, expanding the JS API to all currently supported Macro Functions would be a helpful step towards breaking the reliance on the existing MTScript parser, which would be a benefit overall, especially going forward.
The Solution you'd like
MTScript 2.0 should be Javascript, implemented through GraalVM, as per #245, and bringing Javascript up to feature parity with MTScript is the next major step towards that goal. There are many thorny questions that will arise during implementation (which I expect will revolve around Token Properties, types, etc.) but I think it is time we started answering them. The current MTScript parser is essentially legacy code at this point, being difficult to understand and change, as well as limited in expressive power (max two nested CODE blocks, for example). Giving the macro system a facelift in the form of easy-to-use Javascript could possibly even draw in users who were originally put off by the quirks, intricacies, and issues of MTScript.
The implementation of this solution should be straightforward; find a function implementation in the codebase, copy it over to the relevant file, and change it as necessary to work in the new environment. This is technically a one-person job, but answering those aforementioned thorny questions of implementation and design is a task for the development community. This is a fundamental shift in the design of MapTool; best to not wing it.
When the work is complete, the MTScript Macro Functions could be deprecated, if appropriate. Any new functionality would be directed towards their JS API counterparts, and users would be directed to write their new functions in Javascript, and call them with the js.eval family of functions.
Alternatives that you've considered.
- Doing nothing, and letting JS users keep adding their own boilerplate as appropriate. This is mostly fine, but it does slightly raise the barrier to entry for JS, and also chains MapTool to MTScript parser maintenance for the foreseeable future.
- Moving the boilerplate one level down, into the API. Construct the appropriate command with a StringBuilder, and send it to the MTScript parser. This alleviates the burden on the users, but again chains MapTool to the MTScript parser.
Additional Context
No response
A bit of experimentation later, and I've got a small working example here: adyoungblood@bd5f7ee932980bfc1ea8a2d5d337d4c540ff21da. Even though it's some 800 lines of code, it was mostly just copying functionality from one file into the appropriate JSAPI file. A few considerations did come up, though:
- Token Properties and types in Maptool, how should they work? Properties already store type information, but all the entry from MTScript comes in the form of Strings.
- Nearly every function needs a trusted/owner check (I made an example campaign to demonstrate why, can share if needed), which is currently boilerplate in every implemented function. Can that be fixed with something similar to an InvocationHandler?
- Every function can throw a ParserException, mostly for trusted/owner exceptions. Should this be handled differently? Before, either no action was taken or a default value was returned. Maybe a new Exception type? Or a different design entirely?
That's what has come up for me so far in terms of design decisions that might need solving. What I have currently does work and can be extended to all current Macro Functions, if nothing else.
The plans are to create a new JS API for interaction with MapTool, if we just create a wrapper around the current macro functions we end up just living with all the same problems and never being able to solve them. It's already hard enough to add new functionality without taking the biggest chance we have to leave behind some of the things holding us back the most.
Don't worry, the code I wrote interacts directly with Maptool (Tokens, mostly) itself, it doesn't use the current macro system (parsing, execution, etc.) at all. The JSAPIToken implementation interacts either with its underlying Token object, or the static MapTool instance if it needs to.
what is the progress on this? this issue hasn't been updated since may, i am planning to make my framework on javascript and it would help if there were a complete api so that i don't need to write a lot of boilerplate code, i ask because i would be interested in working on the api if no one is doing so. as it was mentioned that it is a one person job i wouldn't want to hinder progress if someone already is working on it.
I know others have expressed interest in working on this, I am not sure if anyone has started. Its probably worth bringing it up on discord and detailing your ideas to restart the discussion and gather everyones ideas / design that may have already been started.