From 99f244a1d499ad130552a79c520b80d33addad5d Mon Sep 17 00:00:00 2001
From: ZoMinster <zominster@gmail.com>
Date: Mon, 7 Aug 2017 18:50:18 +0800
Subject: [PATCH 1/3] add module and service remove function

---
 BeeHive/BHContext.h       |  2 ++
 BeeHive/BHContext.m       |  5 +++++
 BeeHive/BHModuleManager.h |  2 ++
 BeeHive/BHModuleManager.m | 29 +++++++++++++++++++++++++++++
 4 files changed, 38 insertions(+)

diff --git a/BeeHive/BHContext.h b/BeeHive/BHContext.h
index e6a4773..fdc37a1 100755
--- a/BeeHive/BHContext.h
+++ b/BeeHive/BHContext.h
@@ -62,6 +62,8 @@ typedef enum
 
 - (void)addServiceWithImplInstance:(id)implInstance serviceName:(NSString *)serviceName;
 
+- (void)removeServiceWithServiceName:(NSString *)serviceName;
+
 - (id)getServiceInstanceFromServiceName:(NSString *)serviceName;
 
 @end
diff --git a/BeeHive/BHContext.m b/BeeHive/BHContext.m
index ff26172..67fe0a5 100644
--- a/BeeHive/BHContext.m
+++ b/BeeHive/BHContext.m
@@ -38,6 +38,11 @@ - (void)addServiceWithImplInstance:(id)implInstance serviceName:(NSString *)serv
     [[BHContext shareInstance].servicesByName setObject:implInstance forKey:serviceName];
 }
 
+- (void)removeServiceWithServiceName:(NSString *)serviceName
+{
+    [[BHContext shareInstance].servicesByName removeObjectForKey:serviceName];
+}
+
 - (id)getServiceInstanceFromServiceName:(NSString *)serviceName
 {
     return [[BHContext shareInstance].servicesByName objectForKey:serviceName];
diff --git a/BeeHive/BHModuleManager.h b/BeeHive/BHModuleManager.h
index 643cac5..76dfc3a 100755
--- a/BeeHive/BHModuleManager.h
+++ b/BeeHive/BHModuleManager.h
@@ -56,6 +56,8 @@ typedef NS_ENUM(NSInteger, BHModuleEventType)
 - (void)registerDynamicModule:(Class)moduleClass
        shouldTriggerInitEvent:(BOOL)shouldTriggerInitEvent;
 
+- (void)unRegisterDynamicModule:(Class)moduleClass;
+
 - (void)loadLocalModules;
 
 - (void)registedAllModules;
diff --git a/BeeHive/BHModuleManager.m b/BeeHive/BHModuleManager.m
index 7347ad5..b9b487a 100755
--- a/BeeHive/BHModuleManager.m
+++ b/BeeHive/BHModuleManager.m
@@ -96,6 +96,35 @@ - (void)registerDynamicModule:(Class)moduleClass
     [self addModuleFromObject:moduleClass shouldTriggerInitEvent:shouldTriggerInitEvent];
 }
 
