<commit_before>/* Gobby - GTK-based collaborative text editor
 * Copyright (C) 2008, 2009 Armin Burgmeier <armin@arbur.net>
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "features.hpp"
#include "window.hpp"

#include "core/iconmanager.hpp"
#include "util/config.hpp"
#include "util/file.hpp"
#include "util/i18n.hpp"

#include <libinfinity/common/inf-init.h>

#include <gtkmm/main.h>
#include <gtkmm/messagedialog.h>
#include <giomm/init.h>
#include <glibmm/optionentry.h>
#include <glibmm/optiongroup.h>
#include <glibmm/optioncontext.h>

#include <unique/unique.h>

#include <libintl.h> // bindtextdomain
#include <iostream>

namespace
{
	void handle_exception(const Glib::ustring& message)
	{
		Gtk::MessageDialog dlg("Unhandled exception", false,
			Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
		dlg.set_secondary_text(message);
		dlg.run();

		std::cerr << "Unhandled exception: " << message << std::endl;
	}

	const char* _(const char* str)
	{
		return Gobby::_(str);
	}

	std::string gobby_localedir()
	{
#ifdef G_OS_WIN32
		gchar* root =
			g_win32_get_package_installation_directory_of_module(
				NULL);

		gchar* temp = g_build_filename(root, "share", "locale", NULL);
		g_free(root);

		gchar* result = g_win32_locale_filename_from_utf8(temp);
		g_free(temp);

		std::string cpp_result(result);
		g_free(result);

		return cpp_result;
#else
		return GOBBY_LOCALEDIR;
#endif
	}
}

int main(int argc, char* argv[]) try
{
	g_thread_init(NULL);
	Gio::init();

	setlocale(LC_ALL, "");
	bindtextdomain(GETTEXT_PACKAGE, gobby_localedir().c_str());
	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");

	bool display_version = false;

	Glib::OptionGroup opt_group_gobby("gobby",
		_("Gobby options"), _("Options related to Gobby"));
	Glib::OptionEntry opt_version;
	opt_version.set_short_name('v');
	opt_version.set_long_name("version");
	opt_version.set_description(
		_("Display version information and exit"));
	opt_group_gobby.add_entry(opt_version, display_version);

	Glib::OptionContext opt_ctx;
	opt_ctx.set_help_enabled(true);
	opt_ctx.set_ignore_unknown_options(false);
	opt_ctx.set_main_group(opt_group_gobby);

	// I would rather like to have Gtk::Main on the stack, but I see
	// no other chance to catch exceptions from the command line option
	// parsing. armin.
	// TODO: Maybe we should parse before initializing GTK+, using
	// Gtk::Main::add_gtk_option_group() with open_default_display set
	// to false.
	std::auto_ptr<Gtk::Main> kit;

	try
	{
		kit.reset(new Gtk::Main(argc, argv, opt_ctx));
	}
	catch(Glib::Exception& e)
	{
		std::cerr << e.what() << std::endl;
		return EXIT_FAILURE;
	}

	if(display_version)
	{
		std::cout << "Gobby " << PACKAGE_VERSION << std::endl;
		return EXIT_SUCCESS;
	}

	bool new_instance = false;

	// TODO: add --new-instance option to disable unique
	UniqueApp* app = unique_app_new_with_commands(
		"de.ox539.gobby", NULL, NULL);

	if (!new_instance && unique_app_is_running(app))
	{
		UniqueResponse response;
		if (argc < 2)
		{
			response = unique_app_send_message(
				app, UNIQUE_ACTIVATE, NULL);
		}
		else
		{
			UniqueMessageData* message =
				unique_message_data_new();
			std::vector<const gchar*> uris(argc);
			std::vector<Glib::ustring> uri_strs(argc-1);
			for (int i = 0; i < argc - 1; ++i) {
				uri_strs[i] =
					Gio::File::create_for_commandline_arg(
						argv[i+1])->get_uri();
				uris[i] = uri_strs[i].c_str();
			}

			unique_message_data_set_uris(
				message, const_cast<gchar**>(&uris[0]));
			response = unique_app_send_message(
				app, UNIQUE_OPEN, message);
			unique_message_data_free(message);
		}

		g_object_unref(app);

		if (response == UNIQUE_RESPONSE_OK)
		{
			return 0;
		}
		else
		{
			std::cerr
				<< "uniqueapp error: "
				<< static_cast<int>(response)
				<< std::endl;
			return -1;
		}
	}

	GError* error = NULL;
	if(!inf_init(&error))
	{
		std::string message = error->message;
		g_error_free(error);
		throw std::runtime_error(message);
	}

	Gobby::IconManager icon_manager;

	// Set default icon
	Gtk::Window::set_default_icon_name("gobby-0.5");

	// Read the configuration
	Gobby::Config config(Gobby::config_filename("config.xml"));

	// Create window
	Gobby::Window wnd(argc-1, argv+1, icon_manager, config, app);
	g_object_unref(app);
	wnd.show();

	wnd.signal_hide().connect(sigc::ptr_fun(&Gtk::Main::quit) );
	kit->run();

	//inf_deinit();
	return 0;
}
catch(Glib::Exception& e)
{
	handle_exception(e.what() );
}
catch(std::exception& e)
{
	handle_exception(e.what() );
}
<commit_msg>Fix unique_app_new call, changed service name from org.ox539 to org._0x539<commit_after>/* Gobby - GTK-based collaborative text editor
 * Copyright (C) 2008, 2009 Armin Burgmeier <armin@arbur.net>
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "features.hpp"
#include "window.hpp"

#include "core/iconmanager.hpp"
#include "util/config.hpp"
#include "util/file.hpp"
#include "util/i18n.hpp"

#include <libinfinity/common/inf-init.h>

#include <gtkmm/main.h>
#include <gtkmm/messagedialog.h>
#include <giomm/init.h>
#include <glibmm/optionentry.h>
#include <glibmm/optiongroup.h>
#include <glibmm/optioncontext.h>

#include <unique/unique.h>

#include <libintl.h> // bindtextdomain
#include <iostream>

namespace
{
	void handle_exception(const Glib::ustring& message)
	{
		Gtk::MessageDialog dlg("Unhandled exception", false,
			Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
		dlg.set_secondary_text(message);
		dlg.run();

		std::cerr << "Unhandled exception: " << message << std::endl;
	}

	const char* _(const char* str)
	{
		return Gobby::_(str);
	}

	std::string gobby_localedir()
	{
#ifdef G_OS_WIN32
		gchar* root =
			g_win32_get_package_installation_directory_of_module(
				NULL);

		gchar* temp = g_build_filename(root, "share", "locale", NULL);
		g_free(root);

		gchar* result = g_win32_locale_filename_from_utf8(temp);
		g_free(temp);

		std::string cpp_result(result);
		g_free(result);

		return cpp_result;
#else
		return GOBBY_LOCALEDIR;
#endif
	}
}

int main(int argc, char* argv[]) try
{
	g_thread_init(NULL);
	Gio::init();

	setlocale(LC_ALL, "");
	bindtextdomain(GETTEXT_PACKAGE, gobby_localedir().c_str());
	bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");

	bool display_version = false;

	Glib::OptionGroup opt_group_gobby("gobby",
		_("Gobby options"), _("Options related to Gobby"));
	Glib::OptionEntry opt_version;
	opt_version.set_short_name('v');
	opt_version.set_long_name("version");
	opt_version.set_description(
		_("Display version information and exit"));
	opt_group_gobby.add_entry(opt_version, display_version);

	Glib::OptionContext opt_ctx;
	opt_ctx.set_help_enabled(true);
	opt_ctx.set_ignore_unknown_options(false);
	opt_ctx.set_main_group(opt_group_gobby);

	// I would rather like to have Gtk::Main on the stack, but I see
	// no other chance to catch exceptions from the command line option
	// parsing. armin.
	// TODO: Maybe we should parse before initializing GTK+, using
	// Gtk::Main::add_gtk_option_group() with open_default_display set
	// to false.
	std::auto_ptr<Gtk::Main> kit;

	try
	{
		kit.reset(new Gtk::Main(argc, argv, opt_ctx));
	}
	catch(Glib::Exception& e)
	{
		std::cerr << e.what() << std::endl;
		return EXIT_FAILURE;
	}

	if(display_version)
	{
		std::cout << "Gobby " << PACKAGE_VERSION << std::endl;
		return EXIT_SUCCESS;
	}

	bool new_instance = false;

	// TODO: add --new-instance option to disable unique
	UniqueApp* app = unique_app_new("de._0x539.gobby", NULL);

	if (!new_instance && unique_app_is_running(app))
	{
		UniqueResponse response;
		if (argc < 2)
		{
			response = unique_app_send_message(
				app, UNIQUE_ACTIVATE, NULL);
		}
		else
		{
			UniqueMessageData* message =
				unique_message_data_new();
			std::vector<const gchar*> uris(argc);
			std::vector<Glib::ustring> uri_strs(argc-1);
			for (int i = 0; i < argc - 1; ++i) {
				uri_strs[i] =
					Gio::File::create_for_commandline_arg(
						argv[i+1])->get_uri();
				uris[i] = uri_strs[i].c_str();
			}

			unique_message_data_set_uris(
				message, const_cast<gchar**>(&uris[0]));
			response = unique_app_send_message(
				app, UNIQUE_OPEN, message);
			unique_message_data_free(message);
		}

		g_object_unref(app);

		if (response == UNIQUE_RESPONSE_OK)
		{
			return 0;
		}
		else
		{
			std::cerr
				<< "uniqueapp error: "
				<< static_cast<int>(response)
				<< std::endl;
			return -1;
		}
	}

	GError* error = NULL;
	if(!inf_init(&error))
	{
		std::string message = error->message;
		g_error_free(error);
		throw std::runtime_error(message);
	}

	Gobby::IconManager icon_manager;

	// Set default icon
	Gtk::Window::set_default_icon_name("gobby-0.5");

	// Read the configuration
	Gobby::Config config(Gobby::config_filename("config.xml"));

	// Create window
	Gobby::Window wnd(argc-1, argv+1, icon_manager, config, app);
	g_object_unref(app);
	wnd.show();

	wnd.signal_hide().connect(sigc::ptr_fun(&Gtk::Main::quit) );
	kit->run();

	//inf_deinit();
	return 0;
}
catch(Glib::Exception& e)
{
	handle_exception(e.what() );
}
catch(std::exception& e)
{
	handle_exception(e.what() );
}
<|endoftext|>


<commit_before>///
/// @file  CpuInfo.cpp
/// @brief Get the CPUs cache sizes in bytes.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/CpuInfo.hpp>

#include <cstddef>
#include <string>
#include <vector>

#if defined(_WIN32)

#include <windows.h>

#elif defined(__APPLE__)

#include <sys/types.h>
#include <sys/sysctl.h>

#elif defined(__linux__)

#include <array>
#include <cstdio>
#include <memory>

using namespace std;

namespace {

string getCacheStr(const char* filename)
{
  shared_ptr<FILE> file(fopen(filename, "r"), fclose);
  string cacheStr;

  if (file)
  {
    array<char, 32> buffer;

    while (!feof(file.get()))
    {
      if (fgets(buffer.data(), buffer.size(), file.get()))
        cacheStr += buffer.data();
    }
  }

  return cacheStr;
}

size_t getCacheSize(const char* filename)
{
  size_t cacheSize = 0;
  string cacheStr = getCacheStr(filename);
  size_t pos = cacheStr.find_first_of("0123456789");

  if (pos != string::npos)
  {
    // first character after number
    size_t idx = 0;
    cacheSize = stol(cacheStr.substr(pos), &idx);

    if (idx < cacheStr.size())
    {
      // Last character may be:
      // 'K' = kilobytes
      // 'M' = megabytes
      // 'G' = gigabytes

      if (cacheStr[idx] == 'K')
        cacheSize *= 1024;
      if (cacheStr[idx] == 'M')
        cacheSize *= 1024 * 1024;
      if (cacheStr[idx] == 'G')
        cacheSize *= 1024 * 1024 * 1024;
    }
  }

  return cacheSize;
}

} // namespace

#endif

using namespace std;

namespace primesieve {

CpuInfo::CpuInfo()
  : l1CacheSize_(0),
    l2CacheSize_(0),
    l3CacheSize_(0)
{
  initCache();
}

size_t CpuInfo::l1CacheSize() const
{
  return l1CacheSize_;
}

size_t CpuInfo::l2CacheSize() const
{
  return l2CacheSize_;
}

size_t CpuInfo::l3CacheSize() const
{
  return l3CacheSize_;
}

#if defined(__linux__)

void CpuInfo::initCache()
{
  l1CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index0/size");
  l2CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index2/size");
  l3CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index3/size");
}

#elif defined(__APPLE__)

void CpuInfo::initCache()
{
  size_t l1Length = sizeof(l1CacheSize_);
  size_t l2Length = sizeof(l2CacheSize_);
  size_t l3Length = sizeof(l3CacheSize_);

  sysctlbyname("hw.l1dcachesize", &l1CacheSize_, &l1Length, NULL, 0);
  sysctlbyname("hw.l2cachesize" , &l2CacheSize_, &l2Length, NULL, 0);
  sysctlbyname("hw.l3cachesize" , &l3CacheSize_, &l3Length, NULL, 0);
}

#elif defined(_WIN32)

typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);

void CpuInfo::initCache()
{
  LPFN_GLPI glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation");

  if (glpi)
  {
    DWORD bytes = 0;
    glpi(0, &bytes);
    size_t size = bytes / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
    vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> info(size);
    glpi(info.data(), &bytes);

    for (size_t i = 0; i < size; i++)
    {
      if (info[i].Relationship == RelationCache)
      {
        if (info[i].Cache.Level == 1)
          l1CacheSize_ = info[i].Cache.Size;
        if (info[i].Cache.Level == 2)
          l2CacheSize_ = info[i].Cache.Size;
        if (info[i].Cache.Level == 3)
          l3CacheSize_ = info[i].Cache.Size;
      }
    }
  }
}

#else // Unkown operating system

void CpuInfo::initCache()
{
  l1CacheSize_ = 0;
  l2CacheSize_ = 0;
  l3CacheSize_ = 0;
}

#endif

/// Singleton
const CpuInfo cpuInfo;

} // namespace
<commit_msg>Refactor<commit_after>///
/// @file  CpuInfo.cpp
/// @brief Get the CPUs cache sizes in bytes.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/CpuInfo.hpp>

#include <cstddef>
#include <string>
#include <vector>

#if defined(_WIN32)

#include <windows.h>

#elif defined(__APPLE__)

#include <sys/types.h>
#include <sys/sysctl.h>

#else // all other OSes

#include <array>
#include <cstdio>
#include <memory>

using namespace std;

namespace {

string getCacheStr(const char* filename)
{
  shared_ptr<FILE> file(
      fopen(filename, "r"), fclose);
  array<char, 64> buffer;
  string cacheStr;

  if (file)
  {
    while (!feof(file.get()))
    {
      if (fgets(buffer.data(), buffer.size(), file.get()))
        cacheStr += buffer.data();
    }
  }

  return cacheStr;
}

size_t getCacheSize(const char* filename)
{
  size_t cacheSize = 0;
  string cacheStr = getCacheStr(filename);
  size_t pos = cacheStr.find_first_of("0123456789");

  if (pos != string::npos)
  {
    // first character after number
    size_t idx = 0;
    cacheSize = stol(cacheStr.substr(pos), &idx);

    if (idx < cacheStr.size())
    {
      // Last character may be:
      // 'K' = kilobytes
      // 'M' = megabytes
      // 'G' = gigabytes

      if (cacheStr[idx] == 'K')
        cacheSize *= 1024;
      if (cacheStr[idx] == 'M')
        cacheSize *= 1024 * 1024;
      if (cacheStr[idx] == 'G')
        cacheSize *= 1024 * 1024 * 1024;
    }
  }

  return cacheSize;
}

} // namespace

#endif

using namespace std;

namespace primesieve {

CpuInfo::CpuInfo()
  : l1CacheSize_(0),
    l2CacheSize_(0),
    l3CacheSize_(0)
{
  initCache();
}

size_t CpuInfo::l1CacheSize() const
{
  return l1CacheSize_;
}

size_t CpuInfo::l2CacheSize() const
{
  return l2CacheSize_;
}

size_t CpuInfo::l3CacheSize() const
{
  return l3CacheSize_;
}

#if defined(__APPLE__)

void CpuInfo::initCache()
{
  size_t l1Length = sizeof(l1CacheSize_);
  size_t l2Length = sizeof(l2CacheSize_);
  size_t l3Length = sizeof(l3CacheSize_);

  sysctlbyname("hw.l1dcachesize", &l1CacheSize_, &l1Length, NULL, 0);
  sysctlbyname("hw.l2cachesize" , &l2CacheSize_, &l2Length, NULL, 0);
  sysctlbyname("hw.l3cachesize" , &l3CacheSize_, &l3Length, NULL, 0);
}

#elif defined(_WIN32)

typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);

void CpuInfo::initCache()
{
  LPFN_GLPI glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation");

  if (glpi)
  {
    DWORD bytes = 0;
    glpi(0, &bytes);
    size_t size = bytes / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
    vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> info(size);
    glpi(info.data(), &bytes);

    for (size_t i = 0; i < size; i++)
    {
      if (info[i].Relationship == RelationCache)
      {
        if (info[i].Cache.Level == 1)
          l1CacheSize_ = info[i].Cache.Size;
        if (info[i].Cache.Level == 2)
          l2CacheSize_ = info[i].Cache.Size;
        if (info[i].Cache.Level == 3)
          l3CacheSize_ = info[i].Cache.Size;
      }
    }
  }
}

#else

/// This works on Linux, we also use this for
/// all unkown OSes, it might work.
///
void CpuInfo::initCache()
{
  l1CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index0/size");
  l2CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index2/size");
  l3CacheSize_ = getCacheSize("/sys/devices/system/cpu/cpu0/cache/index3/size");
}

#endif

/// Singleton
const CpuInfo cpuInfo;

} // namespace
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
// Name:      lexer.cpp
// Purpose:   Implementation of wxExLexer class
// Author:    Anton van Wezenbeek
// Copyright: (c) 2013 Anton van Wezenbeek
////////////////////////////////////////////////////////////////////////////////

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <algorithm>
#include <functional>
//#include <numeric> // both for accumulate
#include <wx/stc/stc.h>
#include <wx/tokenzr.h>
#include <wx/xml/xml.h>
#include <wx/extension/lexer.h>
#include <wx/extension/lexers.h>
#include <wx/extension/util.h> // for wxExAlignText

// We always use lines with 80 characters.
const int line_size = 80;

wxExLexer::wxExLexer()
{
  Initialize();
}

wxExLexer::wxExLexer(const wxXmlNode* node)
{
  Initialize();

  Set(node);
}

void wxExLexer::Apply(wxStyledTextCtrl* stc, bool clear) const
{
  if (clear)
  {
    stc->ClearDocumentStyle();
  }

  for_each (m_Properties.begin(), m_Properties.end(),
    std::bind2nd(std::mem_fun_ref(&wxExProperty::ApplyReset), stc));

  // Reset keywords, also if no lexer is available.
  for (size_t setno = 0; setno < wxSTC_KEYWORDSET_MAX; setno++)
  {
    stc->SetKeyWords(setno, wxEmptyString);
  }

  if (clear)
  {
    wxExLexers::Get()->ApplyGlobalStyles(stc);
  }

  if (wxExLexers::Get()->GetThemeOk())
  {
    for (const auto& it : m_KeywordsSet)
    {
      stc->SetKeyWords(
        it.first,
        GetKeywordsString(it.first));
    }

    wxExLexers::Get()->GetDefaultStyle().Apply(stc);
    wxExLexers::Get()->ApplyIndicators(stc);
    wxExLexers::Get()->ApplyProperties(stc);
    wxExLexers::Get()->ApplyMarkers(stc);

    for_each (m_Properties.begin(), m_Properties.end(),
      std::bind2nd(std::mem_fun_ref(&wxExProperty::Apply), stc));

    for_each (m_Styles.begin(), m_Styles.end(),
      std::bind2nd(std::mem_fun_ref(&wxExStyle::Apply), stc));
  }

  // And finally colour the entire document.
  stc->Colourise(0, stc->GetLength() - 1);
}

void wxExLexer::ApplyWhenSet(
  const wxString& lexer, wxStyledTextCtrl* stc, bool clear)
{
  stc->SetLexerLanguage(m_ScintillaLexer);

  if (m_ScintillaLexer.empty() && lexer.empty())
  {
    m_IsOk = (stc->GetLexer() == wxSTC_LEX_NULL);
  }
  else
  {
    m_IsOk = (stc->GetLexer() != wxSTC_LEX_NULL);
  }

  if (m_IsOk)
  {
    stc->SetStyleBits(stc->GetStyleBitsNeeded());
    Apply(stc, clear);

    if (m_ScintillaLexer == "diff")
    {
      stc->SetEdgeMode(wxSTC_EDGE_NONE);
    }
  }
}

void wxExLexer::AutoMatch(const wxString& lexer)
{
  for (const auto& it : wxExLexers::Get()->GetMacros(lexer))
  {
    for (const auto& style : wxExLexers::Get()->GetThemeMacros())
    {
      if (it.first.Contains(style.first))
      {
        m_Styles.push_back(wxExStyle(it.second, style.second));
        break;
      }
    }
  }
}

const wxString wxExLexer::CommentComplete(const wxString& comment) const
{
  if (m_CommentEnd.empty())
  {
    return wxEmptyString;
  }

  // Fill out rest of comment with spaces, and comment end string.
  const int n = line_size - comment.size() - m_CommentEnd.size();

  if (n <= 0)
  {
    return wxEmptyString;
  }

  const wxString blanks = wxString(' ', n);

  return blanks + m_CommentEnd;
}

const wxString wxExLexer::GetFormattedText(
  const wxString& lines,
  const wxString& header,
  bool fill_out_with_space,
  bool fill_out) const
{
  wxString text = lines, header_to_use = header;
  size_t nCharIndex;

  wxString out;

  // Process text between the carriage return line feeds.
  while ((nCharIndex = text.find("\n")) != wxString::npos)
  {
    out << wxExAlignText(
      text.substr(0, nCharIndex),
      header_to_use,
      fill_out_with_space,
      fill_out,
      *this);

    text = text.substr(nCharIndex + 1);
    header_to_use = wxString(' ', header.size());
  }

  if (!text.empty())
  {
    out << wxExAlignText(
      text,
      header_to_use,
      fill_out_with_space,
      fill_out,
      *this);
  }

  return out;
}

const wxString wxExLexer::GetKeywordsString(int keyword_set) const
{
  if (keyword_set == -1)
  {
    return GetKeywordsStringSet(m_Keywords);
  }
  else
  {
    const auto it = m_KeywordsSet.find(keyword_set);

    if (it != m_KeywordsSet.end())
    {
      return GetKeywordsStringSet(it->second);
    }
  }

  return wxEmptyString;
}

const wxString wxExLexer::GetKeywordsStringSet(
  const std::set<wxString>& kset) const
{
  // accumulate would be nice, but does not add a space, could not do it easily.
  // return accumulate(kset.begin(), kset.end(), wxEmptyString);
  wxString keywords;

  for (const auto& it : kset)
  {
    keywords += it + " ";
  }

  return keywords.Trim(); // remove the ending space
}

void wxExLexer::Initialize()
{
  m_IsOk = false;

  m_CommentBegin.clear();
  m_CommentBegin2.clear();
  m_CommentEnd.clear();
  m_CommentEnd2.clear();
  m_Styles.clear();
  m_Extensions.clear();
  m_Properties.clear();
  m_Keywords.clear();
  m_KeywordsSet.clear();
  m_ScintillaLexer.clear();
  m_DisplayLexer.clear();
}

bool wxExLexer::IsKeyword(const wxString& word) const
{
  return m_Keywords.find(word) != m_Keywords.end();
}

bool wxExLexer::KeywordStartsWith(const wxString& word) const
{
  const auto it = m_Keywords.lower_bound(word);
  return
    it != m_Keywords.end() &&
    it->StartsWith(word);
}

const wxString wxExLexer::MakeComment(
  const wxString& text,
  bool fill_out_with_space,
  bool fill_out) const
{
  wxString out;

  text.find("\n") != wxString::npos ?
    out << GetFormattedText(text, wxEmptyString, fill_out_with_space, fill_out):
    out << wxExAlignText(text, wxEmptyString, fill_out_with_space, fill_out, *this);

  return out;
}

const wxString wxExLexer::MakeComment(
  const wxString& prefix,
  const wxString& text) const
{
  wxString out;

  text.find("\n") != wxString::npos ?
    out << GetFormattedText(text, prefix, true, true):
    out << wxExAlignText(text, prefix, true, true, *this);

  return out;
}

const wxString wxExLexer::MakeSingleLineComment(
  const wxString& text,
  bool fill_out_with_space,
  bool fill_out) const
{
  if (m_CommentBegin.empty() && m_CommentEnd.empty())
  {
    return text;
  }

  // First set the fill_out_character.
  wxUniChar fill_out_character;

  if (fill_out_with_space || m_ScintillaLexer == "hypertext")
  {
    fill_out_character = ' ';
  }
  else
  {
    if (text.empty())
    {
      if (m_CommentBegin == m_CommentEnd)
           fill_out_character = '-';
      else fill_out_character = m_CommentBegin[m_CommentBegin.size() - 1];
    }
    else   fill_out_character = ' ';
  }

  wxString out = m_CommentBegin + fill_out_character + text;

  // Fill out characters.
  if (fill_out)
  {
    // To prevent filling out spaces
    if (fill_out_character != ' ' || !m_CommentEnd.empty())
    {
      const int fill_chars = UsableCharactersPerLine() - text.size();

      if (fill_chars > 0)
      {
        const wxString fill_out(fill_out_character, fill_chars);
        out += fill_out;
      }
    }
  }

  if (!m_CommentEnd.empty()) out += fill_out_character + m_CommentEnd;

  return out;
}

bool wxExLexer::Reset(wxStyledTextCtrl* stc)
{
  Initialize();

  stc->SetLexer(wxSTC_LEX_NULL);

  m_IsOk = (stc->GetLexer() == wxSTC_LEX_NULL);

  if (m_IsOk)
  {
    Apply(stc, true);
  }

  return m_IsOk;
}

bool wxExLexer::Set(
  const wxString& lexer,
  wxStyledTextCtrl* stc,
  bool clear)
{
  (*this) = wxExLexers::Get()->FindByName(lexer);

  if (!m_IsOk)
  {
    (*this) = wxExLexers::Get()->FindByText(stc->GetLine(0));
  }

  ApplyWhenSet(lexer, stc, clear);

  if (!m_IsOk)
  {
    wxLogError("Lexer is not known: " + m_ScintillaLexer);
  }

  return m_IsOk;
}

bool wxExLexer::Set(const wxExLexer& lexer, wxStyledTextCtrl* stc)
{
  if (lexer.GetScintillaLexer().empty())
  {
    (*this) = wxExLexers::Get()->FindByText(stc->GetLine(0));
  }
  else
  {
    if (this != &lexer)
    {
      (*this) = lexer;
    }
  }

  ApplyWhenSet(lexer.GetScintillaLexer(), stc, true);

  return m_IsOk;
}

void wxExLexer::Set(const wxXmlNode* node)
{
  m_ScintillaLexer = node->GetAttribute("name");

  // Just set ok if there is a lexer,
  // when we Apply to a stc component we really can set it.
  m_IsOk = !m_ScintillaLexer.empty();

  if (!m_IsOk)
  {
    wxLogError("Missing lexer on line: %d", node->GetLineNumber());
  }
  else
  {
    m_DisplayLexer = (!node->GetAttribute("display").empty() ?
      node->GetAttribute("display"):
      m_ScintillaLexer);

    m_Extensions = node->GetAttribute("extensions");

    AutoMatch((!node->GetAttribute("macro").empty() ?
      node->GetAttribute("macro"):
      m_ScintillaLexer));

    if (m_ScintillaLexer == "hypertext")
    {
      // As our lexers.xml files cannot use xml comments,
      // add them here.
      m_CommentBegin = "<!--";
      m_CommentEnd = "-->";
    }

    wxXmlNode *child = node->GetChildren();

    while (child)
    {
      if (child->GetName() == "styles")
      {
        wxExNodeStyles(child, m_ScintillaLexer, m_Styles);
      }
      else if (child->GetName() == "keywords")
      {
        if (!SetKeywords(child->GetNodeContent().Strip(wxString::both)))
        {
          wxLogError(
            "Keywords could not be set on line: %d",
            child->GetLineNumber());
        }
      }
      else if (child->GetName() == "properties")
      {
        wxExNodeProperties(child, m_Properties);
      }
      else if (child->GetName() == "comments")
      {
        m_CommentBegin = child->GetAttribute("begin1");
        m_CommentEnd = child->GetAttribute("end1");
        m_CommentBegin2 = child->GetAttribute("begin2");
        m_CommentEnd2 = child->GetAttribute("end2");
      }

      child = child->GetNext();
    }
  }
}

// Adds the specified keywords to the keywords map and the keywords set.
// The text might contain the keyword set after a ':'.
// Returns true if keyword could be added
// and false if specified set is illegal.
// Empties existing keywords.
bool wxExLexer::SetKeywords(const wxString& value)
{
  if (!m_Keywords.empty())
  {
    m_Keywords.clear();
  }

  if (!m_KeywordsSet.empty())
  {
    m_KeywordsSet.clear();
  }

  std::set<wxString> keywords_set;

  wxStringTokenizer tkz(value, "\r\n ");

  int setno = 0;

  while (tkz.HasMoreTokens())
  {
    const wxString line = tkz.GetNextToken();
    wxStringTokenizer fields(line, ":");

    wxString keyword;

    if (fields.CountTokens() > 1)
    {
      keyword = fields.GetNextToken();

      const int new_setno = atoi(fields.GetNextToken().c_str());

      if (new_setno >= wxSTC_KEYWORDSET_MAX)
      {
        return false;
      }

      if (new_setno != setno)
      {
        if (!keywords_set.empty())
        {
          m_KeywordsSet.insert(make_pair(setno, keywords_set));
          keywords_set.clear();
        }

        setno = new_setno;
      }

      keywords_set.insert(keyword);
    }
    else
    {
      keyword = line;
      keywords_set.insert(line);
    }

    m_Keywords.insert(keyword);
  }

  m_KeywordsSet.insert(make_pair(setno, keywords_set));

  return true;
}

void wxExLexer::SetProperty(const wxString& name, const wxString& value)
{
  for (auto& it : m_Properties)
  {
    if (it.GetName() == name)
    {
      it.Set(value);
      return;
    }
  }

  m_Properties.push_back(wxExProperty(name, value));
}

int wxExLexer::UsableCharactersPerLine() const
{
  // We adjust this here for
  // the space the beginning and end of the comment characters occupy.
  return line_size
    - ((m_CommentBegin.size() != 0) ? m_CommentBegin.size() + 1 : 0)
    - ((m_CommentEnd.size() != 0) ? m_CommentEnd.size() + 1 : 0);
}
<commit_msg>fixed error message<commit_after>////////////////////////////////////////////////////////////////////////////////
// Name:      lexer.cpp
// Purpose:   Implementation of wxExLexer class
// Author:    Anton van Wezenbeek
// Copyright: (c) 2013 Anton van Wezenbeek
////////////////////////////////////////////////////////////////////////////////

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <algorithm>
#include <functional>
//#include <numeric> // both for accumulate
#include <wx/stc/stc.h>
#include <wx/tokenzr.h>
#include <wx/xml/xml.h>
#include <wx/extension/lexer.h>
#include <wx/extension/lexers.h>
#include <wx/extension/util.h> // for wxExAlignText

// We always use lines with 80 characters.
const int line_size = 80;

wxExLexer::wxExLexer()
{
  Initialize();
}

wxExLexer::wxExLexer(const wxXmlNode* node)
{
  Initialize();

  Set(node);
}

void wxExLexer::Apply(wxStyledTextCtrl* stc, bool clear) const
{
  if (clear)
  {
    stc->ClearDocumentStyle();
  }

  for_each (m_Properties.begin(), m_Properties.end(),
    std::bind2nd(std::mem_fun_ref(&wxExProperty::ApplyReset), stc));

  // Reset keywords, also if no lexer is available.
  for (size_t setno = 0; setno < wxSTC_KEYWORDSET_MAX; setno++)
  {
    stc->SetKeyWords(setno, wxEmptyString);
  }

  if (clear)
  {
    wxExLexers::Get()->ApplyGlobalStyles(stc);
  }

  if (wxExLexers::Get()->GetThemeOk())
  {
    for (const auto& it : m_KeywordsSet)
    {
      stc->SetKeyWords(
        it.first,
        GetKeywordsString(it.first));
    }

    wxExLexers::Get()->GetDefaultStyle().Apply(stc);
    wxExLexers::Get()->ApplyIndicators(stc);
    wxExLexers::Get()->ApplyProperties(stc);
    wxExLexers::Get()->ApplyMarkers(stc);

    for_each (m_Properties.begin(), m_Properties.end(),
      std::bind2nd(std::mem_fun_ref(&wxExProperty::Apply), stc));

    for_each (m_Styles.begin(), m_Styles.end(),
      std::bind2nd(std::mem_fun_ref(&wxExStyle::Apply), stc));
  }

  // And finally colour the entire document.
  stc->Colourise(0, stc->GetLength() - 1);
}

void wxExLexer::ApplyWhenSet(
  const wxString& lexer, wxStyledTextCtrl* stc, bool clear)
{
  stc->SetLexerLanguage(m_ScintillaLexer);

  if (m_ScintillaLexer.empty() && lexer.empty())
  {
    m_IsOk = (stc->GetLexer() == wxSTC_LEX_NULL);
  }
  else
  {
    m_IsOk = (stc->GetLexer() != wxSTC_LEX_NULL);
  }

  if (m_IsOk)
  {
    stc->SetStyleBits(stc->GetStyleBitsNeeded());
    Apply(stc, clear);

    if (m_ScintillaLexer == "diff")
    {
      stc->SetEdgeMode(wxSTC_EDGE_NONE);
    }
  }
}

void wxExLexer::AutoMatch(const wxString& lexer)
{
  for (const auto& it : wxExLexers::Get()->GetMacros(lexer))
  {
    for (const auto& style : wxExLexers::Get()->GetThemeMacros())
    {
      if (it.first.Contains(style.first))
      {
        m_Styles.push_back(wxExStyle(it.second, style.second));
        break;
      }
    }
  }
}

const wxString wxExLexer::CommentComplete(const wxString& comment) const
{
  if (m_CommentEnd.empty())
  {
    return wxEmptyString;
  }

  // Fill out rest of comment with spaces, and comment end string.
  const int n = line_size - comment.size() - m_CommentEnd.size();

  if (n <= 0)
  {
    return wxEmptyString;
  }

  const wxString blanks = wxString(' ', n);

  return blanks + m_CommentEnd;
}

const wxString wxExLexer::GetFormattedText(
  const wxString& lines,
  const wxString& header,
  bool fill_out_with_space,
  bool fill_out) const
{
  wxString text = lines, header_to_use = header;
  size_t nCharIndex;

  wxString out;

  // Process text between the carriage return line feeds.
  while ((nCharIndex = text.find("\n")) != wxString::npos)
  {
    out << wxExAlignText(
      text.substr(0, nCharIndex),
      header_to_use,
      fill_out_with_space,
      fill_out,
      *this);

    text = text.substr(nCharIndex + 1);
    header_to_use = wxString(' ', header.size());
  }

  if (!text.empty())
  {
    out << wxExAlignText(
      text,
      header_to_use,
      fill_out_with_space,
      fill_out,
      *this);
  }

  return out;
}

const wxString wxExLexer::GetKeywordsString(int keyword_set) const
{
  if (keyword_set == -1)
  {
    return GetKeywordsStringSet(m_Keywords);
  }
  else
  {
    const auto it = m_KeywordsSet.find(keyword_set);

    if (it != m_KeywordsSet.end())
    {
      return GetKeywordsStringSet(it->second);
    }
  }

  return wxEmptyString;
}

const wxString wxExLexer::GetKeywordsStringSet(
  const std::set<wxString>& kset) const
{
  // accumulate would be nice, but does not add a space, could not do it easily.
  // return accumulate(kset.begin(), kset.end(), wxEmptyString);
  wxString keywords;

  for (const auto& it : kset)
  {
    keywords += it + " ";
  }

  return keywords.Trim(); // remove the ending space
}

void wxExLexer::Initialize()
{
  m_IsOk = false;

  m_CommentBegin.clear();
  m_CommentBegin2.clear();
  m_CommentEnd.clear();
  m_CommentEnd2.clear();
  m_Styles.clear();
  m_Extensions.clear();
  m_Properties.clear();
  m_Keywords.clear();
  m_KeywordsSet.clear();
  m_ScintillaLexer.clear();
  m_DisplayLexer.clear();
}

bool wxExLexer::IsKeyword(const wxString& word) const
{
  return m_Keywords.find(word) != m_Keywords.end();
}

bool wxExLexer::KeywordStartsWith(const wxString& word) const
{
  const auto it = m_Keywords.lower_bound(word);
  return
    it != m_Keywords.end() &&
    it->StartsWith(word);
}

const wxString wxExLexer::MakeComment(
  const wxString& text,
  bool fill_out_with_space,
  bool fill_out) const
{
  wxString out;

  text.find("\n") != wxString::npos ?
    out << GetFormattedText(text, wxEmptyString, fill_out_with_space, fill_out):
    out << wxExAlignText(text, wxEmptyString, fill_out_with_space, fill_out, *this);

  return out;
}

const wxString wxExLexer::MakeComment(
  const wxString& prefix,
  const wxString& text) const
{
  wxString out;

  text.find("\n") != wxString::npos ?
    out << GetFormattedText(text, prefix, true, true):
    out << wxExAlignText(text, prefix, true, true, *this);

  return out;
}

const wxString wxExLexer::MakeSingleLineComment(
  const wxString& text,
  bool fill_out_with_space,
  bool fill_out) const
{
  if (m_CommentBegin.empty() && m_CommentEnd.empty())
  {
    return text;
  }

  // First set the fill_out_character.
  wxUniChar fill_out_character;

  if (fill_out_with_space || m_ScintillaLexer == "hypertext")
  {
    fill_out_character = ' ';
  }
  else
  {
    if (text.empty())
    {
      if (m_CommentBegin == m_CommentEnd)
           fill_out_character = '-';
      else fill_out_character = m_CommentBegin[m_CommentBegin.size() - 1];
    }
    else   fill_out_character = ' ';
  }

  wxString out = m_CommentBegin + fill_out_character + text;

  // Fill out characters.
  if (fill_out)
  {
    // To prevent filling out spaces
    if (fill_out_character != ' ' || !m_CommentEnd.empty())
    {
      const int fill_chars = UsableCharactersPerLine() - text.size();

      if (fill_chars > 0)
      {
        const wxString fill_out(fill_out_character, fill_chars);
        out += fill_out;
      }
    }
  }

  if (!m_CommentEnd.empty()) out += fill_out_character + m_CommentEnd;

  return out;
}

bool wxExLexer::Reset(wxStyledTextCtrl* stc)
{
  Initialize();

  stc->SetLexer(wxSTC_LEX_NULL);

  m_IsOk = (stc->GetLexer() == wxSTC_LEX_NULL);

  if (m_IsOk)
  {
    Apply(stc, true);
  }

  return m_IsOk;
}

bool wxExLexer::Set(
  const wxString& lexer,
  wxStyledTextCtrl* stc,
  bool clear)
{
  (*this) = wxExLexers::Get()->FindByName(lexer);

  if (!m_IsOk)
  {
    (*this) = wxExLexers::Get()->FindByText(stc->GetLine(0));
  }

  ApplyWhenSet(lexer, stc, clear);

  if (!m_IsOk)
  {
    wxLogError("Lexer is not known: " + lexer);
  }

  return m_IsOk;
}

bool wxExLexer::Set(const wxExLexer& lexer, wxStyledTextCtrl* stc)
{
  if (lexer.GetScintillaLexer().empty())
  {
    (*this) = wxExLexers::Get()->FindByText(stc->GetLine(0));
  }
  else
  {
    if (this != &lexer)
    {
      (*this) = lexer;
    }
  }

  ApplyWhenSet(lexer.GetScintillaLexer(), stc, true);

  return m_IsOk;
}

void wxExLexer::Set(const wxXmlNode* node)
{
  m_ScintillaLexer = node->GetAttribute("name");

  // Just set ok if there is a lexer,
  // when we Apply to a stc component we really can set it.
  m_IsOk = !m_ScintillaLexer.empty();

  if (!m_IsOk)
  {
    wxLogError("Missing lexer on line: %d", node->GetLineNumber());
  }
  else
  {
    m_DisplayLexer = (!node->GetAttribute("display").empty() ?
      node->GetAttribute("display"):
      m_ScintillaLexer);

    m_Extensions = node->GetAttribute("extensions");

    AutoMatch((!node->GetAttribute("macro").empty() ?
      node->GetAttribute("macro"):
      m_ScintillaLexer));

    if (m_ScintillaLexer == "hypertext")
    {
      // As our lexers.xml files cannot use xml comments,
      // add them here.
      m_CommentBegin = "<!--";
      m_CommentEnd = "-->";
    }

    wxXmlNode *child = node->GetChildren();

    while (child)
    {
      if (child->GetName() == "styles")
      {
        wxExNodeStyles(child, m_ScintillaLexer, m_Styles);
      }
      else if (child->GetName() == "keywords")
      {
        if (!SetKeywords(child->GetNodeContent().Strip(wxString::both)))
        {
          wxLogError(
            "Keywords could not be set on line: %d",
            child->GetLineNumber());
        }
      }
      else if (child->GetName() == "properties")
      {
        wxExNodeProperties(child, m_Properties);
      }
      else if (child->GetName() == "comments")
      {
        m_CommentBegin = child->GetAttribute("begin1");
        m_CommentEnd = child->GetAttribute("end1");
        m_CommentBegin2 = child->GetAttribute("begin2");
        m_CommentEnd2 = child->GetAttribute("end2");
      }

      child = child->GetNext();
    }
  }
}

// Adds the specified keywords to the keywords map and the keywords set.
// The text might contain the keyword set after a ':'.
// Returns true if keyword could be added
// and false if specified set is illegal.
// Empties existing keywords.
bool wxExLexer::SetKeywords(const wxString& value)
{
  if (!m_Keywords.empty())
  {
    m_Keywords.clear();
  }

  if (!m_KeywordsSet.empty())
  {
    m_KeywordsSet.clear();
  }

  std::set<wxString> keywords_set;

  wxStringTokenizer tkz(value, "\r\n ");

  int setno = 0;

  while (tkz.HasMoreTokens())
  {
    const wxString line = tkz.GetNextToken();
    wxStringTokenizer fields(line, ":");

    wxString keyword;

    if (fields.CountTokens() > 1)
    {
      keyword = fields.GetNextToken();

      const int new_setno = atoi(fields.GetNextToken().c_str());

      if (new_setno >= wxSTC_KEYWORDSET_MAX)
      {
        return false;
      }

      if (new_setno != setno)
      {
        if (!keywords_set.empty())
        {
          m_KeywordsSet.insert(make_pair(setno, keywords_set));
          keywords_set.clear();
        }

        setno = new_setno;
      }

      keywords_set.insert(keyword);
    }
    else
    {
      keyword = line;
      keywords_set.insert(line);
    }

    m_Keywords.insert(keyword);
  }

  m_KeywordsSet.insert(make_pair(setno, keywords_set));

  return true;
}

void wxExLexer::SetProperty(const wxString& name, const wxString& value)
{
  for (auto& it : m_Properties)
  {
    if (it.GetName() == name)
    {
      it.Set(value);
      return;
    }
  }

  m_Properties.push_back(wxExProperty(name, value));
}

int wxExLexer::UsableCharactersPerLine() const
{
  // We adjust this here for
  // the space the beginning and end of the comment characters occupy.
  return line_size
    - ((m_CommentBegin.size() != 0) ? m_CommentBegin.size() + 1 : 0)
    - ((m_CommentEnd.size() != 0) ? m_CommentEnd.size() + 1 : 0);
}
<|endoftext|>


<commit_before>#include "api/plugin_instance.h"
#include "core/core.h"
#include "core/log.h"
#include "core/math.h"
#include "core/plugin_handler.h"
#include "session/session.h"
#include "settings.h"
#include "ui/imgui/imgui.h"
#include "ui/imgui_setup.h"
#include "ui/ui_layout.h"
#include "ui/menu.h"

#include <bgfx.h>
#include <bgfxplatform.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef PRODBG_WIN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

// TODO: Fix me

int Window_buildPluginMenu(PluginData** plugins, int count);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct Context
{
    int width;
    int height;
    float mouseX;
    float mouseY;
    int mouseLmb;
    Session* session;   // one session right now
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static Context s_context;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static const char* s_plugins[] =
{
    "sourcecode_plugin",
    "disassembly_plugin",
    "locals_plugin",
    "callstack_plugin",
    "registers_plugin",
#ifdef PRODBG_MAC
    "lldb_plugin",
#endif
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void setLayout(UILayout* layout)
{
    Context* context = &s_context;
	IMGUI_preUpdate(context->mouseX, context->mouseY, context->mouseLmb);
	Session_setLayout(context->session, layout, context->width, context->height);
	IMGUI_postUpdate();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void loadLayout()
{
	UILayout layout;

    if (UILayout_loadLayout(&layout, "data/current_layout.yaml"))
	{
		setLayout(&layout);
		return;
	}

    if (UILayout_loadLayout(&layout, "data/default_layout.yaml"))
		setLayout(&layout);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_create(void* window, int width, int height)
{
    Context* context = &s_context;
    //Rect settingsRect;

    context->session = Session_create();

    //Settings_getWindowRect(&settingsRect);
    //width = settingsRect.width;
    //height = settingsRect.height;

    (void)window;

    for (uint32_t i = 0; i < sizeof_array(s_plugins); ++i)
    {
        if (!PluginHandler_addPlugin(OBJECT_DIR, s_plugins[i]))
            return;
    }

#if BX_PLATFORM_OSX
    bgfx::osxSetNSWindow(window);
#elif BX_PLATFORM_WINDOWS
    bgfx::winSetHwnd((HWND)window);
#else
    //bgfx::winSetHwnd(0);
#endif

    bgfx::init();
    bgfx::reset(width, height);
    bgfx::setViewSeq(0, true);

    context->width = width;
    context->height = height;

    IMGUI_setup(width, height);

	loadLayout();

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_update()
{
    Context* context = &s_context;

    bgfx::setViewRect(0, 0, 0, (uint16_t)context->width, (uint16_t)context->height);
    bgfx::setViewClear(0, BGFX_CLEAR_COLOR_BIT | BGFX_CLEAR_DEPTH_BIT, 0x101010ff, 1.0f, 0);
    bgfx::submit(0);

    IMGUI_preUpdate(context->mouseX, context->mouseY, context->mouseLmb);

    // TODO: Support multiple sessions

    Session_update(context->session);

    /*

       bool show = true;

       ImGui::Begin("ImGui Test", &show, ImVec2(550, 480), true, ImGuiWindowFlags_ShowBorders);

       if (ImGui::Button("Test0r testing!"))
       {
        printf("test\n");
       }

       ImGui::End();
     */

    IMGUI_postUpdate();

    bgfx::frame();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setWindowSize(int width, int height)
{
    Context* context = &s_context;

    context->width = width;
    context->height = height;

    bgfx::reset(width, height);
    IMGUI_setup(width, height);
    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_applicationLaunched()
{
#ifdef PRODBG_MAC
	int pluginCount = 0;
	printf("building menu!\n");
	Window_buildPluginMenu(PluginHandler_getPlugins(&pluginCount), pluginCount);
#endif
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_destroy()
{
	UILayout layout;
    Context* context = &s_context;

    Session_getLayout(context->session, &layout, context->width, context->height);
    UILayout_saveLayout(&layout, "data/current_layout.yaml");

    Settings_save();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_timedUpdate()
{
    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Events

void ProDBG_event(int eventId)
{
    Context* context = &s_context;

    int count;

    PluginData** pluginsData = PluginHandler_getPlugins(&count);

	// TODO: This code really needs to be made more robust.

    if (eventId >= PRODBG_MENU_PLUGIN_START && eventId < PRODBG_MENU_PLUGIN_START + 9)
	{
		ViewPluginInstance* instance = PluginInstance_createViewPlugin(pluginsData[eventId - PRODBG_MENU_PLUGIN_START]);
		Session_addViewPlugin(context->session, instance);
		return;
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_scroll(float deltaX, float deltaY, int flags)
{
    (void)deltaX;
    (void)deltaY;
    (void)flags;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setMousePos(float x, float y)
{
    Context* context = &s_context;

    context->mouseX = x;
    context->mouseY = y;

    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setMouseState(int button, int state)
{
    Context* context = &s_context;
    (void)button;

    context->mouseLmb = state;

    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*

   namespace prodbg
   {

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   static const char* s_plugins[] =
   {
    "SourceCodePlugin",
    "CallStackPlugin",
    "Registers",
    "Locals",
    "Disassembly",
   #ifdef PRODBG_MAC
    "LLDBPlugin",
   #endif
   };

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   int realMain(int argc, const char** argv)
   {
    (void)argc;
    (void)argv;

    for (uint32_t i = 0; i < sizeof_array(s_plugins); ++i)
    {
        if (!PluginHandler_addPlugin(OBJECT_DIR, s_plugins[i]))
            return 0;
    }

    uint32_t width = 1280;
    uint32_t height = 720;
    uint32_t debug = BGFX_DEBUG_TEXT;
    uint32_t reset = BGFX_RESET_VSYNC;

    bgfx::init();
    bgfx::reset(width, height, reset);

    // Enable debug text.
    bgfx::setDebug(debug);

    // Set view 0 clear state.
    bgfx::setViewClear(0
        , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
        , 0x303030ff
        , 1.0f
        , 0
        );

    bgfx::setViewSeq(0, true);

    entry::MouseState mouseState;

    IMGUI_setup((int)width, (int)height);

    while (!entry::processEvents(width, height, debug, reset, &mouseState))
    {
        // Set view 0 default viewport.
        bgfx::setViewRect(0, 0, 0, (uint16_t)width, (uint16_t)height);

        // This dummy draw call is here to make sure that view 0 is cleared
        // if no other draw calls are submitted to view 0.
        bgfx::submit(0);

        IMGUI_preUpdate(&mouseState);

        bool show = true;

        ImGui::Begin("ImGui Test", &show, ImVec2(550,480), true, ImGuiWindowFlags_ShowBorders);

        if (ImGui::Button("Test0r testing!"))
        {
            printf("test\n");
        }

        ImGui::End();

        // Use debug font to print information about this example.
        //bgfx::dbgTextClear();
        //bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/00-helloworld");
        //bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Initialization and debug text.");

        IMGUI_postUpdate();

        // Advance to next frame. Rendering thread will be kicked to
        // process submitted rendering primitives.
        bgfx::frame();
    }

    // Shutdown bgfx.
    bgfx::shutdown();

    return 0; //Application_init(argc, argv);
   }

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   }

   extern "C"
   {

   int _main_(int argc, char** argv)
   {
    return prodbg::realMain(argc, (const char**)argv);
   }

   }

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   #ifdef WIN32

   extern "C" int main(int _argc, char** _argv);

   int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
   {
    char* temp[] = { "foo" };
    main(1, temp);
   }

   #endif

 */

<commit_msg>Added onLoadRun<commit_after>#include "api/plugin_instance.h"
#include "core/core.h"
#include "core/log.h"
#include "core/math.h"
#include "core/plugin_handler.h"
#include "session/session.h"
#include "settings.h"
#include "ui/imgui/imgui.h"
#include "ui/imgui_setup.h"
#include "ui/ui_layout.h"
#include "ui/menu.h"

#include <bgfx.h>
#include <bgfxplatform.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef PRODBG_WIN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

// TODO: Fix me

int Window_buildPluginMenu(PluginData** plugins, int count);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

struct Context
{
    int width;
    int height;
    float mouseX;
    float mouseY;
    int mouseLmb;
    Session* session;   // one session right now
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static Context s_context;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static const char* s_plugins[] =
{
    "sourcecode_plugin",
    "disassembly_plugin",
    "locals_plugin",
    "callstack_plugin",
    "registers_plugin",
#ifdef PRODBG_MAC
    "lldb_plugin",
#endif
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void setLayout(UILayout* layout)
{
    Context* context = &s_context;
	IMGUI_preUpdate(context->mouseX, context->mouseY, context->mouseLmb);
	Session_setLayout(context->session, layout, context->width, context->height);
	IMGUI_postUpdate();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void loadLayout()
{
	UILayout layout;

    if (UILayout_loadLayout(&layout, "data/current_layout.yaml"))
	{
		setLayout(&layout);
		return;
	}

    if (UILayout_loadLayout(&layout, "data/default_layout.yaml"))
		setLayout(&layout);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_create(void* window, int width, int height)
{
    Context* context = &s_context;
    //Rect settingsRect;

    context->session = Session_create();

    //Settings_getWindowRect(&settingsRect);
    //width = settingsRect.width;
    //height = settingsRect.height;

    (void)window;

    for (uint32_t i = 0; i < sizeof_array(s_plugins); ++i)
    {
        if (!PluginHandler_addPlugin(OBJECT_DIR, s_plugins[i]))
            return;
    }

#if BX_PLATFORM_OSX
    bgfx::osxSetNSWindow(window);
#elif BX_PLATFORM_WINDOWS
    bgfx::winSetHwnd((HWND)window);
#else
    //bgfx::winSetHwnd(0);
#endif

    bgfx::init();
    bgfx::reset(width, height);
    bgfx::setViewSeq(0, true);

    context->width = width;
    context->height = height;

    IMGUI_setup(width, height);

	loadLayout();

}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_update()
{
    Context* context = &s_context;

    bgfx::setViewRect(0, 0, 0, (uint16_t)context->width, (uint16_t)context->height);
    bgfx::setViewClear(0, BGFX_CLEAR_COLOR_BIT | BGFX_CLEAR_DEPTH_BIT, 0x101010ff, 1.0f, 0);
    bgfx::submit(0);

    IMGUI_preUpdate(context->mouseX, context->mouseY, context->mouseLmb);

    // TODO: Support multiple sessions

    Session_update(context->session);

    /*

       bool show = true;

       ImGui::Begin("ImGui Test", &show, ImVec2(550, 480), true, ImGuiWindowFlags_ShowBorders);

       if (ImGui::Button("Test0r testing!"))
       {
        printf("test\n");
       }

       ImGui::End();
     */

    IMGUI_postUpdate();

    bgfx::frame();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setWindowSize(int width, int height)
{
    Context* context = &s_context;

    context->width = width;
    context->height = height;

    bgfx::reset(width, height);
    IMGUI_setup(width, height);
    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_applicationLaunched()
{
#ifdef PRODBG_MAC
	int pluginCount = 0;
	printf("building menu!\n");
	Window_buildPluginMenu(PluginHandler_getPlugins(&pluginCount), pluginCount);
#endif
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_destroy()
{
	UILayout layout;
    Context* context = &s_context;

    Session_getLayout(context->session, &layout, context->width, context->height);
    UILayout_saveLayout(&layout, "data/current_layout.yaml");

    Settings_save();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_timedUpdate()
{
    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static void onLoadRunExec()
{
    Context* context = &s_context;
	PluginData* pluginData = PluginHandler_findPlugin(0, "lldb_plugin", "LLDB Mac", true);

	if (!pluginData)
	{
		log_error("Unable to find LLDB Mac backend\n");
		return;
	}

	// Hacky hack

	Session_startLocal(context->session, (PDBackendPlugin*)pluginData->plugin, OBJECT_DIR "/crashing_native");
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Events

void ProDBG_event(int eventId)
{
    Context* context = &s_context;

    int count;

    PluginData** pluginsData = PluginHandler_getPlugins(&count);

	// TODO: This code really needs to be made more robust.

    if (eventId >= PRODBG_MENU_PLUGIN_START && eventId < PRODBG_MENU_PLUGIN_START + 9)
	{
		ViewPluginInstance* instance = PluginInstance_createViewPlugin(pluginsData[eventId - PRODBG_MENU_PLUGIN_START]);
		Session_addViewPlugin(context->session, instance);
		return;
	}

	switch (eventId)
	{
		case PRODBG_MENU_FILE_OPEN_AND_RUN_EXE :
		{
			onLoadRunExec();
			break;
		}
	}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_scroll(float deltaX, float deltaY, int flags)
{
    (void)deltaX;
    (void)deltaY;
    (void)flags;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setMousePos(float x, float y)
{
    Context* context = &s_context;

    context->mouseX = x;
    context->mouseY = y;

    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void ProDBG_setMouseState(int button, int state)
{
    Context* context = &s_context;
    (void)button;

    context->mouseLmb = state;

    ProDBG_update();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/*

   namespace prodbg
   {

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   static const char* s_plugins[] =
   {
    "SourceCodePlugin",
    "CallStackPlugin",
    "Registers",
    "Locals",
    "Disassembly",
   #ifdef PRODBG_MAC
    "LLDBPlugin",
   #endif
   };

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   int realMain(int argc, const char** argv)
   {
    (void)argc;
    (void)argv;

    for (uint32_t i = 0; i < sizeof_array(s_plugins); ++i)
    {
        if (!PluginHandler_addPlugin(OBJECT_DIR, s_plugins[i]))
            return 0;
    }

    uint32_t width = 1280;
    uint32_t height = 720;
    uint32_t debug = BGFX_DEBUG_TEXT;
    uint32_t reset = BGFX_RESET_VSYNC;

    bgfx::init();
    bgfx::reset(width, height, reset);

    // Enable debug text.
    bgfx::setDebug(debug);

    // Set view 0 clear state.
    bgfx::setViewClear(0
        , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
        , 0x303030ff
        , 1.0f
        , 0
        );

    bgfx::setViewSeq(0, true);

    entry::MouseState mouseState;

    IMGUI_setup((int)width, (int)height);

    while (!entry::processEvents(width, height, debug, reset, &mouseState))
    {
        // Set view 0 default viewport.
        bgfx::setViewRect(0, 0, 0, (uint16_t)width, (uint16_t)height);

        // This dummy draw call is here to make sure that view 0 is cleared
        // if no other draw calls are submitted to view 0.
        bgfx::submit(0);

        IMGUI_preUpdate(&mouseState);

        bool show = true;

        ImGui::Begin("ImGui Test", &show, ImVec2(550,480), true, ImGuiWindowFlags_ShowBorders);

        if (ImGui::Button("Test0r testing!"))
        {
            printf("test\n");
        }

        ImGui::End();

        // Use debug font to print information about this example.
        //bgfx::dbgTextClear();
        //bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/00-helloworld");
        //bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Initialization and debug text.");

        IMGUI_postUpdate();

        // Advance to next frame. Rendering thread will be kicked to
        // process submitted rendering primitives.
        bgfx::frame();
    }

    // Shutdown bgfx.
    bgfx::shutdown();

    return 0; //Application_init(argc, argv);
   }

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   }

   extern "C"
   {

   int _main_(int argc, char** argv)
   {
    return prodbg::realMain(argc, (const char**)argv);
   }

   }

   ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   #ifdef WIN32

   extern "C" int main(int _argc, char** _argv);

   int CALLBACK WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
   {
    char* temp[] = { "foo" };
    main(1, temp);
   }

   #endif

 */

<|endoftext|>


<commit_before>#include <memory>

#include <realm/util/network.hpp>
#include <realm/util/event_loop.hpp>

using namespace realm;
using namespace realm::util;

namespace {

class SocketImpl;
class DeadlineTimerImpl;

class EventLoopImpl: public EventLoop {
public:
    EventLoopImpl():
        m_io_service() // Throws
    {
    }

    ~EventLoopImpl() noexcept override final
    {
    }

    std::unique_ptr<Socket> make_socket() override final;
    std::unique_ptr<DeadlineTimer> make_timer() override final;

    void post(PostCompletionHandler handler) override final
    {
        m_io_service.post(std::move(handler)); // Throws
    }

    void run() override final
    {
        m_io_service.run(); // Throws
    }

    void stop() noexcept override final
    {
        m_io_service.stop();
    }

    void reset() noexcept override final
    {
        m_io_service.reset();
    }

    network::io_service& get_service() noexcept
    {
        return m_io_service;
    }

private:
    network::io_service m_io_service;
};

class SocketImpl: public Socket {
public:
    SocketImpl(EventLoopImpl& event_loop):
        m_event_loop(event_loop),
        m_socket(event_loop.get_service()), // Throws
        m_input_stream(m_socket), // Throws
        m_shared_error_code(std::make_shared<std::error_code>()) // Throws
    {
    }

    ~SocketImpl() noexcept override final
    {
    }

    void async_connect(std::string host, port_type port, SocketSecurity security,
                       ConnectCompletionHandler handler) override final
    {
        if (security != SocketSecurity::None)
            throw std::runtime_error("Unsupported socket security");
        if (m_socket.is_open())
            throw std::runtime_error("Already connected");
        // Discard buffered input from when the connection was last established
        m_input_stream.reset();
        std::stringstream out;
        out.imbue(std::locale::classic());
        out << port;
        network::resolver::query query{host, out.str()};
        network::resolver resolver{m_socket.service()};
        // FIXME: Avoid synchronous DNS lookup
        std::error_code ec;
        resolver.resolve(query, m_endpoints, ec);
        if (ec) {
            // Direct callbacks are not allowed, so we need to postpone it using
            // post(). Also, we need to make use of an error code object whose
            // ownership is shared betweeen this socket object and the post
            // handler, because connect completion handlers must be cancaleable
            // up until the point int time where it starts to execute.
            std::shared_ptr<std::error_code> sec = m_shared_error_code;
            REALM_ASSERT(!*sec);
            *sec = ec;
            // FIXME: Use [handler=std::move(handler), sec=std::move(sec)] in
            // C++14 to avoid a potentially expensive copy of user specified
            // completion handler into the lambda
            auto handler_2 = [handler, sec] {
                std::error_code ec = *sec;
                *sec = std::error_code();
                handler(ec); // Throws
            };
            m_socket.service().post(std::move(handler_2)); // Throws
            return;
        }
        // Try each endpoint in turn
        try_next_endpoint(m_endpoints.begin(), std::move(handler)); // Throws
        m_connect_in_progress = true;
    }

    void async_read(char* data, size_t size, ReadCompletionHandler handler) override final
    {
        if (m_connect_in_progress || !m_socket.is_open())
            throw std::runtime_error("Not connected");
        m_input_stream.async_read(data, size, std::move(handler));
    }

    void async_read_until(char* data, size_t size, char delim,
                          ReadCompletionHandler handler) override final
    {
        if (m_connect_in_progress || !m_socket.is_open())
            throw std::runtime_error("Not connected");
        m_input_stream.async_read_until(data, size, delim, std::move(handler));
    }

    void async_write(const char* data, size_t size, WriteCompletionHandler handler) override final
    {
        if (m_connect_in_progress || !m_socket.is_open())
            throw std::runtime_error("Not connected");
        m_socket.async_write(data, size, std::move(handler));
    }

    void close() noexcept override final
    {
        m_socket.close();
    }

    void cancel() noexcept override final
    {
        *m_shared_error_code = error::operation_aborted;
        if (m_connect_in_progress) {
            m_socket.close();
            m_connect_in_progress = false;
        }
        else {
            m_socket.cancel();
        }
    }

    EventLoop& get_event_loop() noexcept override final
    {
        return m_event_loop;
    }

private:
    EventLoopImpl& m_event_loop;
    network::socket m_socket;
    network::buffered_input_stream m_input_stream;
    network::endpoint::list m_endpoints;
    bool m_connect_in_progress = false;
    std::shared_ptr<std::error_code> m_shared_error_code;

    void try_next_endpoint(network::endpoint::list::iterator i, ConnectCompletionHandler handler)
    {
        REALM_ASSERT(i != m_endpoints.end());
        // FIXME: Use [this, handler=std::move(handler)] in C++14 to avoid a
        // potentially expensive copy of user specified completion handler into
        // the lambda
        auto handler_2 = [=](std::error_code ec) {
            // Note: If `ec` is `operation_aborted`, the the socket object may
            // already have been destroyed.
            if (ec != error::operation_aborted) {
                REALM_ASSERT(m_connect_in_progress);
                if (ec) {
                    m_socket.close();
                    auto i_2 = i + 1;
                    if (i_2 < m_endpoints.end()) {
                        try_next_endpoint(i_2, std::move(handler)); // Throws
                        return;
                    }
                }
                m_connect_in_progress = false;
            }
            handler(ec); // Throws
        };
        m_socket.async_connect(*i, std::move(handler_2)); // Throws
    }
};

class DeadlineTimerImpl: public DeadlineTimer {
public:
    DeadlineTimerImpl(EventLoopImpl& event_loop):
        m_event_loop(event_loop),
        m_timer(event_loop.get_service()) // Throws
    {
    }

    void async_wait(Duration delay, WaitCompletionHandler handler) override final
    {
        m_timer.async_wait(delay, std::move(handler));
    }

    void cancel() noexcept override final
    {
        m_timer.cancel();
    }

    EventLoop& get_event_loop() noexcept override final
    {
        return m_event_loop;
    }

private:
    EventLoopImpl& m_event_loop;
    network::deadline_timer m_timer;
};

inline std::unique_ptr<Socket> EventLoopImpl::make_socket()
{
    return std::unique_ptr<Socket>(new SocketImpl(*this));
}

inline std::unique_ptr<DeadlineTimer> EventLoopImpl::make_timer()
{
    return std::unique_ptr<DeadlineTimer>(new DeadlineTimerImpl(*this));
}

class ImplementationImpl: public EventLoop::Implementation {
public:
    std::string name() const
    {
        return "posix";
    }
    std::unique_ptr<EventLoop> make_event_loop()
    {
        return std::unique_ptr<EventLoop>(new EventLoopImpl()); // Throws
    }
};

ImplementationImpl g_implementation;

} // unnamed namespace

namespace realm {
namespace _impl {

EventLoop::Implementation& get_posix_event_loop_impl()
{
    return g_implementation;
}

} // namespace _impl
} // namespace realm
<commit_msg>Use C++14 moving lambda captures<commit_after>#include <memory>

#include <realm/util/network.hpp>
#include <realm/util/event_loop.hpp>

using namespace realm;
using namespace realm::util;

namespace {

class SocketImpl;
class DeadlineTimerImpl;

class EventLoopImpl: public EventLoop {
public:
    EventLoopImpl():
        m_io_service() // Throws
    {
    }

    ~EventLoopImpl() noexcept override final
    {
    }

    std::unique_ptr<Socket> make_socket() override final;
    std::unique_ptr<DeadlineTimer> make_timer() override final;

    void post(PostCompletionHandler handler) override final
    {
        m_io_service.post(std::move(handler)); // Throws
    }

    void run() override final
    {
        m_io_service.run(); // Throws
    }

    void stop() noexcept override final
    {
        m_io_service.stop();
    }

    void reset() noexcept override final
    {
        m_io_service.reset();
    }

    network::io_service& get_service() noexcept
    {
        return m_io_service;
    }

private:
    network::io_service m_io_service;
};

class SocketImpl: public Socket {
public:
    SocketImpl(EventLoopImpl& event_loop):
        m_event_loop(event_loop),
        m_socket(event_loop.get_service()), // Throws
        m_input_stream(m_socket), // Throws
        m_shared_error_code(std::make_shared<std::error_code>()) // Throws
    {
    }

    ~SocketImpl() noexcept override final
    {
    }

    void async_connect(std::string host, port_type port, SocketSecurity security,
                       ConnectCompletionHandler handler) override final
    {
        if (security != SocketSecurity::None)
            throw std::runtime_error("Unsupported socket security");
        if (m_socket.is_open())
            throw std::runtime_error("Already connected");
        // Discard buffered input from when the connection was last established
        m_input_stream.reset();
        std::stringstream out;
        out.imbue(std::locale::classic());
        out << port;
        network::resolver::query query{host, out.str()};
        network::resolver resolver{m_socket.service()};
        // FIXME: Avoid synchronous DNS lookup
        std::error_code ec;
        resolver.resolve(query, m_endpoints, ec);
        if (ec) {
            // Direct callbacks are not allowed, so we need to postpone it using
            // post(). Also, we need to make use of an error code object whose
            // ownership is shared betweeen this socket object and the post
            // handler, because connect completion handlers must be cancaleable
            // up until the point int time where it starts to execute.
            std::shared_ptr<std::error_code> sec = m_shared_error_code;
            REALM_ASSERT(!*sec);
            *sec = ec;
            auto handler_2 = [handler=std::move(handler), sec=std::move(sec)] {
                std::error_code ec = *sec;
                *sec = std::error_code();
                handler(ec); // Throws
            };
            m_socket.service().post(std::move(handler_2)); // Throws
            return;
        }
        // Try each endpoint in turn
        try_next_endpoint(m_endpoints.begin(), std::move(handler)); // Throws
        m_connect_in_progress = true;
    }

    void async_read(char* data, size_t size, ReadCompletionHandler handler) override final
    {
        if (m_connect_in_progress || !m_socket.is_open())
            throw std::runtime_error("Not connected");
        m_input_stream.async_read(data, size, std::move(handler));
    }

    void async_read_until(char* data, size_t size, char delim,
                          ReadCompletionHandler handler) override final
    {
        if (m_connect_in_progress || !m_socket.is_open())
            throw std::runtime_error("Not connected");
        m_input_stream.async_read_until(data, size, delim, std::move(handler));
    }

    void async_write(const char* data, size_t size, WriteCompletionHandler handler) override final
    {
        if (m_connect_in_progress || !m_socket.is_open())
            throw std::runtime_error("Not connected");
        m_socket.async_write(data, size, std::move(handler));
    }

    void close() noexcept override final
    {
        m_socket.close();
    }

    void cancel() noexcept override final
    {
        *m_shared_error_code = error::operation_aborted;
        if (m_connect_in_progress) {
            m_socket.close();
            m_connect_in_progress = false;
        }
        else {
            m_socket.cancel();
        }
    }

    EventLoop& get_event_loop() noexcept override final
    {
        return m_event_loop;
    }

private:
    EventLoopImpl& m_event_loop;
    network::socket m_socket;
    network::buffered_input_stream m_input_stream;
    network::endpoint::list m_endpoints;
    bool m_connect_in_progress = false;
    std::shared_ptr<std::error_code> m_shared_error_code;

    void try_next_endpoint(network::endpoint::list::iterator i, ConnectCompletionHandler handler)
    {
        REALM_ASSERT(i != m_endpoints.end());
        auto handler_2 = [this, handler=std::move(handler), i](std::error_code ec) {
            // Note: If `ec` is `operation_aborted`, the the socket object may
            // already have been destroyed.
            if (ec != error::operation_aborted) {
                REALM_ASSERT(m_connect_in_progress);
                if (ec) {
                    m_socket.close();
                    auto i_2 = i + 1;
                    if (i_2 < m_endpoints.end()) {
                        try_next_endpoint(i_2, std::move(handler)); // Throws
                        return;
                    }
                }
                m_connect_in_progress = false;
            }
            handler(ec); // Throws
        };
        m_socket.async_connect(*i, std::move(handler_2)); // Throws
    }
};

class DeadlineTimerImpl: public DeadlineTimer {
public:
    DeadlineTimerImpl(EventLoopImpl& event_loop):
        m_event_loop(event_loop),
        m_timer(event_loop.get_service()) // Throws
    {
    }

    void async_wait(Duration delay, WaitCompletionHandler handler) override final
    {
        m_timer.async_wait(delay, std::move(handler));
    }

    void cancel() noexcept override final
    {
        m_timer.cancel();
    }

    EventLoop& get_event_loop() noexcept override final
    {
        return m_event_loop;
    }

private:
    EventLoopImpl& m_event_loop;
    network::deadline_timer m_timer;
};

inline std::unique_ptr<Socket> EventLoopImpl::make_socket()
{
    return std::unique_ptr<Socket>(new SocketImpl(*this));
}

inline std::unique_ptr<DeadlineTimer> EventLoopImpl::make_timer()
{
    return std::unique_ptr<DeadlineTimer>(new DeadlineTimerImpl(*this));
}

class ImplementationImpl: public EventLoop::Implementation {
public:
    std::string name() const
    {
        return "posix";
    }
    std::unique_ptr<EventLoop> make_event_loop()
    {
        return std::unique_ptr<EventLoop>(new EventLoopImpl()); // Throws
    }
};

ImplementationImpl g_implementation;

} // unnamed namespace

namespace realm {
namespace _impl {

EventLoop::Implementation& get_posix_event_loop_impl()
{
    return g_implementation;
}

} // namespace _impl
} // namespace realm
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library 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 Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef _OGL_ATTRIBUTE_INL_
#define _OGL_ATTRIBUTE_INL_

#include <sofa/component/visualmodel/OglAttribute.h>
#include <sofa/component/topology/PointSetTopologyChange.h>
#include <sofa/component/topology/TriangleSetTopologyChange.h>
#include <sofa/component/topology/QuadSetTopologyChange.h>
#include <sofa/component/topology/TetrahedronSetTopologyChange.h>
#include <sofa/component/topology/HexahedronSetTopologyChange.h>
#include <sofa/core/ObjectFactory.h>

namespace sofa
{

namespace component
{

namespace visualmodel
{

using namespace sofa::core::componentmodel::topology;
using namespace sofa::component::topology;

template < int size, unsigned int type, class DataTypes>
OglAttribute< size, type, DataTypes>::OglAttribute() :
    OglShaderElement()
    , _abo ( -1 )
    , usage( GL_STATIC_DRAW)
    ,value( initData(&value, "value", "internal Data"))
{
    _topology = NULL;
}

template < int size, unsigned int type, class DataTypes>
OglAttribute< size, type, DataTypes>::~OglAttribute()
{
    glDeleteBuffers(1, &_abo);
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::init()
{
    OglShaderElement::init();
    getContext()->get( _topology);

    if ( ( int ) _abo == -1 ) glGenBuffers ( 1, &_abo );
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::initVisual ()
{
    const ResizableExtVector<DataTypes>& data = value.getValue();
    unsigned int totalSize = data.size() *sizeof ( data[0] );
    std::cout << "Size : " << totalSize << std::endl;
    glBindBuffer ( GL_ARRAY_BUFFER, _abo );
    glBufferData ( GL_ARRAY_BUFFER,
            totalSize,
            NULL,
            usage );
    // Fill the buffer
    glBufferSubData ( GL_ARRAY_BUFFER,
            0,
            totalSize,
            data.getData() );
    _index = shader->getAttribute ( 0, id.getValue().c_str() );

    enable();
    glBindBuffer(GL_ARRAY_BUFFER,0);

}

template < int size, unsigned int type, class DataTypes>
bool OglAttribute< size, type, DataTypes>::updateABO()
{
    GLvoid* attrib_bo = NULL;
    glBindBuffer(GL_ARRAY_BUFFER, _abo);

    attrib_bo = (GLvoid*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);

    if(attrib_bo == NULL)
    {
        std::cerr << "OglAttribute : Unknown error when updating attribute indices buffer "<< std::endl;
        return false;
    }
    const ResizableExtVector<DataTypes>& val = value.getValue();
    memcpy(attrib_bo, &(val[0]), val.size()*sizeof(val[0]));
    glUnmapBuffer(GL_ARRAY_BUFFER);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    return true;
}

template < int size, unsigned int type, class DataTypes>
ResizableExtVector<DataTypes>* OglAttribute< size, type, DataTypes>::beginEdit()
{
    return value.beginEdit();
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::endEdit()
{
    value.endEdit();
}

template < int size, unsigned int type, class DataTypes>
const ResizableExtVector<DataTypes>& OglAttribute< size, type, DataTypes>::getValue() const
{
    return value.getValue();
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::setValue ( const ResizableExtVector<DataTypes>& value )
{
    ResizableExtVector<DataTypes>& val = * ( this->value.beginEdit() );
    val = value;
    this->value.endEdit();
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::enable()
{
    glBindBuffer(GL_ARRAY_BUFFER, _abo);
    glEnableVertexAttribArray ( _index );
    glVertexAttribPointer ( _index, size, type, GL_FALSE, 0, ( char* ) NULL + 0 );
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::disable()
{
    glDisableVertexAttribArray ( _index );
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::fwdDraw(Pass)
{
    enable();
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::bwdDraw(Pass)
{
    disable();
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::reinit()
{
    init();
    initVisual();
}

// Only resizing and renumbering is done. 'value' has to be set by external components.
template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::handleTopologyChange()
{
    if( _topology)
    {
        std::list<const TopologyChange *>::const_iterator itBegin=_topology->firstChange();
        std::list<const TopologyChange *>::const_iterator itEnd=_topology->lastChange();

        while( itBegin != itEnd )
        {
            core::componentmodel::topology::TopologyChangeType changeType = (*itBegin)->getChangeType();

            switch( changeType )
            {
            case core::componentmodel::topology::ENDING_EVENT:
            {
                //sout << "INFO_print : Vis - ENDING_EVENT" << sendl;
                updateVisual();
                break;
            }

            case core::componentmodel::topology::TRIANGLESADDED:
            {
                //sout << "INFO_print : Vis - TRIANGLESADDED" << sendl;
                break;
            }

            case core::componentmodel::topology::QUADSADDED:
            {
                //sout << "INFO_print : Vis - QUADSADDED" << sendl;
                break;
            }

            case core::componentmodel::topology::TRIANGLESREMOVED:
            {
                //sout << "INFO_print : Vis - TRIANGLESREMOVED" << sendl;
                break;
            }

            case core::componentmodel::topology::QUADSREMOVED:
            {
                //sout << "INFO_print : Vis - QUADSREMOVED" << sendl;
                break;
            }

            case core::componentmodel::topology::POINTSADDED:
            {
                //sout << "INFO_print : Vis - POINTSADDED" << sendl;

                unsigned int nbPoints = ( static_cast< const PointsAdded * >( *itBegin ) )->getNbAddedVertices();
                ResizableExtVector<DataTypes>& data = *value.beginEdit();
                data.resize( data.size() + nbPoints);
                value.endEdit();
                break;
            }

            // Case "POINTSREMOVED" added to propagate the treatment to the Visual Model

            case core::componentmodel::topology::POINTSREMOVED:
            {
                //sout << "INFO_print : Vis - POINTSREMOVED" << sendl;

                const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRemoved * >( *itBegin ) )->getArray();
                ResizableExtVector<DataTypes>& data = *value.beginEdit();
                unsigned int last = data.size();

                for ( unsigned int i = 0; i < tab.size(); ++i)
                {
                    last--;
                    data[tab[i]] = data[last];
                }
                data.resize( last);
                value.endEdit();

                break;
            }

            // Case "POINTSRENUMBERING" added to propagate the treatment to the Visual Model

            case core::componentmodel::topology::POINTSRENUMBERING:
            {
                //sout << "INFO_print : Vis - POINTSRENUMBERING" << sendl;

                const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRenumbering * >( *itBegin ) )->getinv_IndexArray();
                ResizableExtVector<DataTypes>& data = *value.beginEdit();
                vector<DataTypes> tmp;
                for ( unsigned int i = 0; i < tab.size(); ++i)
                {
                    tmp.push_back( data[tab[i]]);
                }
                for ( unsigned int i = 0; i < tab.size(); ++i)
                {
                    data[i] = tmp[i];
                }
                value.endEdit();

                break;
            }

            default:
                // Ignore events that are not Triangle  related.
                break;
            }; // switch( changeType )

            ++itBegin;
        } // while( changeIt != last; )
    }
}

}

}

}

#endif
<commit_msg>r4579/sofa-dev : FIX : forgot one line ...<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library 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 Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef _OGL_ATTRIBUTE_INL_
#define _OGL_ATTRIBUTE_INL_

#include <sofa/component/visualmodel/OglAttribute.h>
#include <sofa/component/topology/PointSetTopologyChange.h>
#include <sofa/component/topology/TriangleSetTopologyChange.h>
#include <sofa/component/topology/QuadSetTopologyChange.h>
#include <sofa/component/topology/TetrahedronSetTopologyChange.h>
#include <sofa/component/topology/HexahedronSetTopologyChange.h>
#include <sofa/core/ObjectFactory.h>

namespace sofa
{

namespace component
{

namespace visualmodel
{

using namespace sofa::core::componentmodel::topology;
using namespace sofa::component::topology;

template < int size, unsigned int type, class DataTypes>
OglAttribute< size, type, DataTypes>::OglAttribute() :
    OglShaderElement()
    , _abo ( -1 )
    , usage( GL_STATIC_DRAW)
    ,value( initData(&value, "value", "internal Data"))
{
    _topology = NULL;
}

template < int size, unsigned int type, class DataTypes>
OglAttribute< size, type, DataTypes>::~OglAttribute()
{
    glDeleteBuffers(1, &_abo);
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::init()
{
    OglShaderElement::init();
    getContext()->get( _topology);

    if ( ( int ) _abo == -1 ) glGenBuffers ( 1, &_abo );
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::initVisual ()
{
    const ResizableExtVector<DataTypes>& data = value.getValue();
    unsigned int totalSize = data.size() *sizeof ( data[0] );
    std::cout << "Size : " << totalSize << std::endl;
    glBindBuffer ( GL_ARRAY_BUFFER, _abo );
    glBufferData ( GL_ARRAY_BUFFER,
            totalSize,
            NULL,
            usage );
    // Fill the buffer
    glBufferSubData ( GL_ARRAY_BUFFER,
            0,
            totalSize,
            data.getData() );
    _index = shader->getAttribute ( 0, id.getValue().c_str() );

    enable();
    glBindBuffer(GL_ARRAY_BUFFER,0);

}

template < int size, unsigned int type, class DataTypes>
bool OglAttribute< size, type, DataTypes>::updateABO()
{
    GLvoid* attrib_bo = NULL;
    glBindBuffer(GL_ARRAY_BUFFER, _abo);

    attrib_bo = (GLvoid*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);

    if(attrib_bo == NULL)
    {
        std::cerr << "OglAttribute : Unknown error when updating attribute indices buffer "<< std::endl;
        return false;
    }
    const ResizableExtVector<DataTypes>& val = value.getValue();
    memcpy(attrib_bo, &(val[0]), val.size()*sizeof(val[0]));
    glUnmapBuffer(GL_ARRAY_BUFFER);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    return true;
}

template < int size, unsigned int type, class DataTypes>
ResizableExtVector<DataTypes>* OglAttribute< size, type, DataTypes>::beginEdit()
{
    return value.beginEdit();
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::endEdit()
{
    value.endEdit();
}

template < int size, unsigned int type, class DataTypes>
const ResizableExtVector<DataTypes>& OglAttribute< size, type, DataTypes>::getValue() const
{
    return value.getValue();
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::setValue ( const ResizableExtVector<DataTypes>& value )
{
    ResizableExtVector<DataTypes>& val = * ( this->value.beginEdit() );
    val = value;
    this->value.endEdit();
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::enable()
{
    glBindBuffer(GL_ARRAY_BUFFER, _abo);
    glEnableVertexAttribArray ( _index );
    glVertexAttribPointer ( _index, size, type, GL_FALSE, 0, ( char* ) NULL + 0 );
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::disable()
{
    glDisableVertexAttribArray ( _index );
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::fwdDraw(Pass)
{
    enable();
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::bwdDraw(Pass)
{
    disable();
}

template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::reinit()
{
    init();
    initVisual();
}

// Only resizing and renumbering is done. 'value' has to be set by external components.
template < int size, unsigned int type, class DataTypes>
void OglAttribute< size, type, DataTypes>::handleTopologyChange()
{
    if( _topology)
    {
        std::list<const TopologyChange *>::const_iterator itBegin=_topology->firstChange();
        std::list<const TopologyChange *>::const_iterator itEnd=_topology->lastChange();

        while( itBegin != itEnd )
        {
            core::componentmodel::topology::TopologyChangeType changeType = (*itBegin)->getChangeType();

            switch( changeType )
            {
            case core::componentmodel::topology::ENDING_EVENT:
            {
                //sout << "INFO_print : Vis - ENDING_EVENT" << sendl;
                updateVisual();
                break;
            }

            case core::componentmodel::topology::TRIANGLESADDED:
            {
                //sout << "INFO_print : Vis - TRIANGLESADDED" << sendl;
                break;
            }

            case core::componentmodel::topology::QUADSADDED:
            {
                //sout << "INFO_print : Vis - QUADSADDED" << sendl;
                break;
            }

            case core::componentmodel::topology::TRIANGLESREMOVED:
            {
                //sout << "INFO_print : Vis - TRIANGLESREMOVED" << sendl;
                break;
            }

            case core::componentmodel::topology::QUADSREMOVED:
            {
                //sout << "INFO_print : Vis - QUADSREMOVED" << sendl;
                break;
            }

            case core::componentmodel::topology::POINTSADDED:
            {
                //sout << "INFO_print : Vis - POINTSADDED" << sendl;

                unsigned int nbPoints = ( static_cast< const PointsAdded * >( *itBegin ) )->getNbAddedVertices();
                ResizableExtVector<DataTypes>& data = *value.beginEdit();
                data.resize( data.size() + nbPoints);
                value.endEdit();
                break;
            }

            // Case "POINTSREMOVED" added to propagate the treatment to the Visual Model

            case core::componentmodel::topology::POINTSREMOVED:
            {
                //sout << "INFO_print : Vis - POINTSREMOVED" << sendl;

                const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRemoved * >( *itBegin ) )->getArray();
                ResizableExtVector<DataTypes>& data = *value.beginEdit();
                unsigned int last = data.size();

                for ( unsigned int i = 0; i < tab.size(); ++i)
                {
                    last--;
                    data[tab[i]] = data[last];
                }
                data.resize( last);
                value.endEdit();

                break;
            }

            // Case "POINTSRENUMBERING" added to propagate the treatment to the Visual Model

            case core::componentmodel::topology::POINTSRENUMBERING:
            {
                //sout << "INFO_print : Vis - POINTSRENUMBERING" << sendl;

                const sofa::helper::vector<unsigned int> tab = ( static_cast< const sofa::component::topology::PointsRenumbering * >( *itBegin ) )->getinv_IndexArray();
                ResizableExtVector<DataTypes>& data = *value.beginEdit();
                vector<DataTypes> tmp;
                for ( unsigned int i = 0; i < tab.size(); ++i)
                {
                    tmp.push_back( data[tab[i]]);
                }
                for ( unsigned int i = 0; i < tab.size(); ++i)
                {
                    data[i] = tmp[i];
                }
                value.endEdit();

                break;
            }

            default:
                // Ignore events that are not Triangle  related.
                break;
            }; // switch( changeType )

            ++itBegin;
        } // while( changeIt != last; )
    }
}

}

}

}

#endif
<|endoftext|>