DynamicObject's getProperty not being called in JavaScript engine


Hi Jules,
I have some issues with the DynamicObject class in JavaScript.
I'm trying to bridge my own Param system to Javascript using DynamicObjects. What i would like to do is forward calls on invoked DynamicObjects  to my params object. See code at the end of the post.

This works fine when setting properties, so that when a user types in Params.scale = 10; It will call setProperty and i'll forward it to param->setValue, and call the base method as well.

This does not work when reading properties. So i can't do this var scale = Params.scale;  In the JavaScript engine getProperty won't be called because it uses getProperties, which just directly access the NameValueSet. 

if (var* prop = o->getProperties().getVarPointer (functionName))

                    return *prop;

 

So my question is, why isn't getProperty being called instead of getProperties().getVarPointer()?
If you would call getProperty it would allow us to have much more flexibility.

 

​
class JSParams : public DynamicObject
{
private:

ra::ParamContainer::Ptr params;

public:

    JSParams(ra::ParamContainer::Ptr params_)

        : params(params_)

    {

    }
    
    static Indentifier getClassName()
    {
       static const Identifier i("Params");
       return i;
    }

    bool hasProperty (const Identifier& propertyName) const
    {
        return params->getParam(propertyName.toString()) != nullptr;
    }

    var getProperty (const Identifier& propertyName) const
    {
         //this never get's called!
        ra::ParamBase::Ptr param = params->getParam(propertyName.toString());
        return param->getValue();

    }

    void setProperty (const Identifier& propertyName, const var& newValue)
    {
        //this get's called
        ra::ParamBase::Ptr param = params->getParam(propertyName.toString());
        param->setValue(newValue);
        DynamicObject::setProperty(propertyName, newValue);
    }

};

It's done like that because it needs to very quickly find out whether a property exists or not, and if it does, to get its value.

When I wrote it, I obviously wasn't thinking about custom objects that might have overrides, I was just writing the most efficient code that I could, because this is a method that needs to be fast to get decent performance.

I just began a bit of refactoring, thinking that if DynamicObject::getProperty returned a var* instead of a var, then that might do the trick, but to do that opens a can of worms that I don't have time to get dragged into right now. I think the whole set of get/set methods for DynamicObject probably needs a re-think as the class is being used in some new ways that weren't planned-for when I first created it.

Allright, in the mean time i've found a workaround for own usecase.

A possible solution could be to create a getPropertyWithDefault(const Identifier& name, var default = var::null); method like you did with the NamedValueSet::getWithDefault

It will check internally and return the right value when it's there, otherwise it'll return var::null; So the default implementation can still be very fast.

I'll see what you can come up with in the end