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

Implement backed (and deferred) config leaves to pick up on POJO mutations #82

Merged
merged 9 commits into from
Jan 24, 2021

Conversation

zeroeightysix
Copy link
Member

@zeroeightysix zeroeightysix commented Jul 6, 2020

Closes #16

I apologise in advance for the atrocious design choices in this PR.

The annotation system currently nicely wraps around only the builder API: it uses no fiber internals. I wanted to maintain this while also being able to introduce an extra check in getValue (checking the corresponding field's value).

One way of achieving this would be to just introduce more methods to the builder to allow this kind of customisation (e.g. a method to change the type of leaf being built, so people can allow the builder to produce something else than a ConfigLeafImpl). This kind of approach seems rather hacky and would reduce the amount of guarantees fiber has when it comes to what type of nodes we're dealing with.

The approach I chose is to not modify API, but instead:

  • Build a leaf the way we did before
  • Remove it from its parent after building
  • Add a new leaf that defers to the built leaf, but is also backed by the field we're currently building a leaf for. This way we can introduce that extra bit of getValue code we needed earlier.

This also means we can:

  • Remove the hacky listeners AnnotatedSettingsImpl adds, and implement them in BackedConfigLeaf instead.

…g from POJO

Also removed an outdated comment in ConfigLeafBuilder: the backing collection should always be a NodeCollection, which we assume to be safe.
@zeroeightysix zeroeightysix added bug Something isn't working annotations Relates to the annotation system labels Jul 6, 2020
@zeroeightysix zeroeightysix added this to the 0.24.0 milestone Jul 6, 2020
@zeroeightysix zeroeightysix requested review from kvverti and Pyrofab July 6, 2020 14:43
@zeroeightysix zeroeightysix marked this pull request as ready for review July 6, 2020 15:30
Copy link
Member

@Pyrofab Pyrofab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool stuff, just needs a bit of polish.

Comment on lines +69 to +103
@Nullable
@Override
public ConfigBranch getParent() {
return parent;
}

@Override
public void attachTo(ConfigBranch parent) throws IllegalTreeStateException {
// Attaching/detaching requires careful inspection of whether or not the parent's items contains `this`.
// In the case of deferred leaves, the leaf in the parent's items is the deferred leaf and not the backing leaf.
// Thus, we can't defer attaching/detaching to the backing leaf, as it will think it's not part of the parent's items.
if (this.parent != null && this.parent != parent) {
throw new IllegalTreeStateException(this + " needs to be detached before changing the parent");
}

// this node may have already been added by the collection
if (parent != null && !parent.getItems().contains(this)) {
parent.getItems().add(this);
}

this.parent = parent;
}

@Override
public void detach() {
// Note: infinite recursion between ConfigNode#detach() and NodeCollection#remove() could occur here,
// but the latter performs the actual collection removal before detaching
if (this.parent != null) {
// here, we also need to avoid triggering a ConcurrentModificationException
// thankfully, remove does not cause a CME if it's a no-op
this.parent.getItems().remove(this);
}

this.parent = null;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't we delegate those methods to the backing node and thus avoid duplicating the logic ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No: attachTo and detach will add / remove this from the parent. We want the backed node to be added to the collection, and not the backing node.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then we should use inheritance to avoid duplicating the code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.parent does not refer to the same field in both contexts, and we can't use #getParent (because we also need the nonexistant #setParent).

The duplication of code here is ugly, I agree, but I don't think we can use inheritance here. It wouldn't really fit into the delegation pattern BackedConfigLeaf follows anyways.

@zeroeightysix zeroeightysix requested a review from Pyrofab July 26, 2020 09:35
@zeroeightysix zeroeightysix merged commit 041bfa5 into 0.24.0 Jan 24, 2021
@zeroeightysix zeroeightysix mentioned this pull request Jan 24, 2021
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
annotations Relates to the annotation system bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants