BuildWeb.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. //
  2. // Copyright (c) 2014-2016 THUNDERBEAST GAMES LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include <stdlib.h>
  23. #include <Atomic/Core/StringUtils.h>
  24. #include <Atomic/IO/FileSystem.h>
  25. #include <Atomic/IO/File.h>
  26. #include <Atomic/Resource/ResourceCache.h>
  27. #include "../ToolSystem.h"
  28. #include "../ToolEnvironment.h"
  29. #include "../Project/Project.h"
  30. #include "../Project/ProjectBuildSettings.h"
  31. #include "../Assets/AssetDatabase.h"
  32. #include "BuildEvents.h"
  33. #include "BuildSystem.h"
  34. #include "BuildWeb.h"
  35. namespace ToolCore
  36. {
  37. BuildWeb::BuildWeb(Context* context, Project* project) : BuildBase(context, project, PLATFORMID_WEB)
  38. {
  39. }
  40. BuildWeb::~BuildWeb()
  41. {
  42. }
  43. void BuildWeb::Initialize()
  44. {
  45. ToolSystem* tsystem = GetSubsystem<ToolSystem>();
  46. Project* project = tsystem->GetProject();
  47. Vector<String> defaultResourcePaths;
  48. GetDefaultResourcePaths(defaultResourcePaths);
  49. for (unsigned i = 0; i < defaultResourcePaths.Size(); i++)
  50. {
  51. AddResourceDir(defaultResourcePaths[i]);
  52. }
  53. BuildDefaultResourceEntries();
  54. // TODO: smart filtering of cache
  55. String projectResources = project->GetResourcePath();
  56. AddProjectResourceDir(projectResources);
  57. AssetDatabase* db = GetSubsystem<AssetDatabase>();
  58. String cachePath = db->GetCachePath();
  59. AddProjectResourceDir(cachePath);
  60. BuildProjectResourceEntries();
  61. }
  62. void BuildWeb::Build(const String& buildPath)
  63. {
  64. ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
  65. ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
  66. Project* project = toolSystem->GetProject();
  67. WebBuildSettings* settings = project->GetBuildSettings()->GetWebBuildSettings();
  68. buildPath_ = AddTrailingSlash(buildPath) + GetBuildSubfolder();
  69. VariantMap buildOutput;
  70. buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Starting Web Deployment</color>\n\n";
  71. SendEvent(E_BUILDOUTPUT, buildOutput);
  72. Initialize();
  73. if (!BuildClean(buildPath_))
  74. return;
  75. String dataPath = tenv->GetToolDataDir();
  76. String buildSourceDir = dataPath + "Deployment/Web";
  77. if (!BuildCreateDirectory(buildPath_))
  78. return;
  79. String resourcePackagePath = buildPath_ + "/AtomicResources.data";
  80. GenerateResourcePackage(resourcePackagePath);
  81. if (!BuildCopyFile(buildSourceDir + "/AtomicPlayer.html", buildPath_ + "/AtomicPlayer.html"))
  82. return;
  83. if (!BuildCopyFile(buildSourceDir + "/AtomicPlayer.html.mem", buildPath_ + "/AtomicPlayer.html.mem"))
  84. return;
  85. if (!BuildCopyFile(buildSourceDir + "/AtomicPlayer.js", buildPath_ + "/AtomicPlayer.js"))
  86. return;
  87. if (!BuildCopyFile(buildSourceDir + "/AtomicLoader.js", buildPath_ + "/AtomicLoader.js"))
  88. return;
  89. // look to see if they specified an ico file, otherwise they get atomic
  90. String myIcon = settings->GetFaviconName();
  91. if (myIcon.Empty())
  92. myIcon = buildSourceDir + "/fav_atomic.ico";
  93. if (!BuildCopyFile( myIcon, buildPath_ + "/favicon.ico"))
  94. return;
  95. // get the title
  96. String myTitle = settings->GetAppName();
  97. // get the (text) size
  98. String myWidth = settings->GetGameWidth();
  99. String myHeight = settings->GetGameHeight();
  100. if ( settings->GetPageTheme() == 0) // editor dark theme
  101. {
  102. if (!ReadReplace ( buildSourceDir + "/index-dark.html", buildPath_ + "/index.html", myTitle, myWidth, myHeight))
  103. return;
  104. if (!BuildCopyFile(buildSourceDir + "/Atomic_Logo_Header-i.png", buildPath_ + "/Atomic_Logo_Header-i.png"))
  105. return;
  106. }
  107. else if ( settings->GetPageTheme() == 1) // editor light theme
  108. {
  109. if (!ReadReplace(buildSourceDir + "/index-light.html", buildPath_ + "/index.html", myTitle, myWidth, myHeight))
  110. return;
  111. if (!BuildCopyFile(buildSourceDir + "/Atomic_Logo_Header-w.png", buildPath_ + "/Atomic_Logo_Header-w.png"))
  112. return;
  113. }
  114. else if ( settings->GetPageTheme() == 2) // Atomic gradient theme
  115. {
  116. if (!ReadReplace(buildSourceDir + "/index-image.html", buildPath_ + "/index.html", myTitle, myWidth, myHeight))
  117. return;
  118. if (!BuildCopyFile(buildSourceDir + "/atomic-gradient.jpg", buildPath_ + "/background.jpg"))
  119. return;
  120. if (!BuildCopyFile(buildSourceDir + "/Atomic_Logo_Header-i.png", buildPath_ + "/Atomic_Logo_Header-i.png"))
  121. return;
  122. }
  123. else if ( settings->GetPageTheme() == 3) // NY Lake theme
  124. {
  125. if (!ReadReplace(buildSourceDir + "/index-image.html", buildPath_ + "/index.html", myTitle, myWidth, myHeight))
  126. return;
  127. if (!BuildCopyFile(buildSourceDir + "/ny-lake.jpg", buildPath_ + "/background.jpg"))
  128. return;
  129. if (!BuildCopyFile(buildSourceDir + "/Atomic_Logo_Header-i.png", buildPath_ + "/Atomic_Logo_Header-i.png"))
  130. return;
  131. }
  132. else if ( settings->GetPageTheme() == 4) // Fireworks theme
  133. {
  134. if (!ReadReplace(buildSourceDir + "/index-image.html", buildPath_ + "/index.html", myTitle, myWidth, myHeight))
  135. return;
  136. if (!BuildCopyFile(buildSourceDir + "/fireworks.jpg", buildPath_ + "/background.jpg"))
  137. return;
  138. if (!BuildCopyFile(buildSourceDir + "/Atomic_Logo_Header-i.png", buildPath_ + "/Atomic_Logo_Header-i.png"))
  139. return;
  140. }
  141. else // theme 5, the retro (original/old) theme
  142. {
  143. if (!BuildCopyFile(buildSourceDir + "/index.html", buildPath_ + "/index.html"))
  144. return;
  145. if (!BuildCopyFile(buildSourceDir + "/Atomic_Logo_Header.png", buildPath_ + "/Atomic_Logo_Header.png"))
  146. return;
  147. }
  148. File file(context_, buildSourceDir + "/AtomicResources_js.template", FILE_READ);
  149. unsigned size = file.GetSize();
  150. SharedArrayPtr<char> buffer(new char[size + 1]);
  151. file.Read(buffer.Get(), size);
  152. buffer[size] = '\0';
  153. String resourcejs = (const char*) buffer.Get();
  154. file.Close();
  155. file.Open(buildPath_ + "/AtomicResources.data", FILE_READ);
  156. int rsize = (int) file.GetSize();
  157. file.Close();
  158. String request;
  159. request.AppendWithFormat("new DataRequest(0, %i, 0, 0).open('GET', '/AtomicResources%s');", rsize, PAK_EXTENSION);
  160. resourcejs.Replace("$$REMOTE_PACKAGE_SIZE$$", ToString("%i", rsize));
  161. resourcejs.Replace("$$ATOMIC_RESOURCES_DATA_REQUEST$$", request);
  162. file.Open(buildPath_ + "/AtomicResources.js", FILE_WRITE);
  163. file.Write(resourcejs.CString(), resourcejs.Length());
  164. file.Close();
  165. buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Web Deployment Complete</color>\n\n";
  166. SendEvent(E_BUILDOUTPUT, buildOutput);
  167. BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
  168. buildSystem->BuildComplete(PLATFORMID_WEB, buildPath_);
  169. //fileSystem->SystemCommandAsync("/Applications/Firefox.app/Contents/MacOS/firefox");
  170. }
  171. bool BuildWeb::ReadReplace ( String infile, String outfile, String title, String width, String height )
  172. {
  173. File file(context_, infile, FILE_READ);
  174. if (file.IsOpen())
  175. {
  176. unsigned size = file.GetSize();
  177. SharedArrayPtr<char> buffer(new char[size + 1]);
  178. file.Read(buffer.Get(), size);
  179. buffer[size] = '\0';
  180. String indexstr = (const char*) buffer.Get();
  181. file.Close();
  182. if (!title.Empty())
  183. indexstr.Replace("Atomic Game Engine Web Player", title);
  184. if (!width.Empty())
  185. {
  186. // see if the string resolves to a positive integer value
  187. int num = atoi(width.CString());
  188. if (num > 0 && num < 16384)
  189. indexstr.Replace("width=\"800\"", "width=\""+ width + "\"" );
  190. }
  191. if (!height.Empty())
  192. {
  193. int num = atoi(height.CString());
  194. if (num > 0 && num < 16384)
  195. indexstr.Replace("height=\"512\"", "height=\""+ height + "\"" );
  196. }
  197. file.Open(outfile, FILE_WRITE);
  198. file.Write(indexstr.CString(), indexstr.Length());
  199. file.Close();
  200. return true;
  201. }
  202. return false;
  203. }
  204. }