-
Notifications
You must be signed in to change notification settings - Fork 26
Optim: oNode attributes lazy loading #79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: require-refactor
Are you sure you want to change the base?
Conversation
|
I like what you're going for here but there are a couple of things that confuse me. You can enable it by setting this value to true : OpenHarmony/openHarmony/base.js Line 419 in 559989a
Would you be ok with adding a few tests for this so we can make sure we're not breaking anything? |
|
Hi, there are no collision between global caching and my lazy loading proposal. When
The lazy loading state is per-instance, so whether the instance is fresh or cached, the behavior is correct. Also, I haven't tested your global caching feature very deeply but by reading the code I've found two issues which look critical to me:
function oNode ( path, oSceneObject ){
var instance = this.$.getInstanceFromCache.call(this, path);
if (instance) return instance;Only path is passed to getInstanceFromCache, but oSceneObject is also a constructor parameter. If two different scene objects requested the same path, they'd incorrectly share the same cached instance.
function oColumn (uniqueName, oAttributeObject){
var instance = this.$.getInstanceFromCache.call(this, uniqueName);
if (instance) return instance;Same issue — only uniqueName is passed, ignoring oAttributeObject. Are they left undefined on purpose? |
|
I get that they are caching different things, I'm just worried about the getter setters directly on the node... If you can write a few tests for it that would be very reassuring and save me the time to go deep into it and we could merge it quicker. I'm talking about things like doing
The scene object should really always be the same; to be honest I would happily remove that argument in the oNode creator now that the lib is more mature (anyway users should never create oNodes themselves). Most people access it through $.scn which is an instance created when the lib is loaded. We could easily make it a singleton instead I guess... Harmony only allows one path and one name for node and columns respectively. So I think in practice this is fine. Actually the passing of AttributeObject is a bit of an architectural issue because depending on the way the column is accessed, it can't always know what it is associated to. Ex: no way to know the attribute when getting There are places in the code where some workaround was added, in frames manipulation/value setting and things like that.
To be clear openHarmony stated goal is to enable scripting from the point of view of people with less background knowledge to access a more intuitive and complete set of features than the native api. I wonder if the ayon code should instead selectively switch to the native api for performance sensitive tasks? Something like selecting a set of nodes based on names I guess could be done this way? Not saying that improving performance in openHarmony wouldn't be nice but it won't always be possible. Note that all of this is irrelevant if we can just validate by test that this doesn't break anything |
|
Oh sure, I misunderstood your first test request, I thought "this" was your global caching system. I wrote tests that you can run with the regular Your concern was right, my previous implementation was requiring the user to access the attribute using I understand your point about Ayon and the philosophy of OH. I started by modifying Ayon's code by calling the native API in the first place TBH. But then I realized I could propose something to OpenHarmony which would benefits the whole API, and here we are. |
I appreciate that! |
| } | ||
|
|
||
| // Create temporary group for scanning | ||
| tempGroupPath = node.add('Top', '_OH_ATTR_SCAN_TEMP_', 'GROUP', 0, 0, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow this is sure inventive but I'm really not sure we can create all the nodes that exist in the software just to init one node!!
If this works for you on your fork that's great but I think maybe we can wait for the nodeType prototype dynamic creation implementation instead of adding something like that even as a temporary workaround!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For sure, I really prefer the design you proposed.
| var tempGroupPath = null; | ||
| try { | ||
| // Get all node types dynamically from Harmony | ||
| var nodeTypeList = node.getNodeTypeList(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this a recent addition? I don't have this function available in harmony 24
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, this is actually very strange, I can see this function in harmony local documentation (through Help menu), while it's not in the online doc... And it works in the API. 😱
|
By the way the tests look great, but yeah that workaround seems really dicey to me to merge right now since we have a cleaner solution in mind already. I almost wish I could merge the tests only! |
Granted, 2 remaining. |
Problem
Creating oNode wrappers is expensive because the constructor eagerly loads ALL node attributes and creates getter/setters for each one, even when only basic properties like
nameorenabledare needed.This causes significant performance issues when creating many node wrappers (e.g.,
getNodesByTypecalls).Solution
Defer attribute loading until first access of the
attributesproperty:refreshAttributes().attributesaccessImpact
Node wrapper creation is now nearly instant. Attributes are only loaded when actually needed.
Test
Regular use of API, more significant on big scenes.