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

[Feature] Custom message types in Locale/Translator #78

Closed
wants to merge 1 commit into from

Conversation

bivashy
Copy link
Contributor

@bivashy bivashy commented Nov 23, 2023

Pull Request Etiquette

  • I have checked the PRs for upcoming features/bug fixes.

Changes

  • Internal code
  • API (affecting end-user code)
  • Other: _

Closes Issue: #75

Description

This pull request makes possible to create custom locale reader types that can send adventure component, discord embed messages, and etc.

Breaking changes:

I believe that this Pull Request doesn't have any breaking changes. Please let me know if you have found one.

How to use:

Simply implement DynamicLocaleReader instead of LocaleReader, and register using Translator#add. childrenList
Example:
ComponentLocaleReader:

public final class ComponentLocaleReader implements DynamicLocaleReader<Component> {

    private static final String ANSI_RED = "\u001B[31m";
    private static final String ANSI_GREEN = "\u001B[32m";
    private final Map<String, Component> components;

    public ComponentLocaleReader(Map<String, Component> components) {
        this.components = components;
    }

    @Override
    public boolean containsKey(String s) {
        return components.containsKey(s);
    }

    @Override
    public Component get(String s) {
        return components.get(s);
    }

    @Override
    public Locale getLocale() {
        return Locale.ENGLISH;
    }

    @Override
    public void reply(CommandActor actor, Component message) {
        // We could cast CommandActor instead, but this is only for example.
        actor.reply(ANSI_GREEN + message.raw());
    }

    @Override
    public void error(CommandActor actor, Component message) {
        // We could cast CommandActor instead, but this is only for example.
        actor.error(ANSI_RED + message.raw());
    }

    @Override
    public Component format(Component component, Object... objects) {
        for (int i = 0; i < objects.length; i += 2)
            component.replace(objects[i].toString(), objects[i + 1].toString());
        return component;
    }

}

Component:

public final class Component {

    private String component;

    public Component(String component) {
        this.component = component;
    }

    public void replace(String pattern, String replacement) {
        component = component.replace(pattern, replacement);
    }

    public String raw() {
        return component;
    }

}

Current state

Currently this Pull Request was tested using ConsoleCommandHandler.

@bivashy bivashy marked this pull request as ready for review November 27, 2023 10:15
@bivashy
Copy link
Contributor Author

bivashy commented Jan 17, 2024

Hello there!
Any update on this?
If you have reviewed this PR, make sure that your comments doesn't have PENDING state (I cannot see them) (Related link)

@Revxrsal
Copy link
Owner

Revxrsal commented Jan 19, 2024

I apologize for not replying earlier. I've seen this, however, I haven't settled on a satisfying design yet. I'm looking for something that ticks these boxes:

  • Backwards-compatibility, such that it plays nicely with the current system. If this is impossible, at least it can work side-by-side until the older one is removed.
  • Type-safety, so attempting to send an unsupported object would show a compile-time error. I'm not sure if that's possible, but it's what I'm aiming for.
  • Intuitiveness, it should be very easy for developers to work with that API. It should avoid doing more magic than the underlying gluing logic, and anyone looking at the code should be able to tell clearly what it does, without having to run it.
  • Efficient, it should avoid creating so many unnecessary wrappers and delegating function calls (although we could go easy on that point).

I'm still considering multiple designs, the most prominent one I have is some sort of Serializers. If you've ever used kotlinx.serialization, it's pretty much the design I'm thinking of, as it ticks all the boxes above. There's still some experimentation and adaptation needed with the idea to ensure the developer experience goes smooth.

I might do a follow-up comment with sample code that shows the concept. If I forget, please shamelessly ping me on Discord. I'm perfectly okay with that 😛

@Revxrsal
Copy link
Owner

This has been addressed in Lamp v4. Thanks for the help.

@Revxrsal Revxrsal closed this Aug 16, 2024
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 this pull request may close these issues.

2 participants