<commit_before>#include "ShaderManager.h"

using namespace Rendering::Manager;
using namespace Rendering::Shader;
using namespace Utility;

#define VS_FULL_COMMAND(fileName, mainFunc) fileName + ":vs:" + mainFunc
#define PS_FULL_COMMAND(fileName, mainFunc) fileName + ":ps:" + mainFunc

ShaderManager::ShaderManager()
{
}

ShaderManager::~ShaderManager(void)
{
	RemoveAllShaderCode();
	RemoveAllShader();
}

bool ShaderManager::CompileFromMemory(ID3DBlob** outBlob, const std::string &shaderCode, const std::string& shaderModel, const std::string& funcName)
{
	DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;

#if defined( DEBUG ) || defined( _DEBUG )
	dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif

	ID3DBlob* pErrorBlob = nullptr;

	HRESULT hr = D3DX11CompileFromMemory(
		shaderCode.data(), shaderCode.size(),
		nullptr, nullptr, nullptr, funcName.data(),
		shaderModel.data(), dwShaderFlags, 0, nullptr,
		outBlob, &pErrorBlob, nullptr);

	if( FAILED(hr) )
	{
		if( pErrorBlob != NULL )
			OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
		if( pErrorBlob ) pErrorBlob->Release();

		ASSERT("Shader Compile Error!");

		return false;
	}
	if( pErrorBlob )
		pErrorBlob->Release();

	return true;
}

bool ShaderManager::CompileFromFile(ID3DBlob** outBlob, const std::string &fileName, const std::string& shaderModel, const std::string& funcName)
{
	HRESULT hr = S_OK;

	DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
	// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
	// Setting this flag improves the shader debugging experience, but still allows
	// the shaders to be optimized and to run exactly the way they will run in
	// the release configuration of this program.
	dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif

	ID3DBlob* pErrorBlob;
	hr = D3DX11CompileFromFile( fileName.data(), NULL, NULL, funcName.data(), shaderModel.data(),
		dwShaderFlags, 0, NULL, outBlob, &pErrorBlob, NULL );
	if( FAILED(hr) )
	{
		if( pErrorBlob != NULL )
			OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
		if( pErrorBlob ) pErrorBlob->Release();
		ASSERT("Shader Compile Error!");
		return false;
	}
	if( pErrorBlob ) pErrorBlob->Release();

	return true;
}

bool ShaderManager::LoadShaderCode(std::string& outCode, const std::string& folderPath, const std::string& fileName, bool recycleCode)
{
	{
		std::string* alreadyCode = _shaderCodes.Find(fileName);
		if(alreadyCode)
		{
			outCode = (*alreadyCode);
			return true;
		}
	}

	std::ifstream file;
	const char* extension[2] = {".fx", ".hlsl"};
	for(int i=0; i<2; ++i)
	{
		file.open(folderPath+fileName+extension[i]);

		if(file.is_open())
			break;
	}

	if(file.good() == false)
	{
		file.close();
		ASSERT("InValid File");
		return false;
	}

	std::string buff;

	while(std::getline(file, buff))
	{
		outCode += buff;
		outCode += "\n";
	}

	if(recycleCode)
		_shaderCodes.Add(fileName, &outCode, true);

	return true;
}

ID3DBlob* ShaderManager::CreateBlob(const std::string& folderPath, const std::string& fileName, const std::string& shaderType, const std::string& mainFunc, bool recycleCode, const std::string* includeCode)
{
	std::string code;
	if(LoadShaderCode(code, folderPath, fileName, recycleCode) == false)
		return nullptr;

	if(includeCode)
		code += (*includeCode);

	ID3DBlob* blob = nullptr;
	if( CompileFromMemory(&blob, code, shaderType+"_5_0", mainFunc) == false )
	{
		ASSERT("Shader Compile Error!");
		return nullptr;

	}
	return blob;
}

ID3DBlob* ShaderManager::CreateBlob(const std::string& folderPath, const std::string& command, bool recyleCode, const std::string* includeCode)
{
	std::string fileName, mainFunc, shaderType;

	if(CommandValidator(command, &fileName, &shaderType, &mainFunc) == false)
	{
		ASSERT("Command Error");
		return nullptr;
	}

	return CreateBlob(folderPath, fileName, shaderType, mainFunc, recyleCode, includeCode);
}

bool ShaderManager::CommandValidator(const std::string& fullCommand, std::string* outFileName, std::string* outShaderType, std::string* outMainFunc)
{
	std::vector<std::string> commands;
	String::Tokenize(fullCommand, commands, ":");

	if(commands.size() != 3)
		return false;
	if(outFileName)
		(*outFileName) = commands[0];
	if(outShaderType)
		(*outShaderType) = commands[1];
	if(outMainFunc)
		(*outMainFunc) = commands[2];

	return true;
}

bool ShaderManager::CommandValidator(const std::string& partlyCommand, const std::string& shaderType, std::string* outFileName, std::string* outMainFunc)
{
	std::vector<std::string> commands;
	String::Tokenize(partlyCommand, commands, ":");

	if(commands.size() != 2)
		return false;
	if(outFileName)
		(*outFileName) = commands[0];
	if(outMainFunc)
		(*outMainFunc) = commands[1];

	return true;
}

VertexShader* ShaderManager::LoadVertexShader(const std::string& folderPath, const std::string& partlyCommand, bool recyleCode, const std::vector<D3D11_INPUT_ELEMENT_DESC>& vertexDeclations, const std::string* includeFileName)
{
	std::string fileName, mainFunc;

	if(CommandValidator(partlyCommand, "vs", &fileName, &mainFunc) == false)
	{
		ASSERT("Command Error");
		return nullptr;
	}

	std::string optionalCode;
	if(includeFileName)
		LoadShaderCode(optionalCode, folderPath, (*includeFileName), true);

	std::string fullCommand = VS_FULL_COMMAND(fileName, mainFunc);
	VertexShader* shader = dynamic_cast<VertexShader*>(_shaders.Find(fullCommand));

	if(shader == nullptr)
	{
		ID3DBlob* blob = CreateBlob(folderPath, fileName, "vs", mainFunc, recyleCode);
		if(blob == nullptr)
			return nullptr;

		shader = new VertexShader(blob);
		if(shader->CreateShader(vertexDeclations.data(), vertexDeclations.size()))
			_shaders.Add(fullCommand, shader, false);
		else
			ASSERT("Error, Not Created VS");
	}

	return shader;
}

PixelShader* ShaderManager::LoadPixelShader(const std::string& folderPath, const std::string& partlyCommand, bool recyleCode, const std::string* includeFileName)
{
	std::string fileName, mainFunc;

	if(CommandValidator(partlyCommand, "ps", &fileName, &mainFunc) == false)
		return nullptr;

	std::string fullCommand = PS_FULL_COMMAND(fileName, mainFunc);
	PixelShader* shader = dynamic_cast<PixelShader*>(_shaders.Find(fullCommand));

	if(shader == nullptr)
	{
		ID3DBlob* blob = CreateBlob(folderPath, fileName, "ps", mainFunc, recyleCode);
		if(blob == nullptr)
			return nullptr;

		shader = new PixelShader(blob);
		if(shader->CreateShader())
			_shaders.Add(fullCommand, shader, false);
		else
			ASSERT("Error, Not Created PS");
	}

	return shader;
}

void ShaderManager::RemoveAllShaderCode()
{
	_shaderCodes.DeleteAll(true);
}

void ShaderManager::RemoveAllShader()
{
	_shaders.DeleteAll(true);
}

void ShaderManager::RemoveShaderCode(const std::string& command)
{
	_shaderCodes.Delete(command, true);
}

void ShaderManager::RemoveShader(const std::string& command)
{
	_shaders.Delete(command, true);
}

BaseShader* ShaderManager::FindShader(const std::string& fileName, const std::string& mainFunc, BaseShader::Type type)
{
	if(type == BaseShader::Type::Vertex)
		return FindVertexShader(fileName, mainFunc);
	else if(type == BaseShader::Type::Pixel)
		return FindPixelShader(fileName, mainFunc);

	return nullptr;
}

VertexShader* ShaderManager::FindVertexShader(const std::string& fileName, const std::string& mainFunc)
{
	return dynamic_cast<VertexShader*>(_shaders.Find(VS_FULL_COMMAND(fileName, mainFunc)));
}

PixelShader* ShaderManager::FindPixelShader(const std::string& fileName, const std::string& mainFunc)
{
	return dynamic_cast<PixelShader*>(_shaders.Find(PS_FULL_COMMAND(fileName, mainFunc)));
}

bool ShaderManager::Add(const std::string& fullCommand, Rendering::Shader::BaseShader* shader)
{
	if(CommandValidator(fullCommand, nullptr, nullptr, nullptr) == false)
		ASSERT("Error, invalied command");

	return _shaders.Add(fullCommand, shader, false) ? true : false;
}<commit_msg>ShaderManager - filename에 확장자가 있으면, 이름만 가지고 바로 파일 읽도록 수정, 쉐이더 로드 시 추가 코드 있으면 넣을 수 있게 수정<commit_after>#include "ShaderManager.h"

using namespace Rendering::Manager;
using namespace Rendering::Shader;
using namespace Utility;

#define VS_FULL_COMMAND(fileName, mainFunc) fileName + ":vs:" + mainFunc
#define PS_FULL_COMMAND(fileName, mainFunc) fileName + ":ps:" + mainFunc

ShaderManager::ShaderManager()
{
}

ShaderManager::~ShaderManager(void)
{
	RemoveAllShaderCode();
	RemoveAllShader();
}

bool ShaderManager::CompileFromMemory(ID3DBlob** outBlob, const std::string &shaderCode, const std::string& shaderModel, const std::string& funcName)
{
	DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;

#if defined( DEBUG ) || defined( _DEBUG )
	dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif

	ID3DBlob* pErrorBlob = nullptr;

	HRESULT hr = D3DX11CompileFromMemory(
		shaderCode.data(), shaderCode.size(),
		nullptr, nullptr, nullptr, funcName.data(),
		shaderModel.data(), dwShaderFlags, 0, nullptr,
		outBlob, &pErrorBlob, nullptr);

	if( FAILED(hr) )
	{
		if( pErrorBlob != NULL )
			OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
		if( pErrorBlob ) pErrorBlob->Release();

		ASSERT("Shader Compile Error!");

		return false;
	}
	if( pErrorBlob )
		pErrorBlob->Release();

	return true;
}

bool ShaderManager::CompileFromFile(ID3DBlob** outBlob, const std::string &fileName, const std::string& shaderModel, const std::string& funcName)
{
	HRESULT hr = S_OK;

	DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
	// Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
	// Setting this flag improves the shader debugging experience, but still allows
	// the shaders to be optimized and to run exactly the way they will run in
	// the release configuration of this program.
	dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif

	ID3DBlob* pErrorBlob;
	hr = D3DX11CompileFromFile( fileName.data(), NULL, NULL, funcName.data(), shaderModel.data(),
		dwShaderFlags, 0, NULL, outBlob, &pErrorBlob, NULL );
	if( FAILED(hr) )
	{
		if( pErrorBlob != NULL )
			OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
		if( pErrorBlob ) pErrorBlob->Release();
		ASSERT("Shader Compile Error!");
		return false;
	}
	if( pErrorBlob ) pErrorBlob->Release();

	return true;
}

bool ShaderManager::LoadShaderCode(std::string& outCode, const std::string& folderPath, const std::string& fileName, bool recycleCode)
{
	{
		std::string* alreadyCode = _shaderCodes.Find(fileName);
		if(alreadyCode)
		{
			outCode = (*alreadyCode);
			return true;
		}
	}

	std::ifstream file;
	if( fileName.find(".") == -1)
	{
		const char* extension[2] = {".fx", ".hlsl"};
		for(int i=0; i<2; ++i)
		{
			file.open(folderPath+fileName+extension[i]);

			if(file.is_open())
				break;
		}
	}
	else //fileName has extension
	{
		file.open(folderPath+fileName);
	}

	if(file.good() == false)
	{
		file.close();
		ASSERT("InValid File");
		return false;
	}

	std::string buff;

	while(std::getline(file, buff))
	{
		outCode += buff;
		outCode += "\n";
	}

	if(recycleCode)
		_shaderCodes.Add(fileName, &outCode, true);

	return true;
}

ID3DBlob* ShaderManager::CreateBlob(const std::string& folderPath, const std::string& fileName, const std::string& shaderType, const std::string& mainFunc, bool recycleCode, const std::string* includeCode)
{
	std::string code;
	if(LoadShaderCode(code, folderPath, fileName, recycleCode) == false)
		return nullptr;

	if(includeCode)
		code = (*includeCode) + code;

	ID3DBlob* blob = nullptr;
	if( CompileFromMemory(&blob, code, shaderType+"_5_0", mainFunc) == false )
	{
		ASSERT("Shader Compile Error!");
		return nullptr;

	}
	return blob;
}

ID3DBlob* ShaderManager::CreateBlob(const std::string& folderPath, const std::string& command, bool recyleCode, const std::string* includeCode)
{
	std::string fileName, mainFunc, shaderType;

	if(CommandValidator(command, &fileName, &shaderType, &mainFunc) == false)
	{
		ASSERT("Command Error");
		return nullptr;
	}

	return CreateBlob(folderPath, fileName, shaderType, mainFunc, recyleCode, includeCode);
}

bool ShaderManager::CommandValidator(const std::string& fullCommand, std::string* outFileName, std::string* outShaderType, std::string* outMainFunc)
{
	std::vector<std::string> commands;
	String::Tokenize(fullCommand, commands, ":");

	if(commands.size() != 3)
		return false;
	if(outFileName)
		(*outFileName) = commands[0];
	if(outShaderType)
		(*outShaderType) = commands[1];
	if(outMainFunc)
		(*outMainFunc) = commands[2];

	return true;
}

bool ShaderManager::CommandValidator(const std::string& partlyCommand, const std::string& shaderType, std::string* outFileName, std::string* outMainFunc)
{
	std::vector<std::string> commands;
	String::Tokenize(partlyCommand, commands, ":");

	if(commands.size() != 2)
		return false;
	if(outFileName)
		(*outFileName) = commands[0];
	if(outMainFunc)
		(*outMainFunc) = commands[1];

	return true;
}

VertexShader* ShaderManager::LoadVertexShader(const std::string& folderPath, const std::string& partlyCommand, bool recyleCode, const std::vector<D3D11_INPUT_ELEMENT_DESC>& vertexDeclations, const std::string* includeFileName)
{
	std::string fileName, mainFunc;

	if(CommandValidator(partlyCommand, "vs", &fileName, &mainFunc) == false)
	{
		ASSERT("Command Error");
		return nullptr;
	}

	std::string optionalCode;
	if(includeFileName)
		LoadShaderCode(optionalCode, folderPath, (*includeFileName), true);

	std::string fullCommand = VS_FULL_COMMAND(fileName, mainFunc);
	VertexShader* shader = dynamic_cast<VertexShader*>(_shaders.Find(fullCommand));

	if(shader == nullptr)
	{
		ID3DBlob* blob = CreateBlob(folderPath, fileName, "vs", mainFunc, recyleCode, &optionalCode);
		if(blob == nullptr)
			return nullptr;

		shader = new VertexShader(blob);
		if(shader->CreateShader(vertexDeclations.data(), vertexDeclations.size()))
			_shaders.Add(fullCommand, shader, false);
		else
			ASSERT("Error, Not Created VS");
	}

	return shader;
}

PixelShader* ShaderManager::LoadPixelShader(const std::string& folderPath, const std::string& partlyCommand, bool recyleCode, const std::string* includeFileName)
{
	std::string fileName, mainFunc;

	if(CommandValidator(partlyCommand, "ps", &fileName, &mainFunc) == false)
		return nullptr;

	std::string fullCommand = PS_FULL_COMMAND(fileName, mainFunc);
	PixelShader* shader = dynamic_cast<PixelShader*>(_shaders.Find(fullCommand));

	std::string optionalCode;
	if(includeFileName)
		LoadShaderCode(optionalCode, folderPath, (*includeFileName), true);

	if(shader == nullptr)
	{
		ID3DBlob* blob = CreateBlob(folderPath, fileName, "ps", mainFunc, recyleCode, &optionalCode);
		if(blob == nullptr)
			return nullptr;

		shader = new PixelShader(blob);
		if(shader->CreateShader())
			_shaders.Add(fullCommand, shader, false);
		else
			ASSERT("Error, Not Created PS");
	}

	return shader;
}

void ShaderManager::RemoveAllShaderCode()
{
	_shaderCodes.DeleteAll(true);
}

void ShaderManager::RemoveAllShader()
{
	_shaders.DeleteAll(true);
}

void ShaderManager::RemoveShaderCode(const std::string& command)
{
	_shaderCodes.Delete(command, true);
}

void ShaderManager::RemoveShader(const std::string& command)
{
	_shaders.Delete(command, true);
}

BaseShader* ShaderManager::FindShader(const std::string& fileName, const std::string& mainFunc, BaseShader::Type type)
{
	if(type == BaseShader::Type::Vertex)
		return FindVertexShader(fileName, mainFunc);
	else if(type == BaseShader::Type::Pixel)
		return FindPixelShader(fileName, mainFunc);

	return nullptr;
}

VertexShader* ShaderManager::FindVertexShader(const std::string& fileName, const std::string& mainFunc)
{
	return dynamic_cast<VertexShader*>(_shaders.Find(VS_FULL_COMMAND(fileName, mainFunc)));
}

PixelShader* ShaderManager::FindPixelShader(const std::string& fileName, const std::string& mainFunc)
{
	return dynamic_cast<PixelShader*>(_shaders.Find(PS_FULL_COMMAND(fileName, mainFunc)));
}

bool ShaderManager::Add(const std::string& fullCommand, Rendering::Shader::BaseShader* shader)
{
	if(CommandValidator(fullCommand, nullptr, nullptr, nullptr) == false)
		ASSERT("Error, invalied command");

	return _shaders.Add(fullCommand, shader, false) ? true : false;
}<|endoftext|>


<commit_before>#include "MainFrame.hpp"
#include "misc_ui.hpp"
#include <wx/accel.h>
#include <wx/utils.h>

#include "AboutDialog.hpp"
#include "libslic3r.h"

namespace Slic3r { namespace GUI {

wxBEGIN_EVENT_TABLE(MainFrame, wxFrame)
wxEND_EVENT_TABLE()

MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
        : MainFrame(title, pos, size, nullptr) {}
MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size, std::shared_ptr<Settings> _gui_config)
        : wxFrame(NULL, wxID_ANY, title, pos, size), loaded(false),
        tabpanel(nullptr), controller(nullptr), plater(nullptr), gui_config(_gui_config), preset_editor_tabs(std::map<wxWindowID, PresetEditor*>())
{
    // Set icon to either the .ico if windows or png for everything else.
    if (the_os == OS::Windows)
        this->SetIcon(wxIcon(var("Slic3r.ico"), wxBITMAP_TYPE_ICO));
    else
        this->SetIcon(wxIcon(var("Slic3r_128px.png"), wxBITMAP_TYPE_PNG));

    this->init_tabpanel();
    this->init_menubar();

    wxToolTip::SetAutoPop(TOOLTIP_TIMER);

    // initialize status bar
    this->statusbar = new ProgressStatusBar(this, -1);
    wxString welcome_text {_("Version SLIC3R_VERSION_REPLACE - Remember to check for updates at http://slic3r.org/")};
    welcome_text.Replace("SLIC3R_VERSION_REPLACE", wxString(SLIC3R_VERSION));
    this->statusbar->SetStatusText(welcome_text);
    this->SetStatusBar(this->statusbar);

    this->loaded = 1;

    // Initialize layout
    {
        wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
        sizer->Add(this->tabpanel, 1, wxEXPAND);
        sizer->SetSizeHints(this);
        this->SetSizer(sizer);
        this->Fit();
        this->SetMinSize(wxSize(760, 490));
        this->SetSize(this->GetMinSize());
        wxTheApp->SetTopWindow(this);
        gui_config->restore_window_pos(this, "main_frame");
        this->Show();
        this->Layout();
    }
    // Set up event handlers.
    this->Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent& e) {
        if (e.CanVeto()) {
            if (!this->plater->prompt_unsaved_changes()) {
                e.Veto();
                return;
            }
            /*
            if ($self->{controller} && $self->{controller}->printing) {
                my $confirm = Wx::MessageDialog->new($self, "You are currently printing. Do you want to stop printing and continue anyway?",
                    'Unfinished Print', wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT);
                if ($confirm->ShowModal == wxID_NO) {
                    $event->Veto;
                    return;
                }
            }

            */
            // save window size
            gui_config->save_window_pos(this, "main_frame");

            // Propagate event
            e.Skip();
        }
    });
}

/// Private initialization function for the main frame tab panel.
void MainFrame::init_tabpanel()
{
    this->tabpanel = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP);
    auto panel = this->tabpanel;

    panel->Bind(wxEVT_AUINOTEBOOK_PAGE_CHANGED, ([=](wxAuiNotebookEvent& e)
    {
        auto tabpanel = this->tabpanel;
        // TODO: trigger processing for activation event
        if (tabpanel->GetSelection() > 1) {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        } else if (this->gui_config->show_host == false && tabpanel->GetSelection() == 1) {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        } else {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | ~wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        }
    }), panel->GetId());

    panel->Bind(wxEVT_AUINOTEBOOK_PAGE_CLOSE, ([=](wxAuiNotebookEvent& e)
    {
        if (typeid(panel) == typeid(Slic3r::GUI::PresetEditor)) {
            wxDELETE(this->preset_editor_tabs[panel->GetId()]);
        }
        wxTheApp->CallAfter([=] { this->tabpanel->SetSelection(0); });
    }), panel->GetId());

    this->plater = new Slic3r::GUI::Plater(panel, _("Plater"), gui_config);
    this->controller = new Slic3r::GUI::Controller(panel, _("Controller"));

    panel->AddPage(this->plater, this->plater->GetName());
    if (this->gui_config->show_host) panel->AddPage(this->controller, this->controller->GetName());

}

