Closed pixelzoom closed 1 year ago
Here's an example from TriatomicMoleculeNode.ts of how I need to instrument MoleculeAngleDragListener. Upon converting to TypeScript, I discovered that phetioDocumentation
is not supported for DragListener and its subclasses.
const atomBDragListener = new MoleculeAngleDragListener( molecule, this, {
phetioDocumentation: 'dragging atom B rotates the molecule',
tandem: dragListenersTandem.createTandem( 'atomBDragListener' )
} );
const bondABDragListener = new MoleculeAngleDragListener( molecule, this, {
phetioDocumentation: 'dragging the bond between atoms A and C rotates the molecule',
tandem: dragListenersTandem.createTandem( 'bondABDragListener' )
} );
const bondBCDragListener = new MoleculeAngleDragListener( molecule, this, {
phetioDocumentation: 'dragging the bond between atoms B and C rotates the molecule',
tandem: dragListenersTandem.createTandem( 'bondBCDragListener' )
} );
Workaround in MoleculeAngleDragListener, see below. This blocks publication of molecule-polarity, unless designers want to punt on the phetioDocumentation.
export type MoleculeAngleDragListenerOptions = SelfOptions &
PickRequired<DragListenerOptions<PressedDragListener>, 'tandem'> &
//TODO https://github.com/phetsims/axon/issues/412 until fixed, phetioDocumentation is ignored
//PickOptional<DragListenerOptions<PressedDragListener>, 'phetioDocumentation'>
PickOptional<PhetioObjectOptions, 'phetioDocumentation'>;
In the workaround, it is unclear to me how that phetioDocumentation
would end up in Studio, since the DragListener is not instrumented. Should we make DragListener extend PhetioObject? Should EnabledComponent extend it too?
There's no expectation that the workaround will result in phetioDocumentation
showing up in Studio. It simply means that I don't need to delete phetioDocumentation
at MoleculeAngleDragListener instantiation sites. The documentation says:
//TODO https://github.com/phetsims/axon/issues/412 until fixed, phetioDocumentation is ignored
... which is why this issue is blocking for molecule-polarity.
Yes, I believe that DragListener needs to extend PhetioObject. I routinely/sadly need to extend PhetioObject for classes that have no state (phetioState: false
), just so I can add phetioDocumentation
that has been requested by designers.
Same problem with molecule-polarity BondAngleDragListener, same "workaround".
One more question before I begin on this, EnabledComponent
has 6 direct subclasses and 1 instantiation site. Should EnabledComponent
itself extend PhetioObject, or only certain places like DragListener
?
UPDATE: I'm aware this question was in the top comment, maybe we need to hear from @zepumph?
... Should
EnabledComponent
itself extend PhetioObject, or only certain places likeDragListener
?
I'm not familiar with how EnabledComponent is used, and what it's intended to be used for. And I suspect that the doc is stale, particularly:
- Base class that defines a settable Property ...
Property?... I see it being used for things that are not Property (buttons, listeners, announcers,..) And while I may have missed something, I don't see it being used anywhere related to Property.
So... I don't know the answer to that question. If @zepumph doesn't have a strong recommendation, I can dive in and look at it more closely.
I think much of the confusion here is about the object that is EnabledComponent. It is not meant to do anything but compose an enabledProperty that can be PhET-iO instrumented. It used to be a mixin, which provided the flexibility that I think @pixelzoom is desiring, but now it isn't, which has caused me to use composition with it in a variety of cases where I need multiple inheritance.
In this case, I have to compose and then pull out the enabledProperty onto my type since I already have a supertype.
Should
EnabledComponent
itself extend PhetioObject
I do not immediately suggest this, because it further deviates from the original intent of EnabledComponent just adding a single Property to the class subtyping it, but I think I defer to @samreid since he currently holds the best vision for EnabledComponent as a class.
It seems like @pixelzoom should open a second issue for if Presslistener should be phet-io instrumented to support phetioDocumentation. Currently it is not instrumented, and just passes in its tandem to the subcomponent PhetioActions (for the data stream). I don't feel too strongly, but it would add a fair number of instrumented listeners to the API that don't really need to be there (just as a placement for documentation I guess).
@zepumph said:
... I don't feel too strongly, but it would add a fair number of instrumented listeners to the API that don't really need to be there (just as a placement for documentation I guess).
I'll leave it up to @arouinfar to decide whether DragListener (and PressListener) needs to be documented. My recollection is that we wanted to be able to document ALL scenery input listeners because Nodes often have more than 1 associated listener.
More specifically, in molecule-polarity, the following documention was requested during PhET-iO design. These seem like useful (maybe even important) descriptions. And they are currently ignored.
// Two Atoms screen
moleculePolarity.twoAtomsScreen.view.moleculeNode.dragListener:
'rotates the molecule by dragging anywhere on it'
// Three Atoms screen
moleculePolarity.threeAtomsScreen.view.moleculeNode.dragListeners.atomBDragListener:
'dragging atom B rotates the molecule',
moleculePolarity.threeAtomsScreen.view.moleculeNode.dragListeners.bondABDragListener:
'dragging the bond between atoms A and C rotates the molecule',
'moleculePolarity.threeAtomsScreen.view.moleculeNode.dragListeners.bondBCDragListener:
'dragging the bond between atoms B and C rotates the molecule'
Thiis would change the API of molecule-polarity.
I'll leave it up to @arouinfar to decide whether DragListener (and PressListener) needs to be documented. My recollection is that we wanted to be able to document ALL scenery input listeners because Nodes often have more than 1 associated listener.
I don't think listeners always need documentation, but there are definitely cases where it is useful, such as molecule-polarity. It seems like optional documentation would be helpful here.
Thanks @arouinfar. To clarify, phetioDocumentation is typically optional. The problem here is that it's currently impossible to provide it, not even optionally.
I made some good progress on converting EnabledComponent to PhetioObject, but at runtime there are too many tandem collisions from newly instrumented things.
@marlitas and I investigated this, and produced this patch:
Note this patch includes the new API for gravity and orbits. This patch does the following:
tandem.createTandem('buttonModel')
instead of tandem: tandem // pass through the parent tandem to hide the implementation detail and make it look as if the firedEmitter is on the button itself
So we are at a good point to get feedback on this question: Do we want buttonModels to remain an implementation detail, or will we be better served by creating a sub-tandem buttonModel
for them, and having the emitter nested under that? This would be a breaking API change, but potentially one that could be managed by migration rules.
Alternatively, we could:
tandem: tandem.parentTandem.createTandem
which we don't like at all.We are at a good point to check in with @zepumph.
Wanna talk on Tuesday. I am pretty firmly in the "buttonModel is an implementation detail" camp, but I don't think I quite understand why it is valuable to instrument it directly for enabledComponent.
Jotting down some notes to streamline our talk on Tuesday.
ButtonModel extends EnabledComponent. If EnabledComponent is changed to extend PhetioObject, then we cannot safely pass tandem and other phet-io metadata to ButtonModel (without collisions). We create a lot of buttonModels like buttonModel = new MyButtonModel(tandem: tandem)
so it thinks it has the same tandem as the parent Button. The buttonModel creates the firedEmitter
. But we could come up with a way to say "don't pass phet-io metadata through to ButtonModel's super--just use it for creating the firedEmitter."
(1) It duplicates the definition of
tandem
instead of getting it from PhetioObject:
Done
(2) Its other options are confusing, because Node has the same options, some with different types:
enabledProperty
,enabled
,enabledPropertyOptions
,phetioEnabledPropertyInstrumented
.
I recommend no changes to this. enabledProperty, enabled, and enabledPropertyOptions all have essentially the same api, and where things differ, it is specific to the different implementations of the Property. EnabledComponent supports checkTandemName
for example, and Node already has an established pattern for instrumenting its sub properties based on the requirements of supporting mutate
(phetioEnabledPropertyInstrumented
). Everything aforementioned is backed by TypeScript and, in my opinion a loud error if you mess up. Happy to discuss further if I'm not understanding fully.
(3) It doesn't provide other PhetioObjectOptions, like
phetioDocumentation
. So I am unable to document MoleculeAngleDragListener.ts and other DragListeners. Should EnabledComponent be a subclass of PhetioObject, perhaps withphetioState: false
?
We will pick this up in https://github.com/phetsims/scenery/issues/1166
RE: https://github.com/phetsims/axon/issues/412#issuecomment-1271884484
In my opinion this work is not worth doing. I know that the iO API does not match the hierarchy, but that is how PhetioObject and the tandem tree were designed. It, in my opinion, is really amazing to not complicate the API with buttonModel
everywhere, when it just isn't needed. When there is a collision while instrumenting new buttons, it is loud and obvious, and we can manage those cases as they come up (they have not come up for 7 years). This should only be progressed if we decided to over in https://github.com/phetsims/scenery/issues/1166.
TL:DR:
This issue took ~30 minutes for me to get caught up in. (3) and the patch in https://github.com/phetsims/axon/issues/412#issuecomment-1271884484 are now property of a side issue. @pixelzoom Please review (1) and (2).
@pixelzoom Please review (1) and (2).
Done. (1) looks correct. I'm OK with "do nothing" for (2).
Feel free to close if there's nothing else to do here.
Reopening because there is a TODO marked for this issue.
Problems with EnabledComponent, encountered during https://github.com/phetsims/molecule-polarity/issues/145 while trying to instrument a DragListener.
(1) It duplicates the definition of
tandem
instead of getting it from PhetioObject:tandem?: Tandem;
(2) Its other options are confusing, because Node has the same options, some with different types:
enabledProperty
,enabled
,enabledPropertyOptions
,phetioEnabledPropertyInstrumented
.(3) It doesn't provide other PhetioObjectOptions, like
phetioDocumentation
. So I am unable to document MoleculeAngleDragListener.ts and other DragListeners. Should EnabledComponent be a subclass of PhetioObject, perhaps withphetioState: false
?