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

Rework currencies #51

Merged
merged 1 commit into from
Dec 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
<artifactId>annotations</artifactId>
<version>${jetbrains.annotations.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
206 changes: 182 additions & 24 deletions api/src/main/java/me/lokka30/treasury/api/economy/currency/Currency.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,69 +12,227 @@

package me.lokka30.treasury.api.economy.currency;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Locale;
import java.util.Objects;
import java.util.UUID;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* @author lokka30, Geolykt
* @since v1.0.0
* One of Treasury's core features is multi-currency support.
* This allows economy providers and plugins to use different
* currencies for different transactions, e.g. a daily reward
* plugin can award players 'Tokens', but a job plugin
* can award players 'Dollars'. Facilitates great customisability.
*
* @author lokka30, Geolykt, MrIvanPlays
* @since v1.0.0
*/
@SuppressWarnings("unused")
public interface Currency {
public class Currency {

/**
* Creates a new currency with random {@link UUID} {@code currencyId} and a {@code startingBalance} handler of
* always returning 0.
*
* @param currencyChar a way to identify the currency via a character e.g. '$' for a dollar. can be null.
* @param roundedDigits to which digit shall we round balances. can specify -1 for no rounding.
* @param conversionCoefficient coefficient at which this currency is going to be converted to other currencies.
* @param balanceFormatter a function, giving a human-readable format of a balance.
* @param names acceptable names of the currency. primary name shall be the first specified.
* @return new currency instance
*/
@NotNull
public static Currency of(
@Nullable Character currencyChar,
int roundedDigits,
double conversionCoefficient,
@NotNull BiFunction<Double, Locale, String> balanceFormatter,
@NotNull String @NotNull... names
) {
return new Currency(
null,
currencyChar,
roundedDigits,
conversionCoefficient,
null,
balanceFormatter,
names
);
}

/**
* Creates a new currency.
*
* @param currencyId the currency id.
* @param currencyChar a way to identify the currency via a character e.g. '$' for a dollar. can be null.
* @param roundedDigits to which digit shall we round balances. can specify -1 for no rounding.
* @param conversionCoefficient coefficient at which this currency is going to be converted to other currencies.
* @param startingBalance a function, giving a starting balance for the inputted player uuid, which can be null.
* @param balanceFormatter a function, giving a human-readable format of a balance.
* @param names acceptable names of the currency. primary name shall be the first specified.
* @return new currency instance
*/
@NotNull
public static Currency of(
@NotNull UUID currencyId,
@Nullable Character currencyChar,
int roundedDigits,
double conversionCoefficient,
@Nullable Function<UUID, Double> startingBalance,
@NotNull BiFunction<Double, Locale, String> balanceFormatter,
@NotNull String @NotNull... names
) {
Objects.requireNonNull(currencyId, "currencyId");
Jikoo marked this conversation as resolved.
Show resolved Hide resolved
return new Currency(
currencyId,
currencyChar,
roundedDigits,
conversionCoefficient,
startingBalance,
balanceFormatter,
names
);
}

private final UUID currencyId;
private final Character currencyChar;
private final String[] names;
private final int roundedDigits;
private double conversionCoefficient;
private final Function<UUID, Double> startingBalance;
private final BiFunction<Double, Locale, String> balanceFormatter;

private Currency(@Nullable UUID currencyId,
@Nullable Character currencyChar,
int roundedDigits,
double conversionCoefficient,
@Nullable Function<UUID, Double> startingBalance,
@NotNull BiFunction<Double, Locale, String> balanceFormatter,
@NotNull String @NotNull... names
) {
if (names.length < 1) {
throw new IllegalArgumentException("Empty array specified for currency name.");
}
this.balanceFormatter = Objects.requireNonNull(balanceFormatter, "balanceFormatter");
this.names = Objects.requireNonNull(names, "names");
MrIvanPlays marked this conversation as resolved.
Show resolved Hide resolved
this.currencyId = currencyId == null ? UUID.randomUUID() : currencyId;
this.currencyChar = currencyChar;
this.roundedDigits = roundedDigits;
this.conversionCoefficient = conversionCoefficient;
this.startingBalance = startingBalance == null ? ($) -> 0d : startingBalance;
}

/**
* @author lokka30
* Gets the {@link UUID} of the currency.
*
* @return the UUID of the currency
* @author lokka30, MrIvanPlays
* @since v1.0.0
* Get the UUID of the currency.
* @return the UUID of the currency.
*/
@NotNull
UUID getCurrencyId();
public UUID getCurrencyId() {
return currencyId;
}

/**
* @author lokka30
* Gets the character which identifies this currency, which may be null.
*
* @return char identifier. could be null
* @author MrIvanPlays
* @since v1.0.0
*/
@Nullable
public Character getCurrencyCharacter() {
MrIvanPlays marked this conversation as resolved.
Show resolved Hide resolved
return currencyChar;
}

/**
* Get the primary name of the currency, e.g. 'dollar' or 'token'.
*
* @return the name of the currency
* @author lokka30, MrIvanPlays
* @since v1.0.0
* Get the name of the currency, e.g. 'dollars' or 'tokens'.
* @return the name of the currency.
*/
@NotNull
String getCurrencyName();
public String getPrimaryCurrencyName() {
return names[0];
}

/**
* @author lokka30
* Get the acceptable currency names. Used for parsing.
*
* @return acceptable currency names
* @author MrIvanPlays
* @since v1.0.0
*/
@NotNull
public String @NotNull [] getCurrencyNames() {
return names;
}

/**
* Some economy providers like to round balances' decimals.
* Economy providers that do not round any digits should specify `-1`.
*
* @return how many rounded digits the provider uses, or `-1` for none
* @author lokka30, MrIvanPlays
* @since v1.0.0
*/
int getRoundedDigits();
public int getRoundedDigits() {
return roundedDigits;
}

/**
* @author lokka30, Geolykt
* Get the conversion coefficient of this currency.
*
* @return conversion coefficient
* @author MrIvanPlays
* @since v1.0.0
*/
public double getConversionCoefficient() {
return conversionCoefficient;
}

/**
* Sets a new conversion coefficient of this currency.
*
* @param conversionCoefficient new conversion coefficient
* @author MrIvanPlays
* @since v1.0.0
*/
protected void setConversionCoefficient(double conversionCoefficient) {
this.conversionCoefficient = conversionCoefficient;
}

/**
* Get the starting balance of the currency.
* The player UUID is nullable, it should be specified if the starting balance
* concerns a PlayerAccount.
* @param playerUUID a UUID of the player account concerned. For global scenarios, specify `null`.
* The player {@link UUID} is nullable, it should be specified if the starting balance
* concerns a {@link me.lokka30.treasury.api.economy.account.PlayerAccount}.
*
* @param playerUUID a UUID of the player account created. For global scenarios, specify `null`.
* @return the starting balance of the currency concerning specified player's UUID.
* @author lokka30, Geolykt, MrIvanPlays
* @since v1.0.0
*/
double getStartingBalance(@Nullable UUID playerUUID);
public double getStartingBalance(@Nullable UUID playerUUID) {
return startingBalance.apply(playerUUID);
}

/**
* Gets a human-readable format of the balance.
* For example, '$1.50' or '1.50 dollars' or 'One dollar and fifty cents'.
*
* @param amount to be formatted.
* @param locale of the formatted balance being requested.
* @return the human-readable format of the specified amount and locale.
* @author lokka30, MrIvanPlays
* @since v1.0.0
*/
@NotNull
String formatBalance(double amount, @NotNull Locale locale);
}
public String formatBalance(double amount, @NotNull Locale locale) {
Objects.requireNonNull(locale, "locale");
return balanceFormatter.apply(amount, locale);
}
}
Loading