mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Use a hash table for finding entities.
This gives a major speed boost :)
This commit is contained in:
parent
32f3f5c06b
commit
6cb3d18fc4
4 changed files with 110 additions and 10 deletions
|
@ -215,8 +215,12 @@ epair_free (void *_ep, void *unused)
|
|||
if (e) {
|
||||
if (!strcmp (e->value, v))
|
||||
return;
|
||||
if (!strcmp (e->key, "targetname") && e->value[0])
|
||||
[map_i removeTarget: self];
|
||||
free (e->value);
|
||||
e->value = strdup (v);
|
||||
if (!strcmp (e->key, "targetname") && e->value[0])
|
||||
[map_i addTarget: self];
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -230,6 +234,8 @@ epair_free (void *_ep, void *unused)
|
|||
epairs->prev = &e->next;
|
||||
epairs = e;
|
||||
Hash_Add (epair_tab, e);
|
||||
if (!strcmp (e->key, "targetname") && e->value[0])
|
||||
[map_i addTarget: self];
|
||||
}
|
||||
|
||||
- (int) numPairs
|
||||
|
|
|
@ -15,6 +15,7 @@ extern id map_i;
|
|||
id currentEntity;
|
||||
id oldselection; // temp when loading a new map
|
||||
float minz, maxz;
|
||||
struct hashtab_s *targets;
|
||||
}
|
||||
|
||||
- (id) newMap;
|
||||
|
@ -34,6 +35,13 @@ extern id map_i;
|
|||
- (id) currentEntity;
|
||||
- (id) setCurrentEntity: ent;
|
||||
|
||||
- (id) addTarget: (id) targ;
|
||||
- (id) removeTarget: (id) targ;
|
||||
- (void) addEntity: (id) ent;
|
||||
- (void) removeEntity: (id) ent;
|
||||
- (void) removeEntityAtIndex: (NSUInteger) index;
|
||||
- (NSArray *) targetsForTargetName: (const char *) targetname;
|
||||
|
||||
- (float) currentMinZ;
|
||||
- (id) setCurrentMinZ: (float)m;
|
||||
- (float) currentMaxZ;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "QF/hash.h"
|
||||
#include "QF/quakeio.h"
|
||||
#include "QF/script.h"
|
||||
#include "QF/sys.h"
|
||||
|
@ -32,10 +33,31 @@ FILE METHODS
|
|||
|
||||
===============================================================================
|
||||
*/
|
||||
static const char *
|
||||
map_targets_getkey (void *_e, void *unused)
|
||||
{
|
||||
Entity *e = (Entity *) _e;
|
||||
return [e valueForQKey: "targetname"];
|
||||
}
|
||||
|
||||
static uintptr_t
|
||||
map_targets_gethash (void *_e, void *unused)
|
||||
{
|
||||
return Hash_String (map_targets_getkey (_e, unused));
|
||||
}
|
||||
|
||||
static int
|
||||
map_targets_compare (void *_e1, void *_e2, void *unused)
|
||||
{
|
||||
return _e1 == _e2;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
self = [super init];
|
||||
array = [[NSMutableArray alloc] init];
|
||||
targets = Hash_NewTable (1021, map_targets_getkey, 0, 0);
|
||||
Hash_SetHashCompare (targets, map_targets_gethash, map_targets_compare);
|
||||
map_i = self;
|
||||
minz = 0;
|
||||
maxz = 80;
|
||||
|
@ -45,6 +67,13 @@ FILE METHODS
|
|||
return self;
|
||||
}
|
||||
|
||||
- (oneway void) dealloc
|
||||
{
|
||||
Hash_DelTable (targets);
|
||||
[array release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id) saveSelected
|
||||
{
|
||||
int i, c;
|
||||
|
@ -65,7 +94,7 @@ FILE METHODS
|
|||
c = [self count];
|
||||
for (i = 0; i < c; i++) {
|
||||
o = [self objectAtIndex: 0];
|
||||
[self removeObjectAtIndex: 0];
|
||||
[self removeEntityAtIndex: 0];
|
||||
[o removeAllObjects];
|
||||
}
|
||||
|
||||
|
@ -98,7 +127,7 @@ FILE METHODS
|
|||
|
||||
[self saveSelected];
|
||||
ent = [[Entity alloc] initClass: "worldspawn"];
|
||||
[self addObject: ent];
|
||||
[self addEntity: ent];
|
||||
currentEntity = NULL;
|
||||
[self setCurrentEntity: ent];
|
||||
[self addSelected];
|
||||
|
@ -167,9 +196,22 @@ FILE METHODS
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) removeObject: o
|
||||
- (void) addEntity: o
|
||||
{
|
||||
[super removeObject: o];
|
||||
const char *t = [o valueForQKey: "targetname"];
|
||||
if (t && t[0])
|
||||
[self addTarget: o];
|
||||
|
||||
[self addObject: o];
|
||||
}
|
||||
|
||||
- (void) removeEntity: o
|
||||
{
|
||||
const char *t = [o valueForQKey: "targetname"];
|
||||
if (t && t[0])
|
||||
[self removeTarget: o];
|
||||
|
||||
[array removeObject: o];
|
||||
|
||||
if (o == currentEntity) // select the world
|
||||
[self setCurrentEntity: [self objectAtIndex: 0]];
|
||||
|
@ -177,6 +219,48 @@ FILE METHODS
|
|||
return;
|
||||
}
|
||||
|
||||
- (void) removeEntityAtIndex: (NSUInteger) index
|
||||
{
|
||||
id o = [self objectAtIndex: index];
|
||||
const char *t = [o valueForQKey: "targetname"];
|
||||
if (t && t[0])
|
||||
[self removeTarget: o];
|
||||
[self removeObjectAtIndex: index];
|
||||
}
|
||||
|
||||
- (id) addTarget: (id) targ
|
||||
{
|
||||
if (Hash_FindElement (targets, targ))
|
||||
return self;
|
||||
printf ("adding %s:%s\n", [targ valueForQKey: "classname"],
|
||||
[targ valueForQKey: "targetname"]);
|
||||
Hash_Add (targets, targ);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id) removeTarget: (id) targ
|
||||
{
|
||||
Hash_DelElement (targets, targ);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSArray *) targetsForTargetName: (const char *) targetname
|
||||
{
|
||||
NSArray *target_list;
|
||||
void **list;
|
||||
int count;
|
||||
|
||||
list = Hash_FindList (targets, targetname);
|
||||
if (!list)
|
||||
return nil;
|
||||
|
||||
for (count = 0; list[count]; count++)
|
||||
;
|
||||
target_list = [NSArray arrayWithObjects: (id *) list count: count];
|
||||
free (list);
|
||||
return target_list;
|
||||
}
|
||||
|
||||
#define FN_DEVLOG "/qcache/devlog"
|
||||
- (id) writeStats
|
||||
{
|
||||
|
@ -260,7 +344,7 @@ readMapFile
|
|||
new = [[Entity alloc] initFromScript: script];
|
||||
if (!new)
|
||||
break;
|
||||
[self addObject: new];
|
||||
[self addEntity: new];
|
||||
} while (1);
|
||||
|
||||
free (dat);
|
||||
|
@ -877,7 +961,7 @@ UI operations
|
|||
continue;
|
||||
|
||||
new = [o copy];
|
||||
[self addObject: new];
|
||||
[self addEntity: new];
|
||||
|
||||
c = [o count];
|
||||
for (j = 0; j < c; j++)
|
||||
|
@ -941,7 +1025,7 @@ UI operations
|
|||
[[sb_newowner objectAtIndex: 0] setSelected: YES];
|
||||
}
|
||||
|
||||
[self addObject: sb_newowner];
|
||||
[self addEntity: sb_newowner];
|
||||
[self setCurrentEntity: sb_newowner];
|
||||
|
||||
[quakeed_i updateAll];
|
||||
|
@ -1096,7 +1180,7 @@ subtractSelection
|
|||
|
||||
if (![currentEntity count]) {
|
||||
o = currentEntity;
|
||||
[self removeObject: o];
|
||||
[self removeEntity: o];
|
||||
}
|
||||
|
||||
Sys_Printf ("subtracted selection\n");
|
||||
|
|
|
@ -1059,6 +1059,7 @@ BOOL fakebrush;
|
|||
const char *targname;
|
||||
vec3_t min, max, temp;
|
||||
const char *targ;
|
||||
NSArray *target_list;
|
||||
|
||||
targ = [parent valueForQKey: "target"];
|
||||
|
||||
|
@ -1068,9 +1069,10 @@ BOOL fakebrush;
|
|||
origin[0] = (bmins[0] + bmaxs[0]) / 2;
|
||||
origin[1] = (bmins[1] + bmaxs[1]) / 2;
|
||||
|
||||
c = [map_i count];
|
||||
target_list = [map_i targetsForTargetName: targ];
|
||||
c = [target_list count];
|
||||
for (i = 0; i < c; i++) {
|
||||
obj = [map_i objectAtIndex: i];
|
||||
obj = [target_list objectAtIndex: i];
|
||||
targname = [obj valueForQKey: "targetname"];
|
||||
if (strcmp (targ, targname))
|
||||
continue;
|
||||
|
|
Loading…
Reference in a new issue