Page 1 of 7

behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 1:45 am
by monte
I'm wondering about adding setprop and getprop handlers for object properties. There's a few good use cases for blocking changes... one example group where setting the margins, show name or show border will stuff up the resizeControl handler. I'm sure there'd be use cases for being aware of changes too... I guess these messages could go to a behavior only because that's the main use case I can think of...

Is there a Properties -> MCNameRef method anywhere... can't seem to find it but would think it would be helpful here so sendsetprop could be used.

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 3:17 am
by phaworth
I'd love to get a message when any property is changed if that's what you are referring to.
Pete

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 3:49 am
by monte
Yeah...

Code: Select all

setProp margins pMargins
   -- don't pass so margins can't be set
end margins

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 8:31 am
by LCMark
<start previous rhetoric>
In the general case, making setProp and getProp work for engine properties as well as custom properties hasn't been done because of the performance issue. Having a message pass all the way through the message path to hit the engine is (relatively speaking) quite slow, so changing the action of engine properties would have a significant impact on the performance of code that sets / gets lots of engine properties.
<end previous rhetoric>

Well, at least that had been the reasoning even before I started... I just did a small (very rough) performance test and it turns out that (in the IDE), letting a message pass all the way through the message path (i.e. to the engine) is 'only' about 5 times slower than getting an engine property - this is a much smaller gap than I remember, but then a few versions ago we did optimize the way handlers were searched at each stage of the message path so maybe that has had a very significant impact on this particular comparison.

The reason I mention this is that it does suggest that with a bit more optimization of how the message path handler lookups, it might be feasible to generally lift the restriction on engine properties on setProp / getProp - i.e. have them work generally, rather than in a behavior / object only case.

Of course, in the mean time, having this work in a 'conditional' way like idle, resizeControl etc. would be a good balance I think. i.e. The message is only sent to the object if the object script or its behavior script contain the getProp or setProp message; if they do then they are sent through the message path in the usual way. The only issue with properties is that this mechanism can't really use a fixed set (computed at compile time of script) to determine whether the handler is present in the script. However, it should be fast enough to use MCHandlerList::exists() to check before sending... If this does have too much of a performance impact, we can just change MCHandlerList to be a hash-table, rather than a binary-searched array :)

In terms of MCNameRefs and property strings, for now you can just construct a name on the fly as needed using MCAutoNameRef... It would be good to have all the syntax related strings as NameRefs rather than const char * though - so this might be a good separate project.

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 9:05 am
by monte
cool... I was thinking you wouldn't like this idea but it sounds like you do ;-)
The reason I mention this is that it does suggest that with a bit more optimization of how the message path handler lookups, it might be feasible to generally lift the restriction on engine properties on setProp / getProp - i.e. have them work generally, rather than in a behavior / object only case.
That would be great. I think the most likely use case is in behaviors though so I think a behavior only solution would be reasonable.
Of course, in the mean time, having this work in a 'conditional' way like idle, resizeControl etc. would be a good balance I think. i.e. The message is only sent to the object if the object script or its behavior script contain the getProp or setProp message; if they do then they are sent through the message path in the usual way. The only issue with properties is that this mechanism can't really use a fixed set (computed at compile time of script) to determine whether the handler is present in the script. However, it should be fast enough to use MCHandlerList::exists() to check before sending... If this does have too much of a performance impact, we can just change MCHandlerList to be a hash-table, rather than a binary-searched array
hashandler ?
In terms of MCNameRefs and property strings, for now you can just construct a name on the fly as needed using MCAutoNameRef... It would be good to have all the syntax related strings as NameRefs rather than const char * though - so this might be a good separate project.
Do you mean createwithcstring? ... I thought there might be a reverse lextable lookup hidden somewhere... I guess if there were then property names wouldn't be duplicated in props.cpp...

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 9:28 am
by LCMark
Oh my only objection to making setProp/getProp work with engine properties was the one which I inherited - i.e. performance.
hashandler ?
Ah - I was looking at MCHandlerArray... Probably better just to use MCHandlerlist::findhandler() directly to check - otherwise you'll do a lookup twice.
Do you mean createwithcstring? ... I thought there might be a reverse lextable lookup hidden somewhere... I guess if there were then property names wouldn't be duplicated in props.cpp...
Yes - you can use MCAutoNameRef and then 'CreateWithCString' to create the name from a c-string.

There isn't a reverse lookup for lextable - the lextable contains all the synonyms too so this makes things a little tricky - its a many-to-one mapping in many cases. Not quite sure how to handle this. I guess one option would be to make setprop/getprop handlers lookup the property index at parse time, and then use that as the sort key in MCHandlerArray. This would solve the synonym issue (synonyms would be resolved at parse-time) as well as saving lookups later on since MCObject::*prop() and friends take a Properties index in the case of engine properties.

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 9:34 am
by LCMark
By the way, 'there may be (small) dragons here'... In numerous places the engine uses getprop() / setprop() internally to set / get object properties - some of these places might not be expecting the potential for script to be executed so this might require a bit of a review if this feature gets working [ just a heads-up ].

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 10:07 am
by monte
Hmm... do you mean add a Properties index to MCHandler and a lookup handler for Properties index to MCHandlerArray? That sounds like a good way to go... if nil then there's no handler for it....

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 10:23 am
by LCMark
Yes - essentially - although a little care will be needed since the handlerarray sorts only by name at the moment. However, what you could do is make it so that engine-prop handlers (which have a property index, rather than a name) are sorted after those which are named in the list. The comparison rule would then be something like:

Code: Select all

  handler_a < handler_b iff (handler_a is custom && handler_b is engine) ||
    (handler_a is custom && handler_b is custom && handler_a.name < handler_b.name) ||
    (handler_a is engine && handler_b is engine && handler_a.prop < handler_b.prop)
Since the two sets of handlers will never intersect (you can't create a 'custom' prop handler with an engine property name at the moment) all should work quite well with minimal changes elsewhere.

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 10:45 am
by monte
Hmm... so handler.name would be nil if it's an engine property?

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 10:57 am
by LCMark
You should probably populate it with the name that was actually parsed since this is used in various places (debug contexts, revAvailableHandlers etc.) - I'm not sure those places would like finding a nil name ;)

There's P_UNDEFINED and P_CUSTOM in Properties - the former could be used to indicate the handler has nothing to do with getprop/setprop; and the latter to indicate its a 'custom' property rather than an engine property.

(Handlers already have a 'prop' Boolean which indicates they are custom props, this could be expanded to be a Properties index instead)

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 11:31 am
by monte
ok... sounds like a plan forming here...

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 5:32 pm
by mwieder
I like the way this is going. I'm still concerned about the performance hit, but I definitely like the way this is going.

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 6:01 pm
by mwieder
It also seems appropriate to this discussion to make sure that the following is also taken into account:

I've got a dial/knob/rotating thing controller (it's a group of graphics and other things) that for most purposes is a circular scrollbar - rotating the dial is like moving the slider in a scrollbar, etc. But I can't say something like

Code: Select all

set the thumbposition of control "dial1"
because "thumbposition" is a property that is restricted to scrollbars.

So I haven't looked at what the engine code is doing to validate the property association (because I'm basically lazy), but what I'd like to see is: at the point where an error is about to be thrown, check to see if there's a property override in place somewhere along the message path and use that, otherwise go ahead and throw the error. There shouldn't be a performance hit because the alternative is the current one of throwing the error and quitting.

Re: behavior object properties set prop/get prop

Posted: Fri Apr 19, 2013 8:42 pm
by monte
Nice idea mwieder... So we could end up creating custom controls that had the same properties as engine ones... cool.