| 942 | } |
| 943 | |
| 944 | Result GetWithExt(HFactory factory, const char* path, const char* ext, void** resource) |
| 945 | { |
| 946 | assert(path); |
| 947 | assert(resource); |
| 948 | *resource = 0; |
| 949 | |
| 950 | Result chk = CheckSuppliedResourcePath(path); |
| 951 | if (chk != RESULT_OK) |
| 952 | return chk; |
| 953 | |
| 954 | if (ext != 0) |
| 955 | { |
| 956 | const char* path_ext = GetExtFromPath(path); |
| 957 | if (strcmp(path_ext, ext) != 0) |
| 958 | { |
| 959 | return RESULT_INVALID_FILE_EXTENSION; |
| 960 | } |
| 961 | } |
| 962 | |
| 963 | dmMutex::ScopedLock lk(factory->m_LoadMutex); |
| 964 | |
| 965 | dmArray<const char*>& stack = factory->m_GetResourceStack; |
| 966 | if (factory->m_RecursionDepth == 0) |
| 967 | { |
| 968 | stack.SetSize(0); |
| 969 | } |
| 970 | |
| 971 | ++factory->m_RecursionDepth; |
| 972 | |
| 973 | uint32_t n = stack.Size(); |
| 974 | for (uint32_t i=0;i<n;i++) |
| 975 | { |
| 976 | if (strcmp(stack[i], path) == 0) |
| 977 | { |
| 978 | dmLogError("Self referring resource detected"); |
| 979 | dmLogError("Reference chain:"); |
| 980 | for (uint32_t j = 0; j < n; ++j) |
| 981 | { |
| 982 | dmLogError("%d: %s", j, stack[j]); |
| 983 | } |
| 984 | dmLogError("%d: %s", n, path); |
| 985 | --factory->m_RecursionDepth; |
| 986 | return RESULT_RESOURCE_LOOP_ERROR; |
| 987 | } |
| 988 | } |
| 989 | |
| 990 | if (stack.Full()) |
| 991 | { |
| 992 | stack.SetCapacity(stack.Capacity() + 16); |
| 993 | } |
| 994 | stack.Push(path); |
| 995 | Result r = CreateAndLoadResource(factory, path, resource); |
| 996 | stack.SetSize(stack.Size() - 1); |
| 997 | --factory->m_RecursionDepth; |
| 998 | return r; |
| 999 | } |
| 1000 | |
| 1001 | Result Get(HFactory factory, const char* path, void** resource) |