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

Destroying an inherited object causes a bit of havoc #84

Closed
Omikhleia opened this issue Aug 13, 2016 · 0 comments · Fixed by #88
Closed

Destroying an inherited object causes a bit of havoc #84

Omikhleia opened this issue Aug 13, 2016 · 0 comments · Fixed by #88

Comments

@Omikhleia
Copy link
Collaborator

Let's do this:

item.new('stuff');
stuff.new('stuff2')
...
stuff.destroy();
stuff2

And we get:

TypeError: Cannot read property 'traitIds' of undefined
    at linearize (...src/lib/world-object-proxy-builder.js:5:9)
    at target.traitIds.forEach.traitId (...src/lib/world-object-proxy-builder.js:8:5)
    at Array.forEach (native)
    at linearize (...src/lib/world-object-proxy-builder.js:5:19)
    at Handler.get (...src/lib/world-object-proxy-builder.js:65:21)
    at output (...src/lib/print.js:47:39)
    at print (...src/lib/print.js:105:5)
    at printHelper (...src/lib/print.js:110:10)
    at ProgrammerController.onEval (...src/controllers/programmer-controller.js:23:27)
    at PlayerController.onInput (...src/controllers/player-controller.js:24:40)

That's kind of an embarrassment, as even all() breaks with the same error afterwards. One workaround is to manually reset the traits of the all offending children nodes (e.g. stuff2.traits = []), but you might not know/remember which it/them (e.g. the parent's destruction might even have been done by somebody else).

I experimented with the following graceful handling for this degraded case:

  • In world-object-proxy-builder.js:
function linearize(target, db, linearization = new C3(target)) {
  target.traitIds.forEach((traitId, index) => {
    const trait = db.findById(traitId);
    if (trait !== undefined) {
        linearization.add(target, trait);
        linearize(trait, db, linearization);
    } else {
        // Attempt at gracefully handle broken trait chain
        target.traitIds.splice(index, 1);
    }
  });
  return linearization.run();
}
  • And similarly in world-object-class-builder.js;
function linearize(object, linearization = new C3(object)) {
  object.traits.forEach((trait, index) => {
    if (trait !== undefined) {
        linearization.add(object, trait);
        linearize(trait, linearization);
    } else {
        // Attempt at gracefully handle broken trait chain
        object.traits.splice(index, 1);
    }
  });
  return linearization.run();
}

Seems to work on my local copy, unless I've missed any edge case... Would that be an appropriate fix/workaround, or is there a better way to handle this case ?

(For the record, another idea for a brief moment was to check all objects for possible dependency and reject the .destroy() call in that case, but don't think it's performance-wise.)

Omikhleia added a commit to Omikhleia/room.js that referenced this issue Aug 16, 2016
Omikhleia added a commit to Omikhleia/room.js that referenced this issue Sep 4, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant