2 Copyright © 1995-2013, 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 FreeVec(oc
->class_id
);
84 } /* if (got class) */
86 FreeTagItems(oc
->create_tags
);
88 } /* if (tagitems copied) */
90 FreeMem(oc
, sizeof (*oc
));
91 } /* if (objcache struct allocated) */
96 VOID
delete_object_cache(ObjectCache
*objectCache
, struct GfxBase
*GfxBase
)
102 oc
= (struct objcache
*)objectCache
;
104 ObtainSemaphore(&oc
->lock
);
106 /* Check if all elements in the object cache are unused */
107 for (i
= 0; i
< oc
->num_objects
; i
++) {
108 if (oc
->cache
[i
].used
) {
109 D(bug("!!!! TRYING TO DELETE AN OBJECT CACHE WITH USED OBJECTS !!!!\n"));
110 ReleaseSemaphore(&oc
->lock
);
119 for (i
= 0; i
< oc
->num_objects
; i
++) {
120 if (NULL
!= oc
->cache
[i
].obj
)
121 OOP_DisposeObject(oc
->cache
[i
].obj
);
126 FreeMem(oc
->cache
, sizeof (*oc
->cache
) * oc
->cachesize
);
128 FreeTagItems(oc
->create_tags
);
130 FreeVec(oc
->class_id
);
132 ReleaseSemaphore(&oc
->lock
);
134 FreeMem(oc
, sizeof (*oc
));
141 OOP_Object
*obtain_cache_object(ObjectCache
*objectCache
, struct GfxBase
*GfxBase
)
145 OOP_Object
*obj
= NULL
;
147 oc
= (struct objcache
*)objectCache
;
149 /* bug("obtain_cache_object(classID=%s, classPtr=%p)\n"
150 , oc->class_id, oc->class_ptr);
152 ObtainSemaphore(&oc
->lock
);
155 /* Look to see if we can find a free object */
156 for (i
= 0; i
< oc
->cachesize
; i
++) {
157 struct cacheitem
*ci
;
160 /* bug("cache[%d]=%p, %d\n", i, ci->obj, ci->used);
161 */ if (NULL
== ci
->obj
) {
172 /* bug("obj found in cache: %p\n", obj);
173 */ if (NULL
== obj
) {
174 struct cacheitem
*ci
;
175 /* No object free, so we try to create a new one.
176 But first we see if the cache can hold it */
178 if (oc
->num_objects
== oc
->cachesize
) {
179 /* Not more space in the cache, try to expand it */
180 struct cacheitem
*newcache
;
182 newcache
= AllocMem(sizeof (*oc
->cache
) * (oc
->cachesize
+ CACHE_INCREMENT
), MEMF_CLEAR
);
183 if (NULL
== newcache
)
186 /* Copy the old cache data */
187 memcpy(newcache
, oc
->cache
, sizeof (*oc
->cache
) * oc
->cachesize
);
190 FreeMem(oc
->cache
, sizeof (*oc
->cache
) * oc
->cachesize
);
193 oc
->cache
= newcache
;
194 oc
->cachesize
+=CACHE_INCREMENT
;
198 /* Try to create a new object */
199 /* bug("Trying to create new object\n");
200 */ ci
= &oc
->cache
[oc
->num_objects
];
203 ci
->obj
= OOP_NewObject(NULL
, oc
->class_id
, oc
->create_tags
);
205 ci
->obj
= OOP_NewObject(oc
->class_ptr
, NULL
, oc
->create_tags
);
218 ReleaseSemaphore(&oc
->lock
);
225 VOID
release_cache_object(ObjectCache
*objectCache
, OOP_Object
*object
, struct GfxBase
*GfxBase
)
229 D(BOOL found
= FALSE
);
231 oc
= (struct objcache
*)objectCache
;
233 ObtainSemaphore(&oc
->lock
);
235 for (i
= 0; i
< oc
->cachesize
; i
++) {
236 struct cacheitem
*ci
;
239 if (NULL
== ci
->obj
) {
242 if (ci
->obj
== object
) {
252 bug("!!!! TRYING TO RELEASE OBJECT CACHE ELEMENT WHICH WAS NOT PRESENT IN CACHE\n");
255 ReleaseSemaphore(&oc
->lock
);