void MainFrame::init_menubar()
{

    wxMenu* menuFile = new wxMenu();
    {
        append_menu_item(menuFile, _(L"Open STL/OBJ/AMF/3MF…"), _("Open a model"), [=](wxCommandEvent& e) { if (this->plater != nullptr) this->plater->add();}, wxID_ANY, "brick_add.png", "Ctrl+O");
    }

    wxMenu* menuPlater = new wxMenu();
    {
    }
    wxMenu* menuObject = new wxMenu();
    {
    }
    wxMenu* menuSettings = new wxMenu();
    {
    }
    wxMenu* menuView = new wxMenu();
    {
    }
    wxMenu* menuWindow = new wxMenu();
    {
    }
    wxMenu* menuHelp = new wxMenu();
    {
        // TODO: Reimplement config wizard
        //menuHelp->AppendSeparator();
        append_menu_item(menuHelp, _("Slic3r &Website"), _("Open the Slic3r website in your browser"), [=](wxCommandEvent& e)
        {
            wxLaunchDefaultBrowser("http://www.slic3r.org");
        });
        append_menu_item(menuHelp, _("Check for &Updates..."), _("Check for new Slic3r versions"), [=](wxCommandEvent& e)
        {
            check_version(true);
        });
        append_menu_item(menuHelp, _("Slic3r &Manual"), _("Open the Slic3r manual in your browser"), [=](wxCommandEvent& e)
        {
            wxLaunchDefaultBrowser("http://manual.slic3r.org/");
        });
        append_menu_item(menuHelp, _("&About Slic3r"), _("Show about dialog"), [=](wxCommandEvent& e)
        {
            auto about = new AboutDialog(nullptr);
            about->ShowModal();
            about->Destroy();
        }, wxID_ABOUT);

    }

    wxMenuBar* menubar = new wxMenuBar();
    menubar->Append(menuFile, _("&File"));
    menubar->Append(menuPlater, _("&Plater"));
    menubar->Append(menuObject, _("&Object"));
    menubar->Append(menuSettings, _("&Settings"));
    menubar->Append(menuView, _("&View"));
    menubar->Append(menuWindow, _("&Window"));
    menubar->Append(menuHelp, _("&Help"));

    this->SetMenuBar(menubar);

}

}} // Namespace Slic3r::GUI
<commit_msg>added one-off menu option to call arrange, currently crashes if no models loaded.<commit_after>#include "MainFrame.hpp"
#include "misc_ui.hpp"
#include <wx/accel.h>
#include <wx/utils.h>

#include "AboutDialog.hpp"
#include "libslic3r.h"

namespace Slic3r { namespace GUI {

wxBEGIN_EVENT_TABLE(MainFrame, wxFrame)
wxEND_EVENT_TABLE()

MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
        : MainFrame(title, pos, size, nullptr) {}
MainFrame::MainFrame(const wxString& title, const wxPoint& pos, const wxSize& size, std::shared_ptr<Settings> _gui_config)
        : wxFrame(NULL, wxID_ANY, title, pos, size), loaded(false),
        tabpanel(nullptr), controller(nullptr), plater(nullptr), gui_config(_gui_config), preset_editor_tabs(std::map<wxWindowID, PresetEditor*>())
{
    // Set icon to either the .ico if windows or png for everything else.
    if (the_os == OS::Windows)
        this->SetIcon(wxIcon(var("Slic3r.ico"), wxBITMAP_TYPE_ICO));
    else
        this->SetIcon(wxIcon(var("Slic3r_128px.png"), wxBITMAP_TYPE_PNG));

    this->init_tabpanel();
    this->init_menubar();

    wxToolTip::SetAutoPop(TOOLTIP_TIMER);

    // initialize status bar
    this->statusbar = new ProgressStatusBar(this, -1);
    wxString welcome_text {_("Version SLIC3R_VERSION_REPLACE - Remember to check for updates at http://slic3r.org/")};
    welcome_text.Replace("SLIC3R_VERSION_REPLACE", wxString(SLIC3R_VERSION));
    this->statusbar->SetStatusText(welcome_text);
    this->SetStatusBar(this->statusbar);

    this->loaded = 1;

    // Initialize layout
    {
        wxSizer* sizer = new wxBoxSizer(wxVERTICAL);
        sizer->Add(this->tabpanel, 1, wxEXPAND);
        sizer->SetSizeHints(this);
        this->SetSizer(sizer);
        this->Fit();
        this->SetMinSize(wxSize(760, 490));
        this->SetSize(this->GetMinSize());
        wxTheApp->SetTopWindow(this);
        gui_config->restore_window_pos(this, "main_frame");
        this->Show();
        this->Layout();
    }
    // Set up event handlers.
    this->Bind(wxEVT_CLOSE_WINDOW, [=](wxCloseEvent& e) {
        if (e.CanVeto()) {
            if (!this->plater->prompt_unsaved_changes()) {
                e.Veto();
                return;
            }
            /*
            if ($self->{controller} && $self->{controller}->printing) {
                my $confirm = Wx::MessageDialog->new($self, "You are currently printing. Do you want to stop printing and continue anyway?",
                    'Unfinished Print', wxICON_QUESTION | wxYES_NO | wxNO_DEFAULT);
                if ($confirm->ShowModal == wxID_NO) {
                    $event->Veto;
                    return;
                }
            }

            */
            // save window size
            gui_config->save_window_pos(this, "main_frame");

            // Propagate event
            e.Skip();
        }
    });
}

/// Private initialization function for the main frame tab panel.
void MainFrame::init_tabpanel()
{
    this->tabpanel = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP);
    auto panel = this->tabpanel;

    panel->Bind(wxEVT_AUINOTEBOOK_PAGE_CHANGED, ([=](wxAuiNotebookEvent& e)
    {
        auto tabpanel = this->tabpanel;
        // TODO: trigger processing for activation event
        if (tabpanel->GetSelection() > 1) {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        } else if (this->gui_config->show_host == false && tabpanel->GetSelection() == 1) {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        } else {
            tabpanel->SetWindowStyle(tabpanel->GetWindowStyleFlag() | ~wxAUI_NB_CLOSE_ON_ACTIVE_TAB);
        }
    }), panel->GetId());

    panel->Bind(wxEVT_AUINOTEBOOK_PAGE_CLOSE, ([=](wxAuiNotebookEvent& e)
    {
        if (typeid(panel) == typeid(Slic3r::GUI::PresetEditor)) {
            wxDELETE(this->preset_editor_tabs[panel->GetId()]);
        }
        wxTheApp->CallAfter([=] { this->tabpanel->SetSelection(0); });
    }), panel->GetId());

    this->plater = new Slic3r::GUI::Plater(panel, _("Plater"), gui_config);
    this->controller = new Slic3r::GUI::Controller(panel, _("Controller"));

    panel->AddPage(this->plater, this->plater->GetName());
    if (this->gui_config->show_host) panel->AddPage(this->controller, this->controller->GetName());

}

void MainFrame::init_menubar()
{

    wxMenu* menuFile = new wxMenu();
    {
        append_menu_item(menuFile, _(L"Open STL/OBJ/AMF/3MF…"), _("Open a model"), [=](wxCommandEvent& e) { if (this->plater != nullptr) this->plater->add();}, wxID_ANY, "brick_add.png", "Ctrl+O");
    }

    wxMenu* menuPlater = new wxMenu();
    {
        append_menu_item(menuPlater, _(L"Arrange…"), _("Arrange models on plater"), [=](wxCommandEvent& e) { if (this->plater != nullptr) this->plater->arrange();}, wxID_ANY, "bricks.png", "Ctrl+G");
    }
    wxMenu* menuObject = new wxMenu();
    {
    }
    wxMenu* menuSettings = new wxMenu();
    {
    }
    wxMenu* menuView = new wxMenu();
    {
    }
    wxMenu* menuWindow = new wxMenu();
    {
    }
    wxMenu* menuHelp = new wxMenu();
    {
        // TODO: Reimplement config wizard
        //menuHelp->AppendSeparator();
        append_menu_item(menuHelp, _("Slic3r &Website"), _("Open the Slic3r website in your browser"), [=](wxCommandEvent& e)
        {
            wxLaunchDefaultBrowser("http://www.slic3r.org");
        });
        append_menu_item(menuHelp, _("Check for &Updates..."), _("Check for new Slic3r versions"), [=](wxCommandEvent& e)
        {
            check_version(true);
        });
        append_menu_item(menuHelp, _("Slic3r &Manual"), _("Open the Slic3r manual in your browser"), [=](wxCommandEvent& e)
        {
            wxLaunchDefaultBrowser("http://manual.slic3r.org/");
        });
        append_menu_item(menuHelp, _("&About Slic3r"), _("Show about dialog"), [=](wxCommandEvent& e)
        {
            auto about = new AboutDialog(nullptr);
            about->ShowModal();
            about->Destroy();
        }, wxID_ABOUT);

    }

    wxMenuBar* menubar = new wxMenuBar();
    menubar->Append(menuFile, _("&File"));
    menubar->Append(menuPlater, _("&Plater"));
    menubar->Append(menuObject, _("&Object"));
    menubar->Append(menuSettings, _("&Settings"));
    menubar->Append(menuView, _("&View"));
    menubar->Append(menuWindow, _("&Window"));
    menubar->Append(menuHelp, _("&Help"));

    this->SetMenuBar(menubar);

}

}} // Namespace Slic3r::GUI
<|endoftext|>


<commit_before>#include <sstream>

#include "StorageFlattening.h"
#include "IRMutator.h"
#include "IROperator.h"
#include "Scope.h"
#include "Bounds.h"
#include "Parameter.h"

namespace Halide {
namespace Internal {

using std::ostringstream;
using std::string;
using std::vector;
using std::map;

namespace {
// Visitor and helper function to test if a piece of IR uses an extern image.
class UsesExternImage : public IRVisitor {
    using IRVisitor::visit;

    void visit(const Call *c) {
        if (c->call_type == Call::Image) {
            result = true;
        } else {
            IRVisitor::visit(c);
        }
    }
public:
    UsesExternImage() : result(false) {}
    bool result;
};

inline bool uses_extern_image(Stmt s) {
    UsesExternImage uses;
    s.accept(&uses);
    return uses.result;
}
}

class FlattenDimensions : public IRMutator {
public:
    FlattenDimensions(const vector<Function> &outputs, const map<string, Function> &e)
        : outputs(outputs), env(e) {}
    Scope<int> scope;
private:
    const vector<Function> &outputs;
    const map<string, Function> &env;
    Scope<int> realizations;

    Expr flatten_args(const string &name, const vector<Expr> &args,
                      bool internal) {
        Expr idx = 0;
        vector<Expr> mins(args.size()), strides(args.size());

        for (size_t i = 0; i < args.size(); i++) {
            string dim = std::to_string(i);
            string stride_name = name + ".stride." + dim;
            string min_name = name + ".min." + dim;
            string stride_name_constrained = stride_name + ".constrained";
            string min_name_constrained = min_name + ".constrained";
            if (scope.contains(stride_name_constrained)) {
                stride_name = stride_name_constrained;
            }
            if (scope.contains(min_name_constrained)) {
                min_name = min_name_constrained;
            }
            strides[i] = Variable::make(Int(32), stride_name);
            mins[i] = Variable::make(Int(32), min_name);
        }

        if (internal) {
            // f(x, y) -> f[(x-xmin)*xstride + (y-ymin)*ystride] This
            // strategy makes sense when we expect x to cancel with
            // something in xmin.  We use this for internal allocations
            for (size_t i = 0; i < args.size(); i++) {
                idx += (args[i] - mins[i]) * strides[i];
            }
        } else {
            // f(x, y) -> f[x*stride + y*ystride - (xstride*xmin +
            // ystride*ymin)]. The idea here is that the last term
            // will be pulled outside the inner loop. We use this for
            // external buffers, where the mins and strides are likely
            // to be symbolic
            Expr base = 0;
            for (size_t i = 0; i < args.size(); i++) {
                idx += args[i] * strides[i];
                base += mins[i] * strides[i];
            }
            idx -= base;
        }

        return idx;
    }

    using IRMutator::visit;

    void visit(const Realize *realize) {
        realizations.push(realize->name, 1);

        Stmt body = mutate(realize->body);

        // Compute the size
        std::vector<Expr> extents;
        for (size_t i = 0; i < realize->bounds.size(); i++) {
          extents.push_back(realize->bounds[i].extent);
          extents[i] = mutate(extents[i]);
        }
        Expr condition = mutate(realize->condition);

        realizations.pop(realize->name);

        vector<int> storage_permutation;
        {
            map<string, Function>::const_iterator iter = env.find(realize->name);
            internal_assert(iter != env.end()) << "Realize node refers to function not in environment.\n";
            const vector<string> &storage_dims = iter->second.schedule().storage_dims();
            const vector<string> &args = iter->second.args();
            for (size_t i = 0; i < storage_dims.size(); i++) {
                for (size_t j = 0; j < args.size(); j++) {
                    if (args[j] == storage_dims[i]) {
                        storage_permutation.push_back((int)j);
                    }
                }
                internal_assert(storage_permutation.size() == i+1);
            }
        }

        internal_assert(storage_permutation.size() == realize->bounds.size());

        stmt = body;
        for (size_t idx = 0; idx < realize->types.size(); idx++) {
            string buffer_name = realize->name;
            if (realize->types.size() > 1) {
                buffer_name = buffer_name + '.' + std::to_string(idx);
            }

            // Make the names for the mins, extents, and strides
            int dims = realize->bounds.size();
            vector<string> min_name(dims), extent_name(dims), stride_name(dims);
            for (int i = 0; i < dims; i++) {
                string d = std::to_string(i);
                min_name[i] = buffer_name + ".min." + d;
                stride_name[i] = buffer_name + ".stride." + d;
                extent_name[i] = buffer_name + ".extent." + d;
            }
            vector<Expr> min_var(dims), extent_var(dims), stride_var(dims);
            for (int i = 0; i < dims; i++) {
                min_var[i] = Variable::make(Int(32), min_name[i]);
                extent_var[i] = Variable::make(Int(32), extent_name[i]);
                stride_var[i] = Variable::make(Int(32), stride_name[i]);
            }

            // Promote the type to be a multiple of 8 bits
            Type t = realize->types[idx].with_bits(realize->types[idx].bytes() * 8);

            // Create a buffer_t object for this allocation.
            vector<Expr> args(dims*3 + 2);
            //args[0] = Call::make(Handle(), Call::null_handle, vector<Expr>(), Call::Intrinsic);
            Expr first_elem = Load::make(t, buffer_name, 0, Buffer(), Parameter());
            args[0] = Call::make(Handle(), Call::address_of, {first_elem}, Call::PureIntrinsic);
            args[1] = make_zero(realize->types[idx]);
            for (int i = 0; i < dims; i++) {
                args[3*i+2] = min_var[i];
                args[3*i+3] = extent_var[i];
                args[3*i+4] = stride_var[i];
            }
            Expr buf = Call::make(type_of<struct buffer_t *>(), Call::create_buffer_t,
                                  args, Call::Intrinsic);
            stmt = LetStmt::make(buffer_name + ".buffer",
                                 buf,
                                 stmt);

            // Make the allocation node
            stmt = Allocate::make(buffer_name, t, extents, condition, stmt);

            // Compute the strides
            for (int i = (int)realize->bounds.size()-1; i > 0; i--) {
                int prev_j = storage_permutation[i-1];
                int j = storage_permutation[i];
                Expr stride = stride_var[prev_j] * extent_var[prev_j];
                stmt = LetStmt::make(stride_name[j], stride, stmt);
            }
            // Innermost stride is one
            if (dims > 0) {
                int innermost = storage_permutation.empty() ? 0 : storage_permutation[0];
                stmt = LetStmt::make(stride_name[innermost], 1, stmt);
            }

            // Assign the mins and extents stored
            for (size_t i = realize->bounds.size(); i > 0; i--) {
                stmt = LetStmt::make(min_name[i-1], realize->bounds[i-1].min, stmt);
                stmt = LetStmt::make(extent_name[i-1], realize->bounds[i-1].extent, stmt);
            }
        }
    }

    struct ProvideValue {
        Expr value;
        string name;
    };

    void flatten_provide_values(vector<ProvideValue> &values, const Provide *provide) {
        values.resize(provide->values.size());

        for (size_t i = 0; i < values.size(); i++) {
            Expr value = mutate(provide->values[i]);

            // Promote the type to be a multiple of 8 bits
            Type t = value.type().with_bits(value.type().bytes() * 8);
            if (t.bits() != value.type().bits()) {
                value = Cast::make(t, value);
            }

            values[i].value = value;
            if (values.size() > 1) {
                values[i].name = provide->name + "." + std::to_string(i);
            } else {
                values[i].name = provide->name;
            }
        }
    }

    // Lower a set of provides
    Stmt flatten_provide_atomic(const Provide *provide) {
        vector<ProvideValue> values;
        flatten_provide_values(values, provide);

        vector<Parameter> output_buffers;
        bool is_output = false;
        for (Function f : outputs) {
            is_output |= f.name() == provide->name;
            if (is_output) {
                output_buffers = f.output_buffers();
                break;
            }
        }
        internal_assert(output_buffers.size() == values.size());
        Stmt result;
        for (size_t i = 0; i < values.size(); i++) {
            const ProvideValue &cv = values[i];

            Expr idx = mutate(flatten_args(cv.name, provide->args, !is_output));
            Expr var = Variable::make(cv.value.type(), cv.name + ".value");
            Stmt store = Store::make(cv.name, var, idx, output_buffers[i]);

            if (result.defined()) {
                result = Block::make(result, store);
            } else {
                result = store;
            }
        }

        for (size_t i = values.size(); i > 0; i--) {
            const ProvideValue &cv = values[i-1];

            result = LetStmt::make(cv.name + ".value", cv.value, result);
        }
        return result;
    }

    Stmt flatten_provide(const Provide *provide) {
        vector<ProvideValue> values;
        flatten_provide_values(values, provide);

        vector<Parameter> output_buffers;
        bool is_output = false;
        for (Function f : outputs) {
            is_output |= f.name() == provide->name;
            if (is_output) {
                output_buffers = f.output_buffers();
                break;
            }
        }
        internal_assert(output_buffers.size() == values.size());
        Stmt result;
        for (size_t i = 0; i < values.size(); i++) {
            const ProvideValue &cv = values[i];

            Expr idx = mutate(flatten_args(cv.name, provide->args, !is_output));
            Stmt store = Store::make(cv.name, cv.value, idx, output_buffers[i]);

            if (result.defined()) {
                result = Block::make(result, store);
            } else {
                result = store;
            }
        }
        return result;
    }

    void visit(const Provide *provide) {
        Stmt result;

        // Handle the provide atomically if necessary. This logic is
        // currently very conservative, it will lower many provides
        // atomically that do not require it.
        if (provide->values.size() == 1) {
            // If there is only one value, we don't need to worry
            // about atomicity.
            result = flatten_provide(provide);
        } else if (!realizations.contains(provide->name) &&
                   uses_extern_image(provide)) {
            // If the provide is not a realization and it uses an
            // input image, it might be aliased. Flatten it atomically
            // because we can't prove the boxes don't overlap.
            result = flatten_provide_atomic(provide);
        } else {
            Box provided = box_provided(Stmt(provide), provide->name);
            Box required = box_required(Stmt(provide), provide->name);

            if (boxes_overlap(provided, required)) {
                // The boxes provided and required might overlap, so
                // the provide must be done atomically.
                result = flatten_provide_atomic(provide);
            } else {
                // The boxes don't overlap.
                result = flatten_provide(provide);
            }
        }
        stmt = result;
    }

    void visit(const Call *call) {
        if (call->call_type == Call::Halide ||
            call->call_type == Call::Image) {
            string name = call->name;
            if (call->call_type == Call::Halide &&
                call->func.outputs() > 1) {
                name = name + '.' + std::to_string(call->value_index);
            }

            bool is_output = false;
            for (Function f : outputs) {
                is_output |= f.name() == call->name;
            }

            bool is_input = env.find(call->name) == env.end();

            // Promote the type to be a multiple of 8 bits
            Type t = call->type.with_bits(call->type.bytes() * 8);

            Expr idx = mutate(flatten_args(name, call->args, !(is_output || is_input)));
            expr = Load::make(t, name, idx, call->image, call->param);

            if (call->type.bits() != t.bits()) {
                expr = Cast::make(call->type, expr);
            }
        } else {
            vector<Expr> args(call->args.size());
            bool changed = false;
            for (size_t i = 0; i < args.size(); i++) {
                args[i] = mutate(call->args[i]);
                if (!args[i].same_as(call->args[i])) changed = true;
            }
            if (!changed) {
                expr = call;
            } else {
                expr = Call::make(call->type, call->name, args, call->call_type);
            }
        }
    }

    void visit(const LetStmt *let) {
        // Discover constrained versions of things.
        bool constrained_version_exists = ends_with(let->name, ".constrained");
        if (constrained_version_exists) {
            scope.push(let->name, 0);
        }

        IRMutator::visit(let);

        if (constrained_version_exists) {
            scope.pop(let->name);
        }
    }
};

Stmt storage_flattening(Stmt s,
                        const vector<Function> &outputs,
                        const map<string, Function> &env) {
    return FlattenDimensions(outputs, env).mutate(s);
}

}
}
<commit_msg>Fix misplaced assert in StorageFlattening. Also fix the creation of the Store node.<commit_after>#include <sstream>

#include "StorageFlattening.h"
#include "IRMutator.h"
#include "IROperator.h"
#include "Scope.h"
#include "Bounds.h"
#include "Parameter.h"

namespace Halide {
namespace Internal {

using std::ostringstream;
using std::string;
using std::vector;
using std::map;

namespace {
// Visitor and helper function to test if a piece of IR uses an extern image.
class UsesExternImage : public IRVisitor {
    using IRVisitor::visit;

    void visit(const Call *c) {
        if (c->call_type == Call::Image) {
            result = true;
        } else {
            IRVisitor::visit(c);
        }
    }
public:
    UsesExternImage() : result(false) {}
    bool result;
};

inline bool uses_extern_image(Stmt s) {
    UsesExternImage uses;
    s.accept(&uses);
    return uses.result;
}
}

class FlattenDimensions : public IRMutator {
public:
    FlattenDimensions(const vector<Function> &outputs, const map<string, Function> &e)
        : outputs(outputs), env(e) {}
    Scope<int> scope;
private:
    const vector<Function> &outputs;
    const map<string, Function> &env;
    Scope<int> realizations;

