package com.natsu.horseutil.utils; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; public final class ServiceRegistry { private static final Map, Object> services = new ConcurrentHashMap<>(); private static final Map, List>> unregisterLogic = new ConcurrentHashMap<>(); private ServiceRegistry() { // prevent instantiation } public static void clear() { unregisterLogic.clear(); services.clear(); } /** * Register a service instance for a given type. * Logs error if already registered. */ @SuppressWarnings("unchecked") @SafeVarargs public static void register(Class type, T instance, Consumer... unregisterLogic) { if (type == null || instance == null) { throw new IllegalArgumentException("Type and instance cannot be null."); } Object existing = services.putIfAbsent(type, instance); if (existing != null) { Logger.error("Service already registered for type: {}", type.getName()); return; } if (unregisterLogic != null && unregisterLogic.length > 0) { List> logicList = new ArrayList<>(); for (Consumer logic : unregisterLogic) { logicList.add((Consumer) logic); } ServiceRegistry.unregisterLogic.put(type, logicList); } } @SafeVarargs @SuppressWarnings("unchecked") public static void register(T instance, Consumer... unregisterLogic) { Class type = (Class) instance.getClass(); register(type, instance, unregisterLogic); } /** * Unregister a service and run its associated unregister logic if present. */ public static void unregister(Class type) { Object instance = services.remove(type); if (instance == null) { Logger.warn("No registered service found for type: {}", type.getName()); return; } List> logics = unregisterLogic.remove(type); if (logics != null) { for (Consumer logic : logics) { try { logic.accept(instance); } catch (Exception e) { Logger.error("Error while executing unregister logic for {}: {}", type.getName(), e.getMessage()); } } } Logger.info("Service unregistered for type: {}", type.getName()); } /** * Unregister all services and execute their unregister logic. */ public static void unregisterAll() { services.forEach((type, instance) -> { List> logics = unregisterLogic.get(type); if (logics != null) { for (Consumer logic : logics) { try { logic.accept(instance); } catch (Exception e) { Logger.error("Error while executing unregister logic for {}: {}", type.getName(), e.getMessage()); } } } Logger.info("Service unregistered for type: {}", type.getName()); }); services.clear(); unregisterLogic.clear(); } /** * Get a registered service, creating a new instance if not registered. */ @SuppressWarnings("unchecked") public static T get(Class type) { return (T) services.computeIfAbsent(type, ServiceRegistry::createInstance); } @SuppressWarnings("unchecked") public static Optional getIfExist(Class type) { if(services.containsKey(type)){ return Optional.ofNullable((T)services.get(type)); }else return Optional.empty(); } /** * Check if a service is registered. */ public static boolean isRegistered(Class type) { return services.containsKey(type); } /** * Create an instance of the given class via reflection (default constructor). */ private static T createInstance(Class type) { try { return type.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new IllegalStateException("Could not create instance for: " + type.getName(), e); } } }