1 /**
2  * Copyright:       Copyright (C) 2018 Gabriel Gheorghe, All Rights Reserved
3  * Authors:         $(Gabriel Gheorghe)
4  * License:         $(LINK2 https://www.gnu.org/licenses/gpl-3.0.txt, GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007)
5  * Source:          $(LINK2 https://github.com/GabyForceQ/LibertyEngine/blob/master/source/liberty/scene/io.d)
6  * Documentation:
7  * Coverage:
8 **/
9 module liberty.scene.io;
10 
11 import std.array : split;
12 import std.conv : to;
13 import std.stdio : File;
14 import std..string : strip;
15 import core.stdc.stdio : sscanf;
16 
17 import liberty.framework.light.impl;
18 import liberty.framework.primitive.impl;
19 import liberty.framework.terrain.impl;
20 import liberty.material.impl;
21 import liberty.math.transform;
22 import liberty.scene.impl;
23 import liberty.scene.services;
24 
25 /**
26  * Used for input/output operations on $(D Scene) class.
27  * It implements $(D ISerializable) service.
28 **/
29 abstract class SceneIO : ISerializable {
30   /**
31    * Serialize a scene.
32   **/
33   static void serialize(Scene scene) {
34     // Open the file
35     auto file = File(scene.relativePath, "w");
36     scope(exit) file.close;
37 
38     file.writeln("id: " ~ scene.id);
39 
40     foreach (Primitive entity; cast(Primitive[string])scene.shaderMap["Primitive"].getMap) {
41       file.writeln(
42         "Primitive: { " ~
43           "id: " ~ entity.id ~
44           "transform: [ " ~
45             "location: " ~ entity.component!Transform.getLocation.toString ~ 
46         " ] }"
47       );
48     }
49 
50     foreach (Terrain entity; cast(Terrain[string])scene.shaderMap["Terrain"].getMap) {
51       file.writeln(
52         "Terrain: { " ~
53           "id: " ~ entity.id ~
54           " , size: " ~ entity.getSize.to!string ~
55           " , maxHeight " ~ entity.getMaxHeight.to!string ~
56           " , materials: [ " ~
57             entity.model.materials[0].getTexture.getRelativePath ~
58             " , " ~ entity.model.materials[1].getTexture.getRelativePath ~
59             " , " ~ entity.model.materials[2].getTexture.getRelativePath ~
60             " , " ~ entity.model.materials[3].getTexture.getRelativePath ~
61             " , " ~ entity.model.materials[4].getTexture.getRelativePath ~
62         " ] }"
63       );
64     }
65 
66     /*foreach (entity; scene.getGuiSystem.getMap) {
67       file.writeln(
68         "Widget: { " ~
69           "id: " ~ entity.getId ~
70         " }"
71       );
72     }*/
73 
74     foreach (Light entity; cast(Light[string])scene.shaderMap["Light"].getMap) {
75       file.writeln(
76         "Light: { " ~
77           "id: " ~ entity.id ~
78         " }"
79       );
80     }
81   }
82 
83   /**
84    * Deserialize a scene.
85   **/
86   static void deserialize(Scene scene) {
87     // Open the file
88     auto file = File(scene.relativePath);
89     scope(exit) file.close;
90 
91     // Read the file and build scene
92     auto range = file.byLine();
93     foreach (line; range) {
94       line = line.strip();
95       const char[][] tokens = line.split(" ").dup;
96       if (tokens.length == 0)
97         continue;
98       else if (tokens[0] == "id:")
99         scene.id = cast(string)tokens[1].dup;
100       else if (tokens[0] == "Terrain:")
101         scene.spawn!Terrain(cast(string)tokens[3].dup)
102           .build(tokens[6].dup.to!float, tokens[9].dup.to!float, [
103             new Material(cast(string)tokens[13].dup),
104             new Material(cast(string)tokens[15].dup),
105             new Material(cast(string)tokens[17].dup),
106             new Material(cast(string)tokens[19].dup),
107             new Material(cast(string)tokens[21].dup)
108           ]);
109       else if (tokens[0] == "Light:")
110         scene.spawn!Light(cast(string)tokens[3].dup);
111     }
112   }
113 }