Skip to content

Move Skin functionality out of Drawable into its own classes#67

Merged
cwillisf merged 6 commits intoscratchfoundation:developfrom
cwillisf:skin-classes
Jan 12, 2017
Merged

Move Skin functionality out of Drawable into its own classes#67
cwillisf merged 6 commits intoscratchfoundation:developfrom
cwillisf:skin-classes

Conversation

@cwillisf
Copy link
Copy Markdown
Contributor

@cwillisf cwillisf commented Dec 29, 2016

Moving Skin functionality (corresponding to costumes) out of Drawable (corresponding to sprites & clones) allows multiple Drawable instances to share the same Skin and allows a Drawable to change between Skins without loading the image fresh each time.

In addition, this change moves management of Drawable IDs out of Drawable and into the renderer, which means that Drawable no longer has a "split personality" (static vs. instance). It also makes debugging easier: if you can access the renderer you can inspect all relevant state.

Setting a Skin from a URL has been improved dramatically by this change, but really the renderer shouldn't be responsible for downloading and parsing image files. The new createBitmapSkin and createSVGSkin methods should be used after the renderer's client (the VM, GUI, etc.) obtains an image through a download, the paint editor, etc.

This resolves scratchfoundation/scratch-vm#372

Christopher Willis-Ford added 6 commits December 22, 2016 12:58
This constant will soon be shared with another class.
There is now a `Skin` base class along with `SVGSkin` and `BitmapSkin`
classes for vector and bitmap skin support. Loading a skin by URL is in
the process of being deprecated. In the future skin data should be
downloaded outside the renderer and supplied through new `create*Skin`
API calls.
- Add & correct a few comments
- Make `Drawable` IDs work like `Skin` IDs
- Remove some dead code
- Fix costume resolution in `BitmapSkin` before first `setBitmap` call
- Rename `Drawable` & `Skin` management variables in `RenderWebGL` to
  clarify their purpose and better distinguish them from each other
- Remove problematic premature optimization in `_drawThese`
- Fix missing return statement in `Skin`'s `setRotationCenter`
- Fix mismatch between getTexture & getUniforms in the `Skin` class
This allows any `Drawable` using the `Skin` to update its transform as
necessary.
- `Drawable` now removes its `Skin` on `dispose`, disconnecting events.
- Creating a new `Drawable` doesn't always create a new `Skin` any more:
  now it can share an existing skin.
- Don't throw when asked to update the properties of a `Drawable` that
  has already been destroyed. This seems like a VM bug but was causing
  overwhelming output in the browser for some projects.
Copy link
Copy Markdown
Contributor

@rschamp rschamp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something that stands out is the reference to the renderer in the Skins — is that a necessary evil? I would expect to see the renderer have references to the skins and then do the things it needs to with them rather than have renderer methods called by the skins "magically". Previously it had a reference to gl — was that any better or worse than the renderer itself?

@cwillisf
Copy link
Copy Markdown
Contributor Author

cwillisf commented Jan 3, 2017

Hmm... I was thinking that I made it so they take a reference to the renderer for consistency with Drawable, but it appears that I never committed a version of Drawable that takes a reference to the renderer. Heh.

Taking just gl should be fine -- I'll change it. Circular references tend to feel a little like circular references anyway, and if YAGNI turns out false in this case we can always change it back later.

@cwillisf
Copy link
Copy Markdown
Contributor Author

cwillisf commented Jan 3, 2017

Oh - I found the reason. Hmm...

My upcoming pen code includes the following changes:

  • The renderer itself is an event emitter
  • There's a class called PenSkin which handles all the stuff you need for a pen layer
  • PenSkin listens to an event fired by the renderer, so it takes a reference to the renderer in its constructor
  • In order to unregister for the event, PenSkin holds the reference until Dispose() time

Specifically, PenSkin listens for a stage resize event so that the pen layer can always match the size of the stage.

@rschamp thoughts? Would you prefer a separate event emitter rather than emitting from the renderer itself? Some other way to handle resize notification?

@rschamp
Copy link
Copy Markdown
Contributor

rschamp commented Jan 4, 2017

In the case of the renderer emitting resize events which PenSkin should listen to, I think we could still handle that in the renderer, by attaching the PenSkin's listener from the renderer when the skin is constructed, and unregister it when it's destroyed. This is assuming the renderer constructs and destroys the skins (sorry I am not familiar enough with how it works yet).

But I think since this is dependent on the other work you're doing, we should keep it as-is and refactor later — that sort of thing won't be hard to change.

Copy link
Copy Markdown
Contributor

@thisandagain thisandagain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks really clean. Thanks @cwillisf.

Comment thread src/Drawable.js
if (!willCallCallback) {
callback(null, this._pendingSkin, source);
}
getEnabledEffects () {

This comment was marked as abuse.

This comment was marked as abuse.

@cwillisf cwillisf merged commit 51e8aa9 into scratchfoundation:develop Jan 12, 2017
@cwillisf cwillisf deleted the skin-classes branch January 12, 2017 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"set size to" block does not work under a "when I start as a clone" hat

3 participants