CrewStationScreen::CrewStationScreen()
{
    select_station_button = new GuiButton(this, "", "", [this]()
    {
        button_strip->show();
    });
    select_station_button->setPosition(-20, 20, ATopRight)->setSize(250, 50);
    button_strip = new GuiPanel(this, "");
    button_strip->setPosition(-20, 20, ATopRight)->setSize(250, 50);
    button_strip->hide();

#ifndef __ANDROID__
    if (PreferencesManager::get("music_enabled") == "1")
    {
        threat_estimate = new ThreatLevelEstimate();
        threat_estimate->setCallbacks([](){
            LOG(INFO) << "Switching to ambient music";
            soundManager->playMusicSet(findResources("music/ambient/*.ogg"));
        }, []() {
            LOG(INFO) << "Switching to combat music";
            soundManager->playMusicSet(findResources("music/combat/*.ogg"));
        });
    }
#endif
}
AssetBrowser::AssetBrowser(StudioApp& app)
	: m_editor(*app.getWorldEditor())
	, m_metadata(*app.getMetadata())
	, m_resources(app.getWorldEditor()->getAllocator())
	, m_selected_resource(nullptr)
	, m_autoreload_changed_resource(true)
	, m_changed_files(app.getWorldEditor()->getAllocator())
	, m_is_focus_requested(false)
	, m_changed_files_mutex(false)
	, m_history(app.getWorldEditor()->getAllocator())
	, m_plugins(app.getWorldEditor()->getAllocator())
	, m_on_resource_changed(app.getWorldEditor()->getAllocator())
	, m_app(app)
	, m_is_update_enabled(true)
	, m_current_type(0)
	, m_is_opened(false)
	, m_activate(false)
	, m_history_index(-1)
{
	auto& editor = *app.getWorldEditor();
	auto& allocator = editor.getAllocator();
	m_filter[0] = '\0';
	m_resources.emplace(allocator);

	findResources();

	const char* base_path = editor.getEngine().getDiskFileDevice()->getBasePath();
	m_watchers[0] = FileSystemWatcher::create(base_path, allocator);
	m_watchers[0]->getCallback().bind<AssetBrowser, &AssetBrowser::onFileChanged>(this);
	if (editor.getEngine().getPatchFileDevice())
	{
		base_path = editor.getEngine().getPatchFileDevice()->getBasePath();
		m_watchers[1] = FileSystemWatcher::create(base_path, allocator);
		m_watchers[1]->getCallback().bind<AssetBrowser, &AssetBrowser::onFileChanged>(this);
	}
	else
	{
		m_watchers[1] = nullptr;
	}

	m_auto_reload_action = LUMIX_NEW(allocator, Action)("Auto-reload", "autoReload");
	m_auto_reload_action->is_global = false;
	m_auto_reload_action->func.bind<AssetBrowser, &AssetBrowser::toggleAutoreload>(this);
	m_auto_reload_action->is_selected.bind<AssetBrowser, &AssetBrowser::isAutoreload>(this);
	m_back_action = LUMIX_NEW(allocator, Action)("Back", "back");
	m_back_action->is_global = false;
	m_back_action->func.bind<AssetBrowser, &AssetBrowser::goBack>(this);
	m_forward_action = LUMIX_NEW(allocator, Action)("Forward", "forward");
	m_forward_action->is_global = false;
	m_forward_action->func.bind<AssetBrowser, &AssetBrowser::goForward>(this);
	m_refresh_action = LUMIX_NEW(allocator, Action)("Refresh", "refresh");
	m_refresh_action->is_global = false;
	m_refresh_action->func.bind<AssetBrowser, &AssetBrowser::findResources>(this);
	m_app.addAction(m_auto_reload_action);
	m_app.addAction(m_back_action);
	m_app.addAction(m_forward_action);
	m_app.addAction(m_refresh_action);
}
Beispiel #3
0
void AssetBrowser::onGUI()
{
	if (m_wanted_resource.isValid())
	{
		selectResource(m_wanted_resource);
		m_wanted_resource = "";
	}

	if (!ImGui::BeginDock("Asset Browser", &m_is_opened))
	{
		if (m_activate) ImGui::SetDockActive();
		m_activate = false;
		ImGui::EndDock();
		return;
	}

	if (m_activate) ImGui::SetDockActive();
	m_activate = false;

	if (m_is_focus_requested)
	{
		m_is_focus_requested = false;
		ImGui::SetWindowFocus();
	}

	if (ImGui::Button("Refresh")) findResources();
	ImGui::SameLine();
	ImGui::Checkbox("Autoreload", &m_autoreload_changed_resource);

	auto getter = [](void* data, int idx, const char** out) -> bool
	{
		auto& browser = *static_cast<AssetBrowser*>(data);
		*out = browser.m_plugins[idx]->getName();
		return true;
	};

	ImGui::Combo("Type", &m_current_type, getter, this, m_plugins.size());
	ImGui::InputText("Filter", m_filter, sizeof(m_filter));

	ImGui::ListBoxHeader("Resources");
	auto& resources = m_resources[m_current_type + 1];

	for (auto& resource : resources)
	{
		if (m_filter[0] != '\0' && strstr(resource.c_str(), m_filter) == nullptr) continue;

		bool is_selected = m_selected_resource ? m_selected_resource->getPath() == resource : false;
		if (ImGui::Selectable(resource.c_str(), is_selected))
		{
			selectResource(resource);
		}
	}
	ImGui::ListBoxFooter();
	onGUIResource();
	ImGui::EndDock();
}
EpsilonServer::EpsilonServer()
: GameServer("Server", VERSION_NUMBER)
{
    new GameGlobalInfo();
    PlayerInfo* info = new PlayerInfo();
    info->client_id = 0;
    my_player_info = info;
    engine->setGameSpeed(0.0);
    for(unsigned int n=0; n<factionInfo.size(); n++)
        factionInfo[n]->reset();

    threat_estimate = new ThreatLevelEstimate();
    threat_estimate->setCallbacks([](){
        LOG(INFO) << "Switching to ambient music";
        soundManager->playMusicSet(findResources("music/ambient/*.ogg"));
    }, []() {
        LOG(INFO) << "Switching to combat music";
        soundManager->playMusicSet(findResources("music/combat/*.ogg"));
    });
}
Beispiel #5
0
std::vector<std::string>
DirectorySearch::findResources (std::string path, std::string extension)
{
    // TODO: Move strings to CONSTANTS
    DIR *directory = nullptr;
    struct dirent *entry = nullptr;
    std::string d_name;
    
    // Add trailing slash for recursion
    if (path.at (path.length () - 1) != '/')
    {
        path += "/";
    }

    directory = opendir (path.c_str ());;
    entry = readdir (directory);

    while ((entry = readdir (directory)))
    {
        d_name = entry->d_name;

        if (d_name != "." && d_name != "..") // do not check dots
        {
            entries entry_type = determineType (path + d_name);

            if (entry_type == entries::DIRECTORY)
            {
                findResources (path + d_name, extension);
            }
            else if (entry_type == entries::FILE)
            {
                if (d_name.find(extension, (d_name.length() - extension.length())) != std::string::npos)
                {
                    files.push_back (path + d_name);
                }
            }
            else // DOT or UNKNOWN
            {
                std::cerr << "Error in DirectorySearch::findResources: UNKNOWN or DOT type fell through." << std::endl;
            }
        }
    }
    
    if (directory != nullptr)
    {
        closedir (directory);
    }
    
    return files;

} // DirectorySearch::findResources
AssetBrowser::AssetBrowser(StudioApp& app)
	: m_editor(*app.getWorldEditor())
	, m_metadata(*app.getMetadata())
	, m_resources(app.getWorldEditor()->getAllocator())
	, m_selected_resource(nullptr)
	, m_autoreload_changed_resource(true)
	, m_changed_files(app.getWorldEditor()->getAllocator())
	, m_is_focus_requested(false)
	, m_changed_files_mutex(false)
	, m_history(app.getWorldEditor()->getAllocator())
	, m_plugins(app.getWorldEditor()->getAllocator())
	, m_on_resource_changed(app.getWorldEditor()->getAllocator())
	, m_app(app)
{
	auto& editor = *app.getWorldEditor();
	m_is_update_enabled = true;
	m_filter[0] = '\0';
	m_current_type = 0;
	m_is_opened = false;
	m_activate = false;
	m_resources.emplace(editor.getAllocator());

	findResources();

	const char* base_path = editor.getEngine().getDiskFileDevice()->getBasePath();
	m_watchers[0] = FileSystemWatcher::create(base_path, editor.getAllocator());
	m_watchers[0]->getCallback().bind<AssetBrowser, &AssetBrowser::onFileChanged>(this);
	if (editor.getEngine().getPatchFileDevice())
	{
		base_path = editor.getEngine().getPatchFileDevice()->getBasePath();
		m_watchers[1] = FileSystemWatcher::create(base_path, editor.getAllocator());
		m_watchers[1]->getCallback().bind<AssetBrowser, &AssetBrowser::onFileChanged>(this);
	}
	else
	{
		m_watchers[1] = nullptr;
	}
}
Beispiel #7
0
AssetBrowser::AssetBrowser(Lumix::WorldEditor& editor, Metadata& metadata)
	: m_editor(editor)
	, m_metadata(metadata)
	, m_resources(editor.getAllocator())
	, m_selected_resource(nullptr)
	, m_autoreload_changed_resource(true)
	, m_changed_files(editor.getAllocator())
	, m_is_focus_requested(false)
	, m_changed_files_mutex(false)
	, m_history(editor.getAllocator())
	, m_plugins(editor.getAllocator())
	, m_on_resource_changed(editor.getAllocator())
{
	m_is_update_enabled = true;
	m_filter[0] = '\0';
	m_current_type = 0;
	m_is_opened = false;
	m_activate = false;
	m_resources.emplace(editor.getAllocator());

	findResources();

	const char* base_path = editor.getEngine().getDiskFileDevice()->getBasePath(0);
	m_watchers[0] = FileSystemWatcher::create(base_path, editor.getAllocator());
	m_watchers[0]->getCallback().bind<AssetBrowser, &AssetBrowser::onFileChanged>(this);
	base_path = editor.getEngine().getDiskFileDevice()->getBasePath(1);
	if (Lumix::stringLength(base_path) > 1)
	{
		m_watchers[1] = FileSystemWatcher::create(base_path, editor.getAllocator());
		m_watchers[1]->getCallback().bind<AssetBrowser, &AssetBrowser::onFileChanged>(this);
	}
	else
	{
		m_watchers[1] = nullptr;
	}
}
Beispiel #8
0
void AssetBrowser::addPlugin(IPlugin& plugin)
{
	m_plugins.push(&plugin);
	m_resources.emplace(m_editor.getAllocator());
	findResources();
}
ServerCreationScreen::ServerCreationScreen()
{
    assert(game_server);

    new GuiOverlay(this, "", colorConfig.background);
    (new GuiOverlay(this, "", sf::Color::White))->setTextureTiled("gui/BackgroundCrosses");

    // Set defaults from preferences.
    gameGlobalInfo->player_warp_jump_drive_setting = EPlayerWarpJumpDrive(PreferencesManager::get("server_config_warp_jump_drive_setting", "0").toInt());
    gameGlobalInfo->long_range_radar_range = PreferencesManager::get("server_config_long_range_radar_range", "30000").toInt();
    gameGlobalInfo->scanning_complexity = EScanningComplexity(PreferencesManager::get("server_config_scanning_complexity", "2").toInt());
    gameGlobalInfo->use_beam_shield_frequencies = PreferencesManager::get("server_config_use_beam_shield_frequencies", "1").toInt();
    gameGlobalInfo->use_system_damage = PreferencesManager::get("server_config_use_system_damage", "1").toInt();
    gameGlobalInfo->allow_main_screen_tactical_radar = PreferencesManager::get("server_config_allow_main_screen_tactical_radar", "1").toInt();
    gameGlobalInfo->allow_main_screen_long_range_radar = PreferencesManager::get("server_config_allow_main_screen_long_range_radar", "1").toInt();

    // Create a two-column layout.
    GuiElement* container = new GuiAutoLayout(this, "", GuiAutoLayout::ELayoutMode::LayoutVerticalColumns);
    container->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    GuiElement* left_container = new GuiElement(container, "");
    GuiElement* right_container = new GuiElement(container, "");

    GuiElement* left_panel = new GuiAutoLayout(left_container, "", GuiAutoLayout::LayoutVerticalTopToBottom);
    left_panel->setPosition(0, 20, ATopCenter)->setSize(550, GuiElement::GuiSizeMax);
    GuiElement* right_panel = new GuiAutoLayout(right_container, "", GuiAutoLayout::LayoutVerticalTopToBottom);
    right_panel->setPosition(0, 20, ATopCenter)->setSize(550, GuiElement::GuiSizeMax);

    // Left column contents.
    // General section.
    (new GuiLabel(left_panel, "GENERAL_LABEL", "Server configuration", 30))->addBackground()->setSize(GuiElement::GuiSizeMax, 50);

    // Server name row.
    GuiElement* row = new GuiAutoLayout(left_panel, "", GuiAutoLayout::LayoutHorizontalLeftToRight);
    row->setSize(GuiElement::GuiSizeMax, 50);
    (new GuiLabel(row, "NAME_LABEL", "Server name: ", 30))->setAlignment(ACenterRight)->setSize(250, GuiElement::GuiSizeMax);
    (new GuiTextEntry(row, "SERVER_NAME", game_server->getServerName()))->callback([](string text){game_server->setServerName(text);})->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    // Server password row.
    row = new GuiAutoLayout(left_panel, "", GuiAutoLayout::LayoutHorizontalLeftToRight);
    row->setSize(GuiElement::GuiSizeMax, 50);
    (new GuiLabel(row, "PASSWORD_LABEL", "Server password: "******"SERVER_PASSWORD", ""))->callback([](string text){game_server->setPassword(text);})->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    // Server IP row.
    row = new GuiAutoLayout(left_panel, "", GuiAutoLayout::LayoutHorizontalLeftToRight);
    row->setSize(GuiElement::GuiSizeMax, 50);
    (new GuiLabel(row, "IP_LABEL", "Server IP: ", 30))->setAlignment(ACenterRight)->setSize(250, GuiElement::GuiSizeMax);
    (new GuiLabel(row, "IP", sf::IpAddress::getLocalAddress().toString(), 30))->setAlignment(ACenterLeft)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    // LAN/Internet row.
    row = new GuiAutoLayout(left_panel, "", GuiAutoLayout::LayoutHorizontalLeftToRight);
    row->setSize(GuiElement::GuiSizeMax, 50);
    (new GuiLabel(row, "LAN_INTERNET_LABEL", "Server visibility: ", 30))->setAlignment(ACenterRight)->setSize(250, GuiElement::GuiSizeMax);
    (new GuiSelector(row, "LAN_INTERNET_SELECT", [](int index, string value) {
        if (index == 1)
            game_server->registerOnMasterServer("http://daid.eu/ee/register.php");
        else
            game_server->stopMasterServerRegistry();
    }))->setOptions({"LAN only", "Internet"})->setSelectionIndex(0)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    // Player Ships section.
    (new GuiLabel(left_panel, "PLAYER_SHIP_LABEL", "Player ship options", 30))->addBackground()->setSize(GuiElement::GuiSizeMax, 50);

    // Warp/Jump drive row.
    row = new GuiAutoLayout(left_panel, "", GuiAutoLayout::LayoutHorizontalLeftToRight);
    row->setSize(GuiElement::GuiSizeMax, 50);
    (new GuiLabel(row, "WARP_JUMP_LABEL", "Warp/Jump: ", 30))->setAlignment(ACenterRight)->setSize(250, GuiElement::GuiSizeMax);
    (new GuiSelector(row, "WARP_JUMP_SELECT", [](int index, string value) {
        gameGlobalInfo->player_warp_jump_drive_setting = EPlayerWarpJumpDrive(index);
    }))->setOptions({"Ship default", "Warp drive", "Jump drive", "Both", "Neither"})->setSelectionIndex((int)gameGlobalInfo->player_warp_jump_drive_setting)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    // Radar range limit row.
    row = new GuiAutoLayout(left_panel, "", GuiAutoLayout::LayoutHorizontalLeftToRight);
    row->setSize(GuiElement::GuiSizeMax, 50);
    (new GuiLabel(row, "RADAR_LABEL", "Radar range: ", 30))->setAlignment(ACenterRight)->setSize(250, GuiElement::GuiSizeMax);
    (new GuiSelector(row, "RADAR_SELECT", [](int index, string value) {
        gameGlobalInfo->long_range_radar_range = index * 5000 + 10000;
    }))->setOptions({"10U", "15U", "20U", "25U", "30U", "35U", "40U", "45U", "50U"})->setSelectionIndex((gameGlobalInfo->long_range_radar_range - 10000.0) / 5000.0)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    // Main screen section.
    (new GuiLabel(left_panel, "MAIN_SCREEN_LABEL", "Main screen options", 30))->addBackground()->setSize(GuiElement::GuiSizeMax, 50);

    // Radar row.
    row = new GuiAutoLayout(left_panel, "", GuiAutoLayout::LayoutHorizontalLeftToRight);
    row->setSize(GuiElement::GuiSizeMax, 50);
    (new GuiToggleButton(row, "MAIN_TACTICAL_TOGGLE", "Tactical radar", [](bool value) {
        gameGlobalInfo->allow_main_screen_tactical_radar = value == 1;
    }))->setValue(gameGlobalInfo->allow_main_screen_tactical_radar)->setSize(275, GuiElement::GuiSizeMax)->setPosition(0, 0, ACenterLeft);
    (new GuiToggleButton(row, "MAIN_LONG_RANGE_TOGGLE", "Long range radar", [](bool value) {
        gameGlobalInfo->allow_main_screen_long_range_radar = value == 1;
    }))->setValue(gameGlobalInfo->allow_main_screen_long_range_radar)->setSize(275, GuiElement::GuiSizeMax)->setPosition(0, 0, ACenterRight);

    // Game rules section.
    (new GuiLabel(left_panel, "GAME_RULES_LABEL", "Game rules", 30))->addBackground()->setSize(GuiElement::GuiSizeMax, 50);

    // Science scan complexity selector.
    row = new GuiAutoLayout(left_panel, "", GuiAutoLayout::LayoutHorizontalLeftToRight);
    row->setSize(GuiElement::GuiSizeMax, 50);
    (new GuiLabel(row, "GAME_SCANNING_COMPLEXITY_LABEL", "Scan complexity: ", 30))->setAlignment(ACenterRight)->setSize(250, GuiElement::GuiSizeMax);
    (new GuiSelector(row, "GAME_SCANNING_COMPLEXITY", [](int index, string value) {
        gameGlobalInfo->scanning_complexity = EScanningComplexity(index);
    }))->setOptions({"None (delay)", "Simple", "Normal", "Advanced"})->setSelectionIndex((int)gameGlobalInfo->scanning_complexity)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    // Frequency and system damage row.
    row = new GuiAutoLayout(left_panel, "", GuiAutoLayout::LayoutHorizontalLeftToRight);
    row->setSize(GuiElement::GuiSizeMax, 50);
    (new GuiToggleButton(row, "GAME_FREQUENCIES_TOGGLE", "Beam/shield frequencies", [](bool value) {
        gameGlobalInfo->use_beam_shield_frequencies = value == 1;
    }))->setValue(gameGlobalInfo->use_beam_shield_frequencies)->setSize(275, GuiElement::GuiSizeMax)->setPosition(0, 0, ACenterLeft);

    (new GuiToggleButton(row, "GAME_SYS_DAMAGE_TOGGLE", "Per-system damage", [](bool value) {
        gameGlobalInfo->use_system_damage = value == 1;
    }))->setValue(gameGlobalInfo->use_system_damage)->setSize(275, GuiElement::GuiSizeMax)->setPosition(0, 0, ACenterRight);

    // Right column contents.
    // Scenario section.
    (new GuiLabel(right_panel, "SCENARIO_LABEL", "Scenario", 30))->addBackground()->setSize(GuiElement::GuiSizeMax, 50);
    // List each scenario derived from scenario_*.lua files in Resources.
    GuiListbox* scenario_list = new GuiListbox(right_panel, "SCENARIO_LIST", [this](int index, string value) {
        selectScenario(value);
    });
    scenario_list->setSize(GuiElement::GuiSizeMax, 300);

    // Show the scenario description text.
    GuiPanel* panel = new GuiPanel(right_panel, "SCENARIO_DESCRIPTION_BOX");
    panel->setSize(GuiElement::GuiSizeMax, 200);
    scenario_description = new GuiScrollText(panel, "SCENARIO_DESCRIPTION", "");
    scenario_description->setTextSize(24)->setMargins(15)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    // If the scenario has variations, show and select from them.
    variation_container = new GuiAutoLayout(right_panel, "VARIATION_CONTAINER", GuiAutoLayout::LayoutVerticalTopToBottom);
    variation_container->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    row = new GuiAutoLayout(variation_container, "", GuiAutoLayout::LayoutHorizontalLeftToRight);
    row->setSize(GuiElement::GuiSizeMax, 50);
    (new GuiLabel(row, "VARIATION_LABEL", "Variation: ", 30))->setAlignment(ACenterRight)->setSize(250, GuiElement::GuiSizeMax);
    variation_selection = new GuiSelector(row, "VARIATION_SELECT", [this](int index, string value) {
        gameGlobalInfo->variation = variation_names_list.at(index);
        variation_description->setText(variation_descriptions_list.at(index));
    });
    variation_selection->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    panel = new GuiPanel(variation_container, "VARIATION_DESCRIPTION_BOX");
    panel->setSize(GuiElement::GuiSizeMax, 150);
    variation_description = new GuiScrollText(panel, "VARIATION_DESCRIPTION", "");
    variation_description->setTextSize(24)->setMargins(15)->setSize(GuiElement::GuiSizeMax, GuiElement::GuiSizeMax);

    // Buttons beneath the columns.
    // Close server button.
    (new GuiButton(left_container, "CLOSE_SERVER", "Close server", [this]() {
        destroy();
        disconnectFromServer();
        returnToMainMenu();
    }))->setPosition(0, -50, ABottomCenter)->setSize(300, 50);

    // Start server button.
    (new GuiButton(right_container, "START_SERVER", "Start scenario", [this]() {
        startScenario();
    }))->setPosition(0, -50, ABottomCenter)->setSize(300, 50);

    // Fetch and sort all Lua files starting with "scenario_".
    std::vector<string> scenario_filenames = findResources("scenario_*.lua");
    std::sort(scenario_filenames.begin(), scenario_filenames.end());

    // For each scenario file, extract its name, then add it to the list.
    for(string filename : scenario_filenames)
    {
        ScenarioInfo info(filename);
        scenario_list->addEntry(info.name, filename);
    }
    // Select the first scenario in the list by default.
    scenario_list->setSelectionIndex(0);
    selectScenario(scenario_list->getSelectionValue());

    gameGlobalInfo->reset();
}
void AssetBrowser::update()
{
	PROFILE_FUNCTION();

	auto* patch = m_editor.getEngine().getPatchFileDevice();
	if ((patch && !Lumix::equalStrings(patch->getBasePath(), m_patch_base_path)) ||
		(!patch && m_patch_base_path[0] != '\0'))
	{
		findResources();
	}
	if (!m_is_update_enabled) return;
	bool is_empty;
	{
		Lumix::MT::SpinLock lock(m_changed_files_mutex);
		is_empty = m_changed_files.empty();
	}

	while (!is_empty)
	{
		Lumix::Path path;
		{
			Lumix::MT::SpinLock lock(m_changed_files_mutex);
			
			path = m_changed_files.back();
			m_changed_files.pop();
			is_empty = m_changed_files.empty();
		}

		char ext[10];
		Lumix::PathUtils::getExtension(ext, Lumix::lengthOf(ext), path.c_str());
		m_on_resource_changed.invoke(path, ext);

		Lumix::uint32 resource_type = getResourceType(path.c_str());
		if (resource_type == 0) continue;

		if (m_autoreload_changed_resource) m_editor.getEngine().getResourceManager().reload(path);

		char tmp_path[Lumix::MAX_PATH_LENGTH];
		if (m_editor.getEngine().getPatchFileDevice())
		{
			Lumix::copyString(tmp_path, m_editor.getEngine().getPatchFileDevice()->getBasePath());
			Lumix::catString(tmp_path, path.c_str());
		}

		if (!m_editor.getEngine().getPatchFileDevice() || !PlatformInterface::fileExists(tmp_path))
		{
			Lumix::copyString(tmp_path, m_editor.getEngine().getDiskFileDevice()->getBasePath());
			Lumix::catString(tmp_path, path.c_str());

			if (!PlatformInterface::fileExists(tmp_path))
			{
				int index = getTypeIndexFromManagerType(resource_type);
				m_resources[index].eraseItemFast(path);
				continue;
			}
		}

		char dir[Lumix::MAX_PATH_LENGTH];
		char filename[Lumix::MAX_PATH_LENGTH];
		Lumix::PathUtils::getDir(dir, sizeof(dir), path.c_str());
		Lumix::PathUtils::getFilename(filename, sizeof(filename), path.c_str());
		addResource(dir, filename);
	}
	m_changed_files.clear();
}