Added javadocs for clarity

Optimized methods in TikTokGiftEventHandler and TikTokGenericEventMapper
This commit is contained in:
kohlerpop1
2024-07-01 17:02:08 -04:00
parent 1736236ccf
commit 8d715d4f50
6 changed files with 61 additions and 77 deletions

View File

@@ -29,8 +29,6 @@ import io.github.jwdeveloper.tiktok.data.models.users.User;
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage; import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
import lombok.Getter; import lombok.Getter;
@EventMeta(eventType = EventType.Message) @EventMeta(eventType = EventType.Message)
@Getter @Getter
public class TikTokGiftComboEvent extends TikTokGiftEvent { public class TikTokGiftComboEvent extends TikTokGiftEvent {
@@ -43,12 +41,9 @@ public class TikTokGiftComboEvent extends TikTokGiftEvent {
public static TikTokGiftComboEvent of(Gift gift, int combo, GiftComboStateType comboState) { public static TikTokGiftComboEvent of(Gift gift, int combo, GiftComboStateType comboState) {
return new TikTokGiftComboEvent( return new TikTokGiftComboEvent(
gift, gift,
new User(0L, "Test", new Picture("")), new User(0L, "Test", new Picture("")),
WebcastGiftMessage WebcastGiftMessage.newBuilder().setComboCount(combo).build(),
.newBuilder() comboState);
.setComboCount(combo)
.build(),
comboState);
} }
} }

View File

@@ -22,7 +22,6 @@
*/ */
package io.github.jwdeveloper.tiktok.data.events.gift; package io.github.jwdeveloper.tiktok.data.events.gift;
import io.github.jwdeveloper.tiktok.annotations.*; import io.github.jwdeveloper.tiktok.annotations.*;
import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent; import io.github.jwdeveloper.tiktok.data.events.common.TikTokHeaderEvent;
import io.github.jwdeveloper.tiktok.data.models.Picture; import io.github.jwdeveloper.tiktok.data.models.Picture;
@@ -31,8 +30,6 @@ import io.github.jwdeveloper.tiktok.data.models.users.User;
import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage; import io.github.jwdeveloper.tiktok.messages.webcast.WebcastGiftMessage;
import lombok.Getter; import lombok.Getter;
@EventMeta(eventType = EventType.Message) @EventMeta(eventType = EventType.Message)
@Getter @Getter
public class TikTokGiftEvent extends TikTokHeaderEvent { public class TikTokGiftEvent extends TikTokHeaderEvent {

View File

@@ -23,9 +23,9 @@
package io.github.jwdeveloper.tiktok.data.models.gifts; package io.github.jwdeveloper.tiktok.data.models.gifts;
public enum GiftComboStateType { public enum GiftComboStateType {
Finished,
Begin, Begin,
Active; Active,
Finished;
public static GiftComboStateType fromNumber(long number) { public static GiftComboStateType fromNumber(long number) {
return switch ((int) number) { return switch ((int) number) {

View File

@@ -123,8 +123,11 @@ public interface EventsBuilder<T> {
} }
/** /**
* Invoked for gifts that has no combo, or when combo finishes * Triggers for these different reasons:
* * <ol>
* <li>User sends gifts that have no combo (most of expensive gifts)</li>
* <li>{@link TikTokGiftComboEvent} has combaState = {@link GiftComboStateType#Finished}</li>
* </ol>
* @param action consumable action * @param action consumable action
* @return self instance * @return self instance
*/ */
@@ -133,19 +136,19 @@ public interface EventsBuilder<T> {
} }
/** /**
* Triggered every time gift is sent * Triggered every time a gift is sent
* <p>Example when user sends gift with combo</p>
* <ul>
* <li>Combo: 1 -> comboState = {@link GiftComboStateType#Begin}</li>
* <li>Combo: 4 -> comboState = {@link GiftComboStateType#Active}</li>
* <li>Combo: 8 -> comboState = {@link GiftComboStateType#Active}</li>
* <li>Combo: 12 -> comboState = {@link GiftComboStateType#Finished}</li>
* </ul>
* Both {@link TikTokGiftComboEvent} and {@link TikTokGiftEvent} events are triggered when comboState is Finished
* *
* @apiNote {@link GiftComboStateType} has 3 states: {@link GiftComboStateType#Begin Begin}, {@link GiftComboStateType#Active Active}, & {@link GiftComboStateType#Finished Finished}
* @param action consumable action * @param action consumable action
* @return self instance * @return self instance
* @see GiftComboStateType it has 3 states
*
* <p>Example when user sends gift with combo</p>
* <p>>Combo: 1 -> comboState = GiftSendType.Begin</p>
* <p>Combo: 4 -> comboState = GiftSendType.Active</p>
* <p>Combo: 8 -> comboState = GiftSendType.Active</p>
* <p>Combo: 12 -> comboState = GiftSendType.Finished</p>
* <p>
* Remember if comboState is Finished both TikTokGiftComboEvent and TikTokGiftEvent event gets triggered
*/ */
default T onGiftCombo(EventConsumer<TikTokGiftComboEvent> action) { default T onGiftCombo(EventConsumer<TikTokGiftComboEvent> action) {
return onEvent(TikTokGiftComboEvent.class, action); return onEvent(TikTokGiftComboEvent.class, action);

View File

@@ -27,26 +27,24 @@ import io.github.jwdeveloper.tiktok.exceptions.TikTokMessageMappingException;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays; import java.util.*;
import java.util.HashMap;
import java.util.Map;
/** /**
* Goal of this class is to map ProtocolBuffer objects to TikTok Event in generic way * Goal of this class is to map ProtocolBuffer objects to TikTok Event in generic way
* * <ul>
* First parameter is ProtocolBuffer class type * <li>First parameter is ProtocolBuffer class type</li>
* Second parameters is TikTokEvent class type * <li>Second parameters is TikTokEvent class type</li>
* Third parameters is bytes payload * <li>Third parameters is bytes payload</li>
* * </ul>
* mapToEvent(WebcastGiftMessage.class, TikTokGiftEvent.class, payload) * <p>mapToEvent(WebcastGiftMessage.class, TikTokGiftEvent.class, payload)</p>
* * <p>How does it work?</p>
* How does it work? * <ol>
* 1. Finds method `parseFrom(byte[] bytes)` inside ProtocolBuffer class * <li>Finds method `parseFrom(byte[] bytes)` inside ProtocolBuffer class</li>
* 2. put payload to the method methods and create new instance of ProtcolBuffer object * <li>Put payload to the method methods and create new instance of ProtcolBuffer object</li>
* 3. Finds in TikTokEvent constructor that takes ProtocolBuffer type as parameter * <li>Finds in TikTokEvent constructor that takes ProtocolBuffer type as parameter</li>
* 4. create new Instance in TikTokEvents using object from step 2 and constructor from step 3 * <li>Create new Instance in TikTokEvents using object from step 2 and constructor from step 3</li>
* * </ol>
* methodCache and constructorCache are used to boost performance * methodCache and constructorCache are used to boost performance
*/ */
public class TikTokGenericEventMapper { public class TikTokGenericEventMapper {
@@ -74,34 +72,27 @@ public class TikTokGenericEventMapper {
} }
} }
public Method getParsingMethod(Class<?> input) throws NoSuchMethodException { public Method getParsingMethod(Class<?> input) throws RuntimeException {
if (methodCache.containsKey(input)) { return methodCache.computeIfAbsent(input, aClass -> {
return methodCache.get(input); try {
} return aClass.getDeclaredMethod("parseFrom", byte[].class);
var method = input.getDeclaredMethod("parseFrom", byte[].class); } catch (NoSuchMethodException e) {
methodCache.put(input, method); throw new RuntimeException(e);
return method; }
});
} }
private Constructor<?> getParsingConstructor(Class<?> input, Class<?> output) { private Constructor<?> getParsingConstructor(Class<?> input, Class<?> output) {
var pair = new TypePair(input, output); return constructorCache.computeIfAbsent(new TypePair(input, output), pair -> {
if (constructorCache.containsKey(pair)) { var optional = Arrays.stream(output.getConstructors())
return constructorCache.get(pair);
}
var optional = Arrays.stream(output.getConstructors())
.filter(ea -> Arrays.stream(ea.getParameterTypes()) .filter(ea -> Arrays.stream(ea.getParameterTypes())
.toList() .toList()
.contains(input)) .contains(input))
.findFirst(); .findFirst();
if (optional.isEmpty()) { if (optional.isEmpty())
throw new TikTokMessageMappingException(input, output, "Unable to find constructor with input class type"); throw new TikTokMessageMappingException(input, output, "Unable to find constructor with input class type");
} return optional.get();
});
constructorCache.put(pair, optional.get());
return optional.get();
} }
} }

View File

@@ -55,11 +55,6 @@ public class TikTokGiftEventHandler {
} }
public List<TikTokEvent> handleGift(WebcastGiftMessage currentMessage) { public List<TikTokEvent> handleGift(WebcastGiftMessage currentMessage) {
var userId = currentMessage.getUser().getId();
var currentType = GiftComboStateType.fromNumber(currentMessage.getSendType());
var containsPreviousMessage = giftsMessages.containsKey(userId);
//If gift is not streakable just return onGift event //If gift is not streakable just return onGift event
if (currentMessage.getGift().getType() != 1) { if (currentMessage.getGift().getType() != 1) {
var comboEvent = getGiftComboEvent(currentMessage, GiftComboStateType.Finished); var comboEvent = getGiftComboEvent(currentMessage, GiftComboStateType.Finished);
@@ -67,7 +62,11 @@ public class TikTokGiftEventHandler {
return List.of(comboEvent, giftEvent); return List.of(comboEvent, giftEvent);
} }
if (!containsPreviousMessage) { var userId = currentMessage.getUser().getId();
var currentType = GiftComboStateType.fromNumber(currentMessage.getSendType());
var previousMessage = giftsMessages.get(userId);
if (previousMessage == null) {
if (currentType == GiftComboStateType.Finished) { if (currentType == GiftComboStateType.Finished) {
return List.of(getGiftEvent(currentMessage)); return List.of(getGiftEvent(currentMessage));
} else { } else {
@@ -76,7 +75,6 @@ public class TikTokGiftEventHandler {
} }
} }
var previousMessage = giftsMessages.get(userId);
var previousType = GiftComboStateType.fromNumber(previousMessage.getSendType()); var previousType = GiftComboStateType.fromNumber(previousMessage.getSendType());
if (currentType == GiftComboStateType.Active && if (currentType == GiftComboStateType.Active &&
previousType == GiftComboStateType.Active) { previousType == GiftComboStateType.Active) {
@@ -114,9 +112,9 @@ public class TikTokGiftEventHandler {
gift = giftsManager.getByName(giftMessage.getGift().getName()); gift = giftsManager.getByName(giftMessage.getGift().getName());
if (gift == Gift.UNDEFINED) { if (gift == Gift.UNDEFINED) {
gift = new Gift(giftId, gift = new Gift(giftId,
giftMessage.getGift().getName(), giftMessage.getGift().getName(),
giftMessage.getGift().getDiamondCount(), giftMessage.getGift().getDiamondCount(),
Picture.map(giftMessage.getGift().getImage())); Picture.map(giftMessage.getGift().getImage()));
giftsManager.attachGift(gift); giftsManager.attachGift(gift);
} }