    Expr flatten_args(const string &name, const vector<Expr> &args,
                      bool internal) {
        Expr idx = 0;
        vector<Expr> mins(args.size()), strides(args.size());

        for (size_t i = 0; i < args.size(); i++) {
            string dim = std::to_string(i);
            string stride_name = name + ".stride." + dim;
            string min_name = name + ".min." + dim;
            string stride_name_constrained = stride_name + ".constrained";
            string min_name_constrained = min_name + ".constrained";
            if (scope.contains(stride_name_constrained)) {
                stride_name = stride_name_constrained;
            }
            if (scope.contains(min_name_constrained)) {
                min_name = min_name_constrained;
            }
            strides[i] = Variable::make(Int(32), stride_name);
            mins[i] = Variable::make(Int(32), min_name);
        }

        if (internal) {
            // f(x, y) -> f[(x-xmin)*xstride + (y-ymin)*ystride] This
            // strategy makes sense when we expect x to cancel with
            // something in xmin.  We use this for internal allocations
            for (size_t i = 0; i < args.size(); i++) {
                idx += (args[i] - mins[i]) * strides[i];
            }
        } else {
            // f(x, y) -> f[x*stride + y*ystride - (xstride*xmin +
            // ystride*ymin)]. The idea here is that the last term
            // will be pulled outside the inner loop. We use this for
            // external buffers, where the mins and strides are likely
            // to be symbolic
            Expr base = 0;
            for (size_t i = 0; i < args.size(); i++) {
                idx += args[i] * strides[i];
                base += mins[i] * strides[i];
            }
            idx -= base;
        }

        return idx;
    }

    using IRMutator::visit;

    void visit(const Realize *realize) {
        realizations.push(realize->name, 1);

        Stmt body = mutate(realize->body);

        // Compute the size
        std::vector<Expr> extents;
        for (size_t i = 0; i < realize->bounds.size(); i++) {
          extents.push_back(realize->bounds[i].extent);
          extents[i] = mutate(extents[i]);
        }
        Expr condition = mutate(realize->condition);

        realizations.pop(realize->name);

        vector<int> storage_permutation;
        {
            map<string, Function>::const_iterator iter = env.find(realize->name);
            internal_assert(iter != env.end()) << "Realize node refers to function not in environment.\n";
            const vector<string> &storage_dims = iter->second.schedule().storage_dims();
            const vector<string> &args = iter->second.args();
            for (size_t i = 0; i < storage_dims.size(); i++) {
                for (size_t j = 0; j < args.size(); j++) {
                    if (args[j] == storage_dims[i]) {
                        storage_permutation.push_back((int)j);
                    }
                }
                internal_assert(storage_permutation.size() == i+1);
            }
        }

        internal_assert(storage_permutation.size() == realize->bounds.size());

        stmt = body;
        for (size_t idx = 0; idx < realize->types.size(); idx++) {
            string buffer_name = realize->name;
            if (realize->types.size() > 1) {
                buffer_name = buffer_name + '.' + std::to_string(idx);
            }

            // Make the names for the mins, extents, and strides
            int dims = realize->bounds.size();
            vector<string> min_name(dims), extent_name(dims), stride_name(dims);
            for (int i = 0; i < dims; i++) {
                string d = std::to_string(i);
                min_name[i] = buffer_name + ".min." + d;
                stride_name[i] = buffer_name + ".stride." + d;
                extent_name[i] = buffer_name + ".extent." + d;
            }
            vector<Expr> min_var(dims), extent_var(dims), stride_var(dims);
            for (int i = 0; i < dims; i++) {
                min_var[i] = Variable::make(Int(32), min_name[i]);
                extent_var[i] = Variable::make(Int(32), extent_name[i]);
                stride_var[i] = Variable::make(Int(32), stride_name[i]);
            }

            // Promote the type to be a multiple of 8 bits
            Type t = realize->types[idx].with_bits(realize->types[idx].bytes() * 8);

            // Create a buffer_t object for this allocation.
            vector<Expr> args(dims*3 + 2);
            //args[0] = Call::make(Handle(), Call::null_handle, vector<Expr>(), Call::Intrinsic);
            Expr first_elem = Load::make(t, buffer_name, 0, Buffer(), Parameter());
            args[0] = Call::make(Handle(), Call::address_of, {first_elem}, Call::PureIntrinsic);
            args[1] = make_zero(realize->types[idx]);
            for (int i = 0; i < dims; i++) {
                args[3*i+2] = min_var[i];
                args[3*i+3] = extent_var[i];
                args[3*i+4] = stride_var[i];
            }
            Expr buf = Call::make(type_of<struct buffer_t *>(), Call::create_buffer_t,
                                  args, Call::Intrinsic);
            stmt = LetStmt::make(buffer_name + ".buffer",
                                 buf,
                                 stmt);

            // Make the allocation node
            stmt = Allocate::make(buffer_name, t, extents, condition, stmt);

            // Compute the strides
            for (int i = (int)realize->bounds.size()-1; i > 0; i--) {
                int prev_j = storage_permutation[i-1];
                int j = storage_permutation[i];
                Expr stride = stride_var[prev_j] * extent_var[prev_j];
                stmt = LetStmt::make(stride_name[j], stride, stmt);
            }
            // Innermost stride is one
            if (dims > 0) {
                int innermost = storage_permutation.empty() ? 0 : storage_permutation[0];
                stmt = LetStmt::make(stride_name[innermost], 1, stmt);
            }

            // Assign the mins and extents stored
            for (size_t i = realize->bounds.size(); i > 0; i--) {
                stmt = LetStmt::make(min_name[i-1], realize->bounds[i-1].min, stmt);
                stmt = LetStmt::make(extent_name[i-1], realize->bounds[i-1].extent, stmt);
            }
        }
    }

    struct ProvideValue {
        Expr value;
        string name;
    };

    void flatten_provide_values(vector<ProvideValue> &values, const Provide *provide) {
        values.resize(provide->values.size());

        for (size_t i = 0; i < values.size(); i++) {
            Expr value = mutate(provide->values[i]);

            // Promote the type to be a multiple of 8 bits
            Type t = value.type().with_bits(value.type().bytes() * 8);
            if (t.bits() != value.type().bits()) {
                value = Cast::make(t, value);
            }

            values[i].value = value;
            if (values.size() > 1) {
                values[i].name = provide->name + "." + std::to_string(i);
            } else {
                values[i].name = provide->name;
            }
        }
    }

    // Lower a set of provides
    Stmt flatten_provide_atomic(const Provide *provide) {
        vector<ProvideValue> values;
        flatten_provide_values(values, provide);

        vector<Parameter> output_buffers;
        bool is_output = false;
        for (Function f : outputs) {
            is_output |= f.name() == provide->name;
            if (is_output) {
                output_buffers = f.output_buffers();
                internal_assert(output_buffers.size() == values.size());
                break;
            }
        }

        Stmt result;
        for (size_t i = 0; i < values.size(); i++) {
            const ProvideValue &cv = values[i];

            Expr idx = mutate(flatten_args(cv.name, provide->args, !is_output));
            Expr var = Variable::make(cv.value.type(), cv.name + ".value");
            Stmt store = Store::make(cv.name, var, idx, is_output ? output_buffers[i] : Parameter());

            if (result.defined()) {
                result = Block::make(result, store);
            } else {
                result = store;
            }
        }

        for (size_t i = values.size(); i > 0; i--) {
            const ProvideValue &cv = values[i-1];

            result = LetStmt::make(cv.name + ".value", cv.value, result);
        }
        return result;
    }

    Stmt flatten_provide(const Provide *provide) {
        vector<ProvideValue> values;
        flatten_provide_values(values, provide);

        vector<Parameter> output_buffers;
        bool is_output = false;
        for (Function f : outputs) {
            is_output |= f.name() == provide->name;
            if (is_output) {
                output_buffers = f.output_buffers();
                internal_assert(output_buffers.size() == values.size());
                break;
            }
        }

        Stmt result;
        for (size_t i = 0; i < values.size(); i++) {
            const ProvideValue &cv = values[i];

            Expr idx = mutate(flatten_args(cv.name, provide->args, !is_output));
            Stmt store = Store::make(cv.name, cv.value, idx, is_output ? output_buffers[i] : Parameter());

            if (result.defined()) {
                result = Block::make(result, store);
            } else {
                result = store;
            }
        }
        return result;
    }

    void visit(const Provide *provide) {
        Stmt result;

        // Handle the provide atomically if necessary. This logic is
        // currently very conservative, it will lower many provides
        // atomically that do not require it.
        if (provide->values.size() == 1) {
            // If there is only one value, we don't need to worry
            // about atomicity.
            result = flatten_provide(provide);
        } else if (!realizations.contains(provide->name) &&
                   uses_extern_image(provide)) {
            // If the provide is not a realization and it uses an
            // input image, it might be aliased. Flatten it atomically
            // because we can't prove the boxes don't overlap.
            result = flatten_provide_atomic(provide);
        } else {
            Box provided = box_provided(Stmt(provide), provide->name);
            Box required = box_required(Stmt(provide), provide->name);

            if (boxes_overlap(provided, required)) {
                // The boxes provided and required might overlap, so
                // the provide must be done atomically.
                result = flatten_provide_atomic(provide);
            } else {
                // The boxes don't overlap.
                result = flatten_provide(provide);
            }
        }
        stmt = result;
    }

    void visit(const Call *call) {
        if (call->call_type == Call::Halide ||
            call->call_type == Call::Image) {
            string name = call->name;
            if (call->call_type == Call::Halide &&
                call->func.outputs() > 1) {
                name = name + '.' + std::to_string(call->value_index);
            }

            bool is_output = false;
            for (Function f : outputs) {
                is_output |= f.name() == call->name;
            }

            bool is_input = env.find(call->name) == env.end();

            // Promote the type to be a multiple of 8 bits
            Type t = call->type.with_bits(call->type.bytes() * 8);

            Expr idx = mutate(flatten_args(name, call->args, !(is_output || is_input)));
            expr = Load::make(t, name, idx, call->image, call->param);

            if (call->type.bits() != t.bits()) {
                expr = Cast::make(call->type, expr);
            }
        } else {
            vector<Expr> args(call->args.size());
            bool changed = false;
            for (size_t i = 0; i < args.size(); i++) {
                args[i] = mutate(call->args[i]);
                if (!args[i].same_as(call->args[i])) changed = true;
            }
            if (!changed) {
                expr = call;
            } else {
                expr = Call::make(call->type, call->name, args, call->call_type);
            }
        }
    }

    void visit(const LetStmt *let) {
        // Discover constrained versions of things.
        bool constrained_version_exists = ends_with(let->name, ".constrained");
        if (constrained_version_exists) {
            scope.push(let->name, 0);
        }

        IRMutator::visit(let);

        if (constrained_version_exists) {
            scope.pop(let->name);
        }
    }
};

Stmt storage_flattening(Stmt s,
                        const vector<Function> &outputs,
                        const map<string, Function> &env) {
    return FlattenDimensions(outputs, env).mutate(s);
}

}
}
<|endoftext|>