+- (void)unRegisterDynamicModule:(Class)moduleClass {
+    if (!moduleClass) {
+        return;
+    }
+    [self.BHModuleInfos filterUsingPredicate:[NSPredicate predicateWithFormat:@"%@!=%@", kModuleInfoNameKey, NSStringFromClass(moduleClass)]];
+    __block NSInteger index = -1;
+    [self.BHModules enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+        if ([obj isKindOfClass:moduleClass]) {
+            index = idx;
+            *stop = YES;
+        }
+    }];
+    if (index >= 0) {
+        [self.BHModules removeObjectAtIndex:index];
+    }
+    [self.BHModulesByEvent enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull key, NSMutableArray<id<BHModuleProtocol>> * _Nonnull obj, BOOL * _Nonnull stop) {
+        __block NSInteger index = -1;
+        [obj enumerateObjectsUsingBlock:^(id<BHModuleProtocol>  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
+            if ([obj isKindOfClass:moduleClass]) {
+                index = idx;
+                *stop = NO;
+            }
+        }];
+        if (index >= 0) {
+            [obj removeObjectAtIndex:index];
+        }
+    }];
+}
+
 - (void)registedAllModules
 {
 

From d179be1333d24a04cb3ceca2a15e72b145f3b3a2 Mon Sep 17 00:00:00 2001
From: ZoMinster <zominster@gmail.com>
Date: Thu, 10 Aug 2017 17:42:08 +0800
Subject: [PATCH 2/3] =?UTF-8?q?=E4=BC=98=E5=8C=96invocation=E8=BF=94?=
 =?UTF-8?q?=E5=9B=9E=E5=80=BC=E8=8E=B7=E5=8F=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 BeeHive/BHRouter.m | 122 +++++++++++++++++++++++++++++++++------------
 1 file changed, 89 insertions(+), 33 deletions(-)

diff --git a/BeeHive/BHRouter.m b/BeeHive/BHRouter.m
index 34e31e3..b679135 100644
--- a/BeeHive/BHRouter.m
+++ b/BeeHive/BHRouter.m
@@ -17,6 +17,84 @@
 #import "BHModuleManager.h"
 #import "BHServiceManager.h"
 
+@interface NSObject (BHRetType)
+
++ (id)bh_getReturnFromInv:(NSInvocation *)inv withSig:(NSMethodSignature *)sig;
+
+@end
+
+@implementation NSObject (BHRetType)
+
++ (id)bh_getReturnFromInv:(NSInvocation *)inv withSig:(NSMethodSignature *)sig {
+    NSUInteger length = [sig methodReturnLength];
+    if (length == 0) return nil;
+    
+    char *type = (char *)[sig methodReturnType];
+    while (*type == 'r' || // const
+           *type == 'n' || // in
+           *type == 'N' || // inout
+           *type == 'o' || // out
+           *type == 'O' || // bycopy
+           *type == 'R' || // byref
+           *type == 'V') { // oneway
+        type++; // cutoff useless prefix
+    }
+    
+#define return_with_number(_type_) \
+do { \
+_type_ ret; \
+[inv getReturnValue:&ret]; \
+return @(ret); \
+} while (0)
+    
+    switch (*type) {
+        case 'v': return nil; // void
+        case 'B': return_with_number(bool);
+        case 'c': return_with_number(char);
+        case 'C': return_with_number(unsigned char);
+        case 's': return_with_number(short);
+        case 'S': return_with_number(unsigned short);
+        case 'i': return_with_number(int);
+        case 'I': return_with_number(unsigned int);
+        case 'l': return_with_number(int);
+        case 'L': return_with_number(unsigned int);
+        case 'q': return_with_number(long long);
+        case 'Q': return_with_number(unsigned long long);
+        case 'f': return_with_number(float);
+        case 'd': return_with_number(double);
+        case 'D': { // long double
+            long double ret;
+            [inv getReturnValue:&ret];
+            return [NSNumber numberWithDouble:ret];
+        };
+            
+        case '@': { // id
+            id ret = nil;
+            [inv getReturnValue:&ret];
+            return ret;
+        };
+            
+        case '#': { // Class
+            Class ret = nil;
+            [inv getReturnValue:&ret];
+            return ret;
+        };
+            
+        default: { // struct / union / SEL / void* / unknown
+            const char *objCType = [sig methodReturnType];
+            char *buf = calloc(1, length);
+            if (!buf) return nil;
+            [inv getReturnValue:buf];
+            NSValue *value = [NSValue valueWithBytes:buf objCType:objCType];
+            free(buf);
+            return value;
+        };
+    }
+#undef return_with_number
+}
+
+@end
+
 static NSString *const BHRClassRegex = @"(?<=T@\")(.*)(?=\",)";
 
 typedef NS_ENUM(NSUInteger, BHRViewControlerEnterMode) {
@@ -513,12 +591,12 @@ + (id)safePerformAction:(SEL)action
               forTarget:(NSObject *)target
              withParams:(NSDictionary *)params
 {
-    NSMethodSignature* methodSig = [target methodSignatureForSelector:action];
-    if(methodSig == nil) {
-        return nil;
-    }
-    const char* retType = [methodSig methodReturnType];
-    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
+    NSMethodSignature * sig = [self methodSignatureForSelector:action];
+    if (!sig) { return nil; }
+    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig];
+    if (!inv) { return nil; }
+    [inv setTarget:target];
+    [inv setSelector:action];
     NSArray<NSString *> *keys = params.allKeys;
     keys = [keys sortedArrayUsingComparator:^NSComparisonResult(NSString *  _Nonnull obj1, NSString *  _Nonnull obj2) {
         if (obj1.integerValue < obj2.integerValue) {
@@ -531,34 +609,12 @@ + (id)safePerformAction:(SEL)action
     }];
     [keys enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
         id value = params[obj];
-        [invocation setArgument:&value atIndex:idx+2];
+        [inv setArgument:&value atIndex:idx+2];
     }];
-    [invocation setSelector:action];
-    [invocation setTarget:target];
-    [invocation invoke];
-    if (strcmp(retType, @encode(void)) == 0) {
-        return nil;
-    } else if (strcmp(retType, @encode(NSInteger)) == 0) {
-        NSInteger result = 0;
-        [invocation getReturnValue:&result];
-        return @(result);
-    } else if (strcmp(retType, @encode(BOOL)) == 0) {
-        BOOL result = NO;
-        [invocation getReturnValue:&result];
-        return @(result);
-    } else if (strcmp(retType, @encode(CGFloat)) == 0) {
-        CGFloat result = 0;
-        [invocation getReturnValue:&result];
-        return @(result);
-    } else if (strcmp(retType, @encode(NSUInteger)) == 0) {
-        NSUInteger result = 0;
-        [invocation getReturnValue:&result];
-        return @(result);
-    } else {
-        id result = nil;
-        [invocation getReturnValue:&result];
-        return result;
-    }
+    [inv invoke];
+    return [NSObject bh_getReturnFromInv:inv withSig:sig];
 }
 
 @end
+
+

From 2b0392136b5e15d4ef46e4de57e674ee06f14a5b Mon Sep 17 00:00:00 2001
From: ZoMinster <zominster@gmail.com>
Date: Sat, 12 Aug 2017 10:33:01 +0800
Subject: [PATCH 3/3] =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=A2=9E=E5=8A=A0?=
 =?UTF-8?q?=E4=BC=98=E5=85=88=E7=BA=A7=EF=BC=8C=E5=90=8C=E4=B8=80level?=
 =?UTF-8?q?=E4=BC=98=E5=85=88=E7=BA=A7=E8=B6=8A=E5=A4=A7=E8=B6=8A=E4=BC=98?=
 =?UTF-8?q?=E5=85=88=EF=BC=8C=E4=B8=BB=E8=A6=81=E8=80=83=E8=99=91=E5=88=B0?=
 =?UTF-8?q?=E5=90=8C=E4=B8=80=E7=BA=A7=E4=B9=9F=E6=9C=89=E5=8F=AF=E8=83=BD?=
 =?UTF-8?q?=E6=9C=89=E5=8A=A0=E8=BD=BD=E5=85=88=E5=90=8E=E8=A6=81=E6=B1=82?=
 =?UTF-8?q?=EF=BC=8C=E4=B8=8D=E5=90=8Clevel=E4=BF=9D=E6=8C=81=E5=8E=9F?=
 =?UTF-8?q?=E6=9C=89=E9=80=BB=E8=BE=91=EF=BC=8Cbaselevel=E4=BC=98=E5=85=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 BeeHive/BHModuleManager.m            | 29 ++++++++++++++++++++++------
 BeeHive/BHModuleProtocol.h           |  2 ++
 BeeHive/BeeHive.bundle/BeeHive.plist |  4 ++++
 3 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/BeeHive/BHModuleManager.m b/BeeHive/BHModuleManager.m
index b9b487a..4a8c57c 100755
--- a/BeeHive/BHModuleManager.m
+++ b/BeeHive/BHModuleManager.m
@@ -15,6 +15,7 @@
 #define kModuleArrayKey     @"moduleClasses"
 #define kModuleInfoNameKey  @"moduleClass"
 #define kModuleInfoLevelKey @"moduleLevel"
+#define kModuleInfoPriorityKey @"modulePriority"
 
 static  NSString *kSetupSelector = @"modSetUp:";
 static  NSString *kInitSelector = @"modInit:";
@@ -129,10 +130,15 @@ - (void)registedAllModules
 {
 
     [self.BHModuleInfos sortUsingComparator:^NSComparisonResult(NSDictionary *module1, NSDictionary *module2) {
-      NSNumber *module1Level = (NSNumber *)[module1 objectForKey:kModuleInfoLevelKey];
-      NSNumber *module2Level =  (NSNumber *)[module2 objectForKey:kModuleInfoLevelKey];
-        
-        return [module1Level intValue] > [module2Level intValue];
+        NSNumber *module1Level = (NSNumber *)[module1 objectForKey:kModuleInfoLevelKey];
+        NSNumber *module2Level =  (NSNumber *)[module2 objectForKey:kModuleInfoLevelKey];
+        if (module1Level.integerValue != module2Level.integerValue) {
+            return module1Level.integerValue > module2Level.integerValue;
+        } else {
+            NSNumber *module1Priority = (NSNumber *)[module1 objectForKey:kModuleInfoPriorityKey];
+            NSNumber *module2Priority = (NSNumber *)[module2 objectForKey:kModuleInfoPriorityKey];
+            return module1Priority.integerValue < module2Priority.integerValue;
+        }
     }];
     
     NSMutableArray *tmpArray = [NSMutableArray array];
@@ -263,8 +269,19 @@ - (void)addModuleFromObject:(id)object
             if ([moduleInstance2 respondsToSelector:@selector(basicModuleLevel)]) {
                 module2Level = @(BHModuleBasic);
             }
-            
-            return [module1Level intValue] > [module2Level intValue];
+            if (module1Level.integerValue != module2Level.integerValue) {
+                return module1Level.integerValue > module2Level.integerValue;
+            } else {
+                NSInteger module1Priority = 0;
+                NSInteger module2Priority = 0;
+                if ([moduleInstance1 respondsToSelector:@selector(modulePriority)]) {
+                    module1Priority = [moduleInstance1 modulePriority];
+                }
+                if ([moduleInstance2 respondsToSelector:@selector(modulePriority)]) {
+                    module2Priority = [moduleInstance2 modulePriority];
+                }
+                return module1Priority < module2Priority;
+            }
         }];
         [self registerEventsByModuleInstance:moduleInstance];
         
