Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
ContentManager.cs
浏览该文件的文档.
1using System.Collections.Concurrent;
2using Engine;
4using Engine.Media;
5// ReSharper disable MethodOverloadWithOptionalParameter
6
7namespace Game {
8 public class ContentInfo {
9 public MemoryStream ContentStream;
10 public string AbsolutePath;
11 public string ContentPath;
12 public string ContentSuffix;
13 public string Filename;
14 public Lock InUse = new();
15
16 public ContentInfo(string AbsolutePath_) {
17 AbsolutePath = AbsolutePath_;
18 int pos = AbsolutePath_.LastIndexOf('.');
19 ContentPath = pos > -1 ? AbsolutePath_.Substring(0, pos) : AbsolutePath_;
20 ContentSuffix = pos > -1 ? AbsolutePath.Substring(pos) : null;
21 Filename = Path.GetFileName(AbsolutePath);
22 }
23
24 public void SetContentStream(Stream stream) {
25 if (stream is MemoryStream memoryStream) {
26 ContentStream = memoryStream;
27 ContentStream.Position = 0L;
28 }
29 else {
30 throw new Exception($"Can't set ContentStream width type {stream.GetType().Name}");
31 }
32 }
33
34 // 确认不需要此步也能正常运行,现仅作检测和设置Position为0用
35 public Stream Duplicate() {
36 if (ContentStream == null
37 || !ContentStream.CanRead
38 || !ContentStream.CanWrite) {
39 throw new Exception("ContentStream has been disposed");
40 }
41 ContentStream.Position = 0L;
42 return ContentStream;
43 }
44
45 public void Dispose() {
46 ContentStream?.Dispose();
47 }
48 }
49
50 public static class ContentManager {
51 internal static ConcurrentDictionary<string, ContentInfo> Resources = [];
52 internal static Dictionary<string, IContentReader.IContentReader> ReaderList = [];
53 internal static ConcurrentDictionary<string, List<object>> Caches = [];
54 internal static object syncObj = new();
55
56 public static void Initialize() {
57 ReaderList.Clear();
58 Resources.Clear();
59 Caches.Clear();
60 Display.DeviceReset += Display_DeviceReset;
61 }
62
63 public static T Get<T>(string name) where T : class => Get(typeof(T), name, null, true) as T;
64
65 public static T Get<T>(string name, string suffix = null) where T : class => Get(typeof(T), name, suffix, true) as T;
66
67 public static T Get<T>(string name, string suffix = null, bool throwOnNotFound = true) where T : class =>
68 Get(typeof(T), name, suffix, throwOnNotFound) as T;
69
70 public static object Get(Type type, string name) => Get(type, name, null, true);
71
72 public static object Get(Type type, string name, string suffix = null) => Get(type, name, suffix, true);
73
74 public static object Get(Type type, string name, string suffix = null, bool throwOnNotFound = true) {
75 ArgumentNullException.ThrowIfNull(type);
76 object obj = null;
77 string key = suffix == null ? name : name + (suffix.StartsWith('.') ? suffix : $".{suffix}");
78 if (type == typeof(Subtexture)) {
79 return TextureAtlasManager.GetSubtexture(name, throwOnNotFound);
80 }
81 if (Caches.TryGetValue(key, out List<object> cacheList)) {
82 obj = cacheList.Find(f => f.GetType() == type);
83 }
84 if (obj != null) {
85 return obj;
86 }
87 if (ReaderList.TryGetValue(type.FullName ?? type.Name, out IContentReader.IContentReader reader)) {
88 List<ContentInfo> contents = [];
89 string p;
90 if (suffix == null) {
91 for (int i = 0; i < reader.DefaultSuffix.Length; i++) {
92 p = $"{name}.{reader.DefaultSuffix[i]}";
93 if (Caches.TryGetValue(p, out List<object> cacheList2)) {
94 obj = cacheList2.Find(f => f.GetType() == type);
95 }
96 if (obj != null) {
97 if (cacheList == null) {
98 cacheList = [];
99 Caches.AddOrUpdate(key, cacheList, (_, _) => cacheList);
100 }
101 cacheList.Add(obj);
102 return obj;
103 }
104 if (Resources.TryGetValue(p, out ContentInfo contentInfo)) {
105 contents.Add(contentInfo);
106 }
107 }
108 }
109 else {
110 if (Resources.TryGetValue(key, out ContentInfo contentInfo)) {
111 contents.Add(contentInfo);
112 }
113 }
114 if (contents.Count == 0) {
115 //没有找到对应资源
116 return throwOnNotFound ? throw new Exception($"Not Found Res [{key}][{type.FullName}]") : null;
117 }
118 obj = reader.Get([.. contents]);
119 }
120 if (cacheList == null
121 && !Caches.TryGetValue(key, out cacheList)) {
122 cacheList = [];
123 Caches.AddOrUpdate(key, cacheList, (_, _) => cacheList);
124 }
125 cacheList.Add(obj);
126 return obj;
127 }
128
129 public static void Add(ContentInfo contentInfo) {
130 Resources.AddOrUpdate(contentInfo.AbsolutePath, contentInfo, (_, _) => contentInfo);
131 }
132
137 public static void Dispose(string name) {
138 lock (syncObj) {
139 if (Caches.TryGetValue(name, out List<object> list)) {
140 List<object> toRemove = new();
141 foreach (object t in list) {
142 if (t is IDisposable d) {
143 d.Dispose();
144 }
145 toRemove.Add(t);
146 }
147 foreach (object t in toRemove) {
148 list.Remove(t);
149 }
150 }
151 }
152 }
153
155 public static bool ContainsKey(string key) => Resources.ContainsKey(key);
156
157 public static bool IsContent(object content) {
158 foreach (List<object> l in Caches.Values) {
159 foreach (object d in l) {
160 if (d == content) {
161 return true;
162 }
163 }
164 }
165 return false;
166 }
167
168 public static void Display_DeviceReset() {
169 foreach (KeyValuePair<string, List<object>> i in Caches) {
170 string k = i.Key;
171 for (int j = 0; j < i.Value.Count; j++) {
172 object t = i.Value[j];
173 if (t is Texture2D
174 || t is Model
175 || t is BitmapFont) {
176 i.Value[j] = Get(t.GetType(), k);
177 }
178 }
179 }
180 }
181
182 public static ReadOnlyList<ContentInfo> List() => new(Resources.Values.ToDynamicArray());
183
184 public static ReadOnlyList<ContentInfo> List(string directory) {
185 List<ContentInfo> contents = [];
186 if (!directory.EndsWith('/')) {
187 directory += "/";
188 }
189 foreach (ContentInfo content in Resources.Values) {
190 if (content.ContentPath.StartsWith(directory)) {
191 contents.Add(content);
192 }
193 }
194 return new ReadOnlyList<ContentInfo>(contents);
195 }
196
197 public static void AddContentReader(IContentReader.IContentReader reader) {
198 ReaderList.TryAdd(reader.Type, reader);
199 }
200 }
201}
void SetContentStream(Stream stream)
ContentInfo(string AbsolutePath_)
MemoryStream ContentStream
static ConcurrentDictionary< string, ContentInfo > Resources
static bool ContainsKey(string key)
static object Get(Type type, string name)
static void AddContentReader(IContentReader.IContentReader reader)
static void Add(ContentInfo contentInfo)
static T Get< T >(string name)
static void Display_DeviceReset()
static ReadOnlyList< ContentInfo > List()
static Dictionary< string, IContentReader.IContentReader > ReaderList
static ConcurrentDictionary< string, List< object > > Caches
static ReadOnlyList< ContentInfo > List(string directory)
static void Dispose(string name)
可能需要带上文件后缀,即获取名字+获取的后缀
static bool IsContent(object content)
static Subtexture GetSubtexture(string name, bool throwOnNotFound)