Files
watrbx-game-engine/iOS/RobloxUI/Source/Data/RBXMessagesPollingService.mm
2025-09-18 17:55:52 -04:00

160 lines
5.7 KiB
Plaintext

//
// RBXMessagesPollingService
// Periodically polls the server for user notifications
//
// Created by Kyler Mulherin on 9/17/14.
// Copyright (c) 2014 ROBLOX. All rights reserved.
//
#import "RBXMessagesPollingService.h"
#import "LoginManager.h"
#import "FastLog.h"
#import "RobloxNotifications.h"
//------ Server Fast Flags ---------
FASTFLAGVARIABLE(NotificationPollingServiceEnabled, true);
FASTINTVARIABLE(NotificationPollingServiceInterval, 10);
@implementation RBXMessagesPollingService
+(id) sharedInstance
{
static dispatch_once_t rbxNotServObj = 0;
__strong static id _sharedObject = nil;
dispatch_once(&rbxNotServObj, ^{ // Need to use GCD for thread-safe allocation
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}
-(id) init
{
//counter
_totalMessages = 0;
_totalFriendRequests = 0;
_requestCompleted = YES;
//observers
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(beginPolling) name:RBX_NOTIFY_DID_LEAVE_GAME object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pausePolling) name:RBX_NOTIFY_GAME_JOINED object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(decrementMessagesTotal) name:RBX_NOTIFY_READ_MESSAGE object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pulseNotification) name:RBX_NOTIFY_LOGIN_SUCCEEDED object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clearTotalMessages) name:RBX_NOTIFY_LOGGED_OUT object:nil];
//since friend requests are handled on the web, there is no way to communicate natively that the total has decremented
return self;
}
-(void) clean
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self deactivateNotificationTimer];
}
//server flags
- (BOOL)isServiceEnabled
{
return FFlag::NotificationPollingServiceEnabled;
}
- (int)getPollingInterval
{
return FInt::NotificationPollingServiceInterval;
}
//service functions
-(void) beginPolling { [self toggleTimer:YES];}
-(void) pausePolling { [self toggleTimer:NO]; }
-(void) toggleTimer:(BOOL)isOn
{
//use fast flags to simply escape if this service is not enabled
if (! [self isServiceEnabled]) return;
//to ensure that the timer is started and stopped on the same thread, dispatch the command here
dispatch_async(dispatch_get_main_queue(), ^
{
_requestCompleted = YES;
if (isOn) [self activateNotificationTimer];
else [self deactivateNotificationTimer];
});
}
-(void) activateNotificationTimer
{
if (!_notificationTimer)
{
_notificationTimer = [NSTimer scheduledTimerWithTimeInterval:[self getPollingInterval]
target:self
selector:@selector(fetchNotificationsFromServer)
userInfo:nil
repeats:YES];
}
}
-(void) deactivateNotificationTimer
{
if (_notificationTimer)
[_notificationTimer invalidate];
_notificationTimer = nil;
}
//count and total functions
-(NSDictionary*) createNotification
{
return [NSDictionary dictionaryWithObjects:@[[NSNumber numberWithInt:_totalMessages],[NSNumber numberWithInt:_totalFriendRequests]]
forKeys:@[@"unreadMessages", @"friendRequests"]];
}
-(void) fetchNotificationsFromServer
{
//escape if the user is not logged into an account
if (![[UserInfo CurrentPlayer] userLoggedIn]) { return; }
//do not perform multiple requests, wait for one to complete before requesting another
if (!_requestCompleted) return;
_requestCompleted = NO;
[RobloxData fetchTotalNotificationsForUser:[UserInfo CurrentPlayer].userId WithCompletion:^(RBXNotifications* notifications)
{
_requestCompleted = YES;
if (notifications)
{
if (_totalMessages != notifications.unreadMessages)
{
_totalMessages = notifications.unreadMessages;
[[NSNotificationCenter defaultCenter] postNotificationName:RBX_NOTIFY_INBOX_UPDATED object:nil];
}
if (_totalFriendRequests != notifications.unansweredFriendRequests)
{
_totalFriendRequests = notifications.unansweredFriendRequests;
[[NSNotificationCenter defaultCenter] postNotificationName:RBX_NOTIFY_FRIEND_REQUESTS_UPDATED object:nil];
}
}
}];
}
-(void) decrementMessagesTotal
{
_totalMessages = (_totalMessages - 1 <= 0) ? 0 : _totalMessages - 1;
[[NSNotificationCenter defaultCenter] postNotificationName:RBX_NOTIFY_NEW_MESSAGES_TOTAL object:nil];
}
-(void) decrementFriendRequestsTotal
{
_totalFriendRequests = (_totalFriendRequests - 1 <= 0) ? 0 : _totalFriendRequests - 1;
[[NSNotificationCenter defaultCenter] postNotificationName:RBX_NOTIFY_NEW_FRIEND_REQUESTS_TOTAL object:nil];
}
-(void) clearTotalMessages
{
//the user has logged out, clear the counter and notify any listeners
_totalMessages = 0;
_totalFriendRequests = 0;
[[NSNotificationCenter defaultCenter] postNotificationName:RBX_NOTIFY_NEW_MESSAGES_TOTAL object:[self createNotification]];
}
-(void) pulseNotification
{
[[NSNotificationCenter defaultCenter] postNotificationName:RBX_NOTIFY_NEW_MESSAGES_TOTAL object:[self createNotification]];
[[NSNotificationCenter defaultCenter] postNotificationName:RBX_NOTIFY_NEW_FRIEND_REQUESTS_TOTAL object:[self createNotification]];
}
@end