bundle_compiler.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (c) 2012-2015 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "config.h"
  6. #include "bundle_compiler.h"
  7. #include "vector.h"
  8. #include "dynamic_string.h"
  9. #include "allocator.h"
  10. #include "os.h"
  11. #include "log.h"
  12. #include "path.h"
  13. #include "disk_filesystem.h"
  14. #include "compile_options.h"
  15. #include "temp_allocator.h"
  16. #include "sort_map.h"
  17. #include "lua_resource.h"
  18. #include "texture_resource.h"
  19. #include "mesh_resource.h"
  20. #include "sound_resource.h"
  21. #include "sprite_resource.h"
  22. #include "package_resource.h"
  23. #include "unit_resource.h"
  24. #include "physics_resource.h"
  25. #include "material_resource.h"
  26. #include "font_resource.h"
  27. #include "level_resource.h"
  28. #include "shader.h"
  29. namespace crown
  30. {
  31. BundleCompiler::BundleCompiler(const char* source_dir, const char* bundle_dir)
  32. : _source_fs(source_dir)
  33. , _bundle_fs(bundle_dir)
  34. , _compilers(default_allocator())
  35. {
  36. namespace pcr = physics_config_resource;
  37. namespace phr = physics_resource;
  38. namespace pkr = package_resource;
  39. namespace sdr = sound_resource;
  40. namespace mhr = mesh_resource;
  41. namespace utr = unit_resource;
  42. namespace txr = texture_resource;
  43. namespace mtr = material_resource;
  44. namespace lur = lua_resource;
  45. namespace ftr = font_resource;
  46. namespace lvr = level_resource;
  47. namespace spr = sprite_resource;
  48. namespace shr = shader_resource;
  49. namespace sar = sprite_animation_resource;
  50. register_resource_compiler(SCRIPT_TYPE, lur::compile);
  51. register_resource_compiler(TEXTURE_TYPE, txr::compile);
  52. register_resource_compiler(MESH_TYPE, mhr::compile);
  53. register_resource_compiler(SOUND_TYPE, sdr::compile);
  54. register_resource_compiler(UNIT_TYPE, utr::compile);
  55. register_resource_compiler(SPRITE_TYPE, spr::compile);
  56. register_resource_compiler(PACKAGE_TYPE, pkr::compile);
  57. register_resource_compiler(PHYSICS_TYPE, phr::compile);
  58. register_resource_compiler(MATERIAL_TYPE, mtr::compile);
  59. register_resource_compiler(PHYSICS_CONFIG_TYPE, pcr::compile);
  60. register_resource_compiler(FONT_TYPE, ftr::compile);
  61. register_resource_compiler(LEVEL_TYPE, lvr::compile);
  62. register_resource_compiler(SHADER_TYPE, shr::compile);
  63. register_resource_compiler(SPRITE_ANIMATION_TYPE, sar::compile);
  64. DiskFilesystem temp;
  65. temp.create_directory(bundle_dir);
  66. }
  67. bool BundleCompiler::compile(const char* type, const char* name, const char* platform)
  68. {
  69. StringId64 _type(type);
  70. StringId64 _name(name);
  71. TempAllocator512 alloc;
  72. DynamicString path(alloc);
  73. TempAllocator512 alloc2;
  74. DynamicString src_path(alloc2);
  75. src_path += name;
  76. src_path += ".";
  77. src_path += type;
  78. char res_name[1 + 2*StringId64::STRING_LENGTH];
  79. _type.to_string(res_name);
  80. res_name[16] = '-';
  81. _name.to_string(res_name + 17);
  82. path::join(CROWN_DATA_DIRECTORY, res_name, path);
  83. CE_LOGI("%s <= %s.%s", res_name, name, type);
  84. File* outf = _bundle_fs.open(path.c_str(), FOM_WRITE);
  85. CompileOptions opts(_source_fs, outf, platform);
  86. compile(_type, src_path.c_str(), opts);
  87. _bundle_fs.close(outf);
  88. return true;
  89. }
  90. bool BundleCompiler::compile_all(const char* platform)
  91. {
  92. Vector<DynamicString> files(default_allocator());
  93. BundleCompiler::scan("", files);
  94. if (!_source_fs.is_file("crown.config"))
  95. {
  96. CE_LOGD("'crown.config' does not exist.");
  97. return false;
  98. }
  99. File* src = _source_fs.open("crown.config", FOM_READ);
  100. File* dst = _bundle_fs.open("crown.config", FOM_WRITE);
  101. src->copy_to(*dst, src->size());
  102. _source_fs.close(src);
  103. _bundle_fs.close(dst);
  104. if (!_bundle_fs.exists("data"))
  105. _bundle_fs.create_directory("data");
  106. // Compile all resources
  107. for (uint32_t i = 0; i < vector::size(files); i++)
  108. {
  109. if (files[i].ends_with(".tga")
  110. || files[i].ends_with(".dds")
  111. || files[i].ends_with(".sh")
  112. || files[i].ends_with(".sc")
  113. || files[i].starts_with(".")
  114. || files[i].ends_with(".config")
  115. || files[i].ends_with(".tmp")
  116. || files[i].ends_with(".wav"))
  117. continue;
  118. const char* filename = files[i].c_str();
  119. const char* type = path::extension(filename);
  120. char name[256];
  121. const uint32_t size = type - filename - 1;
  122. strncpy(name, filename, size);
  123. name[size] = '\0';
  124. compile(type, name, platform);
  125. }
  126. return true;
  127. }
  128. void BundleCompiler::register_resource_compiler(StringId64 type, CompileFunction compiler)
  129. {
  130. CE_ASSERT_NOT_NULL(compiler);
  131. sort_map::set(_compilers, type, compiler);
  132. sort_map::sort(_compilers);
  133. }
  134. void BundleCompiler::compile(StringId64 type, const char* path, CompileOptions& opts)
  135. {
  136. CE_ASSERT(sort_map::has(_compilers, type), "Compiler not found");
  137. sort_map::get(_compilers, type, (CompileFunction)NULL)(path, opts);
  138. }
  139. void BundleCompiler::scan(const char* cur_dir, Vector<DynamicString>& files)
  140. {
  141. Vector<DynamicString> my_files(default_allocator());
  142. _source_fs.list_files(cur_dir, my_files);
  143. for (uint32_t i = 0; i < vector::size(my_files); i++)
  144. {
  145. DynamicString file_i(default_allocator());
  146. if (strcmp(cur_dir, "") != 0)
  147. {
  148. file_i += cur_dir;
  149. file_i += '/';
  150. }
  151. file_i += my_files[i];
  152. if (_source_fs.is_directory(file_i.c_str()))
  153. {
  154. BundleCompiler::scan(file_i.c_str(), files);
  155. }
  156. else // Assume a regular file
  157. {
  158. vector::push_back(files, file_i);
  159. }
  160. }
  161. }
  162. namespace bundle_compiler
  163. {
  164. bool main(bool do_compile, bool do_continue, const char* platform)
  165. {
  166. if (do_compile)
  167. {
  168. bool ok = bundle_compiler_globals::compiler()->compile_all(platform);
  169. if (!ok || !do_continue)
  170. {
  171. return false;
  172. }
  173. }
  174. return true;
  175. }
  176. } // namespace bundle_compiler
  177. namespace bundle_compiler_globals
  178. {
  179. char _buffer[sizeof(BundleCompiler)];
  180. BundleCompiler* _compiler = NULL;
  181. void init(const char* source_dir, const char* bundle_dir)
  182. {
  183. #if CROWN_PLATFORM_LINUX || CROWN_PLATFORM_WINDOWS
  184. _compiler = new (_buffer) BundleCompiler(source_dir, bundle_dir);
  185. #endif
  186. }
  187. void shutdown()
  188. {
  189. _compiler->~BundleCompiler();
  190. _compiler = NULL;
  191. }
  192. BundleCompiler* compiler()
  193. {
  194. return _compiler;
  195. }
  196. } // namespace bundle_compiler_globals
  197. } // namespace crown