diff --git a/BeeHive/BHModuleProtocol.h b/BeeHive/BHModuleProtocol.h
index c11d5ac..1f2440f 100755
--- a/BeeHive/BHModuleProtocol.h
+++ b/BeeHive/BHModuleProtocol.h
@@ -24,6 +24,8 @@
 //如果不去设置Level默认是Normal
 //basicModuleLevel不去实现默认Normal
 - (void)basicModuleLevel;
+//越大越优先
+- (NSInteger)modulePriority;
 
 - (BOOL)async;
 
diff --git a/BeeHive/BeeHive.bundle/BeeHive.plist b/BeeHive/BeeHive.bundle/BeeHive.plist
index 9be99b9..d80b7a9 100644
--- a/BeeHive/BeeHive.bundle/BeeHive.plist
+++ b/BeeHive/BeeHive.bundle/BeeHive.plist
@@ -11,12 +11,16 @@
 			<string>HomeModule</string>
 			<key>moduleLevel</key>
 			<integer>1</integer>
+			<key>modulePriority</key>
+			<string>600</string>
 		</dict>
 		<dict>
 			<key>moduleClass</key>
 			<string>TMTradeAdapter</string>
 			<key>moduleLevel</key>
 			<integer>1</integer>
+			<key>modulePriority</key>
+			<string>599</string>
 		</dict>
 	</array>
 </dict>