mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-18 15:38:28 +02:00
Merge MatrixKit develop with commit hash: b85b736313bec0592bd1cabc68035d97f5331137
This commit is contained in:
271
Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSourceManager.m
Normal file
271
Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSourceManager.m
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomDataSourceManager.h"
|
||||
|
||||
@interface MXKRoomDataSourceManager()
|
||||
{
|
||||
MXSession *mxSession;
|
||||
|
||||
/**
|
||||
The list of running roomDataSources.
|
||||
Each key is a room ID. Each value, the MXKRoomDataSource instance.
|
||||
*/
|
||||
NSMutableDictionary *roomDataSources;
|
||||
|
||||
/**
|
||||
Observe UIApplicationDidReceiveMemoryWarningNotification to dispose of any resources that can be recreated.
|
||||
*/
|
||||
id UIApplicationDidReceiveMemoryWarningNotificationObserver;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static NSMutableDictionary *_roomDataSourceManagers = nil;
|
||||
static Class _roomDataSourceClass;
|
||||
|
||||
@implementation MXKRoomDataSourceManager
|
||||
|
||||
+ (MXKRoomDataSourceManager *)sharedManagerForMatrixSession:(MXSession *)mxSession
|
||||
{
|
||||
// Manage a pool of managers: one per Matrix session
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
_roomDataSourceManagers = [NSMutableDictionary dictionary];
|
||||
});
|
||||
|
||||
MXKRoomDataSourceManager *roomDataSourceManager;
|
||||
|
||||
// Compute an id for this mxSession object: its pointer address as a string
|
||||
NSString *mxSessionId = [NSString stringWithFormat:@"%p", mxSession];
|
||||
|
||||
@synchronized(_roomDataSourceManagers)
|
||||
{
|
||||
if (_roomDataSourceClass == nil)
|
||||
{
|
||||
// Set default class
|
||||
_roomDataSourceClass = MXKRoomDataSource.class;
|
||||
}
|
||||
// If not available yet, create the `MXKRoomDataSourceManager` for this Matrix session
|
||||
roomDataSourceManager = _roomDataSourceManagers[mxSessionId];
|
||||
if (!roomDataSourceManager)
|
||||
{
|
||||
roomDataSourceManager = [[MXKRoomDataSourceManager alloc]initWithMatrixSession:mxSession];
|
||||
_roomDataSourceManagers[mxSessionId] = roomDataSourceManager;
|
||||
}
|
||||
}
|
||||
|
||||
return roomDataSourceManager;
|
||||
}
|
||||
|
||||
+ (void)removeSharedManagerForMatrixSession:(MXSession*)mxSession
|
||||
{
|
||||
// Compute the id for this mxSession object: its pointer address as a string
|
||||
NSString *mxSessionId = [NSString stringWithFormat:@"%p", mxSession];
|
||||
|
||||
@synchronized(_roomDataSourceManagers)
|
||||
{
|
||||
MXKRoomDataSourceManager *roomDataSourceManager = [_roomDataSourceManagers objectForKey:mxSessionId];
|
||||
if (roomDataSourceManager)
|
||||
{
|
||||
[roomDataSourceManager destroy];
|
||||
[_roomDataSourceManagers removeObjectForKey:mxSessionId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)registerRoomDataSourceClass:(Class)roomDataSourceClass
|
||||
{
|
||||
// Sanity check: accept only MXKRoomDataSource classes or sub-classes
|
||||
NSParameterAssert([roomDataSourceClass isSubclassOfClass:MXKRoomDataSource.class]);
|
||||
|
||||
@synchronized(_roomDataSourceManagers)
|
||||
{
|
||||
if (roomDataSourceClass !=_roomDataSourceClass)
|
||||
{
|
||||
_roomDataSourceClass = roomDataSourceClass;
|
||||
|
||||
NSArray *mxSessionIds = _roomDataSourceManagers.allKeys;
|
||||
for (NSString *mxSessionId in mxSessionIds)
|
||||
{
|
||||
MXKRoomDataSourceManager *roomDataSourceManager = [_roomDataSourceManagers objectForKey:mxSessionId];
|
||||
if (roomDataSourceManager)
|
||||
{
|
||||
[roomDataSourceManager destroy];
|
||||
[_roomDataSourceManagers removeObjectForKey:mxSessionId];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)initWithMatrixSession:(MXSession *)matrixSession
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
mxSession = matrixSession;
|
||||
roomDataSources = [NSMutableDictionary dictionary];
|
||||
_releasePolicy = MXKRoomDataSourceManagerReleasePolicyNeverRelease;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXSessionDidLeaveRoom:) name:kMXSessionDidLeaveRoomNotification object:nil];
|
||||
|
||||
// Observe UIApplicationDidReceiveMemoryWarningNotification
|
||||
UIApplicationDidReceiveMemoryWarningNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXLogDebug(@"[MXKRoomDataSourceManager] %@: Received memory warning.", self);
|
||||
|
||||
// Reload all data sources (except the current used ones) to reduce memory usage.
|
||||
for (MXKRoomDataSource *roomDataSource in self->roomDataSources.allValues)
|
||||
{
|
||||
if (!roomDataSource.delegate)
|
||||
{
|
||||
[roomDataSource reload];
|
||||
}
|
||||
}
|
||||
|
||||
}];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidLeaveRoomNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)destroy
|
||||
{
|
||||
[self reset];
|
||||
|
||||
if (UIApplicationDidReceiveMemoryWarningNotificationObserver)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:UIApplicationDidReceiveMemoryWarningNotificationObserver];
|
||||
UIApplicationDidReceiveMemoryWarningNotificationObserver = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark
|
||||
|
||||
- (BOOL)isServerSyncInProgress
|
||||
{
|
||||
// Check first the matrix session state
|
||||
if (mxSession.state == MXSessionStateSyncInProgress)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Check all data sources (events process is asynchronous, server sync may not be complete in data source).
|
||||
for (MXKRoomDataSource *roomDataSource in roomDataSources.allValues)
|
||||
{
|
||||
if (roomDataSource.serverSyncEventCount)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark
|
||||
|
||||
- (void)reset
|
||||
{
|
||||
NSArray *roomIds = roomDataSources.allKeys;
|
||||
for (NSString *roomId in roomIds)
|
||||
{
|
||||
[self closeRoomDataSourceWithRoomId:roomId forceClose:YES];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)roomDataSourceForRoom:(NSString *)roomId create:(BOOL)create onComplete:(void (^)(MXKRoomDataSource *roomDataSource))onComplete
|
||||
{
|
||||
NSParameterAssert(roomId);
|
||||
|
||||
// If not available yet, create the room data source
|
||||
MXKRoomDataSource *roomDataSource = roomDataSources[roomId];
|
||||
|
||||
if (!roomDataSource && create && roomId)
|
||||
{
|
||||
[_roomDataSourceClass loadRoomDataSourceWithRoomId:roomId andMatrixSession:mxSession onComplete:^(id roomDataSource) {
|
||||
[self addRoomDataSource:roomDataSource];
|
||||
onComplete(roomDataSource);
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
onComplete(roomDataSource);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)addRoomDataSource:(MXKRoomDataSource *)roomDataSource
|
||||
{
|
||||
roomDataSources[roomDataSource.roomId] = roomDataSource;
|
||||
}
|
||||
|
||||
- (void)closeRoomDataSourceWithRoomId:(NSString*)roomId forceClose:(BOOL)forceRelease;
|
||||
{
|
||||
// Check first whether this roomDataSource is well handled by this manager
|
||||
if (!roomId || !roomDataSources[roomId])
|
||||
{
|
||||
MXLogDebug(@"[MXKRoomDataSourceManager] Failed to close an unknown room id: %@", roomId);
|
||||
return;
|
||||
}
|
||||
|
||||
MXKRoomDataSource *roomDataSource = roomDataSources[roomId];
|
||||
|
||||
// According to the policy, it is interesting to keep the room data source in life: it can keep managing echo messages
|
||||
// in background for instance
|
||||
MXKRoomDataSourceManagerReleasePolicy releasePolicy = _releasePolicy;
|
||||
if (forceRelease)
|
||||
{
|
||||
// Act as ReleaseOnClose policy
|
||||
releasePolicy = MXKRoomDataSourceManagerReleasePolicyReleaseOnClose;
|
||||
}
|
||||
|
||||
switch (releasePolicy)
|
||||
{
|
||||
case MXKRoomDataSourceManagerReleasePolicyReleaseOnClose:
|
||||
|
||||
// Destroy and forget the instance
|
||||
[roomDataSource destroy];
|
||||
[roomDataSources removeObjectForKey:roomDataSource.roomId];
|
||||
break;
|
||||
|
||||
case MXKRoomDataSourceManagerReleasePolicyNeverRelease:
|
||||
|
||||
// The close here consists in no more sending actions to the current view controller, the room data source delegate
|
||||
roomDataSource.delegate = nil;
|
||||
|
||||
// Keep the instance for life (reduce memory usage by flushing room data if the number of bubbles is over 30).
|
||||
[roomDataSource limitMemoryUsage:roomDataSource.maxBackgroundCachedBubblesCount];
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didMXSessionDidLeaveRoom:(NSNotification *)notif
|
||||
{
|
||||
if (mxSession == notif.object)
|
||||
{
|
||||
// The room is no more available, remove it from the manager
|
||||
[self closeRoomDataSourceWithRoomId:notif.userInfo[kMXSessionNotificationRoomIdKey] forceClose:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user