#include <learning.h>
#define SAVE SAVEPATH +"search"
mapping rooms, /* rooms[ keyword ] = array of rooms with this keyword
*/
objects, /* objects[ keyword ] = array of objects with this keyword
*/
keywords, /* keywords[ filename ] = array of keywords defined
* by file
*/
functions; /* functions[ filename ] = array of functions defined
* by object filename
*/
string *directories; /* Array holding the directories that still need
* checking.
* Used only while collecting information from
* rooms in the domain.
*/
nosave string word;
/* create() is the first function called in any object when it is
* cloned.
*/
void create() {
/* seteuid is needed for the save_object and restore_object calls
*/
seteuid( (string)master()->get_bb_uid() );
/* restore the saved values for the
*/
unguarded( (: restore_object, SAVE :) );
} /* create() */
/* Given words keywords chosen so far,
* return ({ ({ keywords }), ({ rooms }), ({ objects }) }),
* where keywords are all keywords that are in at least one of the rooms
* or objects, objects are all objects having all words defined
* and rooms are all rooms having all words defined.
*/
mixed get_keywords( string *words ) {
string *found_words, *found_rooms, *found_objects, key, *value;
if( sizeof( words ) ) {
/* all files known */
found_objects = keys( keywords );
foreach( word in words ) {
/* remove all files that haven't defined the keyword */
if( objects[ word ] ) {
found_objects = filter_array( found_objects,
(: member_array( $1, objects[ word ] ) != -1 :) );
} else {
found_objects = ({ });
}
}
/* all files known */
found_rooms = keys( keywords );
foreach( word in words ) {
/* remove all files that haven't defined the keyword */
if( rooms[ word ] ) {
found_rooms = filter_array( found_rooms,
(: member_array( $1, rooms[ word ] ) != -1 :) );
} else {
found_rooms = ({ });
}
}
found_words = ({ });
foreach( word in found_rooms ) {
found_words -= keywords[ word ]; /* remove duplicates */
found_words += keywords[ word ]; /* add new ones */
}
foreach( word in found_objects ) {
found_words -= keywords[ word ]; /* remove duplicates */
found_words += keywords[ word ]; /* add new ones */
}
found_words -= words; /* remove those found already */
} else {
found_rooms = ({ });
foreach( key, value in rooms ) {
found_rooms -= value; /* remove duplicates */
found_rooms += value; /* add new ones */
}
found_objects = ({ });
foreach( key, value in objects ) {
found_objects -= value; /* remove duplicates */
found_objects += value; /* add new ones */
}
found_words = keys( rooms );
found_words -= keys( objects );
found_words += keys( objects );
}
return ({ found_words, found_rooms, found_objects });
} /* get_keyword() */
/* Get information for specific file.
*/
void update_info_for( string file ) {
string *words, word;
object obj;
if( !catch( file->force_load() ) ) {
obj = find_object( file );
words = obj->query_property( "commented functions" );
if( words ) {
functions[ file ] = words;
}
words = obj->query_property( "keywords" );
if( words ) {
keywords[ file ] = words;
if( function_exists( "add_exit", obj ) ) { /* it's a room */
foreach ( word in words ) {
if( rooms[ word ] ) {
rooms[ word ] -= ({ file }); /* remove previous definition */
rooms[ word ] += ({ file }); /* add new */
} else {
rooms[ word ] = ({ file });
}
}
} else {
foreach ( word in words ) {
if( objects[ word ] ) {
objects[ word ] -= ({ file }); /* remove previous definition */
objects[ word ] += ({ file }); /* add new */
} else {
objects[ word ] = ({ file });
}
}
}
}
if( !directories ) { /* This is a single room so save the new info */
unguarded( (: save_object, SAVE :) );
}
}
} /* update_info_for() */
/* This function does the same as the update command used on the room
* Basically, it moves all users in the room, to the void, destructs the room
* loads it again, and moves prople back again.
*/
void update_search( string room ) {
object *obs;
int i;
obs = all_inventory( find_object( room ) );
i = sizeof( obs );
while( i-- ) {
if ( userp( obs[ i ] ) ) {
obs[ i ]->move( "/room/void" );
} else {
obs = delete( obs, i, 1 );
}
}
room->dest_me();
room->force_load();
obs->move( room );
} /* update_search() */
/* collects the information from the next directory in line, adding new
* subdirectories when found.
*/
void collect_one() {
string dir;
mixed dirs, file_info;
dir = directories[ 0 ];
dirs = get_dir( dir, -1 );
if( dirs ) {
foreach ( file_info in dirs ) {
if( file_info[ 1 ] == -2 ) { /* it's a directory */
if( file_info[ 0 ] != "old" ) { /* ignore the files in the old dir */
directories = directories + ({ dir + file_info[ 0 ] +"/" });
}
} else { /* it's a file */
if( ( sizeof( file_info[ 0 ] ) > 2 ) &&
( file_info[ 0 ][ <2 .. <1 ] == ".c" ) ) {
update_info_for( dir + file_info[ 0 ][ 0 .. <3 ] );
}
}
}
}
directories = directories[ 1 .. <1 ]; /* remove the dir that where just checked*/
if( find_call_out( "collect_one" ) == -1 && sizeof( directories ) ) {
call_out( "collect_one", 3 );
} else if( !sizeof( directories ) ) { /* we are done so save */
/* tell me it's done */
tell_object( find_living( "olorin" ), "Collect finished.\n" );
directories = 0;
/* and save it */
unguarded( (: save_object, SAVE :) );
/* this call is to restore all the keyword and function exits
* to the first search and function rooms
*/
update_search( LEARNING +"search" );
update_search( LEARNING +"functions" );
}
} /* collect_one */
void collect() {
/* This function will start a run through all files in the subdirectories of
* "/d/learning" and collect the needed information.
*/
rooms=([ ]);
objects=([ ]);
functions=([ ]);
keywords=([ ]);
directories=({ "/d/learning/" });
collect_one();
} /* collect() */
int query_collecting() {
if( directories ) {
return 1;
} else {
return 0;
}
} /* query_collecting() */
string find_room( string *words ) {
object thing, *things;
string word_mark;
if( !sizeof( words ) )
return LEARNING +"search";
word_mark = implode( sort_array( words, 1 ), ", " );
things = children( SEARCH_ROOM ) - ({ find_object( SEARCH_ROOM ) });
foreach ( thing in things ) {
if ( (string)thing->query_marker() == word_mark )
return file_name( thing );
}
thing = clone_object( SEARCH_ROOM );
thing->set_marker( word_mark, words );
return file_name( thing );
} /* find_room() */
string find_function_room( string word ) {
object thing, *things;
if( !word )
return LEARNING +"functions";
things = children( FUNCTION_ROOM ) - ({ find_object( FUNCTION_ROOM ) });
foreach ( thing in things ) {
if ( (string)thing->query_marker() == word )
return file_name( thing );
}
thing = clone_object( FUNCTION_ROOM );
thing->set_marker( word );
return file_name( thing );
} /* find_function_room() */
string *query_functions() {
string *functions_found, key, *value;
functions_found = ({ });
foreach ( key, value in functions ) {
functions_found -= value; /* remove duplicates */
functions_found += value;
}
return sort_array( functions_found, 1 );
} /* query_functions() */
string *query_rooms_with_function( string word ) {
string *rooms_found, key, *value;
rooms_found = ({ });
foreach ( key, value in functions ) {
if ( member_array( word, value ) != -1 )
rooms_found += ({ key });
}
return rooms_found;
} /* query_rooms_with_function() */