| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- #include "BsScriptBuildManager.h"
- #include "BsMonoManager.h"
- #include "BsMonoClass.h"
- #include "BsMonoMethod.h"
- #include "BsMonoUtil.h"
- #include "BsScriptPlatformInfo.h"
- #include "BsFileSystem.h"
- #include "BsIconUtility.h"
- #include "BsCoreThread.h"
- #include "BsGameSettings.h"
- #include "BsFileSerializer.h"
- #include "BsProjectLibrary.h"
- #include "BsProjectResourceMeta.h"
- #include "BsResources.h"
- #include "BsPrefab.h"
- #include "BsEditorApplication.h"
- #include "BsResourceManifest.h"
- #include "BsBuiltinResources.h"
- namespace BansheeEngine
- {
- ScriptBuildManager::ScriptBuildManager(MonoObject* instance)
- :ScriptObject(instance)
- { }
- void ScriptBuildManager::initRuntimeData()
- {
- metaData.scriptClass->addInternalCall("Internal_GetAvailablePlatforms", &ScriptBuildManager::internal_GetAvailablePlatforms);
- metaData.scriptClass->addInternalCall("Internal_GetActivePlatform", &ScriptBuildManager::internal_GetActivePlatform);
- metaData.scriptClass->addInternalCall("Internal_SetActivePlatform", &ScriptBuildManager::internal_SetActivePlatform);
- metaData.scriptClass->addInternalCall("Internal_GetActivePlatformInfo", &ScriptBuildManager::internal_GetActivePlatformInfo);
- metaData.scriptClass->addInternalCall("Internal_GetPlatformInfo", &ScriptBuildManager::internal_GetPlatformInfo);
- metaData.scriptClass->addInternalCall("Internal_GetFrameworkAssemblies", &ScriptBuildManager::internal_GetFrameworkAssemblies);
- metaData.scriptClass->addInternalCall("Internal_GetMainExecutable", &ScriptBuildManager::internal_GetMainExecutable);
- metaData.scriptClass->addInternalCall("Internal_GetDefines", &ScriptBuildManager::internal_GetDefines);
- metaData.scriptClass->addInternalCall("Internal_GetNativeBinaries", &ScriptBuildManager::internal_GetNativeBinaries);
- metaData.scriptClass->addInternalCall("Internal_GetBuildFolder", &ScriptBuildManager::internal_GetBuildFolder);
- metaData.scriptClass->addInternalCall("Internal_InjectIcons", &ScriptBuildManager::internal_InjectIcons);
- metaData.scriptClass->addInternalCall("Internal_PackageResources", &ScriptBuildManager::internal_PackageResources);
- metaData.scriptClass->addInternalCall("Internal_CreateStartupSettings", &ScriptBuildManager::internal_CreateStartupSettings);
- }
- MonoArray* ScriptBuildManager::internal_GetAvailablePlatforms()
- {
- const Vector<PlatformType>& availableType = BuildManager::instance().getAvailablePlatforms();
- ScriptArray outArray = ScriptArray::create<UINT32>((UINT32)availableType.size());
- UINT32 idx = 0;
- for (auto& type : availableType)
- outArray.set(idx++, type);
- return outArray.getInternal();
- }
- PlatformType ScriptBuildManager::internal_GetActivePlatform()
- {
- return BuildManager::instance().getActivePlatform();
- }
- void ScriptBuildManager::internal_SetActivePlatform(PlatformType value)
- {
- BuildManager::instance().setActivePlatform(value);
- }
- MonoObject* ScriptBuildManager::internal_GetActivePlatformInfo()
- {
- return ScriptPlatformInfo::create(BuildManager::instance().getActivePlatformInfo());
- }
- MonoObject* ScriptBuildManager::internal_GetPlatformInfo(PlatformType type)
- {
- return ScriptPlatformInfo::create(BuildManager::instance().getPlatformInfo(type));
- }
- MonoArray* ScriptBuildManager::internal_GetFrameworkAssemblies(PlatformType type)
- {
- Vector<WString> frameworkAssemblies = BuildManager::instance().getFrameworkAssemblies(type);
- ScriptArray outArray = ScriptArray::create<WString>((UINT32)frameworkAssemblies.size());
- UINT32 idx = 0;
- for (auto& assemblyName : frameworkAssemblies)
- outArray.set(idx++, MonoUtil::wstringToMono(MonoManager::instance().getDomain(), assemblyName));
- return outArray.getInternal();
- }
- MonoString* ScriptBuildManager::internal_GetMainExecutable(PlatformType type)
- {
- return MonoUtil::wstringToMono(MonoManager::instance().getDomain(), BuildManager::instance().getMainExecutable(type).toWString());
- }
- MonoString* ScriptBuildManager::internal_GetDefines(PlatformType type)
- {
- return MonoUtil::wstringToMono(MonoManager::instance().getDomain(), BuildManager::instance().getDefines(type));
- }
- MonoArray* ScriptBuildManager::internal_GetNativeBinaries(PlatformType type)
- {
- Vector<Path> paths = BuildManager::instance().getNativeBinaries(type);
- UINT32 numEntries = (UINT32)paths.size();
- ScriptArray outArray = ScriptArray::create<WString>(numEntries);
- for (UINT32 i = 0; i < numEntries; i++)
- {
- outArray.set(i, MonoUtil::wstringToMono(MonoManager::instance().getDomain(), paths[i].toWString()));
- }
- return outArray.getInternal();
- }
- MonoString* ScriptBuildManager::internal_GetBuildFolder(ScriptBuildFolder folder, PlatformType platform)
- {
- Path path;
- if (folder == ScriptBuildFolder::FrameworkAssemblies)
- {
- Path assemblyFolder = MonoManager::instance().getFrameworkAssembliesFolder();
- assemblyFolder.makeAbsolute(FileSystem::getWorkingDirectoryPath());
- Path sourceFolder = BuildManager::instance().getBuildFolder(BuildFolder::SourceRoot, platform);
- path = assemblyFolder.makeRelative(sourceFolder);
- }
- else if (folder == ScriptBuildFolder::Mono)
- {
- Path monoEtcFolder = MonoManager::instance().getMonoEtcFolder();
- monoEtcFolder.makeAbsolute(FileSystem::getWorkingDirectoryPath());
- Path sourceFolder = BuildManager::instance().getBuildFolder(BuildFolder::SourceRoot, platform);
- path = monoEtcFolder.makeRelative(sourceFolder);
- }
- else
- {
- BuildFolder nativeFolderType = BuildFolder::SourceRoot;
- switch (folder)
- {
- case ScriptBuildFolder::SourceRoot:
- nativeFolderType = BuildFolder::SourceRoot;
- break;
- case ScriptBuildFolder::DestinationRoot:
- nativeFolderType = BuildFolder::DestinationRoot;
- break;
- case ScriptBuildFolder::NativeBinaries:
- nativeFolderType = BuildFolder::NativeBinaries;
- break;
- case ScriptBuildFolder::BansheeAssemblies:
- nativeFolderType = BuildFolder::BansheeAssemblies;
- break;
- case ScriptBuildFolder::Data:
- nativeFolderType = BuildFolder::Data;
- break;
- }
- path = BuildManager::instance().getBuildFolder(nativeFolderType, platform);
- }
- return MonoUtil::wstringToMono(MonoManager::instance().getDomain(), path.toWString());
- }
- void ScriptBuildManager::internal_InjectIcons(MonoString* filePath, ScriptPlatformInfo* info)
- {
- if (info == nullptr)
- return;
- Path executablePath = MonoUtil::monoToWString(filePath);
- Map<UINT32, PixelDataPtr> icons;
- SPtr<PlatformInfo> platformInfo = info->getPlatformInfo();
- switch (platformInfo->type)
- {
- case PlatformType::Windows:
- {
- SPtr<WinPlatformInfo> winPlatformInfo = std::static_pointer_cast<WinPlatformInfo>(platformInfo);
- struct IconData
- {
- UINT32 size;
- HTexture texture;
- PixelDataPtr pixels;
- };
- IconData textures[] =
- {
- { 16, winPlatformInfo->icon16 },
- { 32, winPlatformInfo->icon32 },
- { 48, winPlatformInfo->icon48 },
- { 64, winPlatformInfo->icon64 },
- { 96, winPlatformInfo->icon96 },
- { 128, winPlatformInfo->icon128 },
- { 192, winPlatformInfo->icon192 },
- { 256, winPlatformInfo->icon256 }
- };
- for (auto& entry : textures)
- {
- auto& texProps = entry.texture->getProperties();
- entry.pixels = texProps.allocateSubresourceBuffer(0);
- entry.texture->readSubresource(gCoreAccessor(), 0, entry.pixels);
- icons[entry.size] = entry.pixels;
- }
- gCoreAccessor().submitToCoreThread(true);
- }
- break;
- }
- IconUtility::updateIconExe(executablePath, icons);
- }
- void ScriptBuildManager::internal_PackageResources(MonoString* buildFolder, ScriptPlatformInfo* info)
- {
- UnorderedSet<Path> usedResources;
- // Get all resources manually included in build
- Vector<ProjectLibrary::ResourceEntry*> buildResources = gProjectLibrary().getResourcesForBuild();
- for (auto& entry : buildResources)
- {
- if (entry->meta == nullptr)
- {
- LOGWRN("Cannot include resource in build, missing meta file for: " + entry->path.toString());
- continue;
- }
- Path resourcePath;
- if (gResources().getFilePathFromUUID(entry->meta->getUUID(), resourcePath))
- usedResources.insert(resourcePath);
- else
- LOGWRN("Cannot include resource in build, missing imported asset for: " + entry->path.toString());
- }
- // Include main scene
- SPtr<PlatformInfo> platformInfo;
- if (info != nullptr)
- platformInfo = info->getPlatformInfo();
- if (platformInfo != nullptr)
- {
- Path resourcePath;
- if (gResources().getFilePathFromUUID(platformInfo->mainScene.getUUID(), resourcePath))
- usedResources.insert(resourcePath);
- else
- LOGWRN("Cannot include main scene in build, missing imported asset.");
- }
- // Find dependencies of all resources
- Vector<Path> newResources;
- for (auto& entry : usedResources)
- newResources.push_back(entry);
- while (!newResources.empty())
- {
- Vector<Path> allDependencies;
- for (auto& entry : newResources)
- {
- Vector<String> curDependencies = gResources().getDependencies(entry);
- for (auto& entry : curDependencies)
- {
- Path resourcePath;
- if (gResources().getFilePathFromUUID(entry, resourcePath))
- {
- if (usedResources.find(resourcePath) == usedResources.end())
- {
- allDependencies.push_back(resourcePath);
- newResources.push_back(resourcePath);
- }
- }
- }
- }
- newResources = allDependencies;
- }
- // Copy resources
- Path outputPath = MonoUtil::monoToWString(buildFolder);
- outputPath.append(GAME_RESOURCES_FOLDER_NAME);
- FileSystem::createDir(outputPath);
- for (auto& entry : usedResources)
- {
- String uuid;
- BS_ASSERT(gResources().getUUIDFromFilePath(entry, uuid));
- Path sourcePath = gProjectLibrary().uuidToPath(uuid);
- ProjectLibrary::LibraryEntry* libEntry = gProjectLibrary().findEntry(sourcePath);
- assert(libEntry != nullptr && libEntry->type == ProjectLibrary::LibraryEntryType::File);
- ProjectLibrary::ResourceEntry* resEntry = static_cast<ProjectLibrary::ResourceEntry*>(libEntry);
- // If resource is prefab make sure to update it in case any of the prefabs it is referencing changed
- if (resEntry->meta->getTypeID() == TID_Prefab)
- {
- HPrefab prefab = static_resource_cast<Prefab>(gProjectLibrary().load(sourcePath));
- prefab->_updateChildInstances();
- // TODO - I should also clear prefab diffs
- gProjectLibrary().saveEntry(prefab);
- }
- else
- {
- Path destPath = outputPath;
- destPath.setFilename(entry.getFilename());
- FileSystem::copy(entry, destPath);
- }
- }
- // Save icon
- Path iconFolder = FileSystem::getWorkingDirectoryPath();
- iconFolder.append(BuiltinResources::EngineIconFolder);
- Path sourceRoot = BuildManager::instance().getBuildFolder(BuildFolder::SourceRoot, platformInfo->type);
- iconFolder.makeRelative(sourceRoot);
- Path destRoot = BuildManager::instance().getBuildFolder(BuildFolder::DestinationRoot, platformInfo->type);
- Path destIconFile = destRoot;
- destIconFile.append(iconFolder);
- destIconFile.setFilename(BuiltinResources::IconTextureName + L".asset");
- switch (platformInfo->type)
- {
- case PlatformType::Windows:
- {
- SPtr<WinPlatformInfo> winPlatformInfo = std::static_pointer_cast<WinPlatformInfo>(platformInfo);
- gResources().save(winPlatformInfo->taskbarIcon, destIconFile, false);
- }
- };
- // Save manifest
- Path manifestPath = outputPath;
- manifestPath.append(GAME_RESOURCE_MANIFEST_NAME);
- Path internalResourcesFolder = gEditorApplication().getProjectPath();
- internalResourcesFolder.append(PROJECT_INTERNAL_DIR);
- ResourceManifestPtr manifest = gProjectLibrary()._getManifest();
- ResourceManifest::save(manifest, manifestPath, internalResourcesFolder);
- }
- void ScriptBuildManager::internal_CreateStartupSettings(MonoString* buildFolder, ScriptPlatformInfo* info)
- {
- SPtr<PlatformInfo> platformInfo;
- if (info != nullptr)
- platformInfo = info->getPlatformInfo();
- SPtr<GameSettings> gameSettings;
- if (platformInfo != nullptr)
- {
- gameSettings->mainSceneUUID = platformInfo->mainScene.getUUID();
- gameSettings->fullscreen = platformInfo->fullscreen;
- gameSettings->resolutionWidth = platformInfo->windowedWidth;
- gameSettings->resolutionWidth = platformInfo->windowedHeight;
- switch (platformInfo->type)
- {
- case(PlatformType::Windows) :
- {
- SPtr<WinPlatformInfo> winPlatformInfo = std::static_pointer_cast<WinPlatformInfo>(platformInfo);
- gameSettings->titleBarText = winPlatformInfo->titlebarText;
- }
- break;
- }
- }
- Path outputPath = MonoUtil::monoToWString(buildFolder);
- outputPath.append(GAME_SETTINGS_NAME);
- FileEncoder fe(outputPath);
- fe.encode(gameSettings.get());
- }
- }
|