When asked to load an extension, the Extension Manager starts up a new
Worker. That worker runs the message dispatch system as well as an
instance of the new `ExtensionWorker` class, which will load the desired
extension and register it with the extension system.
Extensions, placed in `./src/extensions/*.js`, are now processed by
Webpack as separate entry points and packed into an `extensions`
subdirectory in the output.
Still to do: query an extension's information, including the blocks it
provides, and register that information with the VM, GUI, etc.
* Add glide to dropdown block
* Use helper functions instead of copy-paste
* Wrong syntax for array 😒
* Aha
* Fix some Travis issues
* Aha!! This should work
* Wow, Travis is strict about spacing!
* Make requested changes
Rename function getTarget to getTargetXY
Rename parameter TO to targetName
Central dispatch and worker dispatch share most of their code now by
inheriting from a new shared dispatch class.
Also, the format of passed messages has been altered to make it easier
to understand in a debugger.
This allows a service to postpone communication with other services
until it can be sure that it's registered with central dispatch. Service
registration on the main thread always happens immediately, but that
version of `setService` still returns a Promise for consistency.
The tests run using TinyWorker, which emulates web workers on Node.
There are quite a few quirks in that situation due to the differences
between Node and Webpack as well as the differences between TinyWorker
and real Web Workers.
The tests also exposed a few bugs in the dispatch system, which have now
been fixed. Most notably, if a method called through the dispatch system
throws an exception that exception will now be passed back to the
caller. Previously the exception would escape the dispatch system and
the caller would never hear any response at all.
This message dispatch system allows a "service" to register itself under
a particular name, and then anyone can call any method on that service
from any context (the main "window" thread or any worker). Return values
are passed back through promise resolution.