-
-
Notifications
You must be signed in to change notification settings - Fork 21
GH-930 Msg placeholders & Async placeholder for future #1203
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
base: master
Are you sure you want to change the base?
Changes from all commits
b3764bd
af593f1
1f98392
cf7151e
1407a28
a8c6659
2633ef6
dc6f963
aa360dd
a128154
6e7e842
81b610e
450a2d7
9f0d5eb
3e5a511
082e063
229af5e
7b5eee0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| package com.eternalcode.core.feature.msg; | ||
|
|
||
| import com.eternalcode.core.feature.msg.toggle.MsgState; | ||
| import com.eternalcode.core.feature.msg.toggle.MsgToggleRepository; | ||
| import com.eternalcode.core.injector.annotations.Inject; | ||
| import com.eternalcode.core.injector.annotations.component.Controller; | ||
| import com.eternalcode.core.placeholder.PlaceholderRegistry; | ||
| import com.eternalcode.core.placeholder.Placeholder; | ||
| import com.eternalcode.core.placeholder.watcher.PlaceholderWatcherKey; | ||
| import com.eternalcode.core.publish.Subscribe; | ||
| import com.eternalcode.core.publish.event.EternalInitializeEvent; | ||
| import com.eternalcode.core.translation.Translation; | ||
| import com.eternalcode.core.translation.TranslationManager; | ||
| import java.util.UUID; | ||
|
|
||
| @Controller | ||
| public class MsgPlaceholderSetup { | ||
|
|
||
| public static final PlaceholderWatcherKey<MsgState> MSG_STATE = PlaceholderWatcherKey.of("msg_state", MsgState.class); | ||
|
|
||
| private final MsgService msgService; | ||
| private final MsgToggleRepository msgToggleRepository; | ||
| private final TranslationManager translationManager; | ||
|
|
||
| @Inject | ||
| MsgPlaceholderSetup( | ||
| MsgService msgService, | ||
| MsgToggleRepository msgToggleRepository, | ||
| TranslationManager translationManager | ||
| ) { | ||
| this.msgService = msgService; | ||
| this.msgToggleRepository = msgToggleRepository; | ||
| this.translationManager = translationManager; | ||
| } | ||
|
|
||
| @Subscribe(EternalInitializeEvent.class) | ||
| void setUpPlaceholders(PlaceholderRegistry registry) { | ||
| Translation translation = this.translationManager.getMessages(); | ||
|
|
||
| registry.register(Placeholder.ofBoolean( | ||
| "socialspy_status", | ||
| player -> this.msgService.isSpy(player.getUniqueId()) | ||
| )); | ||
|
|
||
| registry.register(Placeholder.of( | ||
| "socialspy_status_formatted", | ||
| player -> { | ||
| UUID uuid = player.getUniqueId(); | ||
| return this.msgService.isSpy(uuid) | ||
| ? translation.msg().placeholders().socialSpyEnabled() | ||
| : translation.msg().placeholders().socialSpyDisabled(); | ||
| } | ||
| )); | ||
|
|
||
| registry.register(Placeholder.async( | ||
| "msg_status", | ||
| MSG_STATE, | ||
| player -> msgToggleRepository.getPrivateChatState(player), | ||
| state -> state.name().toLowerCase() | ||
| )); | ||
|
|
||
| registry.register(Placeholder.async( | ||
| "msg_status_formatted", | ||
| MSG_STATE, | ||
| player -> msgToggleRepository.getPrivateChatState(player), | ||
| state -> state == MsgState.ENABLED | ||
| ? translation.msg().placeholders().msgEnabled() | ||
| : translation.msg().placeholders().msgDisabled() | ||
| ) | ||
| ); | ||
|
Comment on lines
+55
to
+70
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are registering two asynchronous placeholders, To fix this, the data loading logic should be shared. A possible solution is to adjust the async placeholder API to allow sharing a data source or cache for a given The best approach is to fix the root cause in the async placeholder design to avoid redundant data fetching for related placeholders. |
||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -38,4 +38,22 @@ public class ENMsgMessages extends OkaeriConfig implements MsgMessages { | |||||
| Notice socialSpyEnable = Notice.chat("<color:#9d6eef>► <white>SocialSpy has been {STATE}<white>!"); | ||||||
| Notice socialSpyDisable = Notice.chat("<red>► <white>SocialSpy has been {STATE}<white>!"); | ||||||
|
|
||||||
| @Comment("# Formatowanie placeholderów") | ||||||
P1otrulla marked this conversation as resolved.
Show resolved
Hide resolved
CitralFlo marked this conversation as resolved.
Show resolved
Hide resolved
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is EN translation, so we use English comments
Suggested change
|
||||||
| public ENPlaceholders placeholders = new ENPlaceholders(); | ||||||
|
|
||||||
| @Getter | ||||||
| @Accessors(fluent = true) | ||||||
| public static class ENPlaceholders extends OkaeriConfig implements MsgMessages.Placeholders { | ||||||
CitralFlo marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
| private String loading = "<yellow>Loading..."; | ||||||
|
|
||||||
| private String msgEnabled = "<green>Enabled"; | ||||||
| private String msgDisabled = "<red>Disabled"; | ||||||
| private String socialSpyEnabled = "<green>Enabled"; | ||||||
| private String socialSpyDisabled = "<red>Disabled"; | ||||||
| } | ||||||
|
|
||||||
| public ENPlaceholders placeholders() { | ||||||
| return this.placeholders; | ||||||
| } | ||||||
|
|
||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,51 +1,43 @@ | ||
| package com.eternalcode.core.feature.msg.toggle; | ||
|
|
||
| import com.eternalcode.core.feature.msg.MsgPlaceholderSetup; | ||
| import com.eternalcode.core.injector.annotations.Inject; | ||
| import com.eternalcode.core.injector.annotations.component.Service; | ||
| import com.eternalcode.core.placeholder.PlaceholderRegistry; | ||
| import com.eternalcode.core.placeholder.watcher.PlaceholderWatcher; | ||
| import java.util.UUID; | ||
| import java.util.concurrent.CompletableFuture; | ||
| import java.util.concurrent.ConcurrentHashMap; | ||
|
|
||
| @Service | ||
| class MsgToggleServiceImpl implements MsgToggleService { | ||
Rollczi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| private final MsgToggleRepository msgToggleRepository; | ||
| private final ConcurrentHashMap<UUID, MsgState> cachedToggleStates; | ||
| private final PlaceholderWatcher<MsgState> watcher; | ||
|
|
||
| @Inject | ||
| MsgToggleServiceImpl(MsgToggleRepository msgToggleRepository) { | ||
| this.cachedToggleStates = new ConcurrentHashMap<>(); | ||
| MsgToggleServiceImpl(MsgToggleRepository msgToggleRepository, PlaceholderRegistry registry) { | ||
| this.msgToggleRepository = msgToggleRepository; | ||
|
|
||
| this.watcher = registry.createWatcher(MsgPlaceholderSetup.MSG_STATE); | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| public CompletableFuture<MsgState> getState(UUID playerUniqueId) { | ||
| if (this.cachedToggleStates.containsKey(playerUniqueId)) { | ||
| return CompletableFuture.completedFuture(this.cachedToggleStates.get(playerUniqueId)); | ||
| } | ||
|
|
||
| return this.msgToggleRepository.getPrivateChatState(playerUniqueId); | ||
| public CompletableFuture<MsgState> getState(UUID player) { | ||
| return watcher.track(player, msgToggleRepository.getPrivateChatState(player)); | ||
| } | ||
|
|
||
| @Override | ||
| public CompletableFuture<Void> setState(UUID playerUniqueId, MsgState state) { | ||
| this.cachedToggleStates.put(playerUniqueId, state); | ||
|
|
||
| return this.msgToggleRepository.setPrivateChatState(playerUniqueId, state) | ||
| .exceptionally(throwable -> { | ||
| this.cachedToggleStates.remove(playerUniqueId); | ||
| return null; | ||
| }); | ||
| public CompletableFuture<Void> setState(UUID player, MsgState state) { | ||
| return watcher.track(player, msgToggleRepository.setPrivateChatState(player, state)) | ||
| .thenApply(unused -> null); | ||
| } | ||
|
Comment on lines
23
to
32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The previous implementation of this service used a The new |
||
|
|
||
| @Override | ||
| public CompletableFuture<MsgState> toggleState(UUID playerUniqueId) { | ||
| return this.getState(playerUniqueId).thenCompose(state -> { | ||
| MsgState newState = state.invert(); | ||
| return this.setState(playerUniqueId, newState) | ||
| .thenApply(aVoid -> newState); | ||
| .thenApply(unused -> newState); | ||
| }); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package com.eternalcode.core.placeholder; | ||
|
|
||
| import org.bukkit.entity.Player; | ||
|
|
||
| public interface NamedPlaceholder extends Placeholder { | ||
|
|
||
| @Override | ||
| default String apply(String text, Player targetPlayer) { | ||
| return text.replace("{" + this.getName() + "}", this.provideValue(targetPlayer)); | ||
| } | ||
|
|
||
| String getName(); | ||
|
|
||
| String provideValue(Player targetPlayer); | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,8 @@ | ||
| package com.eternalcode.core.placeholder; | ||
|
|
||
| import com.eternalcode.core.placeholder.watcher.PlaceholderWatcherKey; | ||
| import java.util.UUID; | ||
| import java.util.concurrent.CompletableFuture; | ||
| import org.bukkit.entity.Player; | ||
|
|
||
| import java.util.function.Function; | ||
|
|
@@ -9,27 +12,36 @@ public interface Placeholder { | |
| String apply(String text, Player targetPlayer); | ||
|
|
||
| static Placeholder of(String target, String replacement) { | ||
| return new PlaceholderRaw(target, player -> replacement); | ||
| return new StaticValuePlaceholder(target, player -> replacement); | ||
| } | ||
|
|
||
| static Placeholder of(String target, Function<Player, String> replacement) { | ||
| return new PlaceholderRaw(target, replacement); | ||
| return new StaticValuePlaceholder(target, replacement); | ||
| } | ||
|
|
||
| static Placeholder ofInt(String target, Function<Player, Integer> replacement) { | ||
| return new PlaceholderRaw(target, player -> String.valueOf(replacement.apply(player))); | ||
| return new StaticValuePlaceholder(target, player -> String.valueOf(replacement.apply(player))); | ||
| } | ||
|
|
||
| static Placeholder ofBoolean(String target, Function<Player, Boolean> replacement) { | ||
| return new PlaceholderRaw(target, player -> String.valueOf(replacement.apply(player))); | ||
| return new StaticValuePlaceholder(target, player -> String.valueOf(replacement.apply(player))); | ||
| } | ||
|
|
||
| static Placeholder ofLong(String target, Function<Player, Long> replacement) { | ||
| return new PlaceholderRaw(target, player -> String.valueOf(replacement.apply(player))); | ||
| return new StaticValuePlaceholder(target, player -> String.valueOf(replacement.apply(player))); | ||
| } | ||
|
|
||
| static Placeholder of(String target, Placeholder placeholder) { | ||
| return new PlaceholderRaw(target, player -> placeholder.apply(target, player)); | ||
| return new StaticValuePlaceholder(target, player -> placeholder.apply(target, player)); | ||
| } | ||
|
|
||
| static <T> Placeholder async( | ||
| String target, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would rename target to sth like "placeholderName" |
||
| PlaceholderWatcherKey<T> key, | ||
| Function<UUID, CompletableFuture<T>> loading, | ||
| Function<T, String> mapper | ||
| ) { | ||
| return new PlaceholderAsync<>(target, key, loading, mapper); | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to
PlaceholderApiPlaceholder, or rename other domain classes to have PlaceholderAPI instead of the Api