Oolite
Loading...
Searching...
No Matches
AI(OOPrivate) Category Reference

Instance Methods

(void) - performDeferredCall:withObject:afterDelay:
 
(void) - refreshOwnerDesc
 
(void) - directSetStateMachine:name:
 
(void) - directSetState:
 
(NSDictionary *) - loadStateMachine:jsName:
 
(NSDictionary *) - cleanHandlers:forState:stateMachine:
 
(NSArray *) - cleanActions:forHandler:state:stateMachine:
 

Class Methods

(void) + deferredCallTrampolineWithInfo:
 

Detailed Description

Definition at line 55 of file AI.m.

Method Documentation

◆ cleanActions:forHandler:state:stateMachine:

- (NSArray *) cleanActions: (NSArray *)  actions
forHandler: (NSString *)  handlerKey
state: (NSString *)  stateKey
stateMachine: (NSString *)  smName 

Definition at line 397 of file AI.m.

912 :(NSArray *)actions forHandler:(NSString *)handlerKey state:(NSString *)stateKey stateMachine:(NSString *)smName
913{
914 NSString *action = nil;
915 NSRange spaceRange;
916 NSString *selector = nil;
917 id aliasedSelector = nil;
918 NSMutableArray *result = nil;
919 static NSSet *whitelist = nil;
920 static NSDictionary *aliases = nil;
921 NSArray *whitelistArray1 = nil;
922 NSArray *whitelistArray2 = nil;
923
924 if (whitelist == nil)
925 {
926 whitelistArray1 = [[ResourceManager whitelistDictionary] oo_arrayForKey:@"ai_methods"];
927 if (whitelistArray1 == nil) whitelistArray1 = [NSArray array];
928 whitelistArray2 = [[ResourceManager whitelistDictionary] oo_arrayForKey:@"ai_and_action_methods"];
929 if (whitelistArray2 != nil) whitelistArray1 = [whitelistArray1 arrayByAddingObjectsFromArray:whitelistArray2];
930
931 whitelist = [[NSSet alloc] initWithArray:whitelistArray1];
932 aliases = [[[ResourceManager whitelistDictionary] oo_dictionaryForKey:@"ai_method_aliases"] retain];
933 }
934
935 result = [NSMutableArray arrayWithCapacity:[actions count]];
936 foreach (action, actions)
937 {
938 if (![action isKindOfClass:[NSString class]])
939 {
940 OOLogWARN(@"ai.invalidFormat.action", @"An action in handler \"%@\" for state \"%@\" in AI \"%@\" is not a string, ignoring.", handlerKey, stateKey, smName);
941 continue;
942 }
943
944 // Trim spaces from beginning and end.
945 action = [action stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
946
947 // Cut off parameters.
948 spaceRange = [action rangeOfString:@" "];
949 if (spaceRange.location == NSNotFound) selector = action;
950 else selector = [action substringToIndex:spaceRange.location];
951
952 // Look in alias table.
953 aliasedSelector = [aliases objectForKey:selector];
954 if (aliasedSelector != nil)
955 {
956 if ([aliasedSelector isKindOfClass:[NSString class]])
957 {
958 // Change selector and action to use real method name.
959 selector = aliasedSelector;
960 if (spaceRange.location == NSNotFound) action = aliasedSelector;
961 else action = [aliasedSelector stringByAppendingString:[action substringFromIndex:spaceRange.location]];
962 }
963 else if ([aliasedSelector isKindOfClass:[NSArray class]] && [aliasedSelector count] != 0)
964 {
965 // Alias is complete expression, pretokenized in anticipation of a tokenized future.
966 action = [aliasedSelector componentsJoinedByString:@" "];
967 selector = [[aliasedSelector objectAtIndex:0] description];
968 }
969 }
970
971 // Check for selector in whitelist.
972 if (![whitelist containsObject:selector])
973 {
974 OOLog(@"ai.unpermittedMethod", @"Handler \"%@\" for state \"%@\" in AI \"%@\" uses \"%@\", which is not a permitted AI method.", handlerKey, stateKey, smName, selector);
975 continue;
976 }
977
978 [result addObject:action];
979 }
980
981 // Return immutable copy.
982 return [[result copy] autorelease];
983}
#define OOLogWARN(class, format,...)
Definition OOLogging.h:113
#define OOLog(class, format,...)
Definition OOLogging.h:88
unsigned count
return nil
NSDictionary * whitelistDictionary()

◆ cleanHandlers:forState:stateMachine:

- (NSDictionary *) cleanHandlers: (NSDictionary *)  handlers
forState: (NSString *)  stateKey
stateMachine: (NSString *)  smName 

Definition at line 397 of file AI.m.

887 :(NSDictionary *)handlers forState:(NSString *)stateKey stateMachine:(NSString *)smName
888{
889 NSString *handlerKey = nil;
890 NSArray *handlerActions = nil;
891 NSMutableDictionary *result = nil;
892
893 result = [NSMutableDictionary dictionaryWithCapacity:[handlers count]];
894 foreachkey (handlerKey, handlers)
895 {
896 handlerActions = [handlers objectForKey:handlerKey];
897 if (![handlerActions isKindOfClass:[NSArray class]])
898 {
899 OOLogWARN(@"ai.invalidFormat.handler", @"Handler \"%@\" for state \"%@\" in AI \"%@\" is not an array, ignoring.", handlerKey, stateKey, smName);
900 continue;
901 }
902
903 handlerActions = [self cleanActions:handlerActions forHandler:handlerKey state:stateKey stateMachine:smName];
904 [result setObject:handlerActions forKey:handlerKey];
905 }
906
907 // Return immutable copy.
908 return [[result copy] autorelease];
909}
#define foreachkey(VAR, DICT)
Definition OOCocoa.h:353

◆ deferredCallTrampolineWithInfo:

+ (void) deferredCallTrampolineWithInfo: (NSValue *)  info

Definition at line 397 of file AI.m.

740 :(NSValue *)info
741{
743
744 if (info != nil)
745 {
746 assert(strcmp([info objCType], @encode(OOAIDeferredCallTrampolineInfo)) == 0);
747 [info getValue:&infoStruct];
748
749 [infoStruct.ai performSelector:infoStruct.selector withObject:infoStruct.parameter];
750
751 [infoStruct.ai release];
752 [infoStruct.parameter release];
753 }
754}

◆ directSetState:

- (void) directSetState: (NSString *)  state

Definition at line 397 of file AI.m.

791 :(NSString *)state
792{
793 if (currentState != state)
794 {
795 [currentState release];
796 currentState = [state copy];
797 }
798}

◆ directSetStateMachine:name:

- (void) directSetStateMachine: (NSDictionary *)  newSM
name: (NSString *)  name 

Definition at line 397 of file AI.m.

776 :(NSDictionary *)newSM name:(NSString *)name
777{
778 if (stateMachine != newSM)
779 {
780 [stateMachine release];
781 stateMachine = [newSM copy];
782 }
783 if (stateMachineName != name)
784 {
785 [stateMachineName release];
786 stateMachineName = [name copy];
787 }
788}

◆ loadStateMachine:jsName:

- (NSDictionary *) loadStateMachine: (NSString *)  smName
jsName: (NSString *)  script 

Definition at line 397 of file AI.m.

801 :(NSString *)smName jsName:(NSString *)script
802{
803 NSDictionary *newSM = nil;
804 NSMutableDictionary *cleanSM = nil;
806 NSString *stateKey = nil;
807 NSDictionary *stateHandlers = nil;
808 NSAutoreleasePool *pool = nil;
809
810 if (![smName isEqualToString:@"nullAI.plist"])
811 {
812 // don't cache nullAI since they're different depending on associated JS AI
813 newSM = [cacheMgr objectForKey:smName inCache:@"AIs"];
814 if (newSM != nil && ![newSM isKindOfClass:[NSDictionary class]]) return nil; // catches use of @"nil" to indicate no AI found.
815 }
816
817 if (newSM == nil)
818 {
819 pool = [[NSAutoreleasePool alloc] init];
820 OOLog(@"ai.load", @"Loading and sanitizing AI \"%@\"", smName);
822 OOLogIndentIf(@"ai.load");
823
824 @try
825 {
826 // Load state machine and validate against whitelist.
827 NSString *aiPath = [ResourceManager pathForFileNamed:smName inFolder:@"AIs"];
828 if (aiPath != nil)
829 {
830 newSM = OODictionaryFromFile(aiPath);
831 }
832 if (newSM == nil)
833 {
834 [cacheMgr setObject:@"nil" forKey:smName inCache:@"AIs"];
835 NSString *fromString = @"";
836 if ([self state] != nil)
837 {
838 fromString = [NSString stringWithFormat:@" from %@:%@", [self name], [self state]];
839 }
840 OOLog(@"ai.load.failed.unknownAI", @"Can't switch AI for %@%@ to \"%@\" - could not load file.", [[self owner] shortDescription], fromString, smName);
841 return nil;
842 }
843
844 cleanSM = [NSMutableDictionary dictionaryWithCapacity:[newSM count]];
845
846 foreachkey (stateKey, newSM)
847 {
848 stateHandlers = [newSM objectForKey:stateKey];
849 if (![stateHandlers isKindOfClass:[NSDictionary class]])
850 {
851 OOLogWARN(@"ai.invalidFormat.state", @"State \"%@\" in AI \"%@\" is not a dictionary, ignoring.", stateKey, smName);
852 continue;
853 }
854
855 stateHandlers = [self cleanHandlers:stateHandlers forState:stateKey stateMachine:smName];
856 [cleanSM setObject:stateHandlers forKey:stateKey];
857 }
858 [cleanSM setObject:script forKey:@"jsScript"];
859
860 // Make immutable.
861 newSM = [[cleanSM copy] autorelease];
862
863#if DEBUG_GRAPHVIZ
864 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"generate-ai-graphviz"])
865 {
866 GenerateGraphVizForAIStateMachine(newSM, smName);
867 }
868#endif
869
870 // Cache.
871 [cacheMgr setObject:newSM forKey:smName inCache:@"AIs"];
872 }
873 @finally
874 {
876 }
877
878 [newSM retain];
879 [pool release];
880 [newSM autorelease];
881 }
882
883 return newSM;
884}
void OOLogPushIndent(void)
Definition OOLogging.m:316
void OOLogPopIndent(void)
Definition OOLogging.m:340
#define OOLogIndentIf(class)
Definition OOLogging.h:101
NSDictionary * OODictionaryFromFile(NSString *path)
void setObject:forKey:inCache:(id inElement,[forKey] NSString *inKey,[inCache] NSString *inCacheKey)
id objectForKey:inCache:(NSString *inKey,[inCache] NSString *inCacheKey)
OOCacheManager * sharedCache()
NSString * pathForFileNamed:inFolder:(NSString *fileName,[inFolder] NSString *folderName)