<commit_before>#include "gtest\gtest.h"
#include <fstream>
#include "gui.h"
#include "RenderManager.h"
#include "window.h"
#include "Shader.h"
#include "ShaderProgram.h"
/*
namespace{
	void writeShaderFiles();

	std::string fragData = "\nvoid main(){\ngl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n}";
	std::string vertData = "\nattribute vec4 vertex;\nvoid main(){\ngl_Position = vertex;\n}";

	class ShaderTests: public ::testing::Test{
protected:
	Window *wnd;

	ShaderTests(){
		GUI::initialize();
		Window *tmp = GUI::createWindow(800, 600, false);
		std::string version = "#version ";
		switch(tmp->getMajorVersion())
		{
		case 4: version = version +"400";break;
		case 3: version = version + "300"; break;
		case 2: version = version + "120"; break;
		default: version = version + "120";break;
		}

		fragData = version + fragData;
		vertData = version + vertData;
		tmp->close();
		delete tmp;
		GUI::shutdown();
		writeShaderFiles();
	}
	virtual void SetUp(){
		GUI::initialize();
		RenderManager::initialize();
		wnd = GUI::createWindow(800, 600, false);

	}

	virtual void TearDown(){
		wnd->close();
		delete wnd;
		RenderManager::shutdown();
		GUI::shutdown();
	}
};

	static void writeShaderFiles()
	{
		std::ofstream file;
		file.open("vertTestShader.vert", std::ios::out);
		file.write(vertData.c_str(),vertData.length());
		file.close();

		file.open("fragTestShader.frag", std::ios::out);
		file.write(fragData.c_str(), fragData.length());
		file.close();
	}

TEST_F(ShaderTests, DISABLED_loadShaderValid){
	Shader vertShader;
	Shader fragShader;

	ASSERT_FALSE(vertShader.isCompiled());
	ASSERT_FALSE(vertShader.isLoaded());

	ASSERT_TRUE(vertShader.load("vertTestShader.vert"));
	ASSERT_TRUE(vertShader.isLoaded());

	vertShader.setType(GL_VERTEX_SHADER);
	ASSERT_EQ(GL_VERTEX_SHADER, vertShader.getType());

	ASSERT_TRUE(vertShader.compile());
	ASSERT_TRUE(vertShader.isCompiled());

	ASSERT_NE(vertShader.getID(), 0);

	ASSERT_FALSE(fragShader.isCompiled());
	ASSERT_FALSE(fragShader.isLoaded());

	ASSERT_TRUE(fragShader.load("fragTestShader.frag"));
	ASSERT_TRUE(fragShader.isLoaded());

	fragShader.setType(GL_FRAGMENT_SHADER);
	ASSERT_EQ(GL_FRAGMENT_SHADER, fragShader.getType());

	ASSERT_TRUE(fragShader.compile());
	ASSERT_TRUE(fragShader.isCompiled());

	ASSERT_NE(fragShader.getID(), 0);

	ASSERT_TRUE(vertShader.release());
	ASSERT_FALSE(vertShader.isCompiled());
	ASSERT_TRUE(vertShader.isLoaded());
	ASSERT_EQ(0, vertShader.getID());

	ASSERT_TRUE(fragShader.release());
	ASSERT_FALSE(fragShader.isCompiled());
	ASSERT_TRUE(fragShader.isLoaded());
	ASSERT_EQ(0, fragShader.getID());
}

TEST_F(ShaderTests, DISABLED_invalidUsage){
	Shader shader;
	ASSERT_FALSE(shader.isCompiled());
	ASSERT_FALSE(shader.isLoaded());

	ASSERT_FALSE(shader.compile());
	ASSERT_FALSE(shader.isCompiled());
	ASSERT_FALSE(shader.isLoaded());

	ASSERT_EQ(shader.getID(), 0);
	ASSERT_EQ(shader.getType(), 0);

	ASSERT_TRUE(shader.load("vertTestShader.vert"));
	ASSERT_EQ(shader.getID(), 0);
	ASSERT_EQ(shader.getType(), 0);

	ASSERT_FALSE(shader.isCompiled());
	ASSERT_TRUE(shader.isLoaded());

	ASSERT_FALSE(shader.compile());
	ASSERT_FALSE(shader.isCompiled());
	ASSERT_TRUE(shader.isLoaded());
	ASSERT_EQ(shader.getID(), 0);
	ASSERT_EQ(shader.getType(), 0);

	ASSERT_FALSE(shader.release());
	ASSERT_FALSE(shader.isCompiled());
	ASSERT_TRUE(shader.isLoaded());

	ASSERT_EQ(shader.getID(), 0);
	ASSERT_EQ(shader.getType(), 0);
}

TEST_F(ShaderTests, DISABLED_programValid){
	Shader vertShader;
	Shader fragShader;

	ASSERT_TRUE(vertShader.load("vertTestShader.vert"));
	ASSERT_TRUE(fragShader.load("fragTestShader.frag"));

	vertShader.setType(GL_VERTEX_SHADER);
	fragShader.setType(GL_FRAGMENT_SHADER);

	ASSERT_TRUE(vertShader.compile());
	ASSERT_TRUE(fragShader.compile());

	ShaderProgram program;

	ASSERT_FALSE(program.isLinked());

	ASSERT_TRUE(program.link(vertShader, fragShader));
	ASSERT_TRUE(program.isLinked());

	ASSERT_TRUE(program.use());

	ASSERT_TRUE(program.release());
	ASSERT_FALSE(program.isLinked());
}

//simple visual test
TEST_F(ShaderTests, DISABLED_visualTest){

	const float triangle[] ={
				0.75f, 0.75f, 0.0f, 1.0f,
				0.75f, -0.75f, 0.0f, 1.0f,
				-0.75f, -0.75f, 0.0f, 1.0f,
	};
	GLuint triangleBuff;

	glGenBuffers(1, &triangleBuff);
	glBindBuffer(GL_ARRAY_BUFFER, triangleBuff);
	glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	Shader vert;
	Shader frag;
	ShaderProgram program;

	ASSERT_TRUE(vert.load("vertTestShader.vert"));
	ASSERT_TRUE(frag.load("fragTestShader.frag"));

	vert.setType(GL_VERTEX_SHADER);
	frag.setType(GL_FRAGMENT_SHADER);

	ASSERT_TRUE(vert.compile());
	ASSERT_TRUE(frag.compile());

	ASSERT_TRUE(program.link(vert, frag));

	wnd->show();
	while(!this->wnd->shouldQuit()){
		wnd->pollEvents();

		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		program.use();
		glBindBuffer(GL_ARRAY_BUFFER, triangleBuff);
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
		glDrawArrays(GL_TRIANGLES, 0, 3);

		wnd->swapBuffers();
	}
}

}*/
<commit_msg>Reenabled shader tests<commit_after>#include "gtest\gtest.h"
#include <fstream>
#include "gui.h"
#include "RenderManager.h"
#include "window.h"
#include "Shader.h"
#include "ShaderProgram.h"

namespace{
	void writeShaderFiles();

	std::string fragData = "\nvoid main(){\ngl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n}";
	std::string vertData = "\nattribute vec4 vertex;\nvoid main(){\ngl_Position = vertex;\n}";

	class ShaderTests: public ::testing::Test{
protected:
	Window *wnd;

	ShaderTests(){
		GUI::initialize();
		Window *tmp = GUI::createWindow(800, 600, false);
		std::string version = "#version ";
		switch(tmp->getMajorVersion())
		{
		case 4: version = version +"400";break;
		case 3: version = version + "300"; break;
		case 2: version = version + "120"; break;
		default: version = version + "120";break;
		}

		fragData = version + fragData;
		vertData = version + vertData;
		tmp->close();
		delete tmp;
		GUI::shutdown();
		writeShaderFiles();
	}
	virtual void SetUp(){
		GUI::initialize();
		RenderManager::initialize();
		wnd = GUI::createWindow(800, 600, false);

	}

	virtual void TearDown(){
		wnd->close();
		delete wnd;
		RenderManager::shutdown();
		GUI::shutdown();
	}
};

	static void writeShaderFiles()
	{
		std::ofstream file;
		file.open("vertTestShader.vert", std::ios::out);
		file.write(vertData.c_str(),vertData.length());
		file.close();

		file.open("fragTestShader.frag", std::ios::out);
		file.write(fragData.c_str(), fragData.length());
		file.close();
	}

TEST_F(ShaderTests, DISABLED_loadShaderValid){
	Shader vertShader;
	Shader fragShader;

	ASSERT_FALSE(vertShader.isCompiled());
	ASSERT_FALSE(vertShader.isLoaded());

	ASSERT_TRUE(vertShader.load("vertTestShader.vert"));
	ASSERT_TRUE(vertShader.isLoaded());

	vertShader.setType(GL_VERTEX_SHADER);
	ASSERT_EQ(GL_VERTEX_SHADER, vertShader.getType());

	ASSERT_TRUE(vertShader.compile());
	ASSERT_TRUE(vertShader.isCompiled());

	ASSERT_NE(vertShader.getID(), 0);

	ASSERT_FALSE(fragShader.isCompiled());
	ASSERT_FALSE(fragShader.isLoaded());

	ASSERT_TRUE(fragShader.load("fragTestShader.frag"));
	ASSERT_TRUE(fragShader.isLoaded());

	fragShader.setType(GL_FRAGMENT_SHADER);
	ASSERT_EQ(GL_FRAGMENT_SHADER, fragShader.getType());

	ASSERT_TRUE(fragShader.compile());
	ASSERT_TRUE(fragShader.isCompiled());

	ASSERT_NE(fragShader.getID(), 0);

	ASSERT_TRUE(vertShader.release());
	ASSERT_FALSE(vertShader.isCompiled());
	ASSERT_TRUE(vertShader.isLoaded());
	ASSERT_EQ(0, vertShader.getID());

	ASSERT_TRUE(fragShader.release());
	ASSERT_FALSE(fragShader.isCompiled());
	ASSERT_TRUE(fragShader.isLoaded());
	ASSERT_EQ(0, fragShader.getID());
}

TEST_F(ShaderTests, DISABLED_invalidUsage){
	Shader shader;
	ASSERT_FALSE(shader.isCompiled());
	ASSERT_FALSE(shader.isLoaded());

	ASSERT_FALSE(shader.compile());
	ASSERT_FALSE(shader.isCompiled());
	ASSERT_FALSE(shader.isLoaded());

	ASSERT_EQ(shader.getID(), 0);
	ASSERT_EQ(shader.getType(), 0);

	ASSERT_TRUE(shader.load("vertTestShader.vert"));
	ASSERT_EQ(shader.getID(), 0);
	ASSERT_EQ(shader.getType(), 0);

	ASSERT_FALSE(shader.isCompiled());
	ASSERT_TRUE(shader.isLoaded());

	ASSERT_FALSE(shader.compile());
	ASSERT_FALSE(shader.isCompiled());
	ASSERT_TRUE(shader.isLoaded());
	ASSERT_EQ(shader.getID(), 0);
	ASSERT_EQ(shader.getType(), 0);

	ASSERT_FALSE(shader.release());
	ASSERT_FALSE(shader.isCompiled());
	ASSERT_TRUE(shader.isLoaded());

	ASSERT_EQ(shader.getID(), 0);
	ASSERT_EQ(shader.getType(), 0);
}

TEST_F(ShaderTests, DISABLED_programValid){
	Shader vertShader;
	Shader fragShader;

	ASSERT_TRUE(vertShader.load("vertTestShader.vert"));
	ASSERT_TRUE(fragShader.load("fragTestShader.frag"));

	vertShader.setType(GL_VERTEX_SHADER);
	fragShader.setType(GL_FRAGMENT_SHADER);

	ASSERT_TRUE(vertShader.compile());
	ASSERT_TRUE(fragShader.compile());

	ShaderProgram program;

	ASSERT_FALSE(program.isLinked());

	ASSERT_TRUE(program.link(vertShader, fragShader));
	ASSERT_TRUE(program.isLinked());

	ASSERT_TRUE(program.use());

	ASSERT_TRUE(program.release());
	ASSERT_FALSE(program.isLinked());
}

//simple visual test
TEST_F(ShaderTests, DISABLED_visualTest){

	const float triangle[] ={
				0.75f, 0.75f, 0.0f, 1.0f,
				0.75f, -0.75f, 0.0f, 1.0f,
				-0.75f, -0.75f, 0.0f, 1.0f,
	};
	GLuint triangleBuff;

	glGenBuffers(1, &triangleBuff);
	glBindBuffer(GL_ARRAY_BUFFER, triangleBuff);
	glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	Shader vert;
	Shader frag;
	ShaderProgram program;

	ASSERT_TRUE(vert.load("vertTestShader.vert"));
	ASSERT_TRUE(frag.load("fragTestShader.frag"));

	vert.setType(GL_VERTEX_SHADER);
	frag.setType(GL_FRAGMENT_SHADER);

	ASSERT_TRUE(vert.compile());
	ASSERT_TRUE(frag.compile());

	ASSERT_TRUE(program.link(vert, frag));

	wnd->show();
	while(!this->wnd->shouldQuit()){
		wnd->pollEvents();

		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		program.use();
		glBindBuffer(GL_ARRAY_BUFFER, triangleBuff);
		glEnableVertexAttribArray(0);
		glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
		glDrawArrays(GL_TRIANGLES, 0, 3);

		wnd->swapBuffers();
	}
}

}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// taskwarrior - a command line task list manager.
//
// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
//     Free Software Foundation, Inc.,
//     51 Franklin Street, Fifth Floor,
//     Boston, MA
//     02110-1301
//     USA
//
////////////////////////////////////////////////////////////////////////////////

