From dd6175d9c5982e5e87e51a842bd31ce33a6af12e Mon Sep 17 00:00:00 2001 From: Stefan Urbanek Date: Tue, 4 Jun 2002 17:59:06 +0000 Subject: [PATCH] Added object finders git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/steptalk/trunk@13769 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 28 ++- Documentation/DOTemplate.plist | 20 ++ Documentation/HowTo.txt | 62 ++++-- Documentation/ObjectFinders.txt | 9 + Examples/Shell/STShell.m | 31 ++- Examples/Shell/stshell.m | 1 + Finders/GNUmakefile | 40 ++++ GNUmakefile | 1 + Languages/Smalltalk/STMethodContext.m | 5 +- Source/Headers/StepTalk/STEnvironment.h | 24 +-- Source/Headers/StepTalk/STObjectReference.h | 4 - Source/STEnvironment.m | 212 +++++++++++--------- Source/STFunctions.m | 7 +- Source/STObjCRuntime.m | 7 + Source/STObjectReference.m | 20 +- 15 files changed, 306 insertions(+), 165 deletions(-) create mode 100644 Documentation/DOTemplate.plist create mode 100644 Documentation/ObjectFinders.txt create mode 100644 Finders/GNUmakefile diff --git a/ChangeLog b/ChangeLog index 09ac5c5..ee17506 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2002 Jun 4 + + * STEnvironment: new methods -addObjectFinder:name:, + -addObjectFinderWithName:, -removeObjectFinderWithName:; + new method knownObjectNames; + objectReferenceForObjectWithName: changed to use nil reference on + known object that cannot be currently found + * Finders: new directory containing object finders + * STObjCRuntime: include selectors of metaclasses in + STAllObjectiveCSelectors() + * Documentation/HowTo.txt: rewritten + +2002 Jun 3 + + * STFunctions: renamed "StepTalk/Config" directory to + "StepTalk/Configuration"; fixed bug in STFindAllResources (resourceDir + was ignored) + * STEnvironment: changed method allObjectsDictionary to allObjectNames + +2002 May 30 + + * STEnvironment: removed pools + * STObjectReference: removed method initWithObjectName:pool:create: + 2002 May 29 * STExecutor: fixed typo @@ -35,10 +59,6 @@ Use make appkit=no. * Separated AppTalk -2002 Mar 21 - - * STEnvironment: removed pools - 2002 Mar 17 * STEngine: removed executeScript: methods and use only executeSource: diff --git a/Documentation/DOTemplate.plist b/Documentation/DOTemplate.plist new file mode 100644 index 0000000..50a975a --- /dev/null +++ b/Documentation/DOTemplate.plist @@ -0,0 +1,20 @@ +/* DOTemplate.plist + + This file contains template for a distributed object in the distributed + environment. + + File name is name of the object used in the environment. + + DO files should reside in: + + any_gnustep_root/Library/StepTalk/DistributedObjects +*/ + +{ + Host = "default host name"; + Hosts = ( list of hosts to be searched ); + Tool = "name of a tool that will register the object"; + Arguments = (tool arguments); + Name = "name of the object to be connected"; + Wait = seconds to wait before connection after the tool is launched; +} diff --git a/Documentation/HowTo.txt b/Documentation/HowTo.txt index 68893f6..270f690 100644 --- a/Documentation/HowTo.txt +++ b/Documentation/HowTo.txt @@ -1,28 +1,60 @@ StepTalk HowTo ----------------------- +-------------- + +NOTE: This file has to be written! + +You may consult StepTalk header files. -Here are some references where you may find how to use StepTalk: How to create scripting environment? +------------------------------------ - Tools/stalk.m - -createEnvironment + STEnvironment *env; + + env = [STEnvironment defaultScriptingEnvironment]; +or + env = [STEnvironment environmentWithDescriptionName:envName]; -How to execute code? - Tools/STExecutor.m - -executeScripts - -executeScript:withArguments: +How to register named objects in the scripting environment? +----------------------------------------------------------- + + [env setObject:object forName:@"ObjectName"]; + +like in: + + [env setObject:transcript forName:@"Transcript"]; + +See: STEnvironment + +How to create a scripting engine? +--------------------------------- + + STEngine *engine; + + engine = [STEngine engineForLanguageWithName:langName]; + +See: STLanguage, STEngine + +How to execute a code? +-------------------- + + STEngine *engine; + id result; + + NS_DURING + result = [engine executeCode:line inEnvironment:env]; + NS_HANDLER + /* handle the exception */ + NS_ENDHANDLER + +See: STEngine, NSException How to create a language bundle? - - Languages/Smalltalk/LanguageEngine.m - Languages/Smalltalk/LanguageEngine.h +-------------------------------- + Languages/Smalltalk/SmalltalkEngine.m + Languages/Smalltalk/SmalltalkEngine.h Languages/Smalltalk/STBytecodeInterpreter.m - sendSelectorAtIndex:withArgCount: - -How to create a scriptable server? - - see Examples/Server diff --git a/Documentation/ObjectFinders.txt b/Documentation/ObjectFinders.txt new file mode 100644 index 0000000..2d2536c --- /dev/null +++ b/Documentation/ObjectFinders.txt @@ -0,0 +1,9 @@ +Object Finders +-------------- + +STEnvironment provides mechanisms for named objects. Object finders are objects +that will find an object by a name. The lookup is as follows: + + 1. look for object in environment's object pool + 2. look for object using all environment's finders + diff --git a/Examples/Shell/STShell.m b/Examples/Shell/STShell.m index 228d493..49468ca 100644 --- a/Examples/Shell/STShell.m +++ b/Examples/Shell/STShell.m @@ -30,7 +30,9 @@ #import #import +#import #import +#import #import #import #import @@ -70,15 +72,33 @@ int complete_handler(void) [self initReadline]; - /* FIXME: update on change */ objcSelectors = RETAIN(STAllObjectiveCSelectors()); objectStack = [[NSMutableArray alloc] init]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(bundleLoaded:) + name:NSBundleDidLoadNotification + object:nil]; + prompt = @"StepTalk > "; return self; } +- (void)dealloc +{ + RELEASE(objectStack); + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super dealloc]; +} +-(void)bundleLoaded:(NSNotification *)notif +{ + /* FIXME: update only loaded classes */ + RELEASE(objcSelectors); + objcSelectors = RETAIN(STAllObjectiveCSelectors()); +} - (void)initReadline { @@ -92,7 +112,7 @@ int complete_handler(void) RELEASE(engine); engine = [STEngine engineForLanguageWithName:langName]; - RETAIN(engine); + RETAIN(engine); } - (void)setEnvironment:(STEnvironment *)newEnv @@ -111,11 +131,14 @@ int complete_handler(void) id result; [env setCreatesUnknownObjects:YES]; - + [env setObject:self forName:@"Shell"]; [env setObject:self forName:@"Transcript"]; [env setObject:objectStack forName:@"Objects"]; + /* FIXME: This is unsafe !*/ + [env setObject:env forName:@"Environment"]; + [self showLine:@"Welcome to the StepTalk shell."]; while(1) @@ -227,7 +250,7 @@ int complete_handler(void) set = [NSMutableSet set]; - enumerator = [[env allObjectsDictionary] keyEnumerator]; + enumerator = [[env knownObjectNames] objectEnumerator]; while( (str = [enumerator nextObject]) ) { if( [str hasPrefix:match] ) diff --git a/Examples/Shell/stshell.m b/Examples/Shell/stshell.m index 052af52..fcb721f 100644 --- a/Examples/Shell/stshell.m +++ b/Examples/Shell/stshell.m @@ -144,6 +144,7 @@ } [env loadModule:@"Foundation"]; + [env addObjectFinderWithName:@"DistributedFinder"]; shell = [STShell sharedShell]; [shell setEnvironment:env]; diff --git a/Finders/GNUmakefile b/Finders/GNUmakefile new file mode 100644 index 0000000..d6bd490 --- /dev/null +++ b/Finders/GNUmakefile @@ -0,0 +1,40 @@ +# +# GNUmakefile +# +# Copyright (C) 2002 Stefan Urbanek +# +# Written by: Stefan Urbanek +# +# This file is part of the StepTalk +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free +# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA +# + +GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_USER_ROOT) + +GNUSTEP_MAKEFILES = $(GNUSTEP_SYSTEM_ROOT)/Makefiles + +include $(GNUSTEP_MAKEFILES)/common.make + +ifeq ($(appkit),no) + SUBPROJECTS = DistributedFinder +else + SUBPROJECTS = DistributedFinder # ApplicationFinder +endif + +-include GNUMakefile.preamble +include $(GNUSTEP_MAKEFILES)/aggregate.make +-include GNUMakefile.postamble + diff --git a/GNUmakefile b/GNUmakefile index edb8d3d..d16e1c6 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -33,6 +33,7 @@ CVS_MODULE_NAME = StepTalk SUBPROJECTS = \ Source \ Languages \ + Finders \ Modules \ Tools diff --git a/Languages/Smalltalk/STMethodContext.m b/Languages/Smalltalk/STMethodContext.m index fa43cbf..11806ed 100644 --- a/Languages/Smalltalk/STMethodContext.m +++ b/Languages/Smalltalk/STMethodContext.m @@ -98,9 +98,8 @@ if(![ref object]) { [NSException raise:STGenericException - format:@"Unknown object with name '%@' " - @"in pool '%@'", - [lit objectName], [lit poolName]]; + format:@"Unknown object with name '%@' ", + [lit objectName]]; } [externs addObject:ref]; } diff --git a/Source/Headers/StepTalk/STEnvironment.h b/Source/Headers/StepTalk/STEnvironment.h index 0f0071c..124b5df 100644 --- a/Source/Headers/StepTalk/STEnvironment.h +++ b/Source/Headers/StepTalk/STEnvironment.h @@ -38,18 +38,17 @@ @interface STEnvironment:NSObject { - NSMutableDictionary *pools; NSMutableDictionary *defaultPool; STEnvironmentDescription *description; NSMutableDictionary *classes; /* from description */ -// NSMutableSet *modules; - BOOL fullScripting; BOOL createsUnknownObjects; - + NSMutableDictionary *infoCache; + + NSMutableDictionary *objectFinders; } /** Creating environment */ + (STEnvironment *)defaultScriptingEnvironment; @@ -79,27 +78,18 @@ /** Named objects and object references */ - (NSDictionary *)allObjectsDictionary; - - (void)setObject:(id)anObject forName:(NSString *)objName; - - (void)removeObjectWithName:(NSString *)objName; -- (void)removeObjectWithName:(NSString *)objName - pool:(NSString *)poolName; - - (void)addNamedObjectsFromDictionary:(NSDictionary *)dict; -- (void)addNamedObjectsFromDictionary:(NSDictionary *)dict - pool:(NSString *)poolName; - - (id)objectWithName:(NSString *)objName; -- (id)objectWithName:(NSString *)objName - pool:(NSString *)poolName; - (STObjectReference *)objectReferenceForObjectWithName:(NSString *)name; -- (STObjectReference *)objectReferenceForObjectWithName:(NSString *)name - pool:(NSString *)poolName; -- (void)removePool:(NSString *)poolName; +/** Distributed objects */ +- (void)addObjectFinder:(id)finder name:(NSString*)name; +- (void)addObjectFinderWithName:(NSString *)name; +- (void)removeObjectFinderWithName:(NSString *)name; /** Selector translation */ diff --git a/Source/Headers/StepTalk/STObjectReference.h b/Source/Headers/StepTalk/STObjectReference.h index 60fb00e..874fe6a 100644 --- a/Source/Headers/StepTalk/STObjectReference.h +++ b/Source/Headers/StepTalk/STObjectReference.h @@ -38,10 +38,6 @@ - initWithObjectName:(NSString *)name pool:(NSMutableDictionary *)aPool; -- initWithObjectName:(NSString *)name - pool:(NSMutableDictionary *)aPool - create:(BOOL)createFlag; - - (void)setObject:anObject; - object; diff --git a/Source/STEnvironment.m b/Source/STEnvironment.m index e46d463..3ebcd62 100644 --- a/Source/STEnvironment.m +++ b/Source/STEnvironment.m @@ -39,6 +39,7 @@ #import #import +#import #import #import #import @@ -153,11 +154,11 @@ - (void)dealloc { RELEASE(defaultPool); - RELEASE(pools); RELEASE(description); RELEASE(infoCache); - + RELEASE(objectFinders); + [super dealloc]; } @@ -229,7 +230,7 @@ } /* ----------------------------------------------------------------------- - Object pools + Objects ----------------------------------------------------------------------- */ /** @@ -259,40 +260,6 @@ } } -- (NSMutableDictionary *) poolWithName:(NSString *)poolName -{ - NSMutableDictionary *pool = [pools objectForKey:poolName]; - - if(!defaultPool) - { - defaultPool = [[NSMutableDictionary alloc] init]; - } - - if(!pool) - { - [NSException raise:STGenericException - format:@"Undefined pool with name '%@'", poolName]; - - - pool = defaultPool; - } - - return pool; -} - - -/** - Register object anObject with name objName in pool - poolName. - */ -- (void)addObject:(id)anObject - withName:(NSString *)objName - pool:(NSString *)poolName -{ - - [[self poolWithName:poolName] setObject:anObject forKey:objName]; -} - /** Remove object named objName. */ @@ -301,15 +268,6 @@ [defaultPool removeObjectForKey:objName]; } -/** - Remove object named objName form pool poolName - */ -- (void)removeObjectWithName:(NSString *)objName - pool:(NSString *)poolName -{ - [[self poolWithName:poolName] removeObjectForKey:objName]; -} - /** */ @@ -318,66 +276,56 @@ [defaultPool addEntriesFromDictionary:dict]; } - -- (void)addNamedObjectsFromDictionary:(NSDictionary *)dict - pool:(NSString *)poolName -{ - [[self poolWithName:poolName] addEntriesFromDictionary:dict]; - -} - - (id)objectWithName:(NSString *)objName { - id object; + NSEnumerator *enumerator; + id obj; + id finder; - object = [defaultPool objectForKey:objName]; + obj = [defaultPool objectForKey:objName]; + + if(!obj) + { + enumerator = [objectFinders objectEnumerator]; + while( (finder = [enumerator nextObject]) ) + { + obj = [finder objectWithName:objName]; + if(obj) + { + [defaultPool setObject:obj forKey:objName]; + break; + } + } + } + + return obj; +} + +- (STObjectReference *)objectReferenceForObjectWithName:(NSString *)name +{ + STObjectReference *ref; + id pool = defaultPool; - return object; -} + if( ![self objectWithName:name] ) + { + if([[self knownObjectNames] containsObject:name]) + { + pool = nil; + } + else if(createsUnknownObjects) + { + [defaultPool setObject:STNil forKey:name]; + } + } -- (id)objectWithName:(NSString *)objName - pool:(NSString *)poolName - -{ - id object; - - object = [[self poolWithName:poolName] objectForKey:objName]; - - return object; -} - -- (STObjectReference *)objectReferenceForObjectWithName:(NSString *)name -{ - STObjectReference *ref; - ref = [STObjectReference alloc]; + [ref initWithObjectName:name - pool:defaultPool - create:createsUnknownObjects]; + pool:defaultPool]; return AUTORELEASE(ref); } -- (STObjectReference *)objectReferenceForObjectWithName:(NSString *)name - pool:(NSString *)poolName -{ - STObjectReference *ref; - - ref = [STObjectReference alloc]; - [ref initWithObjectName:name - pool:[self poolWithName:poolName] - create:createsUnknownObjects]; - - return AUTORELEASE(ref); - -} - -- (void)removePool:(NSString *)poolName -{ - [pools removeObjectForKey:poolName]; -} - - /* FIXME: rewrite */ - (STClassInfo *)findClassInfoForObject:(id)anObject { @@ -527,9 +475,79 @@ return selector; } -- (NSDictionary *)allObjectsDictionary +- (NSArray *)allObjectNames { - return [NSDictionary dictionaryWithDictionary:defaultPool]; + return [defaultPool allKeys]; +} + +- (NSArray *)knownObjectNames +{ + NSMutableArray *array = [NSMutableArray array]; + NSEnumerator *enumerator; + id finder; + + [array addObjectsFromArray:[defaultPool allKeys]]; + + enumerator = [objectFinders objectEnumerator]; + while( (finder = [enumerator nextObject]) ) + { + [array addObjectsFromArray:[finder knownObjectNames]]; + } + + return [NSArray arrayWithArray:array]; +} +/** Distributed objects */ +- (void)addObjectFinder:(id)finder name:(NSString*)name +{ + if(!objectFinders) + { + objectFinders = [[NSMutableDictionary alloc] init]; + } + + [objectFinders setObject:finder forKey:name]; +} + +- (void)addObjectFinderWithName:(NSString *)name +{ + NSBundle *bundle; + NSString *path; + id finder; + + if([objectFinders objectForKey:name]) + { + return; + } + + path = STFindResource(name, @"Finders", @"bundle"); + + if(!path) + { + NSLog(@"Unknown object finder with name '%@'", name); + return; + } + + NSLog(@"Finder '%@'", path); + + bundle = [NSBundle bundleWithPath:path]; + if(!bundle) + { + NSLog(@"Unable to load object finder bundle '%@'", path); + return; + } + + finder = [[[bundle principalClass] alloc] init]; + if(!finder) + { + NSLog(@"Unable to create object finder from '%@'", path); + return; + } + + [self addObjectFinder:finder name:name]; +} + +- (void)removeObjectFinderWithName:(NSString *)name +{ + [objectFinders removeObjectForKey:name]; } @end diff --git a/Source/STFunctions.m b/Source/STFunctions.m index 48fccf7..22bf089 100644 --- a/Source/STFunctions.m +++ b/Source/STFunctions.m @@ -89,7 +89,8 @@ NSArray *STFindAllResources(NSString *resourceDir, NSString *extension) while( (path = [enumerator nextObject]) ) { path = [path stringByAppendingPathComponent:STLibraryDirectory]; - + path = [path stringByAppendingPathComponent:resourceDir]; + if( ![manager fileExistsAtPath:path] ) { continue; @@ -109,7 +110,7 @@ NSArray *STFindAllResources(NSString *resourceDir, NSString *extension) } } - return AUTORELEASE([resources copy]); + return [NSArray arrayWithArray:resources]; } NSString *STUserConfigPath(void) @@ -122,7 +123,7 @@ NSString *STUserConfigPath(void) path = [paths objectAtIndex: 0]; path = [path stringByAppendingPathComponent:STLibraryDirectory]; - path = [path stringByAppendingPathComponent:@"Config"]; + path = [path stringByAppendingPathComponent:@"Configuration"]; return path; } diff --git a/Source/STObjCRuntime.m b/Source/STObjCRuntime.m index 71779b4..4c65809 100644 --- a/Source/STObjCRuntime.m +++ b/Source/STObjCRuntime.m @@ -195,6 +195,13 @@ NSArray *STAllObjectiveCSelectors(void) methods = selectors_from_list(class->methods); [array addObjectsFromArray:methods]; } + class = class->class_pointer; + + if(class->methods) + { + methods = selectors_from_list(class->methods); + [array addObjectsFromArray:methods]; + } } /* get rid of duplicates */ diff --git a/Source/STObjectReference.m b/Source/STObjectReference.m index d098300..00ee39b 100644 --- a/Source/STObjectReference.m +++ b/Source/STObjectReference.m @@ -36,30 +36,14 @@ @implementation STObjectReference - initWithObjectName:(NSString *)name pool:(NSMutableDictionary *)aPool { - return [self initWithObjectName:name - pool:pool - create:NO]; -} - -- initWithObjectName:(NSString *)name - pool:(NSMutableDictionary *)aPool - create:(BOOL)createFlag -{ - - [super init]; + self = [super init]; key = RETAIN(name); pool = RETAIN(aPool); - if(![self object] && createFlag) - { - NSDebugLog(@"Creating object name '%@'", name); - [pool setObject:STNil forKey:name]; - } - - return self; } + - (void)dealloc { RELEASE(key);