import 'dart:async'; import 'package:get/get_rx/get_rx.dart'; // Log seviyeleri class LogLevel { final String name; const LogLevel._(this.name); static const DEBUG = LogLevel._('DEBUG'); static const INFO = LogLevel._('INFO'); static const WARNING = LogLevel._('WARNING'); static const ERROR = LogLevel._('ERROR'); @override String toString() => name; } // Global Event Sistemi class FikoYTEventSystem { static final FikoYTEventSystem _instance = FikoYTEventSystem._internal(); factory FikoYTEventSystem() { return _instance; } FikoYTEventSystem._internal(); final _eventController = StreamController.broadcast(); final Map>> _subscriptions = {}; // Category bazlı abone listesi final Map events = {}; // Eventleri tutar // Loglama fonksiyonu void _log(String message, {LogLevel level = LogLevel.INFO}) { final timestamp = DateTime.now().toIso8601String(); print('[$timestamp] [${level.name}] $message'); } // Event sınıfını ekler veya mevcutsa döndürür FikoYTEvent addEvent(FikoYTEvent event) { final eventName = event.name; if (events.containsKey(eventName)) { // Eğer event zaten varsa, mevcut olanı döndür return events[eventName]!; } else { // Yeni event'i ekle events[eventName] = event; return event; } } // Event'e isimle erişim sağlayan fonksiyon FikoYTEvent? getEvent(String eventName) { return events[eventName]; // Event var mı kontrolü eklenmiş durumda } // Event gönderme void sendEvent({ required String eventName, dynamic argument, String? category, }) { final event = getEvent(eventName); if (event == null) { throw Exception("Event '$eventName' tanımlı değil!"); } if (category != null && event.category != category) { _log("Event '$eventName' kategorisi '$category' ile uyuşmuyor!", level: LogLevel.ERROR); throw Exception("Event '$eventName' kategorisi '$category' ile uyuşmuyor!"); } event.send(argument); } // Event dinleme StreamSubscription onEvent({ required String eventName, required void Function(FikoYTEvent) onData, String? category, dynamic customArgs, }) { final event = getEvent(eventName); if (event == null) { throw Exception("Event '$eventName' tanımlı değil!"); } if (category != null) { _subscriptions.putIfAbsent(eventName, () => {}); final categorySubscriptions = _subscriptions[eventName]!; final subscription = _eventController.stream.where((e) => e.name == eventName && (e.category == category)).listen((event) { if (customArgs != null) { event.mergeArguments(customArgs); } // onData fonksiyonunu çağırıyoruz onData(event); }); categorySubscriptions[category ?? "default"] = subscription; _log("Event dinleniyor: $eventName, Kategori: $category", level: LogLevel.INFO); return subscription; } else { _log("Kategori sağlanmalı!", level: LogLevel.ERROR); throw Exception("Kategori sağlanmalı!"); } } // Event duraklatma void pauseEvent({required String eventName, String? category}) { if (category != null && _subscriptions.containsKey(eventName) && _subscriptions[eventName]?.containsKey(category) == true) { final subscription = _subscriptions[eventName]?[category]; if (subscription?.isPaused == true) { _log("Event '$eventName' kategorisi '$category' zaten duraklatılmış.", level: LogLevel.WARNING); return; } subscription?.pause(); _log("Event '$eventName' kategorisi '$category' duraklatıldı.", level: LogLevel.INFO); } else { _log("Event '$eventName' kategorisi '$category' bulunamadı veya tanımlı değil.", level: LogLevel.ERROR); } } // Event'e devam ettirme void resumeEvent({required String eventName, String? category}) { if (category != null && _subscriptions.containsKey(eventName) && _subscriptions[eventName]?.containsKey(category) == true) { final subscription = _subscriptions[eventName]?[category]; if (subscription?.isPaused == false) { _log("Event '$eventName' kategorisi '$category' zaten aktif.", level: LogLevel.WARNING); return; } subscription?.resume(); _log("Event '$eventName' kategorisi '$category' devam ettirildi.", level: LogLevel.INFO); } else { _log("Event '$eventName' kategorisi '$category' bulunamadı veya tanımlı değil.", level: LogLevel.ERROR); } } // Event'i iptal etme void cancelEvent({required String eventName, String? category}) { if (category != null && _subscriptions.containsKey(eventName) && _subscriptions[eventName]?.containsKey(category) == true) { _subscriptions[eventName]?[category]?.cancel(); _subscriptions[eventName]?.remove(category); _log("Event '$eventName' kategorisi '$category' iptal edildi.", level: LogLevel.INFO); } else { _log("Event '$eventName' kategorisi '$category' bulunamadı veya tanımlı değil.", level: LogLevel.ERROR); } } // Tüm event'leri iptal etme void cancelAllEvents() { for (final subscriptions in _subscriptions.values) { for (final subscription in subscriptions.values) { subscription.cancel(); } } _subscriptions.clear(); events.clear(); _log("Tüm event'ler iptal edildi ve sistem sıfırlandı.", level: LogLevel.WARNING); } void dispose() { _eventController.close(); cancelAllEvents(); _log("Global Event System tamamen kapatıldı.", level: LogLevel.ERROR); } } // Event veri sınıfı class FikoYTEvent { final String name; dynamic _arguments; // private variable for arguments final dynamic defaultArguments; // Varsayılan argümanlar String? category; // Event için kategori // Bu harita, eventlerin adlarını ve bunlara karşılık gelen event nesnelerini tutacak. static final Map _eventCache = {}; // Factory constructor factory FikoYTEvent( String name, { String? category, dynamic arguments = const {}, dynamic defaultArguments = const {}, dynamic initialValue, }) { // Eğer aynı isimde bir event zaten varsa, onu döndür if (_eventCache.containsKey(name)) { return _eventCache[name]! as FikoYTEvent; } // Yeni event oluşturuluyorsa, eventCache'e ekle final newEvent = FikoYTEvent._internal( name, category: category, arguments: arguments, defaultArguments: defaultArguments, initialValue: initialValue, ); _eventCache[name] = newEvent; return newEvent; } // Özel constructor FikoYTEvent._internal( this.name, { this.category, dynamic arguments = const {}, this.defaultArguments = const {}, dynamic initialValue, }) : _arguments = arguments { if (initialValue is Function) { _value = Rx(initialValue()); } else { _value = Rx(initialValue ?? null as T); } // Event oluşturulduğunda, mevcut event varsa onu döndür FikoYTEventSystem().addEvent(this); } // Değeri Valuesi late final Rx _value; // Rx olarak değer tipi belirtiliyor. // Getter for value T get value => _value.value; Rx get $value => _value; // Setter for value set value(T newValue) { _value.value = newValue; _value.refresh(); // Değer değiştikçe yenileme } // Getter for arguments dynamic get arguments => _arguments ?? defaultArguments; // Setter (Kopyalama işlemi ile) void mergeArguments(dynamic newArguments) { if (_arguments is Map && newArguments is Map) { _arguments = {..._arguments, ...newArguments}; } else { _arguments = newArguments; } } // Event gönderme void send(dynamic argument) { dynamic finalArguments; // Eğer o anlık bir argüman verilmişse, sadece o anlık işlemde geçerli olacak şekilde birleştirilecek if (argument != null) { finalArguments = argument is Map && _arguments is Map ? {..._arguments, ...argument} : argument; } else { finalArguments = _arguments ?? defaultArguments; } // O anlık argümanları gönderme işlemi FikoYTEventSystem().addEvent(FikoYTEvent(name, arguments: finalArguments, category: category)); } }