realXtend / tundra

realXtend Tundra SDK, a 3D virtual world application platform.
www.realxtend.org
Apache License 2.0
84 stars 70 forks source link

Entity.RemoveComponent(typeName, changeType) - ambiguous call of overloaded function #760

Open Jarno-Poikonen opened 10 years ago

Jarno-Poikonen commented 10 years ago

Only the component id overload works correctly. Passing in componen typename string with or without the component name is ambiguous. Same thing for the ComponentPtr overload, it seems to be confusing comp ptrs with strings. Possibly beacause IComponent.toString() is defined (eg. you can do print(ent.mesh);)

P.S. I am using the Meshmoon Rocket distro. Still needs to be verified if broken in the realXtend repo.

Stinkfist0 commented 10 years ago

Hmm, f.ex entity.RemoveComponent("Mesh") seems to work just fine for me using admino tundra HEAD. Also IComponent has no toString() function (like f.ex. Entity has) per se, but entity.mesh.toString() should use some QtScript's default QObject.toString() implementatioin.

entity.RemoveComponent(entity.mesh) will however produce the following, but that's ok as the syntax should be avoided in general:

Error: In run/evaluate: TypeError: ambiguous call of overloaded function RemoveComponent(); candidates were
    RemoveComponent(ComponentPtr)
    RemoveComponent(QString)

This can be worked around by using the usual (awkward) QtScript overload syntax: entity["RemoveComponent(ComponentPtr)"](entity.mesh)

jonnenauha commented 10 years ago

The toString() is added somewhere, you can afaik do print(ent.mesh); and its just works. So its there. Possibly in the QtScript expose code.

I think we should fix entity.RemoveComponent(ent.mesh). It should be safe to use as long as you dont use ent.mesh after the fact.

Jarno-Poikonen commented 10 years ago
            // Creating a component for removal demostration
    function CreateDemoComponent()
    {
        var component = me.CreateComponent("Mesh", "cone", AttributeChange.Replicate, true);            
        return component;
    } 

    // Removal by component pointer
    var component = CreateDemoComponent();
    me.RemoveComponent(component);

    // Removal by type name
    component = CreateDemoComponent();
    me.RemoveComponent("Mesh", AttributeChange.Replicate);

    // Removal by type name and component name
    component = CreateDemoComponent();
    me.RemoveComponent("Mesh", "cone", AttributeChange.Replicate);      

    // Removal by component id
    component = CreateDemoComponent();
    me.RemoveComponentById(component.id, AttributeChange.Replicate);

    // Removal of all components        
    component = CreateDemoComponent();      
    me.RemoveAllComponents(AttributeChange.Replicate);
Stinkfist0 commented 10 years ago

In your example the first RemoveComponent will fail due to the overload issue already mentioned. Commenting that out, the second one will fail:

Error: In run/evaluate: TypeError: ambiguous call of overloaded function RemoveComponent(); candidates were
    RemoveComponent(QString,AttributeChange::Type)
    RemoveComponent(QString,QString)
    RemoveComponent(QString)
    RemoveComponent(ComponentPtr)
    RemoveComponent(ComponentPtr,AttributeChange::Type)

This would have been very useful information when submitting the original issue and would have helped to get to the bottom of this right away. I've edited the title to reflect the issue better.

To work around your issue for now use either of the following:

me.RemoveComponent("Mesh");
// or
me.RemoveComponent("Mesh", "", AttributeChange.Replicate);

Also note that me.RemoveAllComponents(); is not a smart move to be made from Script component of the me entity. ;)

jonnenauha commented 10 years ago

@Stinkfist0 Did you find out why this happens?