◆ performDeferredCall:withObject:afterDelay:

- (void) performDeferredCall: (SEL)  selector
withObject: (id)  object
afterDelay: (NSTimeInterval)  delay 

Definition at line 397 of file AI.m.

719 :(SEL)selector withObject:(id)object afterDelay:(NSTimeInterval)delay
720{
722 NSValue *info = nil;
723
724 if (selector != NULL)
725 {
726 infoStruct.ai = [self retain];
727 infoStruct.selector = selector;
728 infoStruct.parameter = object;
729
730 info = [[NSValue alloc] initWithBytes:&infoStruct objCType:@encode(OOAIDeferredCallTrampolineInfo)];
731
732 [[AI class] performSelector:@selector(deferredCallTrampolineWithInfo:)
733 withObject:info
734 afterDelay:delay];
735 [info release];
736 }
737}
Definition AI.h:38

◆ refreshOwnerDesc

- (void) refreshOwnerDesc

Definition at line 397 of file AI.m.

758{
759 ShipEntity *owner = [self owner];
760 [ownerDesc release];
761 if ([owner isPlayer])
762 {
763 ownerDesc = @"player autopilot";
764 }
765 else if (owner != nil)
766 {
767 ownerDesc = [[NSString alloc] initWithFormat:@"%@ %d", [owner name], [owner universalID]];
768 }
769 else
770 {
771 ownerDesc = @"no owner";
772 }
773}
OOUniversalID universalID
Definition Entity.h:89
NSString * name
Definition ShipEntity.h:327

The documentation for this category was generated from the following file: