Skip to content

Commit

Permalink
feat(api): virtual components
Browse files Browse the repository at this point in the history
  • Loading branch information
kashike committed Dec 1, 2022
1 parent 0f69b0c commit 259561c
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 5 deletions.
19 changes: 19 additions & 0 deletions api/src/main/java/net/kyori/adventure/text/Component.java
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,25 @@ public interface Component extends ComponentBuilderApplicable, ComponentLike, Ex
return text(String.valueOf(value), color, decorations);
}

/*
* --------------------------
* ---- VirtualComponent ----
* --------------------------
*/

/**
* Creates a virtual component with a value.
*
* @param virtual the value
* @return a virtual component
* @since 4.13.0
*/
@Contract(value = "_ -> new", pure = true)
static @NotNull VirtualComponent virtual(final @NotNull VirtualComponentHolder<?> virtual) {
requireNonNull(virtual, "virtual");
return VirtualComponentImpl.createVirtual(virtual);
}

/*
* -------------------------------
* ---- TranslatableComponent ----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

import static java.util.Objects.requireNonNull;

final class TextComponentImpl extends AbstractComponent implements TextComponent {
class TextComponentImpl extends AbstractComponent implements TextComponent {
private static final boolean WARN_WHEN_LEGACY_FORMATTING_DETECTED = Boolean.TRUE.equals(AdventureProperties.TEXT_WARN_WHEN_LEGACY_FORMATTING_DETECTED.value());
@VisibleForTesting
static final char SECTION_CHAR = '§';
Expand All @@ -56,6 +56,10 @@ static TextComponent create(final @NotNull List<? extends ComponentLike> childre
);
}

TextComponent create0(final @NotNull List<? extends ComponentLike> children, final @NotNull Style style, final @NotNull String content) {
return create(children, style, content);
}

private static @NotNull TextComponent createDirect(final @NotNull String content) {
return new TextComponentImpl(Collections.emptyList(), Style.empty(), content);
}
Expand Down Expand Up @@ -90,17 +94,17 @@ static TextComponent create(final @NotNull List<? extends ComponentLike> childre
@Override
public @NotNull TextComponent content(final @NotNull String content) {
if (Objects.equals(this.content, content)) return this;
return create(this.children, this.style, content);
return this.create0(this.children, this.style, content);
}

@Override
public @NotNull TextComponent children(final @NotNull List<? extends ComponentLike> children) {
return create(children, this.style, this.content);
return this.create0(children, this.style, this.content);
}

@Override
public @NotNull TextComponent style(final @NotNull Style style) {
return create(this.children, style, this.content);
return this.create0(this.children, style, this.content);
}

@Override
Expand Down
46 changes: 46 additions & 0 deletions api/src/main/java/net/kyori/adventure/text/VirtualComponent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2022 KyoriPowered
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.kyori.adventure.text;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

/**
* A virtual component.
*
* @since 4.13.0
*/
@ApiStatus.Experimental
public interface VirtualComponent extends TextComponent {
/**
* Gets the virtual value.
*
* <p>This property is transient, and not guaranteed to survive during any sort of transformations.</p>
*
* @return the virtual value
* @since 4.13.0
*/
@ApiStatus.Experimental
@NotNull VirtualComponentHolder<?> virtual();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2022 KyoriPowered
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.kyori.adventure.text;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.UnknownNullability;

/**
* A holder for a virtual component value.
*
* @param <V> the stored value type
* @since 4.13.0
*/
@ApiStatus.Experimental
public interface VirtualComponentHolder<V> {
/**
* Gets the stored value.
*
* @return the stored value
* @since 4.13.0
*/
@ApiStatus.Experimental
@UnknownNullability V unbox();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* This file is part of adventure, licensed under the MIT License.
*
* Copyright (c) 2017-2022 KyoriPowered
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package net.kyori.adventure.text;

import java.util.Collections;
import java.util.List;
import net.kyori.adventure.text.format.Style;
import org.jetbrains.annotations.NotNull;

final class VirtualComponentImpl extends TextComponentImpl implements VirtualComponent {
static VirtualComponent createVirtual(final @NotNull VirtualComponentHolder<?> virtual) {
return new VirtualComponentImpl(Collections.emptyList(), Style.empty(), "", virtual);
}

private final VirtualComponentHolder<?> virtual;

private VirtualComponentImpl(final @NotNull List<Component> children, final @NotNull Style style, final @NotNull String content, final @NotNull VirtualComponentHolder<?> virtual) {
super(children, style, content);
this.virtual = virtual;
}

@Override
VirtualComponent create0(final @NotNull List<? extends ComponentLike> children, final @NotNull Style style, final @NotNull String content) {
return new VirtualComponentImpl(ComponentLike.asComponents(children, IS_NOT_EMPTY), style, content, this.virtual);
}

@Override
public @NotNull VirtualComponentHolder<?> virtual() {
return this.virtual;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import net.kyori.adventure.text.StorageNBTComponent;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.text.VirtualComponent;
import org.jetbrains.annotations.NotNull;

/**
Expand All @@ -43,7 +44,10 @@
*/
public abstract class AbstractComponentRenderer<C> implements ComponentRenderer<C> {
@Override
public @NotNull Component render(final @NotNull Component component, final @NotNull C context) {
public @NotNull Component render(@NotNull Component component, final @NotNull C context) {
if (component instanceof VirtualComponent) {
component = this.renderVirtual((VirtualComponent) component, context);
}
if (component instanceof TextComponent) {
return this.renderText((TextComponent) component, context);
} else if (component instanceof TranslatableComponent) {
Expand Down Expand Up @@ -129,6 +133,17 @@ public abstract class AbstractComponentRenderer<C> implements ComponentRenderer<
*/
protected abstract @NotNull Component renderText(final @NotNull TextComponent component, final @NotNull C context);

/**
* Renders a virtual component.
*
* @param component the component
* @param context the context
* @return the rendered component
*/
protected @NotNull Component renderVirtual(final @NotNull VirtualComponent component, final @NotNull C context) {
return component;
}

/**
* Renders a translatable component.
*
Expand Down

0 comments on commit 259561c

Please sign in to comment.