Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "DirectoryTree.h"
- using namespace SkyeCuillin;
- DirectoryTree::Record* DirectoryTree::CreateSubtree(const std::string& directory)
- {
- std::vector<std::string> list;
- Engine::Files::DirectoryRead(directory, list);
- Record* r = new Record(Type::DIRECTORY, directory.substr(directory.find_last_of('/') + 1));
- for (size_t i = 0; i < list.size(); i++)
- {
- if (list[i][list[i].length() - 1] == '/')
- {
- r->mChildren.push_back(CreateSubtree(directory + "/" + list[i].substr(0, list[i].length() - 1)));
- }
- else
- {
- printf("%s\n", (directory + "/" + list[i]).c_str());
- Record* rec = new Record(Type::FILE, list[i]);
- ProcessFile(rec, directory + "/" + list[i], list);
- r->mChildren.push_back(rec);
- }
- }
- return r;
- }
- void DirectoryTree::ProcessFile(Record* r, const std::string& file, std::vector<std::string>& files)
- {
- Engine::LoaderDevIL textureLoader(mLog);
- Engine::LoaderAssimp modelLoader(mLog, mRenderer);
- modelLoader.SetManagers(mMeshManager, mModelManager, mTextureManager);
- modelLoader.SetTextureHeap(mRenderer->Heap(), nullptr);
- if ((file.find(".tga") != std::string::npos) || (file.find(".png") != std::string::npos))
- {
- Engine::Manager<Engine::Texture>::Node* node = mTextureManager->GetNode(file);
- Engine::LoaderDevIL::Image* image = textureLoader.Load(file);
- if (image != nullptr)
- {
- image->mUseAlphaMipmap = false;
- textureLoader.GenerateMipmaps(image);
- }
- Engine::Texture* t = new Engine::Texture(file);
- t->InitMipmaps(mRenderer, image->mWidth, image->mHeight, 1, image->mMipLevels, Engine::Graphics::RGBA8, (const void**)image->mMipmaps);
- t->SetName(file);
- if (node == nullptr)
- {
- mTextureManager->Insert<Engine::Texture>(file, t);
- node = mTextureManager->GetNode(file);
- }
- else
- {
- delete node->mItem;
- node->mItem = t;
- }
- delete image;
- r->mResourceType = ResourceType::TEXTURE;
- r->mResource = node;
- }
- else if (file.find(".obj") != std::string::npos)
- {
- Engine::Manager<Engine::Model>::Node* node = mModelManager->GetNode(file);
- Engine::Model* mdl = modelLoader.Load(file);
- if (node == nullptr)
- {
- mModelManager->Insert<Engine::Model>(file, mdl);
- node = mModelManager->GetNode(file);
- }
- else
- {
- delete node->mItem;
- node->mItem = mdl;
- }
- r->mResourceType = ResourceType::MODEL;
- r->mResource = node;
- }
- else if (file.find(".cpp") != std::string::npos)
- {
- // Check if there isn't dll that corresponds to the cpp file
- bool compile = true;
- for (size_t i = 0; i < files.size(); i++)
- {
- std::string filesName = files[i].substr(0, files[i].length() - 4);
- std::string cmpName = Engine::Files::GetFile(file.substr(0, file.length() - 4));
- if ((files[i].substr(0, files[i].length() - 4) == Engine::Files::GetFile(file.substr(0, file.length() - 4))) &&
- (files[i].find(".dll") != std::string::npos))
- {
- // If such dll exists, check if its write time is greater than cpp write time
- if (Engine::Files::GetWriteTime(Engine::Files::GetFolder(file) + files[i]) > Engine::Files::GetWriteTime(file))
- {
- // In such case our dll is most-recent version of the script, we don't need to compile
- compile = false;
- }
- }
- }
- // If we need to compile, build the dll
- if (compile)
- {
- 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/\" \
- /LD \
- ") + file + std::string(" \
- \"Core.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 /GL /MDd /I \
- \"../Source/\" \
- /LD \
- ") + file + std::string(" \
- \"Core.lib\" \
- > Build.log\"");
- #endif
- system(command.c_str());
- // Delete .obj, .exp and .lib files
- 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());
- // 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 the .dll file exists in correct location, enqueue it for loading as next file
- if (Engine::Files::Exists(file.substr(0, file.length() - 4) + std::string(".dll")))
- {
- files.push_back(file.substr(0, file.length() - 4) + std::string(".dll"));
- }
- break;
- default:
- mLog->Print("Compiler", "Error: Invalid Compiler - Can't Compiler Any File!");
- break;
- }
- }
- }
- else if (file.find(".dll") != std::string::npos)
- {
- Engine::Manager<Engine::Plugin>::Node* node = mPluginManager->GetNode(file);
- mLog->Print("Plugin", std::string("Loading plugin: ") + file);
- Engine::Plugin* plugin = new Engine::Plugin(file);
- void* create = plugin->GetProc<void*>("CreateBehavior");
- void* name = plugin->GetProc<void*>("GetName");
- const char* (*fn)() = (const char*(*)())name;
- const char* pluginName = (*fn)();
- if (create == nullptr || name == nullptr)
- {
- mLog->Print("Plugin", std::string("CreateBehavior or GetName function not found!"));
- delete plugin;
- }
- else
- {
- mLog->Print("Plugin", std::string("CreateBehavior and GetName function found!"));
- mLog->Print("Plugin", std::string("Initializing plugin with name: ") + pluginName);
- if (node == nullptr)
- {
- mPluginManager->Insert<Engine::Plugin>(file, plugin);
- node = mPluginManager->GetNode(file);
- Engine::ComponentId componentID = Engine::ComponentTypeId::Get(pluginName);
- Engine::ComponentInterface* componentInterface = new Engine::ComponentInterface();
- componentInterface->CreateComponent = (Engine::Component*(*)())create;
- Engine::ComponentFactory::GetScriptComponentManager().insert(std::pair<Engine::ComponentId, Engine::ComponentInterface*>(componentID, componentInterface));
- }
- else
- {
- delete node->mItem;
- node->mItem = plugin;
- }
- r->mResourceType = ResourceType::SCRIPT;
- r->mResource = node;
- }
- }
- }
- DirectoryTree::Record* DirectoryTree::GetSubtreeRoot(std::string& directory)
- {
- Record* r = mRoot;
- std::string::iterator itDir = directory.begin();
- std::string::iterator itNode = r->mName.begin();
- while (itDir != directory.end() && itNode != r->mName.end() && (*itDir) == (*itNode))
- {
- itDir++;
- itNode++;
- }
- std::vector<std::string> path = Engine::String::Split(directory.substr(itDir - directory.begin()), '/');
- for (size_t i = 0; i < path.size(); i++)
- {
- if (path[i].length() > 0)
- {
- for (size_t j = 0; j < r->mChildren.size(); j++)
- {
- if (r->mChildren[j]->mName == path[i])
- {
- r = r->mChildren[j];
- break;
- }
- }
- }
- }
- return r;
- }
- void DirectoryTree::UpdateSubtree(std::string& directory)
- {
- std::vector<std::string> list;
- Engine::Files::DirectoryRead(directory, list);
- Record* r = GetSubtreeRoot(directory);
- std::set<std::string> nodes;
- for (Record* t : r->mChildren)
- {
- nodes.insert(t->mName);
- }
- for (size_t i = 0; i < list.size(); i++)
- {
- bool found = false;
- std::string name = list[i];
- if (list[i][list[i].length() - 1] == '/')
- {
- name = list[i].substr(0, list[i].length() - 1);
- }
- for (size_t j = 0; j < r->mChildren.size(); j++)
- {
- if (r->mChildren[j]->mName == name)
- {
- found = true;
- nodes.erase(name);
- break;
- }
- }
- if (!found)
- {
- if (list[i][list[i].length() - 1] == '/')
- {
- r->mChildren.push_back(CreateSubtree(directory + "/" + list[i].substr(0, list[i].length() - 1)));
- }
- else
- {
- r->mChildren.push_back(new Record(Type::FILE, list[i]));
- }
- }
- }
- for (const std::string& s : nodes)
- {
- for (size_t j = 0; j < r->mChildren.size(); j++)
- {
- if (r->mChildren[j]->mName == s)
- {
- r->mChildren.erase(r->mChildren.begin() + j);
- break;
- }
- }
- }
- }
- void DirectoryTree::_ImguiRenderRecord(Record* r)
- {
- for (size_t i = 0; i < r->mChildren.size(); i++)
- {
- bool nodeOpen = false;
- if (ImGui::TreeNodeEx(r->mChildren[i]->mName.c_str(),
- //((r->mChildren[i]->mType == Type::FILE && r->mChildren[i]->mResourceType != ResourceType::MODEL) ? ImGuiTreeNodeFlags_Leaf : 0) |
- (r->mChildren[i]->mType == Type::FILE ? ImGuiTreeNodeFlags_Leaf : 0) |
- ImGuiTreeNodeFlags_OpenOnArrow |
- (r->mChildren[i]->mResourceType != ResourceType::MODEL ? ImGuiTreeNodeFlags_DefaultOpen : 0)))
- {
- nodeOpen = true;
- if (r->mChildren[i]->mType != Type::DIRECTORY)
- {
- if (ImGui::BeginDragDropSource())
- {
- printf("%lx\n", r->mChildren[i]->mResource);
- switch (r->mChildren[i]->mResourceType)
- {
- case ResourceType::MODEL:
- ImGui::SetDragDropPayload("RESOURCE_MODEL", &(r->mChildren[i]->mResource), sizeof(Record*));
- ImGui::Text("%s", r->mChildren[i]->mName.c_str());
- break;
- case ResourceType::TEXTURE:
- ImGui::SetDragDropPayload("RESOURCE_TEXTURE", &(r->mChildren[i]->mResource), sizeof(void*));
- ImGui::Image((ImTextureID)(((Engine::Manager<Engine::Texture>::Node*)r->mChildren[i]->mResource)->mItem->GetSRV().mGpuHandle.ptr), ImVec2(64, 64));
- break;
- case ResourceType::SCRIPT:
- ImGui::SetDragDropPayload("RESOURCE_SCRIPT", &(r->mChildren[i]->mResource), sizeof(void*));
- ImGui::Text("%s", r->mChildren[i]->mName.c_str());
- break;
- default:
- break;
- }
- ImGui::EndDragDropSource();
- }
- if (ImGui::IsItemClicked())
- {
- printf("%s\n", r->mChildren[i]->mName.c_str());
- }
- if (r->mChildren[i]->mResourceType == ResourceType::MODEL)
- {
- Engine::Manager<Engine::Model>::Node* node = (Engine::Manager<Engine::Model>::Node*)(r->mChildren[i]->mResource);
- for (size_t j = 0; j < node->Get()->GetMeshesCount(); j++)
- {
- if (ImGui::TreeNodeEx(node->Get()->GetMesh(j)->GetName().c_str(), ImGuiTreeNodeFlags_Leaf))
- {
- if (ImGui::BeginDragDropSource())
- {
- Engine::Mesh* mesh = node->Get()->GetMesh(j);
- ImGui::SetDragDropPayload("RESOURCE_MESH", &mesh, sizeof(void*));
- ImGui::Text("%s", node->Get()->GetMesh(j)->GetName().c_str());
- ImGui::EndDragDropSource();
- }
- }
- ImGui::TreePop();
- }
- }
- }
- }
- if (r->mChildren[i]->mType == Type::DIRECTORY)
- {
- if (nodeOpen)
- {
- _ImguiRenderRecord(r->mChildren[i]);
- }
- }
- if (nodeOpen)
- {
- ImGui::TreePop();
- }
- }
- }
- DirectoryTree::DirectoryTree(const std::string& directory, Engine::Constants* options, Engine::Log* log, Engine::D3DRenderer* renderer)
- {
- std::string path = directory;
- std::replace(path.begin(), path.end(), '\\', '/');
- mPath = path;
- mOptions = options;
- mLog = log;
- mRenderer = renderer;
- std::string compilerType = mOptions->Get<std::string>("Compiler.Type");
- if (compilerType == "Visual Studio 2022")
- {
- mCompilerType = MSVC;
- mCompilerPaths = new std::string[2];
- mCompilerPaths[0] = mOptions->Get<std::string>("Compiler.VCVarsAllPath");
- mCompilerPaths[1] = mOptions->Get<std::string>("Compiler.CLPath");
- }
- else
- {
- mLog->Print("Compiler", std::string("Error: Unknown Compiler or Compiler Not Set - Critical Error - Please Fix Config File!"));
- mCompilerPaths = nullptr;
- }
- }
- DirectoryTree::~DirectoryTree()
- {
- delete mRoot;
- if (mCompilerPaths)
- {
- delete[] mCompilerPaths;
- }
- }
- void DirectoryTree::Initialize()
- {
- mRoot = CreateSubtree(mPath);
- }
- void DirectoryTree::SetManagers(Engine::Manager<Engine::Mesh>* meshManager,
- Engine::Manager<Engine::Model>* modelManager,
- Engine::Manager<Engine::Texture>* textureManager,
- Engine::Manager<Engine::Plugin>* pluginManager)
- {
- mMeshManager = meshManager;
- mModelManager = modelManager;
- mTextureManager = textureManager;
- mPluginManager = pluginManager;
- }
- void DirectoryTree::Imgui()
- {
- _ImguiRenderRecord(mRoot);
- }
- void DirectoryTree::NotifyChange(std::string location)
- {
- mChanges.push_back(location);
- }
- void DirectoryTree::ProcessChanges()
- {
- for (const std::string& s : mChanges)
- {
- printf("Processing: '%s'\n", s.c_str());
- std::string path = mOptions->Get<std::string>("Editor.Resources") + "/" + s;
- std::replace(path.begin(), path.end(), '\\', '/');
- Engine::Files::Type type = Engine::Files::GetType(path);
- if (type == Engine::Files::Type::DIRECTORY)
- {
- UpdateSubtree(path);
- }
- else
- {
- std::string directory = path.substr(0, path.find_last_of('/'));
- mFiles.push_back(path);
- UpdateSubtree(directory);
- }
- mTextureManager->Print();
- }
- mChanges.clear();
- for (const std::string& s : mFiles)
- {
- Engine::LoaderDevIL loader(mLog);
- printf("%s\n", s.c_str());
- if (s.find(".tga") != std::string::npos)
- {
- Engine::Manager<Engine::Texture>::Node* node = mTextureManager->GetNode(s);
- if (node != nullptr)
- {
- Engine::LoaderDevIL::Image* image = loader.Load(s);
- if (image != nullptr)
- {
- image->mUseAlphaMipmap = false;
- loader.GenerateMipmaps(image);
- }
- Engine::Texture* t = new Engine::Texture(s);
- t->InitMipmaps(mRenderer, image->mWidth, image->mHeight, 1, image->mMipLevels, Engine::Graphics::RGBA8, (const void**)image->mMipmaps);
- t->SetName(s);
- delete node->mItem;
- node->mItem = t;
- delete image;
- }
- }
- }
- mFiles.clear();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement