cache.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <draw.h>
  4. #include <thread.h>
  5. #include <mouse.h>
  6. #include <keyboard.h>
  7. #include <control.h>
  8. typedef struct Cache Cache;
  9. struct Cache
  10. {
  11. char *name;
  12. CCache **cache;
  13. int ncache;
  14. };
  15. static struct Cache imagecache = {"image"};
  16. static struct Cache fontcache = {"font"};
  17. static CCache*
  18. getcacheitem(Cache *c, char *name)
  19. {
  20. int i;
  21. for(i=0; i<c->ncache; i++)
  22. if(c->cache[i]!=nil && strcmp(c->cache[i]->name, name)==0){
  23. c->cache[i]->ref++;
  24. return c->cache[i];
  25. }
  26. return nil;
  27. }
  28. static int
  29. namecacheitem(Cache *c, void *image, char *name)
  30. {
  31. int i, free;
  32. CCache *cc;
  33. free = -1;
  34. for(i=0; i<c->ncache; i++){
  35. if(c->cache[i] == nil){
  36. free = i;
  37. continue;
  38. }
  39. if(strcmp(c->cache[i]->name, name) == 0){
  40. werrstr("%s name %q already in use", c->name, name);
  41. return -1;
  42. }
  43. }
  44. cc = ctlmalloc(sizeof(CCache));
  45. cc->image = image;
  46. cc->name = ctlstrdup(name);
  47. if(free >= 0){
  48. cc->index = free;
  49. c->cache[free] = cc;
  50. }else{
  51. cc->index = c->ncache;
  52. c->cache = ctlrealloc(c->cache, (c->ncache+1)*sizeof(CCache*));
  53. c->cache[c->ncache++] = cc;
  54. }
  55. cc->ref = 1;
  56. return 1;
  57. }
  58. static int
  59. freecacheitem(Cache *c, char *name)
  60. {
  61. CCache *cc;
  62. cc = getcacheitem(c, name);
  63. if(cc == nil){
  64. werrstr("%s name %q not in use", c->name, name);
  65. return -1;
  66. }
  67. cc->ref--; /* getcacheitem increments ref */
  68. if(cc->ref-- == 1){
  69. /* client must free object itself */
  70. free(cc->name);
  71. c->cache[cc->index] = nil;
  72. free(cc);
  73. }
  74. return 0;
  75. }
  76. static void
  77. putcacheitem(CCache *cc)
  78. {
  79. if(cc == nil)
  80. return;
  81. cc->ref--;
  82. }
  83. static void
  84. setcacheitemptr(Cache *c, Control *ctl, CCache **cp, char *s)
  85. {
  86. CCache *ci;
  87. ci = getcacheitem(c, s);
  88. if(ci == nil)
  89. ctlerror("%q: %s name %q not defined", ctl->name, c->name, s);
  90. putcacheitem(*cp);
  91. *cp = ci;
  92. }
  93. /* Images */
  94. CImage*
  95. _getctlimage(char *name)
  96. {
  97. return getcacheitem(&imagecache, name);
  98. }
  99. void
  100. _putctlimage(CImage *c)
  101. {
  102. putcacheitem(c);
  103. }
  104. int
  105. namectlimage(Image *image, char *name)
  106. {
  107. return namecacheitem(&imagecache, image, name);
  108. }
  109. int
  110. freectlimage(char *name)
  111. {
  112. return freecacheitem(&imagecache, name);
  113. }
  114. void
  115. _setctlimage(Control *c, CImage **cp, char *s)
  116. {
  117. setcacheitemptr(&imagecache, c, cp, s);
  118. }
  119. /* Fonts */
  120. CFont*
  121. _getctlfont(char *name)
  122. {
  123. return getcacheitem(&fontcache, name);
  124. }
  125. void
  126. _putctlfont(CFont *c)
  127. {
  128. putcacheitem(c);
  129. }
  130. int
  131. namectlfont(Font *font, char *name)
  132. {
  133. return namecacheitem(&fontcache, font, name);
  134. }
  135. int
  136. freectlfont(char *name)
  137. {
  138. return freecacheitem(&fontcache, name);
  139. }
  140. void
  141. _setctlfont(Control *c, CFont **cp, char *s)
  142. {
  143. setcacheitemptr(&fontcache, c, cp, s);
  144. }