2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
6 #include <aros/debug.h>
8 #include <proto/exec.h>
10 #include <proto/utility.h>
11 #include <proto/arossupport.h>
14 #include <exec/alerts.h>
15 #include <exec/memory.h>
16 #include <utility/tagitem.h>
20 #include "graphics_intern.h"
23 #define CACHE_INCREMENT 4
33 struct TagItem
*create_tags
;
34 struct SignalSemaphore lock
;
35 struct cacheitem
*cache
;
43 ObjectCache
*create_object_cache(OOP_Class
*classPtr
, STRPTR classID
, struct TagItem
*createTags
, struct GfxBase
*GfxBase
)
48 if ( (NULL
== classPtr
&& NULL
== classID
)
49 || (NULL
!= classPtr
&& NULL
!= classID
) )
53 oc
= AllocMem(sizeof (*oc
), MEMF_PUBLIC
|MEMF_CLEAR
);
56 InitSemaphore(&oc
->lock
);
57 oc
->cachesize
= CACHE_INCREMENT
;
60 oc
->create_tags
= CloneTagItems(createTags
);
61 if (NULL
!= oc
->create_tags
) {
62 BOOL got_class
= FALSE
;
64 if (NULL
!= classID
) {
65 oc
->class_id
= AllocVec(strlen(classID
) + 1, MEMF_ANY
);
66 if (NULL
!= oc
->class_id
) {
67 strcpy(oc
->class_id
, classID
);
71 oc
->class_ptr
= classPtr
;
77 oc
->cache
= AllocMem(sizeof (*oc
->cache
) * oc
->cachesize
, MEMF_CLEAR
);
78 if (NULL
!= oc
->cache
) {
79 return (ObjectCache
*)oc
;
82 if (NULL
!= oc
->class_id
)
83 FreeVec(oc
->class_id
);
85 } /* if (got class) */
87 FreeTagItems(oc
->create_tags
);
89 } /* if (tagitems copied) */
91 FreeMem(oc
, sizeof (*oc
));
92 } /* if (objcache struct allocated) */
97 VOID
delete_object_cache(ObjectCache
*objectCache
, struct GfxBase
*GfxBase
)
103 oc
= (struct objcache
*)objectCache
;
105 ObtainSemaphore(&oc
->lock
);
107 /* Check if all elements in the object cache are unused */
108 for (i
= 0; i
< oc
->num_objects
; i
++) {
109 if (oc
->cache
[i
].used
) {
110 D(bug("!!!! TRYING TO DELETE AN OBJECT CACHE WITH USED OBJECTS !!!!\n"));
111 ReleaseSemaphore(&oc
->lock
);
120 for (i
= 0; i
< oc
->num_objects
; i
++) {
121 if (NULL
!= oc
->cache
[i
].obj
)
122 OOP_DisposeObject(oc
->cache
[i
].obj
);
127 FreeMem(oc
->cache
, sizeof (*oc
->cache
) * oc
->cachesize
);
129 FreeTagItems(oc
->create_tags
);
131 if (NULL
!= oc
->class_id
)
132 FreeVec(oc
->class_id
);
134 ReleaseSemaphore(&oc
->lock
);
136 FreeMem(oc
, sizeof (*oc
));
143 OOP_Object
*obtain_cache_object(ObjectCache
*objectCache
, struct GfxBase
*GfxBase
)
147 OOP_Object
*obj
= NULL
;
149 oc
= (struct objcache
*)objectCache
;
151 /* bug("obtain_cache_object(classID=%s, classPtr=%p)\n"
152 , oc->class_id, oc->class_ptr);
154 ObtainSemaphore(&oc
->lock
);
157 /* Look to see if we can find a free object */
158 for (i
= 0; i
< oc
->cachesize
; i
++) {
159 struct cacheitem
*ci
;
162 /* bug("cache[%d]=%p, %d\n", i, ci->obj, ci->used);
163 */ if (NULL
== ci
->obj
) {
174 /* bug("obj found in cache: %p\n", obj);
175 */ if (NULL
== obj
) {
176 struct cacheitem
*ci
;
177 /* No object free, so we try to create a new one.
178 But first we see if the cache can hold it */
180 if (oc
->num_objects
== oc
->cachesize
) {
181 /* Not more space in the cache, try to expand it */
182 struct cacheitem
*newcache
;
184 newcache
= AllocMem(sizeof (*oc
->cache
) * (oc
->cachesize
+ CACHE_INCREMENT
), MEMF_CLEAR
);
185 if (NULL
== newcache
)
188 /* Copy the old cache data */
189 memcpy(newcache
, oc
->cache
, sizeof (*oc
->cache
) * oc
->cachesize
);
192 FreeMem(oc
->cache
, sizeof (*oc
->cache
) * oc
->cachesize
);
195 oc
->cache
= newcache
;
196 oc
->cachesize
+=CACHE_INCREMENT
;
200 /* Try to create a new object */
201 /* bug("Trying to create new object\n");
202 */ ci
= &oc
->cache
[oc
->num_objects
];
205 ci
->obj
= OOP_NewObject(NULL
, oc
->class_id
, oc
->create_tags
);
207 ci
->obj
= OOP_NewObject(oc
->class_ptr
, NULL
, oc
->create_tags
);
220 ReleaseSemaphore(&oc
->lock
);
227 VOID
release_cache_object(ObjectCache
*objectCache
, OOP_Object
*object
, struct GfxBase
*GfxBase
)
231 D(BOOL found
= FALSE
);
233 oc
= (struct objcache
*)objectCache
;
235 ObtainSemaphore(&oc
->lock
);
237 for (i
= 0; i
< oc
->cachesize
; i
++) {
238 struct cacheitem
*ci
;
241 if (NULL
== ci
->obj
) {
244 if (ci
->obj
== object
) {
254 bug("!!!! TRYING TO RELEASE OBJECT CACHE ELEMENT WHICH WAS NOT PRESENT IN CACHE\n");
257 ReleaseSemaphore(&oc
->lock
);