WonderlandEngine / api

Wonderland Engine's JavaScript API.
MIT License
10 stars 6 forks source link

Add a way to skip init and start when adding a component #3

Open signorpipo opened 1 year ago

signorpipo commented 1 year ago

When I want to clone a component, and with this I don't mean just creating the same component with the same starting variables, but a clone of the current state, with possibly deep cloning and more elaborate clone decisions, I may want to skip init and start.

This is not different from the copy constructor of C++, which does not execute the normal constructor because with a copy u may prefer to do some other things. This means that in this case it should not be needed to call init and start if u don't want to and can instead be harmful and u may have to do more work in order to deinitialize stuff that is done in the init and start method.

It would be interesting to have a clone method on the component itself in the official API, but I think it would still be interesting to have the chance to add a component without init and start to allow for custom features to be made, should not hurt if u are doing it on purpose.

DavidPeicho commented 1 year ago

I think the idea would be:

class Component {
    copy(params?: Component) {
        if (params !== undefined) {
            const ctor = component.constructor as ComponentConstructor;
            for (const key in params) {
                if (!(key in ctor.Properties)) continue;
                (component as Record<string, any>)[key] = params[key];
            }
        }
        return this;
    }
}

And then people can override that in their components:

class Component {
    copy(params?: Component) {
        // I don't do anything because I am evil!
        return this;
    }
}
signorpipo commented 1 year ago

Would copy be a static method? Maybe the reverse can be done, a clone method where u specify the object on which to add the component?

Edit: For example

class Component { clone(targetObject) { return targetObject.addComponent(this.type, this); } }