Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// <summary>
- /// Compile source (script) file into dll that can be loaded and used
- /// </summary>
- /// <param name="file">Path to source cpp file</param>
- void DirectoryTree::CompileSource(const std::string& file)
- {
- std::string command = "";
- switch (mCompilerType)
- {
- // MSVC Compiler
- case MSVC:
- // Here is the deal, MSVC always generates .obj, .exp, .lib and .dll file in the current folder
- // so, we will call the MSVC compiler with all settings, and let it build dll, writing output
- // to Build.log
- //
- // Once this is done, we will delete .obj, .exp and .lib file as we don't need those anymore.
- // Which is followed by copying .dll file into the folder where .cpp file originally was, this
- // is not all though - as we just generated a new .dll plugin, we also need to queue it for
- // loading!
- //
- // The loading only happens when .dll exists (otherwise the compilation has failed and the
- // Build.log has to be examined.
- //
- // Uses system calls!
- // Compilation (differs for DEBUG vs RELEASE builds)
- #ifdef NDEBUG
- command = std::string("cmd /S /C \"\"") + mCompilerPaths[0] + std::string("/vcvarsall.bat\" amd64 && \
- \"") + mCompilerPaths[1] + std::string("/cl.exe\" /O2 /EHsc /GL /MD \
- /I \"../Source/Engine/\" \
- /I \"../Dependencies/\" \
- /I \"../Dependencies/Bullet/include/\" \
- /LD \
- ") + file + std::string(" \
- \"Engine.lib\" \
- > Build.log\"");
- #else
- command = std::string("cmd /S /C \"\"") + mCompilerPaths[0] + std::string("/vcvarsall.bat\" amd64 && \
- \"") + mCompilerPaths[1] + std::string("/cl.exe\" /O2 /EHsc /DEBUG /ZI /MDd \
- /I \"../Source/Engine/\" \
- /I \"../Dependencies/\" \
- /I \"../Dependencies/Bullet/include/\" \
- /LD \
- ") + file + std::string(" \
- \"Engine_d.lib\" \
- > Build.log\"");
- #endif
- std::cout << command << std::endl;
- system(command.c_str());
- // First, Check compilation results - check whether the output file exists
- if (Engine::Files::Exists("Build.log"))
- {
- // Open the file and look for 'Finished generating code' - which points to compilation success
- std::ifstream buildLog("Build.log");
- bool buildSucessful = false;
- std::string line;
- while (std::getline(buildLog, line))
- {
- if (line.find("Finished generating code") != std::string::npos)
- {
- buildSucessful = true;
- }
- // TODO - these lines can be appended to log at some level
- }
- buildLog.close();
- // At this point we can start processing the new dll and loading it.
- if (buildSucessful)
- {
- // Get previous plugin node using this script
- Engine::Manager<Engine::Plugin>::Node* node = mPluginManager->GetNode(file.substr(0, file.length() - 4) + std::string(".dll"));
- // In case node would exist, we need to store data for each instantiated component in the scene
- // as these also need to be deleted (and re-created after new library is loaded).
- std::map<Engine::GameObject*, std::string> tmp;
- // If the node exists - we will need to unload associated dll, as we have to replace it with a newly compiled one
- if (node != nullptr)
- {
- // Get plugin name first
- void* name = node->Get()->GetProc<void*>("GetName");
- const char* (*fn)() = (const char* (*)())name;
- const char* pluginName = (*fn)();
- // Loop through ALL components of given type, serialize them and delete them
- std::set<Engine::Component*>& components = Engine::ComponentTypeList::GetComponents(Engine::ComponentTypeId::Get(pluginName));
- for (auto it = components.begin(); it != components.end(); it++)
- {
- tmp.insert(std::pair<Engine::GameObject*, std::string>((*it)->mGameObject, (*it)->Serialize()));
- delete (*it);
- }
- components.clear();
- // Unload the node
- node->Get()->Unload();
- }
- // Delete .obj, .exp and .lib files in release builds
- #ifdef NDEBUG
- command = std::string("cmd /S /C \"del ")
- + std::string("\"") + Engine::Files::GetFile(file.substr(0, file.length() - 4)) + std::string(".obj") + std::string("\" ")
- + std::string("\"") + Engine::Files::GetFile(file.substr(0, file.length() - 4)) + std::string(".exp") + std::string("\" ")
- + std::string("\"") + Engine::Files::GetFile(file.substr(0, file.length() - 4)) + std::string(".lib") + std::string("\"\"");
- system(command.c_str());
- #endif
- // Move .dll file
- command = std::string("cmd /S /C \"move ")
- + std::string("\"") + Engine::Files::GetFile(file.substr(0, file.length() - 4)) + std::string(".dll") + std::string("\" ")
- + Engine::Files::GetFolder(file) + std::string("\"");
- system(command.c_str());
- if (node != nullptr)
- {
- node->Get()->Load(file.substr(0, file.length() - 4) + std::string(".dll"));
- void* create = node->Get()->GetProc<void*>("CreateBehavior");
- void* name = node->Get()->GetProc<void*>("GetName");
- const char* (*fn)() = (const char* (*)())name;
- const char* pluginName = (*fn)();
- Engine::ComponentId componentID = Engine::ComponentTypeId::Get(pluginName);
- Engine::ComponentInterface* componentInterface = new Engine::ComponentInterface();
- componentInterface->CreateComponent = (Engine::Component * (*)())create;
- delete Engine::ComponentFactory::GetScriptComponentManager().find(componentID)->second;
- Engine::ComponentFactory::GetScriptComponentManager().find(componentID)->second = componentInterface;
- // Loop through ALL serialized components, create new ones on given entities and deserialize them
- for (auto it = tmp.begin(); it != tmp.end(); it++)
- {
- Engine::Component* component = componentInterface->CreateComponent();
- component->Deserialize(it->second);
- it->first->AddComponent(componentID, component);
- }
- }
- }
- }
- break;
- default:
- mLog->Print("Compiler", "Error: Invalid Compiler - Can't Compiler Any File!");
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement