Oolite 1.91.0.7644-241112-7f5034b
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 

Extends class AI.

Definition at line 397 of file AI.m.

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

Extends class AI.

Definition at line 397 of file AI.m.

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

◆ deferredCallTrampolineWithInfo:

+ (void) deferredCallTrampolineWithInfo: (NSValue *) info

Extends class AI.

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

Extends class AI.

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 

Extends class AI.

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 

Extends class AI.

Definition at line 397 of file AI.m.

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

Extends class AI.

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

Extends class AI.

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: