Skip to content
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

@ccclass won't take effect if there're another class decorators returning new classes #14959

Open
shrinktofit opened this issue May 4, 2023 · 2 comments

Comments

@shrinktofit
Copy link
Contributor

shrinktofit commented May 4, 2023

Testcase files stub:

Testcase.zip

@shrinktofit
Copy link
Contributor Author

shrinktofit commented May 4, 2023

Should be solved be #14961 . Here's my feedback stub to issue emitter:


Updated Reply

Now #14961 gets updated. We turn to provide the original "transferring" functionality in form of a wrapping decorator instead:

@ccclass('CardGameMode')
@ccclass.forward(hasCGEvents()) // Forward the decorator execution to `hasCGEvents()` as if there's `@hasCGEvents()`, but with bug solved
export class CardGameMode extends GameMode {

Now you don't have to manually call _decorator.transferCCClass.


First Reply

Hi.

We have looked through your code and had some conclusions:

  1. Your provided decorator @hasCGEvent() does substitute the original decorating class with a brand new class.

    Cocos Creator currently does not handle this case. Since properties are executed before class decorators, Cocos Creator will temporally stash the properties decorating by @property into "class", which is the class you will in later substitute. This make all @property loose their effects.

    To strike this, Creator in this PR provides a method, [DON'T MERGE] Add _decorator.ccclass.forward() helper decorator to allow transfer cc-class information #14961 , You can call it after you substitute the class, that's, change here:

      newConstructorFunction.prototype = constructorFunction.prototype;
    ++ _decorator.transferCCClass(constructorFunction, newConstructorFunction);
      return newConstructorFunction;

    You should do it in another form. See update above.

  2. Even you applied the change suggested above, you may noticed that you still can not get the properties to be serialized or shown in editor. That's a story related to how Creator find the constructor of an object: it simply take the .constructor of that object.

    However, objects created from new CardGameMode() never have .constructor === CardGameMode. Their .constructor would point to the func you wrapped. You can try to verify it.

    So, we're here suggest you that make the following change:

      if (result.__eventList) {
        // ...
    
    ++  result.constructor = newConstructorFunction;
    
        return result;
      }
    
    return result;

@mikecoker
Copy link
Contributor

mikecoker commented Jun 15, 2023

This looks like a good solution. I'm assuming that I will still need to set the constructor function as stated in 2 of the first reply, but can now use the additional decorator instead of calling the transferCCClass method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants