Mercurial > hg > dmlib
comparison dmres.c @ 359:59045853853d
Make resource management re-entrant.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 16 Oct 2012 21:25:46 +0300 |
parents | 6d9d43bb68eb |
children | a0160ffdf7e5 |
comparison
equal
deleted
inserted
replaced
358:3bdc776a4b33 | 359:59045853853d |
---|---|
6 */ | 6 */ |
7 #include "dmres.h" | 7 #include "dmres.h" |
8 #include <time.h> | 8 #include <time.h> |
9 | 9 |
10 | 10 |
11 #define DMRES_LOCK(x) dmMutexLock(dfResourcesMutex) | 11 DMResource *dmres_new(DMResourceLib *lib, const char *filename, int flags, size_t size) |
12 #define DMRES_UNLOCK(x) dmMutexUnlock(dfResourcesMutex) | |
13 | |
14 | |
15 /* Global variables | |
16 */ | |
17 static BOOL dfResInitialized = FALSE; | |
18 static int dfResFlags = 0; | |
19 static char * dfResPath = NULL; | |
20 DMResource * dfResources = NULL; | |
21 DMMutex * dfResourcesMutex = NULL; | |
22 | |
23 | |
24 #ifdef DM_USE_PACKFS | |
25 static DMPackFile *dfResPackFile = NULL; | |
26 static char * dfResPackFilename = NULL; | |
27 #endif | |
28 | |
29 | |
30 DMResource *dmres_new(const char *filename, int flags, size_t size) | |
31 { | 12 { |
32 DMResource *node = dmMalloc0(sizeof(DMResource)); | 13 DMResource *node = dmMalloc0(sizeof(DMResource)); |
33 if (node == NULL) | 14 if (node == NULL) |
34 return NULL; | 15 return NULL; |
35 | 16 |
17 node->lib = lib; | |
36 node->filename = dm_strdup(filename); | 18 node->filename = dm_strdup(filename); |
37 node->flags = flags; | 19 node->flags = flags; |
38 node->dataSize = size; | 20 node->dataSize = size; |
39 | 21 |
40 return node; | 22 return node; |
82 dmFree(node); | 64 dmFree(node); |
83 } | 65 } |
84 } | 66 } |
85 | 67 |
86 | 68 |
87 static void dmres_insert(DMResource * node) | 69 void dmres_insert(DMResourceLib *lib, DMResource * node) |
88 { | 70 { |
89 if (dfResources != NULL) | 71 if (lib == NULL) |
90 { | 72 return; |
91 node->prev = dfResources->prev; | 73 |
92 dfResources->prev->next = node; | 74 node->lib = lib; |
93 dfResources->prev = node; | 75 |
76 if (lib->resources != NULL) | |
77 { | |
78 node->prev = lib->resources->prev; | |
79 lib->resources->prev->next = node; | |
80 lib->resources->prev = node; | |
94 } | 81 } |
95 else | 82 else |
96 { | 83 { |
97 dfResources = node->prev = node; | 84 lib->resources = node->prev = node; |
98 } | 85 } |
99 | 86 |
100 node->next = NULL; | 87 node->next = NULL; |
101 } | 88 } |
102 | 89 |
103 | 90 |
104 static void dmres_delete(DMResource * node) | 91 void dmres_delete(DMResourceLib *lib, DMResource * node) |
105 { | 92 { |
93 if (lib == NULL) | |
94 return; | |
95 | |
106 if (node->prev) | 96 if (node->prev) |
107 node->prev->next = node->next; | 97 node->prev->next = node->next; |
108 | 98 |
109 if (node->next) | 99 if (node->next) |
110 node->next->prev = node->prev; | 100 node->next->prev = node->prev; |
111 else | 101 else |
112 dfResources->prev = node->prev; | 102 lib->resources->prev = node->prev; |
113 | 103 |
114 node->prev = node->next = NULL; | 104 node->prev = node->next = NULL; |
115 } | 105 } |
116 | 106 |
117 | 107 |
118 DMResource * dmres_find(const char *filename) | 108 DMResource * dmres_find(DMResourceLib *lib, const char *filename) |
119 { | 109 { |
120 DMResource *node, *found = NULL; | 110 DMResource *node, *found = NULL; |
121 | 111 |
122 DMRES_LOCK(); | 112 if (lib == NULL) |
123 | 113 return NULL; |
124 for (node = dfResources; node != NULL; node = node->next) | 114 |
115 dmMutexLock(lib->mutex); | |
116 | |
117 for (node = lib->resources; node != NULL; node = node->next) | |
125 { | 118 { |
126 if (strcmp(node->filename, filename) == 0) | 119 if (strcmp(node->filename, filename) == 0) |
127 { | 120 { |
128 found = node; | 121 found = node; |
129 break; | 122 break; |
130 } | 123 } |
131 } | 124 } |
132 | 125 |
133 DMRES_UNLOCK(); | 126 dmMutexUnlock(lib->mutex); |
134 | 127 |
135 return found; | 128 return found; |
136 } | 129 } |
137 | 130 |
138 | 131 |
320 DMPackEntry *node; | 313 DMPackEntry *node; |
321 int res = DMERR_OK, cres, cdataLeft; | 314 int res = DMERR_OK, cres, cdataLeft; |
322 z_stream cstream; | 315 z_stream cstream; |
323 Uint8 * cbuffer = NULL; | 316 Uint8 * cbuffer = NULL; |
324 | 317 |
318 if (handle->lib == NULL || handle->lib->packFile == NULL) | |
319 return DMERR_NULLPTR; | |
320 | |
325 // Search PACK nodelist for file | 321 // Search PACK nodelist for file |
326 if ((node = dm_pack_find(dfResPackFile->entries, handle->filename)) == NULL) | 322 if ((node = dm_pack_find(handle->lib->packFile->entries, handle->filename)) == NULL) |
327 { | 323 { |
328 dmError("Entry '%s' not found in PACK file.\n", handle->filename); | 324 dmError("Entry '%s' not found in PACK file.\n", handle->filename); |
329 res = DMERR_NOT_FOUND; | 325 res = DMERR_NOT_FOUND; |
330 goto error; | 326 goto error; |
331 } | 327 } |
332 | 328 |
333 // Seek to entry | 329 // Seek to entry |
334 if (fseek(dfResPackFile->file, node->offset, SEEK_SET) == -1) | 330 if (fseek(handle->lib->packFile->file, node->offset, SEEK_SET) == -1) |
335 { | 331 { |
336 dmError("Could not seek node position in PACK file.\n"); | 332 dmError("Could not seek node position in PACK file.\n"); |
337 res = DMERR_FSEEK; | 333 res = DMERR_FSEEK; |
338 goto error; | 334 goto error; |
339 } | 335 } |
376 cstream.avail_out > 0 && cres == Z_OK) | 372 cstream.avail_out > 0 && cres == Z_OK) |
377 { | 373 { |
378 cstream.avail_in = fread( | 374 cstream.avail_in = fread( |
379 cbuffer, sizeof(Uint8), | 375 cbuffer, sizeof(Uint8), |
380 (cdataLeft >= DPACK_TMPSIZE) ? DPACK_TMPSIZE : cdataLeft, | 376 (cdataLeft >= DPACK_TMPSIZE) ? DPACK_TMPSIZE : cdataLeft, |
381 dfResPackFile->file); | 377 handle->lib->packFile->file); |
382 | 378 |
383 cdataLeft -= cstream.avail_in; | 379 cdataLeft -= cstream.avail_in; |
384 cstream.next_in = cbuffer; | 380 cstream.next_in = cbuffer; |
385 cres = inflate(&cstream, Z_FULL_FLUSH); | 381 cres = inflate(&cstream, Z_FULL_FLUSH); |
386 } | 382 } |
538 { | 534 { |
539 // Check fops | 535 // Check fops |
540 if (handle->fops == NULL) | 536 if (handle->fops == NULL) |
541 { | 537 { |
542 #ifdef DM_USE_PACKFS | 538 #ifdef DM_USE_PACKFS |
543 if (dfResFlags & DRF_USE_PACK) | 539 if (handle->lib->flags & DRF_USE_PACK) |
544 handle->fops = &dfPackFileOps; | 540 handle->fops = &dfPackFileOps; |
545 #ifdef DM_USE_STDIO | 541 #ifdef DM_USE_STDIO |
546 else | 542 else |
547 handle->fops = &dfStdioFileOps; | 543 handle->fops = &dfStdioFileOps; |
548 #else | 544 #else |
560 { | 556 { |
561 int ret = DMERR_INIT_FAIL; | 557 int ret = DMERR_INIT_FAIL; |
562 | 558 |
563 // Check if we want to preload raw data? | 559 // Check if we want to preload raw data? |
564 if (((handle->flags & DMF_PRELOAD_RAW) || | 560 if (((handle->flags & DMF_PRELOAD_RAW) || |
565 (dfResFlags & DRF_PRELOAD_ALL)) && | 561 (handle->lib->flags & DRF_PRELOAD_ALL)) && |
566 (handle->flags & DMF_LOADED_RAW) == 0 && | 562 (handle->flags & DMF_LOADED_RAW) == 0 && |
567 handle->fops->preload != NULL) | 563 handle->fops->preload != NULL) |
568 { | 564 { |
569 ret = handle->fops->preload(handle); | 565 ret = handle->fops->preload(handle); |
570 if (ret == DMERR_OK) | 566 if (ret == DMERR_OK) |
586 } | 582 } |
587 } | 583 } |
588 } | 584 } |
589 | 585 |
590 // Check if resource data is to be preloaded | 586 // Check if resource data is to be preloaded |
591 if (((handle->flags & DMF_PRELOAD_RES) || (dfResFlags & DRF_PRELOAD_RES)) && | 587 if (((handle->flags & DMF_PRELOAD_RES) || (handle->lib->flags & DRF_PRELOAD_RES)) && |
592 (handle->flags & DMF_LOADED_RES) == 0 && | 588 (handle->flags & DMF_LOADED_RES) == 0 && |
593 handle->rops != NULL && | 589 handle->rops != NULL && |
594 handle->rops->load != NULL) | 590 handle->rops->load != NULL) |
595 { | 591 { |
596 ret = handle->rops->load(handle); | 592 ret = handle->rops->load(handle); |
607 | 603 |
608 return ret; | 604 return ret; |
609 } | 605 } |
610 | 606 |
611 | 607 |
612 DMResource *dmf_open(const char *filename) | 608 DMResource *dmf_open(DMResourceLib *lib, const char *filename) |
613 { | 609 { |
614 int ret; | 610 int ret; |
615 DMResource *handle; | 611 DMResource *handle; |
616 | 612 |
617 // Check master directory for resource | 613 // Check master directory for resource |
618 if ((handle = dmres_find(filename)) == NULL) | 614 if ((handle = dmres_find(lib, filename)) == NULL) |
619 { | 615 { |
620 #ifdef DM_USE_STDIO | 616 #ifdef DM_USE_STDIO |
621 // Hmm.. does not exist? Fall back to a stdio file | 617 // Hmm.. does not exist? Fall back to a stdio file |
622 handle = dmres_new(filename, 0, 0); | 618 handle = dmres_new(lib, filename, 0, 0); |
623 if (handle == NULL) | 619 if (handle == NULL) |
624 return NULL; | 620 return NULL; |
625 | 621 |
626 handle->fops = &dfStdioFileOps; | 622 handle->fops = &dfStdioFileOps; |
627 dmres_insert(handle); | 623 dmres_insert(lib, handle); |
628 #else | 624 #else |
629 // Stdio not enabled, fail | 625 // Stdio not enabled, fail |
630 return NULL; | 626 return NULL; |
631 #endif | 627 #endif |
632 } | 628 } |
652 | 648 |
653 return NULL; | 649 return NULL; |
654 } | 650 } |
655 | 651 |
656 | 652 |
657 DMResource * dmf_open_memio(const char *filename, Uint8 *buf, size_t len) | 653 DMResource * dmf_create_memio(DMResourceLib *lib, const char *filename, Uint8 *buf, size_t len) |
658 { | 654 { |
659 DMResource *handle; | 655 DMResource *handle; |
660 | 656 |
661 // Check master directory for resource | 657 // Check master directory for resource |
662 if ((handle = dmres_find(filename)) == NULL) | 658 if ((handle = dmres_find(lib, filename)) == NULL) |
663 { | 659 { |
664 // Hmm.. does not exist? Fall back to a stdio file | 660 // Hmm.. does not exist? Fall back to a stdio file |
665 handle = dmres_new(filename, DMF_LOADED_RAW, len); | 661 handle = dmres_new(lib, filename, DMF_LOADED_RAW, len); |
666 if (handle == NULL) | 662 if (handle == NULL) |
667 return NULL; | 663 return NULL; |
668 | 664 |
669 handle->fops = &dfMemIOFileOps; | 665 handle->fops = &dfMemIOFileOps; |
670 handle->data = buf; | 666 handle->data = buf; |
671 dmres_insert(handle); | 667 dmres_insert(lib, handle); |
672 } | 668 } |
673 | 669 |
674 // Increase refcount | 670 // Increase refcount |
675 dmres_ref(handle); | 671 dmres_ref(handle); |
676 | 672 |
679 | 675 |
680 | 676 |
681 #ifdef DM_USE_STDIO | 677 #ifdef DM_USE_STDIO |
682 DMResource * dmf_create_stdio(const char *filename, const char *mode) | 678 DMResource * dmf_create_stdio(const char *filename, const char *mode) |
683 { | 679 { |
684 DMResource *handle = dmres_new(filename, 0, 0); | 680 DMResource *handle = dmres_new(NULL, filename, 0, 0); |
685 if (handle == NULL) | 681 if (handle == NULL) |
686 return NULL; | 682 return NULL; |
687 | 683 |
688 handle->fops = &dfStdioFileOps; | 684 handle->fops = &dfStdioFileOps; |
689 | 685 |
703 } | 699 } |
704 | 700 |
705 | 701 |
706 DMResource * dmf_create_stdio_stream(FILE *fh) | 702 DMResource * dmf_create_stdio_stream(FILE *fh) |
707 { | 703 { |
708 DMResource *handle = dmres_new("", 0, 0); | 704 DMResource *handle = dmres_new(NULL, "", 0, 0); |
709 if (handle == NULL) | 705 if (handle == NULL) |
710 return NULL; | 706 return NULL; |
711 | 707 |
712 handle->fops = &dfStdioFHOps; | 708 handle->fops = &dfStdioFHOps; |
713 handle->fh = fh; | 709 handle->fh = fh; |
801 | 797 |
802 return (n > 0) ? s : NULL; | 798 return (n > 0) ? s : NULL; |
803 } | 799 } |
804 | 800 |
805 | 801 |
806 | |
807 int dmres_ref(DMResource *node) | 802 int dmres_ref(DMResource *node) |
808 { | 803 { |
809 DMRES_LOCK(); | 804 if (node->lib != NULL) dmMutexLock(node->lib->mutex); |
810 node->atime = time(NULL); | 805 node->atime = time(NULL); |
811 node->refcount++; | 806 node->refcount++; |
812 DMRES_UNLOCK(); | 807 if (node->lib != NULL) dmMutexUnlock(node->lib->mutex); |
813 | 808 |
814 return node->refcount; | 809 return node->refcount; |
815 } | 810 } |
816 | 811 |
817 | 812 |
818 int dmres_unref(DMResource *node) | 813 int dmres_unref(DMResource *node) |
819 { | 814 { |
820 DMRES_LOCK(); | 815 if (node->lib != NULL) dmMutexLock(node->lib->mutex); |
821 node->refcount--; | 816 node->refcount--; |
822 DMRES_UNLOCK(); | 817 if (node->lib != NULL) dmMutexUnlock(node->lib->mutex); |
823 | 818 |
824 return node->refcount; | 819 return node->refcount; |
825 } | 820 } |
826 | 821 |
827 | 822 |
859 } | 854 } |
860 return flags; | 855 return flags; |
861 } | 856 } |
862 | 857 |
863 | 858 |
864 int dmres_load_resfile(const char *filename) | 859 int dmres_load_resfile(DMResourceLib *lib, const char *filename) |
865 { | 860 { |
866 int ret = DMERR_OK; | 861 int ret = DMERR_OK; |
867 char line[256]; | 862 char line[256]; |
868 FILE *f = fopen(filename, "r"); | 863 FILE *f = fopen(filename, "r"); |
869 if (f == NULL) | 864 if (f == NULL) |
870 return DMERR_FOPEN; | 865 return DMERR_FOPEN; |
871 | 866 |
872 DMRES_LOCK(); | 867 dmMutexLock(lib->mutex); |
873 | 868 |
874 while (fgets(line, sizeof(line) - 1, f) != NULL) | 869 while (fgets(line, sizeof(line) - 1, f) != NULL) |
875 { | 870 { |
876 int fnstart, fsep; | 871 int fnstart, fsep; |
877 for (fnstart = 0; isspace(line[fnstart]); fnstart++); | 872 for (fnstart = 0; isspace(line[fnstart]); fnstart++); |
881 int flags, i; | 876 int flags, i; |
882 for (i = fsep - 1; i > 0 && isspace(line[i]); i--) | 877 for (i = fsep - 1; i > 0 && isspace(line[i]); i--) |
883 line[i] = 0; | 878 line[i] = 0; |
884 | 879 |
885 for (i = fsep; isspace(line[i]); i++); | 880 for (i = fsep; isspace(line[i]); i++); |
886 | |
887 if (sscanf(&line[i], "%x", &flags) == 1 && | |
888 strlen(&line[fnstart]) > 0) | |
889 { | |
890 | |
891 } | |
892 } | 881 } |
893 } | 882 } |
894 | 883 |
895 DMRES_UNLOCK(); | 884 dmMutexUnlock(lib->mutex); |
896 fclose(f); | 885 fclose(f); |
897 | 886 |
898 return ret; | 887 return ret; |
899 } | 888 } |
900 | 889 |
901 | 890 |
902 int dmres_write_resfile(const char *filename) | 891 int dmres_write_resfile(DMResourceLib *lib, const char *filename) |
903 { | 892 { |
904 int ret; | 893 int ret; |
905 DMResource *node; | 894 DMResource *node; |
906 FILE *f = fopen(filename, "w"); | 895 FILE *f = fopen(filename, "w"); |
907 if (f == NULL) | 896 if (f == NULL) |
908 return DMERR_FOPEN; | 897 return DMERR_FOPEN; |
909 | 898 |
910 DMRES_LOCK(); | 899 dmMutexLock(lib->mutex); |
911 | 900 |
912 for (node = dfResources; node != NULL; node = node->next) | 901 for (node = lib->resources; node != NULL; node = node->next) |
913 { | 902 { |
914 if (fprintf(f, "%s|%08x\n", node->filename, node->flags) < 0) | 903 char tmp[64]; |
904 dmres_flags_to_symbolic(tmp, sizeof(tmp), node->flags); | |
905 if (fprintf(f, "%s|%s\n", node->filename, tmp) < 0) | |
915 { | 906 { |
916 ret = DMERR_FWRITE; | 907 ret = DMERR_FWRITE; |
917 goto error; | 908 goto error; |
918 } | 909 } |
919 } | 910 } |
920 | 911 |
921 error: | 912 error: |
922 DMRES_UNLOCK(); | 913 dmMutexUnlock(lib->mutex); |
923 fclose(f); | 914 fclose(f); |
924 return ret; | 915 return ret; |
925 } | 916 } |
926 | 917 |
927 | 918 |
928 /* Resources subsystem initialization and shutdown routines | 919 /* Resources subsystem initialization and shutdown routines |
929 */ | 920 */ |
930 int dmres_init(const char *filename, const char *path, const int flags, int (*classifier)(DMResource *)) | 921 int dmres_init(DMResourceLib **plib, const char *filename, const char *path, const int flags, int (*classifier)(DMResource *)) |
931 { | 922 { |
932 // Check if we are already initialized | 923 DMResourceLib *lib; |
933 if (dfResInitialized) | 924 |
934 return DMERR_ALREADY_INIT; | 925 // Allocate the resource library structure |
935 | 926 if ((*plib = lib = dmMalloc0(sizeof(DMResourceLib))) == NULL) |
936 dfResFlags = flags; | 927 return DMERR_MALLOC; |
937 dfResPath = dm_strdup((path != NULL) ? path : DMRES_DATA_PATH); | 928 |
938 dfResourcesMutex = dmCreateMutex(); | 929 // Basic data |
930 lib->mutex = dmCreateMutex(); | |
931 lib->flags = flags; | |
932 lib->resPath = dm_strdup((path != NULL) ? path : DMRES_DATA_PATH); | |
939 | 933 |
940 | 934 |
941 if (flags & DRF_USE_PACK) | 935 if (flags & DRF_USE_PACK) |
942 { | 936 { |
943 #ifdef DM_USE_PACKFS | 937 #ifdef DM_USE_PACKFS |
944 int ret; | 938 int ret; |
945 DMPackEntry *node; | 939 DMPackEntry *node; |
946 | 940 |
947 dfResPackFilename = dm_strdup((filename != NULL) ? filename : DMRES_DATA_PACK); | 941 lib->packFilename = dm_strdup((filename != NULL) ? filename : DMRES_DATA_PACK); |
948 | 942 |
949 // Initialize PACK, open as read-only | 943 // Initialize PACK, open as read-only |
950 ret = dm_pack_open(dfResPackFilename, &dfResPackFile, TRUE); | 944 ret = dm_pack_open(lib->packFilename, &lib->packFile, TRUE); |
951 if (ret != DMERR_OK) | 945 if (ret != DMERR_OK) |
952 { | 946 { |
953 dmError("Error opening PACK file '%s', #%i: %s\n", | 947 dmError("Error opening PACK file '%s', #%i: %s\n", |
954 dfResPackFilename, ret, dmErrorStr(ret)); | 948 lib->packFilename, ret, dmErrorStr(ret)); |
955 | 949 |
956 return DMERR_INIT_FAIL; | 950 return DMERR_INIT_FAIL; |
957 } | 951 } |
958 | 952 |
959 // Initialize resources from a PACK file | 953 // Initialize resources from a PACK file |
960 for (node = dfResPackFile->entries; node != NULL; node = node->next) | 954 for (node = lib->packFile->entries; node != NULL; node = node->next) |
961 { | 955 { |
962 DMResource *res = dmres_new(node->filename, node->resFlags & DMF_MASK, node->size); | 956 DMResource *res = dmres_new(lib, node->filename, node->resFlags & DMF_MASK, node->size); |
963 if (res == NULL) | 957 if (res == NULL) |
964 { | 958 { |
965 dmError("Could not allocate memory for resource node '%s' [0x%08x], %d.\n", | 959 dmError("Could not allocate memory for resource node '%s' [0x%08x], %d.\n", |
966 node->filename, node->resFlags, node->size); | 960 node->filename, node->resFlags, node->size); |
967 return DMERR_INIT_FAIL; | 961 return DMERR_INIT_FAIL; |
968 } | 962 } |
969 | 963 |
970 dmres_insert(res); | 964 dmres_insert(lib, res); |
971 } | 965 } |
972 | 966 |
973 #else | 967 #else |
974 // PACK not compiled in, FAIL! | 968 // PACK not compiled in, FAIL! |
975 return DMERR_INIT_FAIL; | 969 return DMERR_INIT_FAIL; |
976 #endif | 970 #endif |
977 } | 971 } |
978 else | 972 else |
979 { | 973 { |
980 // Initialize resources from a resource directory | 974 // Initialize resources from a resource directory |
981 char *resFilename = dm_strdup_printf("%s%s", dfResPath, DMRES_RES_FILE); | 975 char *resFilename = dm_strdup_printf("%s%s", lib->resPath, DMRES_RES_FILE); |
982 int ret = dmres_load_resfile(resFilename); | 976 int ret = dmres_load_resfile(lib, resFilename); |
983 dmFree(resFilename); | 977 dmFree(resFilename); |
984 | 978 |
985 if (ret != DMERR_OK) | 979 if (ret != DMERR_OK) |
986 return DMERR_INIT_FAIL; | 980 return DMERR_INIT_FAIL; |
987 } | 981 } |
988 | 982 |
989 // Okay, classify resources | 983 // Okay, classify resources |
990 if (dfResources != NULL && classifier != NULL) | 984 if (lib->resources != NULL && classifier != NULL) |
991 { | 985 { |
992 DMResource *node; | 986 DMResource *node; |
993 for (node = dfResources; node != NULL; node = node->next) | 987 for (node = lib->resources; node != NULL; node = node->next) |
994 { | 988 { |
995 int ret = classifier(node); | 989 int ret = classifier(node); |
996 if (ret != DMERR_OK) | 990 if (ret != DMERR_OK) |
997 return ret; | 991 return ret; |
998 } | 992 } |
999 } | 993 } |
1000 | 994 |
1001 // Initialization complete | 995 // Initialization complete |
1002 dfResInitialized = TRUE; | |
1003 return DMERR_OK; | 996 return DMERR_OK; |
1004 } | 997 } |
1005 | 998 |
1006 | 999 |
1007 void dmres_close(void) | 1000 int dmres_close(DMResourceLib *lib) |
1008 { | 1001 { |
1009 DMResource *node; | 1002 DMResource *node; |
1010 DMRES_LOCK(); | 1003 |
1011 | 1004 if (lib == NULL) |
1012 if (!dfResInitialized) | 1005 return DMERR_NULLPTR; |
1013 return; | 1006 |
1014 | 1007 dmMutexLock(lib->mutex); |
1008 | |
1015 // Shutdown possible subsystems | 1009 // Shutdown possible subsystems |
1016 #ifdef DM_USE_PACKFS | 1010 #ifdef DM_USE_PACKFS |
1017 if (dfResFlags & DRF_USE_PACK) | 1011 if (lib->flags & DRF_USE_PACK) |
1018 { | 1012 { |
1019 int res = dm_pack_close(dfResPackFile); | 1013 int res = dm_pack_close(lib->packFile); |
1020 if (res != DMERR_OK) | 1014 if (res != DMERR_OK) |
1021 { | 1015 { |
1022 dmError("Error closing PACK, #%i: %s\n", | 1016 dmError("Error closing PACK, #%i: %s\n", |
1023 res, dmErrorStr(res)); | 1017 res, dmErrorStr(res)); |
1024 } | 1018 } |
1025 | 1019 |
1026 dmFree(dfResPackFilename); | 1020 dmFree(lib->packFilename); |
1027 } | 1021 } |
1028 #endif | 1022 #endif |
1029 | 1023 |
1030 // Free resource entries | 1024 // Free resource entries |
1031 node = dfResources; | 1025 node = lib->resources; |
1032 while (node != NULL) | 1026 while (node != NULL) |
1033 { | 1027 { |
1034 DMResource *next = node->next; | 1028 DMResource *next = node->next; |
1035 dmres_free(node); | 1029 dmres_free(node); |
1036 node = next; | 1030 node = next; |
1037 } | 1031 } |
1038 | 1032 |
1039 // Etc. | 1033 // Etc. |
1040 dmFree(dfResPath); | 1034 dmFree(lib->resPath); |
1041 DMRES_UNLOCK(); | 1035 dmMutexUnlock(lib->mutex); |
1042 dmDestroyMutex(dfResourcesMutex); | 1036 dmDestroyMutex(lib->mutex); |
1043 dfResInitialized = FALSE; | 1037 return DMERR_OK; |
1044 } | 1038 } |
1045 | 1039 |
1046 | 1040 |
1047 int dmres_preload(BOOL start, int *loaded, int *total) | 1041 int dmres_preload(DMResourceLib *lib, BOOL start, int *loaded, int *total) |
1048 { | 1042 { |
1049 static DMResource *dfPreload = NULL; | |
1050 int ret = DMERR_OK; | 1043 int ret = DMERR_OK; |
1051 | 1044 |
1052 DMRES_LOCK(); | 1045 dmMutexLock(lib->mutex); |
1053 | 1046 |
1054 // Initialize preloading | 1047 // Initialize preloading |
1055 if (dfPreload == NULL || start) | 1048 if (lib->preload == NULL || start) |
1056 { | 1049 { |
1057 DMResource *node; | 1050 DMResource *node; |
1058 | 1051 |
1059 dfPreload = dfResources; | 1052 lib->preload = lib->resources; |
1060 *loaded = 0; | 1053 *loaded = 0; |
1061 *total = 0; | 1054 *total = 0; |
1062 | 1055 |
1063 // Calculate total number of resources to be preloaded | 1056 // Calculate total number of resources to be preloaded |
1064 for (node = dfResources; node != NULL; node = node->next) | 1057 for (node = lib->resources; node != NULL; node = node->next) |
1065 { | 1058 { |
1066 if ((dfResFlags & (DRF_PRELOAD_ALL | DRF_PRELOAD_RES)) || | 1059 if ((lib->flags & (DRF_PRELOAD_ALL | DRF_PRELOAD_RES)) || |
1067 (node->flags & (DMF_PRELOAD_RAW | DMF_PRELOAD_RES))) | 1060 (node->flags & (DMF_PRELOAD_RAW | DMF_PRELOAD_RES))) |
1068 (*total)++; | 1061 (*total)++; |
1069 } | 1062 } |
1070 } | 1063 } |
1071 else | 1064 else |
1072 if (dfPreload != NULL) | 1065 if (lib->preload != NULL) |
1073 { | 1066 { |
1074 // Initialize fops and preload | 1067 // Initialize fops and preload |
1075 dmf_init_fops(dfPreload); | 1068 dmf_init_fops(lib->preload); |
1076 if ((ret = dmf_preload(dfPreload)) != DMERR_OK) | 1069 if ((ret = dmf_preload(lib->preload)) != DMERR_OK) |
1077 goto error; | 1070 goto error; |
1078 | 1071 |
1079 (*loaded)++; | 1072 (*loaded)++; |
1080 dfPreload = dfPreload->next; | 1073 lib->preload = lib->preload->next; |
1081 } | 1074 } |
1082 | 1075 |
1083 DMRES_UNLOCK(); | 1076 dmMutexUnlock(lib->mutex); |
1084 return (dfPreload == NULL) ? DMERR_OK : DMERR_PROGRESS; | 1077 return (lib->preload == NULL) ? DMERR_OK : DMERR_PROGRESS; |
1085 | 1078 |
1086 error: | 1079 error: |
1087 DMRES_UNLOCK(); | 1080 dmMutexUnlock(lib->mutex); |
1088 return ret; | 1081 return ret; |
1089 } | 1082 } |
1090 | 1083 |
1091 | 1084 |
1092 void dmres_prune(int agems, int flags) | 1085 void dmres_prune(DMResourceLib *lib, int agems, int flags) |
1093 { | 1086 { |
1094 DMResource *node; | 1087 DMResource *node; |
1095 int currtime = time(NULL); | 1088 int currtime = time(NULL); |
1096 DMRES_LOCK(); | 1089 dmMutexLock(lib->mutex); |
1097 | 1090 |
1098 for (node = dfResources; node != NULL; node = node->next) | 1091 for (node = lib->resources; node != NULL; node = node->next) |
1099 { | 1092 { |
1100 // Check if node has refcount of 0 and is | 1093 // Check if node has refcount of 0 and is |
1101 // not marked as persistent resource | 1094 // not marked as persistent resource |
1102 if (node->refcount == 0 && | 1095 if (node->refcount == 0 && |
1103 (node->flags & DMF_PERSIST) == 0 && | 1096 (node->flags & DMF_PERSIST) == 0 && |
1113 dmres_free_raw_data(node); | 1106 dmres_free_raw_data(node); |
1114 } | 1107 } |
1115 } | 1108 } |
1116 } | 1109 } |
1117 | 1110 |
1118 DMRES_UNLOCK(); | 1111 dmMutexUnlock(lib->mutex); |
1119 } | 1112 } |
1120 | 1113 |
1121 | 1114 |
1122 /* Helper resource access routines | 1115 /* Helper resource access routines |
1123 */ | 1116 */ |