ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/src/common/modobject.c
(Generate patch)

Comparing src/common/modobject.c (file contents):
Revision 2.5 by gwlarson, Tue Aug 11 09:54:34 1998 UTC vs.
Revision 2.25 by greg, Sat Jun 21 17:42:17 2025 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1992 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  Routines for tracking object modifiers
6 + *
7 + *  External symbols declared in object.h
8   */
9  
10 < #include  "standard.h"
10 > #include "copyright.h"
11  
12 + #include  "standard.h"
13   #include  "object.h"
14
14   #include  "otypes.h"
15  
16  
18 extern int  (*addobjnotify[])();        /* people to notify of new objects */
19
17   static struct ohtab {
18 <        int  hsiz;                      /* current table size */
19 <        OBJECT  *htab;                  /* table, if allocated */
18 >        int     hsiz;                   /* current table size */
19 >        OBJECT  *htab;                  /* table, if allocated */
20   }  modtab = {100, NULL}, objtab = {1000, NULL}; /* modifiers and objects */
21  
22 < static int  otndx();
22 > static int  otndx(char *, struct ohtab *);
23  
24  
25 < int
26 < objndx(op)                      /* get object number from pointer */
27 < register OBJREC  *op;
25 > OBJECT
26 > objndx(                         /* get object number from pointer */
27 >        OBJREC  *op
28 > )
29   {
30 <        register int  i, j;
31 <
32 <        for (i = nobjects>>6; i >= 0; i--) {
33 <                j = op - objblock[i];
34 <                if (j >= 0 && j < 0100)
35 <                        return((i<<6) + j);
36 <        }
37 <        return(OVOID);
30 > #ifndef ONCACHESIZ
31 > #define ONCACHESIZ      907     /* keep a cache of previous searches */
32 > #endif
33 >        static OBJECT   oncache[ONCACHESIZ];
34 >        const int       ent = (size_t)op % ONCACHESIZ;
35 >        int             i;
36 >                                /* clear cache on first call */
37 >        for (i = ONCACHESIZ*(!oncache[0] & !oncache[1]); i--; )
38 >                oncache[i] = OVOID;
39 >                                /* is this pointer in cache? */
40 >        if ((oncache[ent] != OVOID) & (oncache[ent] < nobjects) &&
41 >                                objptr(oncache[ent]) == op)
42 >                return(oncache[ent]);           /* matches previous search */
43 >                                /* else look for allocated block */
44 >        for (i = (nobjects-1)>>OBJBLKSHFT; i >= 0; i--)
45 >                if ((objblock[i] <= op) & (op < objblock[i]+OBJBLKSIZ)) {
46 >                                /* found it -- save index to cache */
47 >                        oncache[ent] = ((OBJECT)i << OBJBLKSHFT) +
48 >                                                (op - objblock[i]);
49 >                        return(oncache[ent]);
50 >                }
51 >        return(OVOID);          /* not in our array -- may still be valid */
52   }
53  
54  
55 < int
56 < lastmod(obj, mname)             /* find modifier definition before obj */
57 < OBJECT  obj;
58 < char  *mname;
55 > OBJECT
56 > lastmod(                        /* find modifier definition before obj */
57 >        OBJECT  obj,
58 >        char  *mname
59 > )
60   {
61 <        register OBJREC  *op;
62 <        register int  i;
61 >        OBJREC  *op;
62 >        OBJECT  i;
63  
64          i = modifier(mname);            /* try hash table first */
65 <        if (i < obj)
65 >        if ((obj == OVOID) | (i < obj))
66                  return(i);
67          for (i = obj; i-- > 0; ) {      /* need to search */
68                  op = objptr(i);
69 <                if (ismodifier(op->otype) && !strcmp(op->oname, mname))
69 >                if ((ismodifier(op->otype) != 0) & (op->oname[0] == mname[0])
70 >                                && !strcmp(op->oname, mname))
71                          return(i);
72          }
73          return(OVOID);
74   }
75  
76  
77 < int
78 < modifier(mname)                 /* get a modifier number from its name */
79 < char  *mname;
77 > OBJECT
78 > modifier(                       /* get a modifier number from its name */
79 >        char  *mname
80 > )
81   {
82 <        register int  ndx;
82 >        int  ndx;
83  
84          ndx = otndx(mname, &modtab);
85          return(modtab.htab[ndx]);
# Line 72 | Line 87 | char  *mname;
87  
88  
89   #ifdef  GETOBJ
90 < int
91 < object(oname)                   /* get an object number from its name */
92 < char  *oname;
90 > OBJECT
91 > object(                         /* get an object number from its name */
92 >        char  *oname
93 > )
94   {
95 <        register int  ndx;
95 >        int  ndx;
96  
97          ndx = otndx(oname, &objtab);
98          return(objtab.htab[ndx]);
# Line 84 | Line 100 | char  *oname;
100   #endif
101  
102  
103 < insertobject(obj)               /* insert new object into our list */
104 < register OBJECT  obj;
103 > int
104 > eqreal(                         /* are two real values close enough to equal? */
105 >        double  d1,
106 >        double  d2
107 > )
108   {
109 <        register int  i;
109 >        if (d2 != 0.0)
110 >                d1 = d1/d2 - 1.0;
111 >        return((-FTINY <= d1) & (d1 <= FTINY));
112 > }
113  
114 +
115 + int
116 + eqobjects(                      /* check if two objects are equal */
117 +        OBJECT  obj1,
118 +        OBJECT  obj2
119 + )
120 + {
121 +        OBJREC  *op1, *op2;
122 +        int     i, n;
123 +
124 +        while (obj1 != obj2) {
125 +                if (obj1 == OVOID)
126 +                        return(0);
127 +                if (obj2 == OVOID)
128 +                        return(0);
129 +                op1 = objptr(obj1);
130 +                op2 = objptr(obj2);
131 +                if (op1->otype != op2->otype)
132 +                        return(0);
133 +                if (op1->oargs.nsargs != op2->oargs.nsargs)
134 +                        return(0);
135 +                if (op1->oargs.nfargs != op2->oargs.nfargs)
136 +                        return(0);
137 + #ifdef IARGS
138 +                if (op1->oargs.niargs != op2->oargs.niargs)
139 +                        return(0);
140 +                for (i = op1->oargs.niargs; i-- > 0; )
141 +                        if (op1->oargs.iarg[i] != op2->oargs.iarg[i])
142 +                                return(0);
143 + #endif
144 +                for (i = op1->oargs.nfargs; i-- > 0; )
145 +                        if (!eqreal(op1->oargs.farg[i], op2->oargs.farg[i]))
146 +                                return(0);
147 +                n = 0;
148 +                switch (op1->otype) {   /* special cases (KEEP CONSISTENT!) */
149 +                case MOD_ALIAS:
150 +                case MAT_ILLUM:
151 +                case MAT_MIRROR:
152 +                        n = (op1->oargs.nsargs > 0);
153 +                        break;
154 +                case MIX_FUNC:
155 +                case MIX_DATA:
156 +                case MIX_TEXT:
157 +                case MIX_PICT:
158 +                        n = 2*(op1->oargs.nsargs >= 2);
159 +                        break;
160 +                case MAT_CLIP:
161 +                        n = op1->oargs.nsargs;
162 +                        break;
163 +                }
164 +                                        /* check other string arguments */
165 +                for (i = op1->oargs.nsargs; i-- > n; )
166 +                        if (strcmp(op1->oargs.sarg[i], op2->oargs.sarg[i]))
167 +                                return(0);
168 +                while (n-- > 0)         /* check modifier references */
169 +                        if (!eqobjects( lastmod(obj1, op1->oargs.sarg[n]),
170 +                                        lastmod(obj2, op2->oargs.sarg[n]) ))
171 +                                return(0);
172 +                obj1 = op1->omod;
173 +                obj2 = op2->omod;
174 +        }
175 +        return(1);
176 + }
177 +
178 +
179 + void
180 + insertobject(                   /* insert new object into our list */
181 +        OBJECT  obj
182 + )
183 + {
184 +        int  i;
185 +
186          if (ismodifier(objptr(obj)->otype)) {
187                  i = otndx(objptr(obj)->oname, &modtab);
188 +                if (eqobjects(obj, modtab.htab[i]))
189 +                        return; /* don't index if same as earlier def. */
190                  modtab.htab[i] = obj;
191          }
192   #ifdef  GETOBJ
# Line 104 | Line 200 | register OBJECT  obj;
200   }
201  
202  
203 + void
204 + truncobjndx(void)               /* remove bogus table entries past end */
205 + {
206 +        int     ndx;
207 +
208 +        if (nobjects <= 0) {
209 +                if (modtab.htab != NULL) {
210 +                        free(modtab.htab);
211 +                        modtab.htab = NULL;
212 +                        modtab.hsiz = 100;
213 +                }
214 +                if (objtab.htab != NULL) {
215 +                        free(objtab.htab);
216 +                        objtab.htab = NULL;
217 +                        objtab.hsiz = 100;
218 +                }
219 +                return;
220 +        }
221 +        for (ndx = modtab.hsiz*(modtab.htab != NULL); ndx--; )
222 +                if (modtab.htab[ndx] >= nobjects)
223 +                        modtab.htab[ndx] = OVOID;
224 +
225 +        for (ndx = objtab.hsiz*(objtab.htab != NULL); ndx--; )
226 +                if (objtab.htab[ndx] >= nobjects)
227 +                        objtab.htab[ndx] = OVOID;
228 + }
229 +
230 +
231   static int
232 < nexthsiz(oldsiz)                /* return next hash table size */
233 < int  oldsiz;
232 > nexthsiz(                       /* return next hash table size */
233 >        int  oldsiz
234 > )
235   {
236          static int  hsiztab[] = {
237 <                251, 509, 1021, 2039, 4093, 8191, 16381, 0
237 >                251, 509, 1021, 2039, 4093, 8191, 16381,
238 >                32749, 65521, 131071, 262139, 0
239          };
240 <        register int  *hsp;
240 >        int  *hsp;
241  
242          for (hsp = hsiztab; *hsp; hsp++)
243                  if (*hsp > oldsiz)
# Line 121 | Line 247 | int  oldsiz;
247  
248  
249   static int
250 < otndx(name, tab)                /* get object table index for name */
251 < char  *name;
252 < register struct ohtab  *tab;
250 > otndx(                          /* get object table index for name */
251 >        char  *name,
252 >        struct ohtab  *tab
253 > )
254   {
255 +        char    *onm;
256          OBJECT  *oldhtab;
257          int  hval, i;
258 <        register int  ndx;
258 >        int  ndx;
259  
260          if (tab->htab == NULL) {                /* new table */
261                  tab->hsiz = nexthsiz(tab->hsiz);
# Line 142 | Line 270 | register struct ohtab  *tab;
270          hval = shash(name);
271   tryagain:
272          for (i = 0; i < tab->hsiz; i++) {
273 <                ndx = (hval + i*i) % tab->hsiz;
274 <                if (tab->htab[ndx] == OVOID ||
147 <                                !strcmp(objptr(tab->htab[ndx])->oname, name))
273 >                ndx = (hval + (unsigned long)i*i) % tab->hsiz;
274 >                if (tab->htab[ndx] == OVOID)
275                          return(ndx);
276 +                onm = objptr(tab->htab[ndx])->oname;
277 +                if (onm != NULL && !strcmp(onm, name))
278 +                        return(ndx);
279          }
280                                          /* table is full, reallocate */
281          oldhtab = tab->htab;
# Line 153 | Line 283 | tryagain:
283          tab->htab = NULL;
284          while (ndx--)
285                  if (oldhtab[ndx] != OVOID) {
286 <                        i = otndx(objptr(oldhtab[ndx])->oname, tab);
286 >                        onm = objptr(oldhtab[ndx])->oname;
287 >                        if (onm == NULL)
288 >                                continue;
289 >                        i = otndx(onm, tab);
290                          tab->htab[i] = oldhtab[ndx];
291                  }
292 <        free((char *)oldhtab);
292 >        free(oldhtab);
293          goto tryagain;                  /* should happen only once! */
294   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines