2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
6 #include <proto/exec.h>
8 #include <proto/utility.h>
9 #include <proto/arossupport.h>
12 #include <exec/alerts.h>
13 #include <exec/memory.h>
14 #include <utility/tagitem.h>
18 #include "graphics_intern.h"
22 #include <aros/debug.h>
24 #define CACHE_INCREMENT 4
34 struct TagItem
*create_tags
;
35 struct SignalSemaphore lock
;
36 struct cacheitem
*cache
;
44 ObjectCache
*create_object_cache(OOP_Class
*classPtr
, STRPTR classID
, struct TagItem
*createTags
, struct GfxBase
*GfxBase
)
49 if ( (NULL
== classPtr
&& NULL
== classID
)
50 || (NULL
!= classPtr
&& NULL
!= classID
) )
54 oc
= AllocMem(sizeof (*oc
), MEMF_PUBLIC
|MEMF_CLEAR
);
57 InitSemaphore(&oc
->lock
);
58 oc
->cachesize
= CACHE_INCREMENT
;
61 oc
->create_tags
= CloneTagItems(createTags
);
62 if (NULL
!= oc
->create_tags
) {
63 BOOL got_class
= FALSE
;
65 if (NULL
!= classID
) {
66 oc
->class_id
= AllocVec(strlen(classID
) + 1, MEMF_ANY
);
67 if (NULL
!= oc
->class_id
) {
68 strcpy(oc
->class_id
, classID
);
72 oc
->class_ptr
= classPtr
;
78 oc
->cache
= AllocMem(sizeof (*oc
->cache
) * oc
->cachesize
, MEMF_CLEAR
);
79 if (NULL
!= oc
->cache
) {
80 return (ObjectCache
*)oc
;
83 if (NULL
!= oc
->class_id
)
84 FreeVec(oc
->class_id
);
86 } /* if (got class) */
88 FreeTagItems(oc
->create_tags
);
90 } /* if (tagitems copied) */
92 FreeMem(oc
, sizeof (*oc
));
93 } /* if (objcache struct allocated) */
98 VOID
delete_object_cache(ObjectCache
*objectCache
, struct GfxBase
*GfxBase
)
104 oc
= (struct objcache
*)objectCache
;
106 ObtainSemaphore(&oc
->lock
);
108 /* Check if all elements in the object cache are unused */
109 for (i
= 0; i
< oc
->num_objects
; i
++) {
110 if (oc
->cache
[i
].used
) {
111 D(bug("!!!! TRYING TO DELETE AN OBJECT CACHE WITH USED OBJECTS !!!!\n"));
112 ReleaseSemaphore(&oc
->lock
);
121 for (i
= 0; i
< oc
->num_objects
; i
++) {
122 if (NULL
!= oc
->cache
[i
].obj
)
123 OOP_DisposeObject(oc
->cache
[i
].obj
);
128 FreeMem(oc
->cache
, sizeof (*oc
->cache
) * oc
->cachesize
);
130 FreeTagItems(oc
->create_tags
);
132 if (NULL
!= oc
->class_id
)
133 FreeVec(oc
->class_id
);
135 ReleaseSemaphore(&oc
->lock
);
137 FreeMem(oc
, sizeof (*oc
));
144 OOP_Object
*obtain_cache_object(ObjectCache
*objectCache
, struct GfxBase
*GfxBase
)
148 OOP_Object
*obj
= NULL
;
150 oc
= (struct objcache
*)objectCache
;
152 /* bug("obtain_cache_object(classID=%s, classPtr=%p)\n"
153 , oc->class_id, oc->class_ptr);
155 ObtainSemaphore(&oc
->lock
);
158 /* Look to see if we can find a free object */
159 for (i
= 0; i
< oc
->cachesize
; i
++) {
160 struct cacheitem
*ci
;
163 /* bug("cache[%d]=%p, %d\n", i, ci->obj, ci->used);
164 */ if (NULL
== ci
->obj
) {
175 /* bug("obj found in cache: %p\n", obj);
176 */ if (NULL
== obj
) {
177 struct cacheitem
*ci
;
178 /* No object free, so we try to create a new one.
179 But first we see if the cache can hold it */
181 if (oc
->num_objects
== oc
->cachesize
) {
182 /* Not more space in the cache, try to expand it */
183 struct cacheitem
*newcache
;
185 newcache
= AllocMem(sizeof (*oc
->cache
) * (oc
->cachesize
+ CACHE_INCREMENT
), MEMF_CLEAR
);
186 if (NULL
== newcache
)
189 /* Copy the old cache data */
190 memcpy(newcache
, oc
->cache
, sizeof (*oc
->cache
) * oc
->cachesize
);
193 FreeMem(oc
->cache
, sizeof (*oc
->cache
) * oc
->cachesize
);
196 oc
->cache
= newcache
;
197 oc
->cachesize
+=CACHE_INCREMENT
;
201 /* Try to create a new object */
202 /* bug("Trying to create new object\n");
203 */ ci
= &oc
->cache
[oc
->num_objects
];
206 ci
->obj
= OOP_NewObject(NULL
, oc
->class_id
, oc
->create_tags
);
208 ci
->obj
= OOP_NewObject(oc
->class_ptr
, NULL
, oc
->create_tags
);
221 ReleaseSemaphore(&oc
->lock
);
228 VOID
release_cache_object(ObjectCache
*objectCache
, OOP_Object
*object
, struct GfxBase
*GfxBase
)
234 oc
= (struct objcache
*)objectCache
;
236 ObtainSemaphore(&oc
->lock
);
238 for (i
= 0; i
< oc
->cachesize
; i
++) {
239 struct cacheitem
*ci
;
242 if (NULL
== ci
->obj
) {
245 if (ci
->obj
== object
) {
255 bug("!!!! TRYING TO RELEASE OBJECT CACHE ELEMENT WHICH WAS NOT PRESENT IN CACHE\n");
258 ReleaseSemaphore(&oc
->lock
);