9506095485347c344bbb8ec5976b9fddd56047e2
[sdk] / ecere / src / gfx / DisplaySystem.ec
1 namespace gfx;
2
3 import "Mutex"
4 import "Display"
5
6 String printingDocumentName;
7
8 public void SetPrintingDocumentName(String name)
9 {
10    printingDocumentName = name;
11 }
12
13 public class DisplaySystemResPtr : struct
14 {
15    DisplaySystemResPtr prev, next;
16    Resource resource;
17 };
18
19 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
20 static void FreeTexture(NamedLink texture)
21 {
22    Bitmap bitmap = texture.data;
23    bitmap.Free();
24    delete bitmap;
25    delete texture.name;
26 }
27
28 static void FreeMaterial(Material material)
29 {
30    delete material.name;
31 }
32 #endif
33
34 public class DisplaySystem
35 {
36 public:
37    class_no_expansion;
38    ~DisplaySystem()
39    {
40 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
41       OldLink mesh;
42
43       materials.Free(Material::Free);
44       textures.Free(FreeTexture);
45       for(mesh = meshes.first; mesh; mesh = mesh.next)
46          ((Mesh)mesh.data).Free(0);
47       meshes.Free(null);
48 #endif
49
50       if(driverData)
51          driver.DestroyDisplaySystem(this);
52
53       if(driver.displaySystem == this)
54          driver.displaySystem = null;
55    }
56
57    bool Create(const char * driverName, void * window, bool fullScreen)
58    {
59       bool result = false;
60       subclass(DisplayDriver) displayDriver = GetDisplayDriver(driverName);
61       if(displayDriver)
62       {
63          flags.fullScreen = fullScreen;
64          this.window = window;
65          if(displayDriver.CreateDisplaySystem(this))
66             result = true;
67
68          driver = displayDriver;
69          if(!result)
70          {
71             // LogErrorCode(GERR_DISPLAY_INIT_FAILED, driver);
72             displayDriver.displaySystem = null;
73          }
74          else if(!displayDriver.displaySystem)
75          {
76             displayDriver.displaySystem = this;
77          }
78       }
79       return result;
80    }
81
82    Font LoadFont(const char * faceName, float size, FontFlags flags)
83    {
84       Font result = null;
85       subclass(DisplayDriver) driver = this ? this.driver : ((subclass(DisplayDriver))class(LFBDisplayDriver));
86       char * string = CopyString(faceName);
87       char *fonts[32];
88       if(string)
89       {
90          int numFonts = TokenizeWith(string, 32, fonts, ",", true);
91          int c;
92          for(c = 0; c<numFonts; c++)
93          {
94             TrimLSpaces(fonts[c],fonts[c]);
95             TrimRSpaces(fonts[c],fonts[c]);
96             if((result = driver.LoadFont(this, fonts[c], size, flags)))
97             {
98                break;
99             }
100          }
101          delete string;
102       }
103       return result;
104    }
105
106    void UnloadFont(Font font)
107    {
108       subclass(DisplayDriver) driver = this ? this.driver : ((subclass(DisplayDriver))class(LFBDisplayDriver));
109       driver.UnloadFont(this, font);
110    }
111
112    void FontExtent(Font font, const char * text, int len, int * width, int * height)
113    {
114       if(this && text)
115          driver.FontExtent(this, font, text, len, width, height);
116       else
117       {
118          if(width) *width = 0;
119          if(height) *height = 0;
120       }
121    }
122
123    void * LoadResource(Resource resource)
124    {
125       DisplaySystemResPtr res;
126       for(res = resources.first; res; res = res.next)
127       {
128          Resource existing = res.resource;
129
130          if(existing._class == resource._class)
131          {
132             if(resource.OnCompare(existing) == 0)
133                break;
134          }
135       }
136       if(!res)
137       {
138          // res = DisplaySystemResPtr { resource = new classof(resource) };
139          res = DisplaySystemResPtr { resource = eInstance_New(resource._class) };
140          resources.Add(res);
141
142          // This will load e.g. the Bitmap *
143          res.resource.Load(resource, this);
144       }
145       // This would copy e.g. the Bitmap *
146       incref res.resource;
147       resource.Reference(res.resource);
148
149       return res;
150    }
151
152    void UnloadResource(Resource resource, DisplaySystemResPtr res)
153    {
154       // This would clear e.g. the Bitmap *
155       resource.Dereference();
156       if(res)
157       {
158          if(res.resource._refCount == 1)
159          {
160             delete res.resource;
161             resources.Delete(res);
162          }
163          else
164             res.resource._refCount--;
165       }
166    }
167
168    bool Lock()
169    {
170       bool result = false;
171       mutex.Wait();
172
173       if(!current)
174          result = driver.LockSystem(this);
175       else
176          result = true;
177       current++;
178       return result;
179    }
180
181    void Unlock(void)
182    {
183       current--;
184       if(!current)
185          driver.UnlockSystem(this);
186
187       mutex.Release();
188    }
189 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
190    // --- Materials List Management ---
191
192    Material AddNamedMaterial(const char * name)
193    {
194       Material material = materials.FindName(name, false);
195       if(!material)
196       {
197          material = Material { };
198          if(material)
199          {
200             material.name = CopyString(name);
201             if(name)
202                materials.AddName(material);
203             else
204                materials.Add(material);
205          }
206       }
207       return material;
208    }
209
210    bool AddMaterial(Material material)
211    {
212       if(material.name)
213          materials.AddName(material);
214       else
215          materials.Add(material);
216       return true;
217    }
218
219    Material GetMaterial(const char * name)
220    {
221       return materials.FindName(name, false);
222    }
223
224    bool RemoveMaterial(Material material)
225    {
226       delete material.name;
227       materials.Delete(material);
228       return true;
229    }
230
231    void ClearMaterials()
232    {
233       materials.Free(FreeMaterial);
234    }
235
236    // --- Textures List Management ---
237
238    NamedLink AddTexture(const char * name, Bitmap bitmap)
239    {
240       NamedLink item { };
241       if(item)
242       {
243          item.data = bitmap;
244          incref bitmap;
245          item.name = new char[strlen(name) + 1];
246          strcpy(item.name, name);
247          textures.AddName(item);
248       }
249       return item;
250    }
251
252    Bitmap GetTexture(const char * name)
253    {
254       return textures.FindNamedLink(name, false);
255    }
256
257    bool RemoveTexture(const char * name)
258    {
259       NamedLink item = textures.FindName(name, false);
260       if(item)
261       {
262          FreeTexture(item);
263          textures.Delete(item);
264          return true;
265       }
266       return false;
267    }
268
269    void ClearTextures()
270    {
271       textures.Free(FreeTexture);
272    }
273
274    // --- Meshes List Management ---
275
276    OldLink AddMesh(Mesh mesh)
277    {
278       if(this)
279       {
280          OldLink item { };
281          if(item)
282          {
283             item.data = mesh;
284             mesh.displaySystem = this;
285             meshes.Add(item);
286          }
287          return item;
288       }
289       return null;
290    }
291
292    bool RemoveMesh(Mesh mesh)
293    {
294       OldLink item = meshes.FindLink(mesh);
295       if(item)
296       {
297          mesh.Free(0);
298          meshes.Delete(item);
299          return true;
300       }
301       return false;
302    }
303
304    void ClearMeshes()
305    {
306       OldLink mesh;
307       for(mesh = meshes.first; mesh; mesh = mesh.next)
308          ((Mesh)mesh.data).Free(0);
309       meshes.Free(null);
310    }
311 #endif
312
313 private:
314    subclass(DisplayDriver) driver;
315    void * data;
316    void * window;
317    public PixelFormat pixelFormat;
318    public DisplayFlags flags;
319    int numDisplays;
320
321    OldList resources;
322
323 #if !defined(ECERE_VANILLA) && !defined(ECERE_NO3D)
324    // This will all go in resources
325    OldList materials;
326    OldList textures;
327    OldList meshes;
328 #endif
329
330    void * driverData;
331    int current;
332    Mutex mutex { };
333 };