unobserveField(name as String)
Removes the previously established connections between the subject node field identified by name and any callback functions or message ports.
Does this mean that calling node.unobserveField(“fieldName”) will remove from node.fieldName any and all observer “contracts” by any and all components/threads (hence “nuke” them) - or does this apply only to the observers from the current context?
As a reminder, multiple components/threads may have registered observer functions/ports over the same field.
“TheEndless” wrote:
It only applies to the current context. The same context in which observeField was called.
So all observers (functions and ports) established from the current context (interpreter) will be stripped for the field - but the ones from another (e.g. next-door thread) over the same field will survive?
PS. here is amusing thought… what happens if one calls observeField() multiple times in exactly the same context and params? I figure it will either (a) cause multiple consecutive firings of same event or (b) … not.
“EnTerr” wrote:
So all observers (functions and ports) established from the current context (interpreter) will be stripped for the field - but the ones from another (e.g. next-door thread) over the same field will survive?
Correct.
“EnTerr” wrote:
PS. here is amusing thought… what happens if one calls observeField() multiple times in exactly the same context and params? I figure it will either (a) cause multiple consecutive firings of same event or (b) … not.
a.
These questions are all easily tested, so to quote another helpful forum member.. have youtried it?
“TheEndless” wrote:
These questions are all easily tested, so to quote another helpful forum member.. have youtried it?
Touché!
Not quite… but touché, Sir - for digging these examples!
Here is what i mean by “not quite”. There could be different standards on documentation - personally i would be satisfied by one that a “competent and reasonable developer” can read and use. By “reasonable” i mean “a hypothetical person in society who exercises average care, skill, and judgment in conduct” (see Reasonable Person Standard). And by “competent developer” i assume one that knows the difference between between a local and a global variable, between a value and a reference type… actually pretty high bar, comparatively to what we get in Roku world.
To which i posit, such competent&reasonable developer:
reading that Overhand is subclass of Group, will deduce children can be added
will expect 4k video plays like any other, in the absence of explicit disclaimer
will expect “any callback functions or message ports” for unobserveField() to mean the “nuclear option” (everywhere in the app)… and will be wrong on that, per your experiments
So this is an under-documented or wrongly-documented behavior that should be fixed - otherwise unobserveField() is useless, without it being codified whether it affects the other xml-components or not.
“EnTerr” wrote:
will expect “any callback functions or message ports” for unobserveField() to mean the “nuclear option”, everywhere in the app… and will be wrong on that (per your experiments?)
If you consider that the caller of observeField() is the observer, then it stands to reason that that same caller would only be able to undo observations that it has initiated.
“EnTerr” wrote:
will expect “any callback functions or message ports” for unobserveField() to mean the “nuclear option”, everywhere in the app… and will be wrong on that (per your experiments?)
If you consider that the caller of observeField() is the observer, then it stands to reason that that same caller would only be able to undo observations that it has initiated.
No, it does not. I am example of a “competent and reasonable developer” who when reading “any callback functions or message ports” assumes that “ANY” means what it says (that is, EVERY/ALL). In fact, let me broaden that - why would a random reasonable person think otherwise?
I can guess why you think the way you do - you have been long enough around roWanda’s tank. And i am only half-way there (i.e. level “suspicious”) because of lesser exposure. But why do you expect J. Random Hacker to have your mind bends?
“EnTerr” wrote:
why would a random reasonable person think otherwise?
Not debating that the documentation is a little ambiguous, but why would a “competent and reasonable developer” think that any component could randomly delete a different component’s field observations? I could understand the observee being able to remove multiple observers, but one observer deleting another doesn’t make sense to me, especially when you consider that the observers generally aren’t aware of each other’s existence.
“TheEndless” wrote:
… but why would a “competent and reasonable developer” think that any component could randomly delete a different component’s field observations? I could understand the observee being able to remove multiple observers, but one observer deleting another doesn’t make sense to me, especially when you consider that the observers generally aren’t aware of each other’s existence.
Because
A “reasonable person” when seeing unqualified “ANY”, assumes it means what it says - removes any and all. Does it say “current caller’s …”? (It does not.)
Components can already peek & poke at each other’s Fields - intuitively they could meddle with observer functions too (there is no expectation of privacy)
Notice you are muddling here the meaning of “observer” - observers are not objects but “pseudo-methods” (functions defined in XML file extending a class). Say observer myClass::f1() was placed over anotherNode.FieldFoo. It is not such observer myClass::f1() that deletes itself - rather it could be (and likely is) another, unrelated function myClass::g2() that calls anotherNode.unobserveField() to remove “any” observer functions.
And what if (a function from) anotherNode wants to strip all observers from its very own FieldFoo? That is a business use too! It makes a good case for anotherNode.unobserveField(“FieldFoo”) being able to shake all “peeping Toms” off its own field.
Components in SceneGraph are isolated from each other, so while technically the “observer” is the function you register, that function has to be available in the same context as the code that’s calling observeField(). Since that code is isolated to the component, I think it’s fair to refer to the component as the observer.
Now, consider you have a ContentNode that provides the content for multiple grid components (grid1 and grid2). Each grid component may want to register an observer on the ContentNode to monitor for any changes to the data, so it can update its UI. If unobserveField() were nuclear, then grid1 would have no way unregistering its observer when its ContentNode (or visibility) changes without also unregistering grid2’s observer.
“TheEndless” wrote:
Now, consider you have a ContentNode that provides the content for multiple grid components (grid1 and grid2). Each grid component may want to register an observer on the ContentNode to monitor for any changes to the data, so it can update its UI. If unobserveField() were nuclear, then grid1 would have no way unregistering its observer when its ContentNode (or visibility) changes without also unregistering grid2’s observer.
… except that is exactly what unobserveField() does. Putting the record straight, unobserveField() is the “nuclear option” and will annihilate all observers on that component field.
Which is why in 7.5 another set of methods - observeFieldScoped() / unobserveFieldScoped() - was added, which maintains list of observer fn/ports local to the caller, so the flushing would be local in scope. Likewise, it does not provide individual opt-out - if the same component has set two observers on another component.field, both will be removed with unobserveFieldScoped().
So I am going to implement a library by a vendor, and they require that we pass a reference to our SG Video node. In their documentation, they state the following:
During CreateSession(), the [Vendor Name Redacted] Roku Library will first unobserve and later observe for the change in the content of the Video node fields - streamInfo, position, state, duration, streamingSegment, errorCode, errorMsg. Below is a sample code snippet from CreateSession(…)
Yes Tim. But it would make sense that their library simply wants to set up its own observers after they unobserve every possible field to be able to ensure theirs are the only ones running. So just like they did, you can add yours back in, or comment theirs out. Since you can have the same field observed to run an infinite number of callbacks…
“destruk” wrote:
Yes Tim. But it would make sense that their library simply wants to set up its own observers after they unobserve every possible field to be able to ensure theirs are the only ones running. So just like they did, you can add yours back in, or comment theirs out. Since you can have the same field observed to run an infinite number of callbacks…
It may have made sense before, when there was only ObserveField(). Now (7.5+) that there are -Scoped methods, said vendor would do better using ObserveFieldScoped() with their own component and perhaps a separate port. It depends on the exact API needs really, i cannot state with a 100% certainty