#define L10N                                           // Localization complete.

#include <stdlib.h>
#include <Context.h>
#include <Date.h>
#include <ColDescription.h>
#include <text.h>
#include <util.h>
#include <i18n.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
ColumnDescription::ColumnDescription ()
{
  _name  = "description";
  _type  = "string";
  _style = "default";
  _label = STRING_COLUMN_LABEL_DESC;
}

////////////////////////////////////////////////////////////////////////////////
ColumnDescription::~ColumnDescription ()
{
}

////////////////////////////////////////////////////////////////////////////////
bool ColumnDescription::validate (std::string& value)
{
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// Set the minimum and maximum widths for the value.
void ColumnDescription::measure (Task& task, int& minimum, int& maximum)
{
  std::string description = task.get (_name);

  // The text
  // <indent> <date> <anno>
  // ...
  if (_style == "default")
  {
    int indent = context.config.getInteger ("indent.annotation");
    std::string format = context.config.get ("dateformat.annotation");
    if (format == "")
      format = context.config.get ("dateformat");

    int min_desc = longestWord (description);
    int min_anno = indent + Date::length (format);
    minimum = max (min_desc, min_anno);
    maximum = description.length ();

    std::vector <Att> annos;
    task.getAnnotations (annos);
    std::vector <Att>::iterator i;
    for (i = annos.begin (); i != annos.end (); i++)
    {
      int len = min_anno + 1 + i->value ().length ();
      if (len > maximum)
        maximum = len;
    }
  }

  // Just the text
  else if (_style == "desc")
  {
    maximum = description.length ();
    minimum = longestWord (description);
  }

  // The text <date> <anno> ...
  else if (_style == "oneline")
  {
    std::string format = context.config.get ("dateformat.annotation");
    if (format == "")
      format = context.config.get ("dateformat");

    int min_desc = longestWord (description);
    int min_anno = Date::length (format);
    minimum = max (min_desc, min_anno);
    maximum = description.length ();

    std::vector <Att> annos;
    task.getAnnotations (annos);
    std::vector <Att>::iterator i;
    for (i = annos.begin (); i != annos.end (); i++)
      maximum += i->value ().length () + minimum + 1;
  }

  // The te...
  else if (_style == "truncated")
  {
    minimum = 4;
    maximum = description.length ();
  }

  // The text [2]
  else if (_style == "count")
  {
    std::vector <Att> annos;
    task.getAnnotations (annos);

    // <description> + ' ' + '[' + <count> + ']'
    maximum = description.length () + 3 + format ((int)annos.size ()).length ();
    minimum = longestWord (description);
  }

  else
    throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}

////////////////////////////////////////////////////////////////////////////////
void ColumnDescription::render (
  std::vector <std::string>& lines,
  Task& task,
  int width,
  Color& color)
{
  std::string description = task.get (_name);

  // This is a description
  // <date> <anno>
  // ...
  if (_style == "default")
  {
    int indent = context.config.getInteger ("indent.annotation");

    std::vector <Att> annos;
    task.getAnnotations (annos);
    if (annos.size ())
    {
      std::string format = context.config.get ("dateformat.annotation");
      if (format == "")
        format = context.config.get ("dateformat");

      std::vector <Att>::iterator i;
      for (i = annos.begin (); i != annos.end (); i++)
      {
        Date dt (atoi (i->name ().substr (11).c_str ()));
        description += "\n" + std::string (indent, ' ') + dt.toString (format) + " " + i->value ();
      }
    }

    std::vector <std::string> raw;
    wrapText (raw, description, width);

    std::vector <std::string>::iterator i;
    for (i = raw.begin (); i != raw.end (); ++i)
      if (i == raw.begin ())
        lines.push_back (color.colorize (leftJustify (*i, width)));
      else
        lines.push_back (color.colorize (leftJustify (std::string (indent, ' ') + *i, width)));
  }

  // This is a description
  else if (_style == "desc")
  {
    std::vector <std::string> raw;
    wrapText (raw, description, width);

    std::vector <std::string>::iterator i;
    for (i = raw.begin (); i != raw.end (); ++i)
      lines.push_back (color.colorize (leftJustify (*i, width)));
  }

  // This is a description <date> <anno> ...
  else if (_style == "oneline")
  {
    std::vector <Att> annos;
    task.getAnnotations (annos);
    if (annos.size ())
    {
      std::string format = context.config.get ("dateformat.annotation");
      if (format == "")
        format = context.config.get ("dateformat");

      std::vector <Att>::iterator i;
      for (i = annos.begin (); i != annos.end (); i++)
      {
        Date dt (atoi (i->name ().substr (11).c_str ()));
        description += " " + dt.toString (format) + " " + i->value ();
      }
    }

    std::vector <std::string> raw;
    wrapText (raw, description, width);

    std::vector <std::string>::iterator i;
    for (i = raw.begin (); i != raw.end (); ++i)
      lines.push_back (color.colorize (leftJustify (*i, width)));
  }

  // This is a des...
  else if (_style == "truncated")
  {
    int len = description.length ();
    if (len > width)
      lines.push_back (color.colorize (description.substr (0, width - 3) + "..."));
    else
      lines.push_back (color.colorize (leftJustify (description, width)));
  }

  // This is a description [2]
  else if (_style == "count")
  {
    std::vector <Att> annos;
    task.getAnnotations (annos);

    if (annos.size ())
      description += " [" + format ((int) annos.size ()) + "]";

    std::vector <std::string> raw;
    wrapText (raw, description, width);

    std::vector <std::string>::iterator i;
    for (i = raw.begin (); i != raw.end (); ++i)
      lines.push_back (color.colorize (leftJustify (*i, width)));
  }
}

////////////////////////////////////////////////////////////////////////////////
<commit_msg>Bug - ColDescriptionf indent<commit_after>////////////////////////////////////////////////////////////////////////////////
// taskwarrior - a command line task list manager.
//
// Copyright 2006 - 2011, Paul Beckingham, Federico Hernandez.
// All rights reserved.
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the
//
//     Free Software Foundation, Inc.,
//     51 Franklin Street, Fifth Floor,
//     Boston, MA
//     02110-1301
//     USA
//
////////////////////////////////////////////////////////////////////////////////

#define L10N                                           // Localization complete.

#include <stdlib.h>
#include <Context.h>
#include <Date.h>
#include <ColDescription.h>
#include <text.h>
#include <util.h>
#include <i18n.h>

extern Context context;

////////////////////////////////////////////////////////////////////////////////
ColumnDescription::ColumnDescription ()
{
  _name  = "description";
  _type  = "string";
  _style = "default";
  _label = STRING_COLUMN_LABEL_DESC;
}

////////////////////////////////////////////////////////////////////////////////
ColumnDescription::~ColumnDescription ()
{
}

////////////////////////////////////////////////////////////////////////////////
bool ColumnDescription::validate (std::string& value)
{
  return true;
}

////////////////////////////////////////////////////////////////////////////////
// Set the minimum and maximum widths for the value.
void ColumnDescription::measure (Task& task, int& minimum, int& maximum)
{
  std::string description = task.get (_name);

  // The text
  // <indent> <date> <anno>
  // ...
  if (_style == "default")
  {
    int indent = context.config.getInteger ("indent.annotation");
    std::string format = context.config.get ("dateformat.annotation");
    if (format == "")
      format = context.config.get ("dateformat");

    int min_desc = longestWord (description);
    int min_anno = indent + Date::length (format);
    minimum = max (min_desc, min_anno);
    maximum = description.length ();

    std::vector <Att> annos;
    task.getAnnotations (annos);
    std::vector <Att>::iterator i;
    for (i = annos.begin (); i != annos.end (); i++)
    {
      int len = min_anno + 1 + i->value ().length ();
      if (len > maximum)
        maximum = len;
    }
  }

  // Just the text
  else if (_style == "desc")
  {
    maximum = description.length ();
    minimum = longestWord (description);
  }

  // The text <date> <anno> ...
  else if (_style == "oneline")
  {
    std::string format = context.config.get ("dateformat.annotation");
    if (format == "")
      format = context.config.get ("dateformat");

    int min_desc = longestWord (description);
    int min_anno = Date::length (format);
    minimum = max (min_desc, min_anno);
    maximum = description.length ();

    std::vector <Att> annos;
    task.getAnnotations (annos);
    std::vector <Att>::iterator i;
    for (i = annos.begin (); i != annos.end (); i++)
      maximum += i->value ().length () + minimum + 1;
  }

  // The te...
  else if (_style == "truncated")
  {
    minimum = 4;
    maximum = description.length ();
  }

  // The text [2]
  else if (_style == "count")
  {
    std::vector <Att> annos;
    task.getAnnotations (annos);

    // <description> + ' ' + '[' + <count> + ']'
    maximum = description.length () + 3 + format ((int)annos.size ()).length ();
    minimum = longestWord (description);
  }

  else
    throw format (STRING_COLUMN_BAD_FORMAT, _name, _style);
}

////////////////////////////////////////////////////////////////////////////////
void ColumnDescription::render (
  std::vector <std::string>& lines,
  Task& task,
  int width,
  Color& color)
{
  std::string description = task.get (_name);

  // This is a description
  // <date> <anno>
  // ...
  if (_style == "default")
  {
    int indent = context.config.getInteger ("indent.annotation");

    std::vector <Att> annos;
    task.getAnnotations (annos);
    if (annos.size ())
    {
      std::string format = context.config.get ("dateformat.annotation");
      if (format == "")
        format = context.config.get ("dateformat");

      std::vector <Att>::iterator i;
      for (i = annos.begin (); i != annos.end (); i++)
      {
        Date dt (atoi (i->name ().substr (11).c_str ()));
        description += "\n" + std::string (indent, ' ') + dt.toString (format) + " " + i->value ();
      }
    }

    std::vector <std::string> raw;
    wrapText (raw, description, width);

    std::vector <std::string>::iterator i;
    for (i = raw.begin (); i != raw.end (); ++i)
      lines.push_back (color.colorize (leftJustify (*i, width)));
  }

  // This is a description
  else if (_style == "desc")
  {
    std::vector <std::string> raw;
    wrapText (raw, description, width);

    std::vector <std::string>::iterator i;
    for (i = raw.begin (); i != raw.end (); ++i)
      lines.push_back (color.colorize (leftJustify (*i, width)));
  }

  // This is a description <date> <anno> ...
  else if (_style == "oneline")
  {
    std::vector <Att> annos;
    task.getAnnotations (annos);
    if (annos.size ())
    {
      std::string format = context.config.get ("dateformat.annotation");
      if (format == "")
        format = context.config.get ("dateformat");

      std::vector <Att>::iterator i;
      for (i = annos.begin (); i != annos.end (); i++)
      {
        Date dt (atoi (i->name ().substr (11).c_str ()));
        description += " " + dt.toString (format) + " " + i->value ();
      }
    }

    std::vector <std::string> raw;
    wrapText (raw, description, width);

    std::vector <std::string>::iterator i;
    for (i = raw.begin (); i != raw.end (); ++i)
      lines.push_back (color.colorize (leftJustify (*i, width)));
  }

  // This is a des...
  else if (_style == "truncated")
  {
    int len = description.length ();
    if (len > width)
      lines.push_back (color.colorize (description.substr (0, width - 3) + "..."));
    else
      lines.push_back (color.colorize (leftJustify (description, width)));
  }

  // This is a description [2]
  else if (_style == "count")
  {
    std::vector <Att> annos;
    task.getAnnotations (annos);

    if (annos.size ())
      description += " [" + format ((int) annos.size ()) + "]";

    std::vector <std::string> raw;
    wrapText (raw, description, width);

    std::vector <std::string>::iterator i;
    for (i = raw.begin (); i != raw.end (); ++i)
      lines.push_back (color.colorize (leftJustify (*i, width)));
  }
}

////////////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>#include <Socket/BalancingSelector.hpp>
#include <Socket/SocketSerialized.hpp>
#include <iostream>

namespace ntw
{
    BalancingSelector::BalancingSelector(bool read, bool write, bool except,void (*onSel)(SelectManager&,void*,SocketSerialized&),void* _data, unsigned int _min,unsigned int _max,unsigned int max_selector,float timeout):
    nb_selector_max(max_selector),
    max_per_selector(_max),
    min_per_selector(_min),
    timeout(timeout),
    readfds(read),
    writefds(write),
    exceptfds(except),
    onSelect(onSel),
    data(_data),
    do_delete(false),
    _run(false)
    {
        SelectManager& s = newSelector();
        s.setArgs(readfds,writefds,exceptfds,timeout);
        s.onSelect = onSelect;
        s.data = _data;
    }

    bool BalancingSelector::add(SocketSerialized* s)
    {
        unsigned int min_charge = -1;
        SelectManager* min_selector;

        for(SelectManager& selector : selectors)
        {
            unsigned int s = selectors.size();
            if(s <min_charge)
            {
                min_charge = s;
                min_selector = &selector;
            }
        }

        if(min_charge < max_per_selector)
        {
            min_selector->add(s);
        }
        else
        {
            if(nb_selector_max == 0 or selectors.size() < nb_selector_max)
            {
                SelectManager& selector = newSelector();
                selector.add(s);
            }
            return false;
        }
        return true;
    }

    bool BalancingSelector::add(SocketSerialized* sock,std::string host,int port)
    {
        bool res = sock->connect(host,port);
        if(not res or ntw::FuncWrapper::cli::verifyIsConnected(*sock) != NTW_ERROR_NO);
            remove(sock);

        if(res)
        {
            res = add(sock);
        }

        return res;
    }

    bool BalancingSelector::add(Socket::Dommaine dommaine,Socket::Type type,std::string host,int port)
    {
        SocketSerialized* sock = new SocketSerialized(dommaine,type);
        bool res = add(sock,host,port);
        if(not res)
        {
            delete sock;
        }
        return res;
    }

    void BalancingSelector::remove(SocketSerialized* s)
    {
        int i = 0; //pour garder au moins 1 selector
        for(SelectManager& selector : selectors)
        {
            if(selector.remove(s))
            {
                if(i>0 and selector.size() < min_per_selector)
                {
                    //\todo
                    std::cerr<<"[TODO] killer le selector, et redistribuer les sockets"<<std::endl;
                }
            }
            ++i;
        }
    }

    void BalancingSelector::clear()
    {
        for(SelectManager& selector : selectors)
        {
            selector.clear();
        }
        selectors.clear();
    }

    void BalancingSelector::start()
    {
        _run = true;
        for(SelectManager& selector : selectors)
            selector.start();
    }

    void BalancingSelector::stop()
    {
        _run = false;
        for(SelectManager& selector : selectors)
            selector.stop();
    }

    void BalancingSelector::wait()
    {
        for(SelectManager& selector : selectors)
            selector.wait();
    }

    /*void BalancingSelector::detach()
    {
        for(SelectManager& selector : selectors)
            selector.detach();
    }*/

    unsigned int BalancingSelector::size()const
    {
        unsigned int size = 0;
        for(const SelectManager& selector : selectors)
            size += selector.size();
        return size;
    }

    void BalancingSelector::setArgs(bool read,bool write,bool except,float timeout_sec)
    {
        writefds = write;
        readfds = read;
        exceptfds = except;
        timeout = timeout_sec;
        for(SelectManager& selector : selectors)
            selector.setArgs(read,write,except,timeout_sec);
    }

    void BalancingSelector::setRead(bool read)
    {
        readfds = read;
        for(SelectManager& selector : selectors)
            selector.setRead(read);
    }

    void BalancingSelector::setWrite(bool write)
    {
        writefds = write;
        for(SelectManager& selector : selectors)
            selector.setWrite(write);
    }

    void BalancingSelector::setExcept(bool except)
    {
        exceptfds = except;
        for(SelectManager& selector : selectors)
            selector.setExcept(except);
    }

    void BalancingSelector::setTimout(float timeout_sec)
    {
        timeout = timeout_sec;
        for(SelectManager& selector : selectors)
            selector.setTimout(timeout_sec);
    }

    void BalancingSelector::setDelete(bool d)
    {
        do_delete = d;
        for(SelectManager& selector : selectors)
            selector.setTimout(d);
    }

    SelectManager& BalancingSelector::newSelector()
    {
        selectors.emplace_back();

        SelectManager& s = selectors.back();
        s.onSelect = onSelect;
        s.data = data;
        s.setArgs(readfds,writefds,exceptfds,timeout);
        s.setDelete(do_delete);

        if(_run)
            s.start();
        /*if(selectors.size()>1)
            s.detach(); ///< todo
        */
        return s;
    }
}
<commit_msg>remove bug<commit_after>#include <Socket/BalancingSelector.hpp>
#include <Socket/SocketSerialized.hpp>
#include <iostream>

namespace ntw
{
    BalancingSelector::BalancingSelector(bool read, bool write, bool except,void (*onSel)(SelectManager&,void*,SocketSerialized&),void* _data, unsigned int _min,unsigned int _max,unsigned int max_selector,float timeout):
    nb_selector_max(max_selector),
    max_per_selector(_max),
    min_per_selector(_min),
    timeout(timeout),
    readfds(read),
    writefds(write),
    exceptfds(except),
    onSelect(onSel),
    data(_data),
    do_delete(false),
    _run(false)
    {
        SelectManager& s = newSelector();
        s.setArgs(readfds,writefds,exceptfds,timeout);
        s.onSelect = onSelect;
        s.data = _data;
    }

    bool BalancingSelector::add(SocketSerialized* s)
    {
        unsigned int min_charge = -1;
        SelectManager* min_selector;

        for(SelectManager& selector : selectors)
        {
            unsigned int s = selectors.size();
            if(s <min_charge)
            {
                min_charge = s;
                min_selector = &selector;
            }
        }

        if(min_charge < max_per_selector)
        {
            min_selector->add(s);
        }
        else
        {
            if(nb_selector_max == 0 or selectors.size() < nb_selector_max)
            {
                SelectManager& selector = newSelector();
                selector.add(s);
            }
            else
                return false;
        }
        return true;
    }

    bool BalancingSelector::add(SocketSerialized* sock,std::string host,int port)
    {
        bool res = sock->connect(host,port);
        if(not res or ntw::FuncWrapper::cli::verifyIsConnected(*sock) != NTW_ERROR_NO);
            remove(sock);

        if(res)
        {
            res = add(sock);
        }

        return res;
    }

    bool BalancingSelector::add(Socket::Dommaine dommaine,Socket::Type type,std::string host,int port)
    {
        SocketSerialized* sock = new SocketSerialized(dommaine,type);
        bool res = add(sock,host,port);
        if(not res)
        {
            delete sock;
        }
        return res;
    }

    void BalancingSelector::remove(SocketSerialized* s)
    {
        int i = 0; //pour garder au moins 1 selector
        for(SelectManager& selector : selectors)
        {
            if(selector.remove(s))
            {
                if(i>0 and selector.size() < min_per_selector)
                {
                    //\todo
                    std::cerr<<"[TODO] killer le selector, et redistribuer les sockets"<<std::endl;
                }
            }
            ++i;
        }
    }

    void BalancingSelector::clear()
    {
        for(SelectManager& selector : selectors)
        {
            selector.clear();
        }
        selectors.clear();
    }

    void BalancingSelector::start()
    {
        _run = true;
        for(SelectManager& selector : selectors)
            selector.start();
    }

    void BalancingSelector::stop()
    {
        _run = false;
        for(SelectManager& selector : selectors)
            selector.stop();
    }

    void BalancingSelector::wait()
    {
        for(SelectManager& selector : selectors)
            selector.wait();
    }

    /*void BalancingSelector::detach()
    {
        for(SelectManager& selector : selectors)
            selector.detach();
    }*/

    unsigned int BalancingSelector::size()const
    {
        unsigned int size = 0;
        for(const SelectManager& selector : selectors)
            size += selector.size();
        return size;
    }

    void BalancingSelector::setArgs(bool read,bool write,bool except,float timeout_sec)
    {
        writefds = write;
        readfds = read;
        exceptfds = except;
        timeout = timeout_sec;
        for(SelectManager& selector : selectors)
            selector.setArgs(read,write,except,timeout_sec);
    }

    void BalancingSelector::setRead(bool read)
    {
        readfds = read;
        for(SelectManager& selector : selectors)
            selector.setRead(read);
    }

    void BalancingSelector::setWrite(bool write)
    {
        writefds = write;
        for(SelectManager& selector : selectors)
            selector.setWrite(write);
    }

    void BalancingSelector::setExcept(bool except)
    {
        exceptfds = except;
        for(SelectManager& selector : selectors)
            selector.setExcept(except);
    }

    void BalancingSelector::setTimout(float timeout_sec)
    {
        timeout = timeout_sec;
        for(SelectManager& selector : selectors)
            selector.setTimout(timeout_sec);
    }

    void BalancingSelector::setDelete(bool d)
    {
        do_delete = d;
        for(SelectManager& selector : selectors)
            selector.setTimout(d);
    }

    SelectManager& BalancingSelector::newSelector()
    {
        selectors.emplace_back();

        SelectManager& s = selectors.back();
        s.onSelect = onSelect;
        s.data = data;
        s.setArgs(readfds,writefds,exceptfds,timeout);
        s.setDelete(do_delete);

        if(_run)
            s.start();
        /*if(selectors.size()>1)
            s.detach(); ///< todo
        */
        return s;
    }
}
<|endoftext|>