<commit_before>#include <GL/glew.h>
#include "EditorWindow.hpp"

#include "Util/EditorSettings.hpp"
#include <Engine/Util/Log.hpp>

#include "GUI/ImageButton.hpp"
#include "GUI/ImageTextButton.hpp"
#include <Engine/Resources.hpp>
#include <File.png.hpp>
#include <Options.png.hpp>
#include <Play.png.hpp>
#include <NewHymn.png.hpp>
#include <OpenHymn.png.hpp>
#include <ABeeZee.ttf.hpp>
#include <Engine/Hymn.hpp>

EditorWindow::EditorWindow() : Container(nullptr) {
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

    // Enable debug context and set message callback.
    if (EditorSettings::GetInstance().GetBool("Debug Context"))
        glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);

    window = glfwCreateWindow(640, 480, "Hymn to Beauty", nullptr, nullptr);
    if (!window) {
        glfwTerminate();
        /// @todo Print error to log.
    }

    glfwMakeContextCurrent(window);

    gameWindow = nullptr;
    childWindow = nullptr;
    input = new InputHandler(window);
}

EditorWindow::~EditorWindow() {
    delete fileButton;
    delete optionsButton;
    delete playButton;
    delete menuBar;

    delete newHymnButton;
    delete openHymnButton;
    delete fileMenu;

    Resources().FreeTexture2D(fileTexture);
    Resources().FreeTexture2D(optionsTexture);
    Resources().FreeTexture2D(playTexture);

    Resources().FreeTexture2D(newHymnTexture);
    Resources().FreeTexture2D(openHymnTexture);

    delete input;

    Resources().FreeFont(font);

    glfwDestroyWindow(window);
}

void EditorWindow::Init() {
    int width, height;
    glfwGetWindowSize(window, &width, &height);

    font = Resources().CreateFontEmbedded(ABEEZEE_TTF, ABEEZEE_TTF_LENGTH, 24.f);

    // Menu bar.
    menuBar = new GUI::HorizontalLayout(this);
    menuBar->SetSize(glm::vec2(static_cast<float>(width), 64.f));
    AddWidget(menuBar);

    fileTexture = Resources().CreateTexture2D(FILE_PNG, FILE_PNG_LENGTH);
    fileButton = new GUI::ImageButton(menuBar, fileTexture);
    fileButton->SetClickedCallback(std::bind(&OpenFileMenu, this));
    menuBar->AddWidget(fileButton);

    optionsTexture = Resources().CreateTexture2D(OPTIONS_PNG, OPTIONS_PNG_LENGTH);
    optionsButton = new GUI::ImageButton(menuBar, optionsTexture);
    optionsButton->SetClickedCallback(std::bind(&OpenProjectOptions, this));
    menuBar->AddWidget(optionsButton);

    playTexture = Resources().CreateTexture2D(PLAY_PNG, PLAY_PNG_LENGTH);
    playButton = new GUI::ImageButton(menuBar, playTexture);
    playButton->SetClickedCallback(std::bind(&Play, this));
    menuBar->AddWidget(playButton);

    // File menu.
    fileMenu = new GUI::VerticalLayout(this);
    fileMenu->SetSize(glm::vec2(256.f, 2.f * 64.f));
    fileMenu->SetPosition(glm::vec2(0.f, 64.f));
    fileMenu->SetVisible(false);
    AddWidget(fileMenu);

    newHymnTexture = Resources().CreateTexture2D(NEWHYMN_PNG, NEWHYMN_PNG_LENGTH);
    newHymnButton = new GUI::ImageTextButton(fileMenu, newHymnTexture, font, "New Hymn");
    newHymnButton->SetSize(glm::vec2(256.f, 64.f));
    newHymnButton->SetClickedCallback(std::bind(&NewHymn, this));
    fileMenu->AddWidget(newHymnButton);

    openHymnTexture = Resources().CreateTexture2D(OPENHYMN_PNG, OPENHYMN_PNG_LENGTH);
    openHymnButton = new GUI::ImageTextButton(fileMenu, openHymnTexture, font, "Open Hymn");
    openHymnButton->SetSize(glm::vec2(256.f, 64.f));
    openHymnButton->SetClickedCallback(std::bind(&OpenHymn, this));
    fileMenu->AddWidget(openHymnButton);

    glEnable(GL_DEPTH_TEST);
}

bool EditorWindow::ShouldClose() const {
    return (glfwWindowShouldClose(window) != 0);
}

void EditorWindow::Update() {
    // Handle running game.
    if (gameWindow != nullptr) {
        gameWindow->Update();
        if (gameWindow->ShouldClose()) {
            delete gameWindow;
            gameWindow = nullptr;
        }
    } else if (childWindow != nullptr) {
        input->Update();
        input->SetActive();
        childWindow->Update();
    } else if (glfwGetKey(window, GLFW_KEY_F5) == GLFW_PRESS) {
        Play();
    } else {
        input->Update();
        input->SetActive();
        UpdateWidgets();
    }
}

void EditorWindow::Render() {
    int width, height;
    glfwGetWindowSize(window, &width, &height);

    Render(glm::vec2(static_cast<float>(width), static_cast<float>(height)));
}

void EditorWindow::Render(const glm::vec2& screenSize) {
    if (gameWindow != nullptr) {
        gameWindow->Render();
    } else {
        glfwMakeContextCurrent(window);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        RenderWidgets(screenSize);

        if (childWindow != nullptr)
            childWindow->Render(screenSize);

        glfwSwapBuffers(window);
    }
}

glm::vec2 EditorWindow::Size() const {
    int width, height;
    glfwGetWindowSize(window, &width, &height);

    return glm::vec2(static_cast<float>(width), static_cast<float>(height));
}

void EditorWindow::OpenFileMenu() {
    fileMenu->SetVisible(!fileMenu->Visible());
}

void EditorWindow::OpenProjectOptions() {
    ///@todo Project options
    Log() << "Click test!\n";
}

void EditorWindow::Play() {
    gameWindow = new GameWindow();
}

void EditorWindow::NewHymn() {
    childWindow = new GUI::SelectHymnWindow(this);
    childWindow->SetPosition(glm::vec2(0.f, 0.f));
    childWindow->SetSize(Size());
    childWindow->SetClosedCallback(std::bind(&NewHymnClosed, this));
}

void EditorWindow::NewHymnClosed() {
    // Create new hymn
    Hymn().Clear();
    /// @todo Set path.

    delete childWindow;
    childWindow = nullptr;
}

void EditorWindow::OpenHymn() {
    childWindow = new GUI::SelectHymnWindow(this);
    childWindow->SetPosition(glm::vec2(0.f, 0.f));
    childWindow->SetSize(Size());
    childWindow->SetClosedCallback(std::bind(&OpenHymnClosed, this));
}

void EditorWindow::OpenHymnClosed() {
    /// @todo Open hymn.

    delete childWindow;
    childWindow = nullptr;
}
<commit_msg>Set the path when creating a new hymn.<commit_after>#include <GL/glew.h>
#include "EditorWindow.hpp"

#include "Util/EditorSettings.hpp"
#include <Engine/Util/Log.hpp>

#include "GUI/ImageButton.hpp"
#include "GUI/ImageTextButton.hpp"
#include <Engine/Resources.hpp>
#include <File.png.hpp>
#include <Options.png.hpp>
#include <Play.png.hpp>
#include <NewHymn.png.hpp>
#include <OpenHymn.png.hpp>
#include <ABeeZee.ttf.hpp>
#include <Engine/Hymn.hpp>

EditorWindow::EditorWindow() : Container(nullptr) {
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

    // Enable debug context and set message callback.
    if (EditorSettings::GetInstance().GetBool("Debug Context"))
        glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);

    window = glfwCreateWindow(640, 480, "Hymn to Beauty", nullptr, nullptr);
    if (!window) {
        glfwTerminate();
        /// @todo Print error to log.
    }

    glfwMakeContextCurrent(window);

    gameWindow = nullptr;
    childWindow = nullptr;
    input = new InputHandler(window);
}

EditorWindow::~EditorWindow() {
    delete fileButton;
    delete optionsButton;
    delete playButton;
    delete menuBar;

    delete newHymnButton;
    delete openHymnButton;
    delete fileMenu;

    Resources().FreeTexture2D(fileTexture);
    Resources().FreeTexture2D(optionsTexture);
    Resources().FreeTexture2D(playTexture);

    Resources().FreeTexture2D(newHymnTexture);
    Resources().FreeTexture2D(openHymnTexture);

    delete input;

    Resources().FreeFont(font);

    glfwDestroyWindow(window);
}

void EditorWindow::Init() {
    int width, height;
    glfwGetWindowSize(window, &width, &height);

    font = Resources().CreateFontEmbedded(ABEEZEE_TTF, ABEEZEE_TTF_LENGTH, 24.f);

    // Menu bar.
    menuBar = new GUI::HorizontalLayout(this);
    menuBar->SetSize(glm::vec2(static_cast<float>(width), 64.f));
    AddWidget(menuBar);

    fileTexture = Resources().CreateTexture2D(FILE_PNG, FILE_PNG_LENGTH);
    fileButton = new GUI::ImageButton(menuBar, fileTexture);
    fileButton->SetClickedCallback(std::bind(&OpenFileMenu, this));
    menuBar->AddWidget(fileButton);

    optionsTexture = Resources().CreateTexture2D(OPTIONS_PNG, OPTIONS_PNG_LENGTH);
    optionsButton = new GUI::ImageButton(menuBar, optionsTexture);
    optionsButton->SetClickedCallback(std::bind(&OpenProjectOptions, this));
    menuBar->AddWidget(optionsButton);

    playTexture = Resources().CreateTexture2D(PLAY_PNG, PLAY_PNG_LENGTH);
    playButton = new GUI::ImageButton(menuBar, playTexture);
    playButton->SetClickedCallback(std::bind(&Play, this));
    menuBar->AddWidget(playButton);

    // File menu.
    fileMenu = new GUI::VerticalLayout(this);
    fileMenu->SetSize(glm::vec2(256.f, 2.f * 64.f));
    fileMenu->SetPosition(glm::vec2(0.f, 64.f));
    fileMenu->SetVisible(false);
    AddWidget(fileMenu);

    newHymnTexture = Resources().CreateTexture2D(NEWHYMN_PNG, NEWHYMN_PNG_LENGTH);
    newHymnButton = new GUI::ImageTextButton(fileMenu, newHymnTexture, font, "New Hymn");
    newHymnButton->SetSize(glm::vec2(256.f, 64.f));
    newHymnButton->SetClickedCallback(std::bind(&NewHymn, this));
    fileMenu->AddWidget(newHymnButton);

    openHymnTexture = Resources().CreateTexture2D(OPENHYMN_PNG, OPENHYMN_PNG_LENGTH);
    openHymnButton = new GUI::ImageTextButton(fileMenu, openHymnTexture, font, "Open Hymn");
    openHymnButton->SetSize(glm::vec2(256.f, 64.f));
    openHymnButton->SetClickedCallback(std::bind(&OpenHymn, this));
    fileMenu->AddWidget(openHymnButton);

    glEnable(GL_DEPTH_TEST);
}

bool EditorWindow::ShouldClose() const {
    return (glfwWindowShouldClose(window) != 0);
}

void EditorWindow::Update() {
    // Handle running game.
    if (gameWindow != nullptr) {
        gameWindow->Update();
        if (gameWindow->ShouldClose()) {
            delete gameWindow;
            gameWindow = nullptr;
        }
    } else if (childWindow != nullptr) {
        input->Update();
        input->SetActive();
        childWindow->Update();
    } else if (glfwGetKey(window, GLFW_KEY_F5) == GLFW_PRESS) {
        Play();
    } else {
        input->Update();
        input->SetActive();
        UpdateWidgets();
    }
}

void EditorWindow::Render() {
    int width, height;
    glfwGetWindowSize(window, &width, &height);

    Render(glm::vec2(static_cast<float>(width), static_cast<float>(height)));
}

void EditorWindow::Render(const glm::vec2& screenSize) {
    if (gameWindow != nullptr) {
        gameWindow->Render();
    } else {
        glfwMakeContextCurrent(window);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        RenderWidgets(screenSize);

        if (childWindow != nullptr)
            childWindow->Render(screenSize);

        glfwSwapBuffers(window);
    }
}

glm::vec2 EditorWindow::Size() const {
    int width, height;
    glfwGetWindowSize(window, &width, &height);

    return glm::vec2(static_cast<float>(width), static_cast<float>(height));
}

void EditorWindow::OpenFileMenu() {
    fileMenu->SetVisible(!fileMenu->Visible());
}

void EditorWindow::OpenProjectOptions() {
    ///@todo Project options
    Log() << "Click test!\n";
}

void EditorWindow::Play() {
    gameWindow = new GameWindow();
}

void EditorWindow::NewHymn() {
    childWindow = new GUI::SelectHymnWindow(this);
    childWindow->SetPosition(glm::vec2(0.f, 0.f));
    childWindow->SetSize(Size());
    childWindow->SetClosedCallback(std::bind(&NewHymnClosed, this));
}

void EditorWindow::NewHymnClosed() {
    // Create new hymn
    Hymn().Clear();
    Hymn().SetPath(childWindow->GetHymn());

    delete childWindow;
    childWindow = nullptr;
}

void EditorWindow::OpenHymn() {
    childWindow = new GUI::SelectHymnWindow(this);
    childWindow->SetPosition(glm::vec2(0.f, 0.f));
    childWindow->SetSize(Size());
    childWindow->SetClosedCallback(std::bind(&OpenHymnClosed, this));
}

void EditorWindow::OpenHymnClosed() {
    /// @todo Open hymn.

    delete childWindow;
    childWindow = nullptr;
}
<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:2; c-basic-offset:2; indent-tabs-mode:t -*-
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include <string>

#include "LogType.h"
#include "Logger.h"

#include <iostream>
#include "Clock.h"

#include "config.h"

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

// per-process lock.  lame, but this way I protect LogType too!
Mutex logger_lock;

Logger::Logger(string fn, LogType *type)
{
  logger_lock.Lock();
  {
		filename = "log/";
		if (g_conf.log_name) {
			filename += g_conf.log_name;
			::mkdir( filename.c_str(), 0755 );   // make sure dir exists
			filename += "/";
		}
		filename += fn;
		//cout << "log " << filename << endl;
		interval = g_conf.log_interval;

		start = g_clock.now();  // time 0!
		last_logged = 0;
		wrote_header = -1;
		open = false;
		this->type = type;
		wrote_header_last = 0;

		version = 0;
  }
  logger_lock.Unlock();
  flush(false);
}

Logger::~Logger()
{
  flush(true);
  out.close();
}

long Logger::inc(const char *key, long v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_inc(key);
  flush();
  vals[i] += v;
  long r = vals[i];
  logger_lock.Unlock();
  return r;
}

double Logger::finc(const char *key, double v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_inc(key);
  flush();
  fvals[i] += v;
  double r = fvals[i];
  logger_lock.Unlock();
  return r;
}

long Logger::set(const char *key, long v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_set(key);
  flush();
  long r = vals[i] = v;
  logger_lock.Unlock();
  return r;
}

double Logger::fset(const char *key, double v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_set(key);
  flush();
  double r = fvals[i] = v;
  logger_lock.Unlock();
  return r;
}

long Logger::get(const char* key)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  long r = 0;
  if (i >= 0 && (int)vals.size() > i)
		r = vals[i];
  logger_lock.Unlock();
  return r;
}

void Logger::flush(bool force)
{
  if (!g_conf.log) return;
  logger_lock.Lock();

  if (version != type->version) {
		while (type->keys.size() > vals.size())
			vals.push_back(0);
		while (type->keys.size() > fvals.size())
			fvals.push_back(0);
		version = type->version;
  }

  if (!open) {
		out.open(filename.c_str(), ofstream::out);
		open = true;
		//cout << "opening log file " << filename << endl;
  }

  utime_t fromstart = g_clock.now();
  if (fromstart < start) {
		cerr << "logger time jumped backwards from " << start << " to " << fromstart << endl;
		assert(0);
		start = fromstart;
  }
  fromstart -= start;

  while (force ||
				 ((fromstart.sec() > last_logged) &&
					(fromstart.sec() - last_logged >= interval))) {
		last_logged += interval;
		force = false;

		//cout << "logger " << this << " advancing from " << last_logged << " now " << now << endl;

		if (!open) {
			out.open(filename.c_str(), ofstream::out);
			open = true;
			//cout << "opening log file " << filename << endl;
		}

		// header?
		wrote_header_last++;
		if (wrote_header != type->version ||
				wrote_header_last > 10) {
			out << "#" << type->keymap.size();
			for (unsigned i=0; i<type->keys.size(); i++)
				out << "\t" << type->keys[i];
			out << endl;  //out << "\t (" << type->keymap.size() << ")" << endl;
			wrote_header = type->version;
			wrote_header_last = 0;
		}

		// write line to log
		out << last_logged;
		for (unsigned i=0; i<type->keys.size(); i++) {
			if (fvals[i] > 0 && vals[i] == 0)
				out << "\t" << fvals[i];
			else
				out << "\t" << vals[i];
		}
		out << endl;

		// reset the counters
		for (unsigned i=0; i<type->keys.size(); i++) {
			if (type->inc_keys.count(i)) {
				this->vals[i] = 0;
				this->fvals[i] = 0;
			}
		}
  }

  logger_lock.Unlock();
}

<commit_msg>tabbing<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1, as published by the Free Software
 * Foundation.  See file COPYING.
 *
 */

#include <string>

#include "LogType.h"
#include "Logger.h"

#include <iostream>
#include "Clock.h"

#include "config.h"

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

// per-process lock.  lame, but this way I protect LogType too!
Mutex logger_lock;

Logger::Logger(string fn, LogType *type)
{
  logger_lock.Lock();
  {
    filename = "log/";
    if (g_conf.log_name) {
      filename += g_conf.log_name;
      ::mkdir( filename.c_str(), 0755 );   // make sure dir exists
      filename += "/";
    }
    filename += fn;
    //cout << "log " << filename << endl;
    interval = g_conf.log_interval;

    start = g_clock.now();  // time 0!
    last_logged = 0;
    wrote_header = -1;
    open = false;
    this->type = type;
    wrote_header_last = 0;

    version = 0;
  }
  logger_lock.Unlock();
  flush(false);
}

Logger::~Logger()
{
  flush(true);
  out.close();
}

long Logger::inc(const char *key, long v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_inc(key);
  flush();
  vals[i] += v;
  long r = vals[i];
  logger_lock.Unlock();
  return r;
}

double Logger::finc(const char *key, double v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_inc(key);
  flush();
  fvals[i] += v;
  double r = fvals[i];
  logger_lock.Unlock();
  return r;
}

long Logger::set(const char *key, long v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_set(key);
  flush();
  long r = vals[i] = v;
  logger_lock.Unlock();
  return r;
}

double Logger::fset(const char *key, double v)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  if (i < 0) i = type->add_set(key);
  flush();
  double r = fvals[i] = v;
  logger_lock.Unlock();
  return r;
}

long Logger::get(const char* key)
{
  if (!g_conf.log) return 0;
  logger_lock.Lock();
  int i = type->lookup_key(key);
  long r = 0;
  if (i >= 0 && (int)vals.size() > i)
		r = vals[i];
  logger_lock.Unlock();
  return r;
}

void Logger::flush(bool force)
{
  if (!g_conf.log) return;
  logger_lock.Lock();

  if (version != type->version) {
    while (type->keys.size() > vals.size())
      vals.push_back(0);
    while (type->keys.size() > fvals.size())
      fvals.push_back(0);
    version = type->version;
  }

  if (!open) {
    out.open(filename.c_str(), ofstream::out);
    open = true;
    //cout << "opening log file " << filename << endl;
  }

  utime_t fromstart = g_clock.now();
  if (fromstart < start) {
    cerr << "logger time jumped backwards from " << start << " to " << fromstart << endl;
    assert(0);
    start = fromstart;
  }
  fromstart -= start;

  while (force ||
	 ((fromstart.sec() > last_logged) &&
	  (fromstart.sec() - last_logged >= interval))) {
    last_logged += interval;
    force = false;

    //cout << "logger " << this << " advancing from " << last_logged << " now " << now << endl;

    if (!open) {
      out.open(filename.c_str(), ofstream::out);
      open = true;
      //cout << "opening log file " << filename << endl;
    }

    // header?
    wrote_header_last++;
    if (wrote_header != type->version ||
	wrote_header_last > 10) {
      out << "#" << type->keymap.size();
      for (unsigned i=0; i<type->keys.size(); i++)
	out << "\t" << type->keys[i];
      out << endl;  //out << "\t (" << type->keymap.size() << ")" << endl;
      wrote_header = type->version;
      wrote_header_last = 0;
    }

    // write line to log
    out << last_logged;
    for (unsigned i=0; i<type->keys.size(); i++) {
      if (fvals[i] > 0 && vals[i] == 0)
	out << "\t" << fvals[i];
      else
	out << "\t" << vals[i];
    }
    out << endl;

    // reset the counters
    for (unsigned i=0; i<type->keys.size(); i++) {
      if (type->inc_keys.count(i)) {
	this->vals[i] = 0;
	this->fvals[i] = 0;
      }
    }
  }

  logger_lock.Unlock();
}

<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the LICENSE
 * file in the root directory of this source tree.
 */
#include "mcrouter/lib/network/ThriftTransport.h"

#include <folly/fibers/FiberManager.h>
#include <folly/io/async/AsyncSSLSocket.h>
#include <folly/io/async/AsyncSocket.h>
#include <folly/io/async/EventBase.h>
#include <thrift/lib/cpp/async/TAsyncSocket.h>
#include <thrift/lib/cpp2/async/RequestChannel.h>

#include "mcrouter/lib/fbi/cpp/LogFailure.h"
#include "mcrouter/lib/network/AsyncTlsToPlaintextSocket.h"
#include "mcrouter/lib/network/ConnectionOptions.h"
#include "mcrouter/lib/network/McFizzClient.h"
#include "mcrouter/lib/network/SecurityOptions.h"
#include "mcrouter/lib/network/SocketUtil.h"

using apache::thrift::async::TAsyncSocket;

namespace facebook {
namespace memcache {

ThriftTransportBase::ThriftTransportBase(
    folly::EventBase& eventBase,
    ConnectionOptions options)
    : eventBase_(eventBase), connectionOptions_(std::move(options)) {}

void ThriftTransportBase::closeNow() {
  resetClient();
}

void ThriftTransportBase::setConnectionStatusCallbacks(
    ConnectionStatusCallbacks callbacks) {
  connectionCallbacks_ = std::move(callbacks);
}

void ThriftTransportBase::setRequestStatusCallbacks(
    RequestStatusCallbacks callbacks) {
  requestCallbacks_ = std::move(callbacks);
}

void ThriftTransportBase::setThrottle(size_t maxInflight, size_t maxPending) {
  maxInflight_ = maxInflight;
  maxPending_ = maxPending;
}

Transport::RequestQueueStats ThriftTransportBase::getRequestQueueStats() const {
  return RequestQueueStats{0, 0};
}

void ThriftTransportBase::updateTimeoutsIfShorter(
    std::chrono::milliseconds /* connectTimeout */,
    std::chrono::milliseconds /* writeTimeout */) {}

const folly::AsyncTransportWrapper* ThriftTransportBase::getTransport() const {
  return nullptr;
}

double ThriftTransportBase::getRetransmitsPerKb() {
  return 0.0;
}

apache::thrift::async::TAsyncTransport::UniquePtr
ThriftTransportBase::getConnectingSocket() {
  return folly::fibers::runInMainContext(
      [this]() -> apache::thrift::async::TAsyncTransport::UniquePtr {
        auto expectedSocket =
            createTAsyncSocket(eventBase_, connectionOptions_);
        if (expectedSocket.hasError()) {
          LOG_FAILURE(
              "ThriftTransport",
              failure::Category::kBadEnvironment,
              "{}",
              expectedSocket.error().what());
          return {};
        }
        auto socket = std::move(expectedSocket).value();

        auto sockAddressExpected = getSocketAddress(connectionOptions_);
        if (sockAddressExpected.hasError()) {
          const auto& ex = sockAddressExpected.error();
          LOG_FAILURE(
              "ThriftTransport",
              failure::Category::kBadEnvironment,
              "{}",
              ex.what());
          return {};
        }
        folly::SocketAddress address = std::move(sockAddressExpected).value();
        auto socketOptions = createSocketOptions(address, connectionOptions_);
        connectionState_ = ConnectionState::Connecting;

        const auto securityMech =
            connectionOptions_.accessPoint->getSecurityMech();
        if (securityMech == SecurityMech::TLS_TO_PLAINTEXT) {
          socket->setSendTimeout(connectionOptions_.writeTimeout.count());
          socket->getUnderlyingTransport<AsyncTlsToPlaintextSocket>()->connect(
              this,
              address,
              connectionOptions_.connectTimeout,
              std::move(socketOptions));
        } else {
          DCHECK(securityMech == SecurityMech::NONE);
          socket->setSendTimeout(connectionOptions_.writeTimeout.count());
          socket->getUnderlyingTransport<folly::AsyncSocket>()->connect(
              this,
              address,
              connectionOptions_.connectTimeout.count(),
              socketOptions);
        }
        return socket;
      });
}

apache::thrift::RocketClientChannel::Ptr ThriftTransportBase::createChannel() {
  auto socket = getConnectingSocket();
  if (!socket) {
    return nullptr;
  }
  auto channel =
      apache::thrift::RocketClientChannel::newChannel(std::move(socket));
  channel->setProtocolId(apache::thrift::protocol::T_COMPACT_PROTOCOL);
  channel->setCloseCallback(this);
  return channel;
}

apache::thrift::RpcOptions ThriftTransportBase::getRpcOptions(
    std::chrono::milliseconds timeout) const {
  apache::thrift::RpcOptions rpcOptions;
  rpcOptions.setTimeout(timeout);
  rpcOptions.setClientOnlyTimeouts(true);
  return rpcOptions;
}

void ThriftTransportBase::connectSuccess() noexcept {
  assert(connectionState_ == ConnectionState::Connecting);
  connectionState_ = ConnectionState::Up;
  VLOG(5) << "[ThriftTransport] Connection successfully established!";
}

void ThriftTransportBase::connectErr(
    const folly::AsyncSocketException& ex) noexcept {
  assert(connectionState_ == ConnectionState::Connecting);

  connectionState_ = ConnectionState::Error;
  connectionTimedOut_ =
      (ex.getType() == folly::AsyncSocketException::TIMED_OUT);

  VLOG(2) << "[ThriftTransport] Error connecting: " << ex.what();
}

void ThriftTransportBase::channelClosed() {
  VLOG(3) << "[ThriftTransport] Channel closed.";
  resetClient();
}

} // namespace memcache
} // namespace facebook
<commit_msg>Support building mcrouter without thrift client support<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the LICENSE
 * file in the root directory of this source tree.
 */
#include "mcrouter/lib/network/ThriftTransport.h"

#include <folly/fibers/FiberManager.h>
#include <folly/io/async/AsyncSSLSocket.h>
#include <folly/io/async/AsyncSocket.h>
#include <folly/io/async/EventBase.h>
#include <thrift/lib/cpp/async/TAsyncSocket.h>
#include <thrift/lib/cpp2/async/RequestChannel.h>

#include "mcrouter/lib/fbi/cpp/LogFailure.h"
#include "mcrouter/lib/network/AsyncTlsToPlaintextSocket.h"
#include "mcrouter/lib/network/ConnectionOptions.h"
#include "mcrouter/lib/network/McFizzClient.h"
#include "mcrouter/lib/network/SecurityOptions.h"
#include "mcrouter/lib/network/SocketUtil.h"

using apache::thrift::async::TAsyncSocket;

namespace facebook {
namespace memcache {

ThriftTransportBase::ThriftTransportBase(
    folly::EventBase& eventBase,
    ConnectionOptions options)
    : eventBase_(eventBase), connectionOptions_(std::move(options)) {}

void ThriftTransportBase::closeNow() {
  resetClient();
}

void ThriftTransportBase::setConnectionStatusCallbacks(
    ConnectionStatusCallbacks callbacks) {
  connectionCallbacks_ = std::move(callbacks);
}

void ThriftTransportBase::setRequestStatusCallbacks(
    RequestStatusCallbacks callbacks) {
  requestCallbacks_ = std::move(callbacks);
}

void ThriftTransportBase::setThrottle(size_t maxInflight, size_t maxPending) {
  maxInflight_ = maxInflight;
  maxPending_ = maxPending;
}

Transport::RequestQueueStats ThriftTransportBase::getRequestQueueStats() const {
  return RequestQueueStats{0, 0};
}

void ThriftTransportBase::updateTimeoutsIfShorter(
    std::chrono::milliseconds /* connectTimeout */,
    std::chrono::milliseconds /* writeTimeout */) {}

const folly::AsyncTransportWrapper* ThriftTransportBase::getTransport() const {
  return nullptr;
}

double ThriftTransportBase::getRetransmitsPerKb() {
  return 0.0;
}

apache::thrift::async::TAsyncTransport::UniquePtr
ThriftTransportBase::getConnectingSocket() {
  return folly::fibers::runInMainContext(
      [this]() -> apache::thrift::async::TAsyncTransport::UniquePtr {
        auto expectedSocket =
            createTAsyncSocket(eventBase_, connectionOptions_);
        if (expectedSocket.hasError()) {
          LOG_FAILURE(
              "ThriftTransport",
              failure::Category::kBadEnvironment,
              "{}",
              expectedSocket.error().what());
          return {};
        }
        auto socket = std::move(expectedSocket).value();

        auto sockAddressExpected = getSocketAddress(connectionOptions_);
        if (sockAddressExpected.hasError()) {
          const auto& ex = sockAddressExpected.error();
          LOG_FAILURE(
              "ThriftTransport",
              failure::Category::kBadEnvironment,
              "{}",
              ex.what());
          return {};
        }
        folly::SocketAddress address = std::move(sockAddressExpected).value();
        auto socketOptions = createSocketOptions(address, connectionOptions_);
        connectionState_ = ConnectionState::Connecting;

        const auto securityMech =
            connectionOptions_.accessPoint->getSecurityMech();
        if (securityMech == SecurityMech::TLS_TO_PLAINTEXT) {
          socket->setSendTimeout(connectionOptions_.writeTimeout.count());
          socket->getUnderlyingTransport<AsyncTlsToPlaintextSocket>()->connect(
              this,
              address,
              connectionOptions_.connectTimeout,
              std::move(socketOptions));
        } else {
          DCHECK(securityMech == SecurityMech::NONE);
          socket->setSendTimeout(connectionOptions_.writeTimeout.count());
          socket->getUnderlyingTransport<folly::AsyncSocket>()->connect(
              this,
              address,
              connectionOptions_.connectTimeout.count(),
              socketOptions);
        }
        return socket;
      });
}

apache::thrift::RocketClientChannel::Ptr ThriftTransportBase::createChannel() {
  // HHVM supports Debian 8 (EOL 2020-06-30), which includes OpenSSL 1.0.1;
  // Rocket/RSocket require ALPN, which requiers 1.0.2.
  //
  // For these platforms, build MCRouter client without a functional
  // Thrift transport, but continue to permit use as an async Memcache client
  // library for Hack
#ifndef MCROUTER_NOOP_THRIFT_CLIENT
  auto socket = getConnectingSocket();
  if (!socket) {
    return nullptr;
  }
  auto channel =
      apache::thrift::RocketClientChannel::newChannel(std::move(socket));
  channel->setProtocolId(apache::thrift::protocol::T_COMPACT_PROTOCOL);
  channel->setCloseCallback(this);
  return channel;
#else
  return nullptr;
#endif
}

apache::thrift::RpcOptions ThriftTransportBase::getRpcOptions(
    std::chrono::milliseconds timeout) const {
  apache::thrift::RpcOptions rpcOptions;
  rpcOptions.setTimeout(timeout);
  rpcOptions.setClientOnlyTimeouts(true);
  return rpcOptions;
}

void ThriftTransportBase::connectSuccess() noexcept {
  assert(connectionState_ == ConnectionState::Connecting);
  connectionState_ = ConnectionState::Up;
  VLOG(5) << "[ThriftTransport] Connection successfully established!";
}

void ThriftTransportBase::connectErr(
    const folly::AsyncSocketException& ex) noexcept {
  assert(connectionState_ == ConnectionState::Connecting);

  connectionState_ = ConnectionState::Error;
  connectionTimedOut_ =
      (ex.getType() == folly::AsyncSocketException::TIMED_OUT);

  VLOG(2) << "[ThriftTransport] Error connecting: " << ex.what();
}

void ThriftTransportBase::channelClosed() {
  VLOG(3) << "[ThriftTransport] Channel closed.";
  resetClient();
}

} // namespace memcache
} // namespace facebook
<|endoftext|>


<commit_before>
<commit_msg>Delete mistake<commit_after><|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2013 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "libmesh/node.h"
#include "libmesh/elem.h"
#include "libmesh/reference_elem.h"
#include "libmesh/libmesh_singleton.h"
#include "libmesh/threads.h"

// C++ includes
#include <map>
#include <sstream>

//-----------------------------------------------
// anonymous namespace for implementation details
namespace
{
using namespace libMesh;

namespace ElemDataStrings
{
#include "reference_elem.data"
}

typedef Threads::spin_mutex InitMutex;

// Mutex for thread safety.
InitMutex init_mtx;

// map from ElemType to reference element file system object name
typedef std::map<ElemType, const char *> FileMapType;
FileMapType ref_elem_file;
Elem * ref_elem_map[INVALID_ELEM];

class SingletonCache : public libMesh::Singleton
{
public:
  ~SingletonCache()
  {
    for (unsigned int e=0; e<elem_list.size(); e++)
      {
        delete elem_list[e];
        elem_list[e] = NULL;
      }

    elem_list.clear();

    for (unsigned int n=0; n<node_list.size(); n++)
      {
        delete node_list[n];
        node_list[n] = NULL;
      }

    node_list.clear();
  }

  std::vector<Node *> node_list;
  std::vector<Elem *> elem_list;
};

// singleton object, dynamically created and then
// removed at program exit
SingletonCache * singleton_cache = NULL;

Elem * read_ref_elem (const ElemType Type,
                      std::istream & in)
{
  libmesh_assert (singleton_cache != NULL);

  static const unsigned int comm_len = 1024;
  char comm[comm_len];

  std::string foo;
  unsigned int n_elem, n_nodes, elem_type, nn;
  double x, y, z;

  in >> foo;
  in >> n_elem;  /**/ in.getline (comm, comm_len); libmesh_assert_equal_to (n_elem, 1);
  in >> n_nodes; /**/ in.getline (comm, comm_len);
  in >> foo;     /**/ in.getline (comm, comm_len);
  in >> foo;     /**/ in.getline (comm, comm_len);
  in >> foo;     /**/ in.getline (comm, comm_len);
  in >> foo;     /**/ in.getline (comm, comm_len);
  in >> n_elem;  /**/ in.getline (comm, comm_len); libmesh_assert_equal_to (n_elem, 1);

  in >> elem_type;

  libmesh_assert_less (elem_type, INVALID_ELEM);
  libmesh_assert_equal_to (elem_type, static_cast<unsigned int>(Type));
  libmesh_assert_equal_to (n_nodes, Elem::type_to_n_nodes_map[elem_type]);

  // Construct the elem
  Elem * elem = Elem::build(static_cast<ElemType>(elem_type)).release();

  // We are expecing an identity map, so assert it!
  for (unsigned int n=0; n<n_nodes; n++)
    {
      in >> nn;
      libmesh_assert_equal_to (n,nn);
    }

  for (unsigned int n=0; n<n_nodes; n++)
    {
      in >> x >> y >> z;

      Node * node = new Node(x,y,z,n);
      singleton_cache->node_list.push_back(node);

      elem->set_node(n) = node;
    }

  // it is entirely possible we ran out of file or encountered
  // another error.  If so, cleanly abort.
  if (!in)
    {
      delete elem;
      elem = NULL;
      libmesh_error_msg("ERROR while creating element singleton!");
    }

  else
    singleton_cache->elem_list.push_back (elem);

  ref_elem_map[Type] = elem;

  return elem;
}

void init_ref_elem_table()
{
  // ouside mutex - if this pointer is set, we can trust it.
  if (singleton_cache != NULL) return;

  // playing with fire here - lock before touching shared
  // data structures
  InitMutex::scoped_lock lock(init_mtx);

  // inside mutex - pointer may have changed while waiting
  // for the lock to acquire, check it again.
  if (singleton_cache != NULL) return;

  // OK, if we get here we have the lock and we are not
  // initialized.  populate singleton.
  singleton_cache = new SingletonCache;

  // initialize the reference file table
  {
    ref_elem_file.clear();

    // // 1D elements
    ref_elem_file[EDGE2]    = ElemDataStrings::one_edge;
    ref_elem_file[EDGE3]    = ElemDataStrings::one_edge3;
    ref_elem_file[EDGE4]    = ElemDataStrings::one_edge4;

    // 2D elements
    ref_elem_file[TRI3]     = ElemDataStrings::one_tri;
    ref_elem_file[TRI6]     = ElemDataStrings::one_tri6;

    ref_elem_file[QUAD4]    = ElemDataStrings::one_quad;
    ref_elem_file[QUAD8]    = ElemDataStrings::one_quad8;
    ref_elem_file[QUAD9]    = ElemDataStrings::one_quad9;

    // 3D elements
    ref_elem_file[HEX8]     = ElemDataStrings::one_hex;
    ref_elem_file[HEX20]    = ElemDataStrings::one_hex20;
    ref_elem_file[HEX27]    = ElemDataStrings::one_hex27;

    ref_elem_file[TET4]     = ElemDataStrings::one_tet;
    ref_elem_file[TET10]    = ElemDataStrings::one_tet10;

    ref_elem_file[PRISM6]   = ElemDataStrings::one_prism;
    ref_elem_file[PRISM15]  = ElemDataStrings::one_prism15;
    ref_elem_file[PRISM18]  = ElemDataStrings::one_prism18;

    ref_elem_file[PYRAMID5] = ElemDataStrings::one_pyramid;
    ref_elem_file[PYRAMID13] = ElemDataStrings::one_pyramid13;
    ref_elem_file[PYRAMID14] = ElemDataStrings::one_pyramid14;
  }

  // Read'em
  for (FileMapType::const_iterator it=ref_elem_file.begin();
       it != ref_elem_file.end(); ++it)
    {
      std::istringstream stream(it->second);

      read_ref_elem(it->first,
                    stream);
    }
}

// no reason to do this at startup -
// data structures will get initialized *if*
// ReferenceElem::get() is ever called.
// // Class to setup singleton data
// class ReferenceElemSetup : public Singleton::Setup
// {
//   void setup ()
//   {
//     init_ref_elem_table();
//   }
// } reference_elem_setup;

} // anonymous namespace

//----------------------------------------------------------------------------
// external API Implementation
namespace libMesh
{
namespace ReferenceElem
{
const Elem & get (const ElemType Type)
{
  libmesh_assert_less (Type, INVALID_ELEM);

  init_ref_elem_table();

  libmesh_assert (ref_elem_map[Type] != NULL);

  return *ref_elem_map[Type];
}
} // namespace ReferenceElem
} // namespace libMesh
<commit_msg>Ignore overlength string warnings from reference_elem.data<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2013 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "libmesh/node.h"
#include "libmesh/elem.h"
#include "libmesh/reference_elem.h"
#include "libmesh/libmesh_singleton.h"
#include "libmesh/threads.h"

// C++ includes
#include <map>
#include <sstream>

//-----------------------------------------------
// anonymous namespace for implementation details
namespace
{
using namespace libMesh;

namespace ElemDataStrings
{
// GCC 5.2.0 warns about overlength strings in the auto-generated
// reference_elem.data file.
#pragma GCC diagnostic ignored "-Woverlength-strings"
#include "reference_elem.data"
#pragma GCC diagnostic warning "-Woverlength-strings"
}

typedef Threads::spin_mutex InitMutex;

// Mutex for thread safety.
InitMutex init_mtx;

// map from ElemType to reference element file system object name
typedef std::map<ElemType, const char *> FileMapType;
FileMapType ref_elem_file;
Elem * ref_elem_map[INVALID_ELEM];

class SingletonCache : public libMesh::Singleton
{
public:
  ~SingletonCache()
  {
    for (unsigned int e=0; e<elem_list.size(); e++)
      {
        delete elem_list[e];
        elem_list[e] = NULL;
      }

    elem_list.clear();

    for (unsigned int n=0; n<node_list.size(); n++)
      {
        delete node_list[n];
        node_list[n] = NULL;
      }

    node_list.clear();
  }

  std::vector<Node *> node_list;
  std::vector<Elem *> elem_list;
};

// singleton object, dynamically created and then
// removed at program exit
SingletonCache * singleton_cache = NULL;

Elem * read_ref_elem (const ElemType Type,
                      std::istream & in)
{
  libmesh_assert (singleton_cache != NULL);

  static const unsigned int comm_len = 1024;
  char comm[comm_len];

  std::string foo;
  unsigned int n_elem, n_nodes, elem_type, nn;
  double x, y, z;

  in >> foo;
  in >> n_elem;  /**/ in.getline (comm, comm_len); libmesh_assert_equal_to (n_elem, 1);
  in >> n_nodes; /**/ in.getline (comm, comm_len);
  in >> foo;     /**/ in.getline (comm, comm_len);
  in >> foo;     /**/ in.getline (comm, comm_len);
  in >> foo;     /**/ in.getline (comm, comm_len);
  in >> foo;     /**/ in.getline (comm, comm_len);
  in >> n_elem;  /**/ in.getline (comm, comm_len); libmesh_assert_equal_to (n_elem, 1);

  in >> elem_type;

  libmesh_assert_less (elem_type, INVALID_ELEM);
  libmesh_assert_equal_to (elem_type, static_cast<unsigned int>(Type));
  libmesh_assert_equal_to (n_nodes, Elem::type_to_n_nodes_map[elem_type]);

  // Construct the elem
  Elem * elem = Elem::build(static_cast<ElemType>(elem_type)).release();

  // We are expecing an identity map, so assert it!
  for (unsigned int n=0; n<n_nodes; n++)
    {
      in >> nn;
      libmesh_assert_equal_to (n,nn);
    }

  for (unsigned int n=0; n<n_nodes; n++)
    {
      in >> x >> y >> z;

      Node * node = new Node(x,y,z,n);
      singleton_cache->node_list.push_back(node);

      elem->set_node(n) = node;
    }

  // it is entirely possible we ran out of file or encountered
  // another error.  If so, cleanly abort.
  if (!in)
    {
      delete elem;
      elem = NULL;
      libmesh_error_msg("ERROR while creating element singleton!");
    }

  else
    singleton_cache->elem_list.push_back (elem);

  ref_elem_map[Type] = elem;

  return elem;
}

void init_ref_elem_table()
{
  // ouside mutex - if this pointer is set, we can trust it.
  if (singleton_cache != NULL) return;

  // playing with fire here - lock before touching shared
  // data structures
  InitMutex::scoped_lock lock(init_mtx);

  // inside mutex - pointer may have changed while waiting
  // for the lock to acquire, check it again.
  if (singleton_cache != NULL) return;

  // OK, if we get here we have the lock and we are not
  // initialized.  populate singleton.
  singleton_cache = new SingletonCache;

  // initialize the reference file table
  {
    ref_elem_file.clear();

    // // 1D elements
    ref_elem_file[EDGE2]    = ElemDataStrings::one_edge;
    ref_elem_file[EDGE3]    = ElemDataStrings::one_edge3;
    ref_elem_file[EDGE4]    = ElemDataStrings::one_edge4;

    // 2D elements
    ref_elem_file[TRI3]     = ElemDataStrings::one_tri;
    ref_elem_file[TRI6]     = ElemDataStrings::one_tri6;

    ref_elem_file[QUAD4]    = ElemDataStrings::one_quad;
    ref_elem_file[QUAD8]    = ElemDataStrings::one_quad8;
    ref_elem_file[QUAD9]    = ElemDataStrings::one_quad9;

    // 3D elements
    ref_elem_file[HEX8]     = ElemDataStrings::one_hex;
    ref_elem_file[HEX20]    = ElemDataStrings::one_hex20;
    ref_elem_file[HEX27]    = ElemDataStrings::one_hex27;

    ref_elem_file[TET4]     = ElemDataStrings::one_tet;
    ref_elem_file[TET10]    = ElemDataStrings::one_tet10;

    ref_elem_file[PRISM6]   = ElemDataStrings::one_prism;
    ref_elem_file[PRISM15]  = ElemDataStrings::one_prism15;
    ref_elem_file[PRISM18]  = ElemDataStrings::one_prism18;

    ref_elem_file[PYRAMID5] = ElemDataStrings::one_pyramid;
    ref_elem_file[PYRAMID13] = ElemDataStrings::one_pyramid13;
    ref_elem_file[PYRAMID14] = ElemDataStrings::one_pyramid14;
  }

  // Read'em
  for (FileMapType::const_iterator it=ref_elem_file.begin();
       it != ref_elem_file.end(); ++it)
    {
      std::istringstream stream(it->second);

      read_ref_elem(it->first,
                    stream);
    }
}

// no reason to do this at startup -
// data structures will get initialized *if*
// ReferenceElem::get() is ever called.
// // Class to setup singleton data
// class ReferenceElemSetup : public Singleton::Setup
// {
//   void setup ()
//   {
//     init_ref_elem_table();
//   }
// } reference_elem_setup;

} // anonymous namespace

//----------------------------------------------------------------------------
// external API Implementation
namespace libMesh
{
namespace ReferenceElem
{
const Elem & get (const ElemType Type)
{
  libmesh_assert_less (Type, INVALID_ELEM);

  init_ref_elem_table();

  libmesh_assert (ref_elem_map[Type] != NULL);

  return *ref_elem_map[Type];
}
} // namespace ReferenceElem
} // namespace libMesh
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: rsckey.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-20 05:46:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
/****************** I N C L U D E S **************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#ifndef _RSCALL_H
#include <rscall.h>
#endif
#ifndef _RSCTOOLS_HXX
#include <rsctools.hxx>
#endif
#ifndef _RSCHASH_HXX
#include <rschash.hxx>
#endif
#ifndef _RSCKEY_HXX
#include <rsckey.hxx>
#endif

#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
#define _cdecl __cdecl
#endif

/****************** C o d e **********************************************/
/****************** keyword sort function ********************************/
extern "C" {
#if defined( ZTC ) && defined( PM2 )
    int __CLIB KeyCompare( const void * pFirst, const void * pSecond );
#else
#if defined( WNT ) && !defined( WTC ) && !defined (ICC)
    int _cdecl KeyCompare( const void * pFirst, const void * pSecond );
#else
    int KeyCompare( const void * pFirst, const void * pSecond );
#endif
#endif
}

#if defined( WNT ) && !defined( WTC ) && !defined(ICC)
int _cdecl KeyCompare( const void * pFirst, const void * pSecond ){
#else
int KeyCompare( const void * pFirst, const void * pSecond ){
#endif
    if( ((KEY_STRUCT *)pFirst)->nName > ((KEY_STRUCT *)pSecond)->nName )
        return( 1 );
    else if( ((KEY_STRUCT *)pFirst)->nName < ((KEY_STRUCT *)pSecond)->nName )
        return( -1 );
    else
        return( 0 );
}

/*************************************************************************
|*
|*    RscNameTable::RscNameTable()
|*
|*    Beschreibung      RES.DOC
|*    Ersterstellung    MM 28.02.91
|*    Letzte Aenderung  MM 28.02.91
|*
*************************************************************************/
RscNameTable::RscNameTable() {
    bSort    = TRUE;
    nEntries = 0;
    pTable   = NULL;
};

/*************************************************************************
|*
|*    RscNameTable::~RscNameTable()
|*
|*    Beschreibung
|*    Ersterstellung    MM 15.05.91
|*    Letzte Aenderung  MM 15.05.91
|*
*************************************************************************/
RscNameTable::~RscNameTable() {
    if( pTable )
        rtl_freeMemory( pTable );
};

/*************************************************************************
|*
|*    RscNameTable::SetSort()
|*
|*    Beschreibung      RES.DOC
|*    Ersterstellung    MM 28.02.91
|*    Letzte Aenderung  MM 28.02.91
|*
*************************************************************************/
void RscNameTable::SetSort( BOOL bSorted ){
    bSort = bSorted;
    if( bSort && pTable){
        // Schluesselwort Feld sortieren
        qsort( (void *)pTable, nEntries,
               sizeof( KEY_STRUCT ), KeyCompare );
    };
};

/*************************************************************************
|*
|*    RscNameTable::Put()
|*
|*    Beschreibung      RES.DOC
|*    Ersterstellung    MM 28.02.91
|*    Letzte Aenderung  MM 28.02.91
|*
*************************************************************************/
Atom RscNameTable::Put( Atom nName, sal_uInt32 nTyp, long nValue ){
    if( pTable )
        pTable = (KEY_STRUCT *)
                 rtl_reallocateMemory( (void *)pTable,
                 ((nEntries +1) * sizeof( KEY_STRUCT )) );
    else
        pTable = (KEY_STRUCT *)
                 rtl_allocateMemory( ((nEntries +1)
                                 * sizeof( KEY_STRUCT )) );
    pTable[ nEntries ].nName  = nName;
    pTable[ nEntries ].nTyp   = nTyp;
    pTable[ nEntries ].yylval = nValue;
    nEntries++;
    if( bSort )
        SetSort();
    return( nName );
};

Atom RscNameTable::Put( const char * pName, sal_uInt32 nTyp, long nValue )
{
    return( Put( pHS->getID( pName ), nTyp, nValue ) );
};

Atom RscNameTable::Put( Atom nName, sal_uInt32 nTyp )
{
    return( Put( nName, nTyp, (long)nName ) );
};

Atom RscNameTable::Put( const char * pName, sal_uInt32 nTyp )
{
    Atom  nId;

    nId = pHS->getID( pName );
    return( Put( nId, nTyp, (long)nId ) );
};

Atom RscNameTable::Put( Atom nName, sal_uInt32 nTyp, RscTop * pClass )
{
    return( Put( nName, nTyp, (long)pClass ) );
};

Atom RscNameTable::Put( const char * pName, sal_uInt32 nTyp, RscTop * pClass )
{
    return( Put( pHS->getID( pName ), nTyp, (long)pClass ) );
};

/*************************************************************************
|*
|*    RscNameTable::Get()
|*
|*    Beschreibung      RES.DOC
|*    Ersterstellung    MM 28.02.91
|*    Letzte Aenderung  MM 28.02.91
|*
*************************************************************************/
BOOL RscNameTable::Get( Atom nName, KEY_STRUCT * pEle ){
    KEY_STRUCT * pKey = NULL;
    KEY_STRUCT  aSearchName;
    sal_uInt32  i;

    if( bSort ){
        // Suche nach dem Schluesselwort
        aSearchName.nName = nName;
        pKey = (KEY_STRUCT *)bsearch(
#ifdef UNX
                   (const char *) &aSearchName, (char *)pTable,
#else
                   (const void *) &aSearchName, (const void *)pTable,
#endif
                   nEntries, sizeof( KEY_STRUCT ), KeyCompare );
    }
    else{
        i = 0;
        while( i < nEntries && !pKey ){
            if( pTable[ i ].nName == nName )
                pKey = &pTable[ i ];
            i++;
        };
    };

    if( pKey ){ // Schluesselwort gefunden
        *pEle = *pKey;
        return( TRUE );
    };
    return( FALSE );
};

<commit_msg>INTEGRATION: CWS pchfix02 (1.5.20); FILE MERGED 2006/09/01 17:33:21 kaib 1.5.20.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: rsckey.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 15:59:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_rsc.hxx"
/****************** I N C L U D E S **************************************/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

#ifndef _RSCALL_H
#include <rscall.h>
#endif
#ifndef _RSCTOOLS_HXX
#include <rsctools.hxx>
#endif
#ifndef _RSCHASH_HXX
#include <rschash.hxx>
#endif
#ifndef _RSCKEY_HXX
#include <rsckey.hxx>
#endif

#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
#define _cdecl __cdecl
#endif

/****************** C o d e **********************************************/
/****************** keyword sort function ********************************/
extern "C" {
#if defined( ZTC ) && defined( PM2 )
    int __CLIB KeyCompare( const void * pFirst, const void * pSecond );
#else
#if defined( WNT ) && !defined( WTC ) && !defined (ICC)
    int _cdecl KeyCompare( const void * pFirst, const void * pSecond );
#else
    int KeyCompare( const void * pFirst, const void * pSecond );
#endif
#endif
}

#if defined( WNT ) && !defined( WTC ) && !defined(ICC)
int _cdecl KeyCompare( const void * pFirst, const void * pSecond ){
#else
int KeyCompare( const void * pFirst, const void * pSecond ){
#endif
    if( ((KEY_STRUCT *)pFirst)->nName > ((KEY_STRUCT *)pSecond)->nName )
        return( 1 );
    else if( ((KEY_STRUCT *)pFirst)->nName < ((KEY_STRUCT *)pSecond)->nName )
        return( -1 );
    else
        return( 0 );
}

/*************************************************************************
|*
|*    RscNameTable::RscNameTable()
|*
|*    Beschreibung      RES.DOC
|*    Ersterstellung    MM 28.02.91
|*    Letzte Aenderung  MM 28.02.91
|*
*************************************************************************/
RscNameTable::RscNameTable() {
    bSort    = TRUE;
    nEntries = 0;
    pTable   = NULL;
};

/*************************************************************************
|*
|*    RscNameTable::~RscNameTable()
|*
|*    Beschreibung
|*    Ersterstellung    MM 15.05.91
|*    Letzte Aenderung  MM 15.05.91
|*
*************************************************************************/
RscNameTable::~RscNameTable() {
    if( pTable )
        rtl_freeMemory( pTable );
};

/*************************************************************************
|*
|*    RscNameTable::SetSort()
|*
|*    Beschreibung      RES.DOC
|*    Ersterstellung    MM 28.02.91
|*    Letzte Aenderung  MM 28.02.91
|*
*************************************************************************/
void RscNameTable::SetSort( BOOL bSorted ){
    bSort = bSorted;
    if( bSort && pTable){
        // Schluesselwort Feld sortieren
        qsort( (void *)pTable, nEntries,
               sizeof( KEY_STRUCT ), KeyCompare );
    };
};

/*************************************************************************
|*
|*    RscNameTable::Put()
|*
|*    Beschreibung      RES.DOC
|*    Ersterstellung    MM 28.02.91
|*    Letzte Aenderung  MM 28.02.91
|*
*************************************************************************/
Atom RscNameTable::Put( Atom nName, sal_uInt32 nTyp, long nValue ){
    if( pTable )
        pTable = (KEY_STRUCT *)
                 rtl_reallocateMemory( (void *)pTable,
                 ((nEntries +1) * sizeof( KEY_STRUCT )) );
    else
        pTable = (KEY_STRUCT *)
                 rtl_allocateMemory( ((nEntries +1)
                                 * sizeof( KEY_STRUCT )) );
    pTable[ nEntries ].nName  = nName;
    pTable[ nEntries ].nTyp   = nTyp;
    pTable[ nEntries ].yylval = nValue;
    nEntries++;
    if( bSort )
        SetSort();
    return( nName );
};

Atom RscNameTable::Put( const char * pName, sal_uInt32 nTyp, long nValue )
{
    return( Put( pHS->getID( pName ), nTyp, nValue ) );
};

Atom RscNameTable::Put( Atom nName, sal_uInt32 nTyp )
{
    return( Put( nName, nTyp, (long)nName ) );
};

Atom RscNameTable::Put( const char * pName, sal_uInt32 nTyp )
{
    Atom  nId;

    nId = pHS->getID( pName );
    return( Put( nId, nTyp, (long)nId ) );
};

Atom RscNameTable::Put( Atom nName, sal_uInt32 nTyp, RscTop * pClass )
{
    return( Put( nName, nTyp, (long)pClass ) );
};

Atom RscNameTable::Put( const char * pName, sal_uInt32 nTyp, RscTop * pClass )
{
    return( Put( pHS->getID( pName ), nTyp, (long)pClass ) );
};

/*************************************************************************
|*
|*    RscNameTable::Get()
|*
|*    Beschreibung      RES.DOC
|*    Ersterstellung    MM 28.02.91
|*    Letzte Aenderung  MM 28.02.91
|*
*************************************************************************/
BOOL RscNameTable::Get( Atom nName, KEY_STRUCT * pEle ){
    KEY_STRUCT * pKey = NULL;
    KEY_STRUCT  aSearchName;
    sal_uInt32  i;

    if( bSort ){
        // Suche nach dem Schluesselwort
        aSearchName.nName = nName;
        pKey = (KEY_STRUCT *)bsearch(
#ifdef UNX
                   (const char *) &aSearchName, (char *)pTable,
#else
                   (const void *) &aSearchName, (const void *)pTable,
#endif
                   nEntries, sizeof( KEY_STRUCT ), KeyCompare );
    }
    else{
        i = 0;
        while( i < nEntries && !pKey ){
            if( pTable[ i ].nName == nName )
                pKey = &pTable[ i ];
            i++;
        };
    };

    if( pKey ){ // Schluesselwort gefunden
        *pEle = *pKey;
        return( TRUE );
    };
    return( FALSE );
};

<|endoftext|>


<commit_before>/***********************************************************************
	filename: 	CEGUIWindowManager.cpp
	created:	21/2/2004
	author:		Paul D Turner

	purpose:	Implements the WindowManager class
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUIWindowManager.h"
#include "CEGUIWindowFactoryManager.h"
#include "CEGUIWindowFactory.h"
#include "CEGUIWindow.h"
#include "CEGUIExceptions.h"
#include "CEGUIGUILayout_xmlHandler.h"
#include "CEGUIXMLParser.h"
#include <iostream>
#include <sstream>

// Start of CEGUI namespace section
namespace CEGUI
{
/*************************************************************************
	Static Data Definitions
*************************************************************************/
// singleton instance pointer
template<> WindowManager* Singleton<WindowManager>::ms_Singleton	= 0;
// default resource group
String WindowManager::d_defaultResourceGroup;

/*************************************************************************
	Definition of constant data for WindowManager
*************************************************************************/
// Declared in WindowManager
const char	WindowManager::GUILayoutSchemaName[]	= "GUILayout.xsd";
const String WindowManager::GeneratedWindowNameBase("__cewin_uid_");
const String WindowManager::EventNamespace("WindowManager");
const String WindowManager::EventWindowCreated("WindowCreated");
const String WindowManager::EventWindowDestroyed("WindowDestroyed");

/*************************************************************************
    Constructor
*************************************************************************/
WindowManager::WindowManager(void) :
    d_uid_counter(0),
    d_lockCount(0)
{
    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(this));
    Logger::getSingleton().logEvent(
        "CEGUI::WindowManager singleton created " + String(addr_buff));
}

/*************************************************************************
	Destructor
*************************************************************************/
WindowManager::~WindowManager(void)
{
	destroyAllWindows();
    cleanDeadPool();

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(this));
    Logger::getSingleton().logEvent(
        "CEGUI::WindowManager singleton destroyed " + String(addr_buff));
}

/*************************************************************************
	Create a new window of the specified type
*************************************************************************/
Window* WindowManager::createWindow( const String& type, const String& name /*= ""*/, const String& prefix /*= ""*/ )
{
    // only allow creation of Window objects if we are in unlocked state
    if (isLocked())
        throw InvalidRequestException("WindowManager::createWindow - "
                                      "WindowManager is in the locked state.");

    // Make sure that a non-empty name gets passed to the factory
    String finalName(prefix + name);
    // Still empty?
    if (finalName.empty())
    {
        finalName = generateUniqueWindowName();
    }

	if (isWindowPresent(finalName))
	{
		throw AlreadyExistsException("WindowManager::createWindow - A Window object with the name '" + finalName +"' already exists within the system.");
	}

    WindowFactoryManager& wfMgr = WindowFactoryManager::getSingleton();
    WindowFactory* factory = wfMgr.getFactory(type);

    Window* newWindow = factory->createWindow(finalName);
	newWindow->setPrefix(prefix);

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(newWindow));
    Logger::getSingleton().logEvent("Window '" + finalName +"' of type '" +
        type + "' has been created. " + addr_buff, Informative);

    // see if we need to assign a look to this window
    if (wfMgr.isFalagardMappedType(type))
    {
        const WindowFactoryManager::FalagardWindowMapping& fwm = wfMgr.getFalagardMappingForType(type);
        // this was a mapped type, so assign a look to the window so it can finalise
        // its initialisation
        newWindow->d_falagardType = type;
        newWindow->setWindowRenderer(fwm.d_rendererType);
        newWindow->setLookNFeel(fwm.d_lookName);
    }

	d_windowRegistry[finalName] = newWindow;

    // fire event to notify interested parites about the new window.
    WindowEventArgs args(newWindow);
    fireEvent(EventWindowCreated, args);

	return newWindow;
}

/*************************************************************************
	Destroy the given window by pointer
*************************************************************************/
void WindowManager::destroyWindow(Window* window)
{
	if (window)
	{
		// this is done because the name is used for the log after the window is destroyed,
		// if we just did getName() we would get a const ref to the Window's internal name
		// string which is destroyed along with the window so wouldn't exist when the log tried
		// to use it (as I soon discovered).
		String name = window->getName();

		destroyWindow(name);
	}

}

/*************************************************************************
	Destroy the given window by name
*************************************************************************/
void WindowManager::destroyWindow(const String& window)
{
	WindowRegistry::iterator wndpos = d_windowRegistry.find(window);

	if (wndpos != d_windowRegistry.end())
	{
        Window* wnd = wndpos->second;

        // remove entry from the WindowRegistry.
        d_windowRegistry.erase(wndpos);

        // do 'safe' part of cleanup
        wnd->destroy();

        // add window to dead pool
        d_deathrow.push_back(wnd);

        // notify system object of the window destruction
        System::getSingleton().notifyWindowDestroyed(wnd);

        char addr_buff[32];
        sprintf(addr_buff, "(%p)", static_cast<void*>(wnd));
        Logger::getSingleton().logEvent("Window '" + window + "' has been "
            "added to dead pool. " + addr_buff, Informative);

        // fire event to notify interested parites about window destruction.
        // TODO: Perhaps this should fire first, so window is still usable?
        WindowEventArgs args(wnd);
        fireEvent(EventWindowDestroyed, args);
	}

}

/*************************************************************************
	Return a pointer to the named window
*************************************************************************/
Window* WindowManager::getWindow(const String& name) const
{
	WindowRegistry::const_iterator pos = d_windowRegistry.find(name);

	if (pos == d_windowRegistry.end())
	{
		throw UnknownObjectException("WindowManager::getWindow - A Window object with the name '" + name +"' does not exist within the system");
	}

	return pos->second;
}

/*************************************************************************
	Return true if a window with the given name is present
*************************************************************************/
bool WindowManager::isWindowPresent(const String& name) const
{
	return (d_windowRegistry.find(name) != d_windowRegistry.end());
}

/*************************************************************************
	Destroy all Window objects
*************************************************************************/
void WindowManager::destroyAllWindows(void)
{
	String window_name;
	while (!d_windowRegistry.empty())
	{
		window_name = d_windowRegistry.begin()->first;
		destroyWindow(window_name);
	}

}

/*************************************************************************
	Creates a set of windows (a Gui layout) from the information in the
	specified XML file.
*************************************************************************/
Window* WindowManager::loadWindowLayout(const String& filename, const String& name_prefix, const String& resourceGroup, PropertyCallback* callback, void* userdata)
{
	if (filename.empty())
	{
		throw InvalidRequestException("WindowManager::loadWindowLayout - Filename supplied for gui-layout loading must be valid.");
	}

	// log the fact we are about to load a layout
	Logger::getSingleton().logEvent("---- Beginning loading of GUI layout from '" + filename + "' ----", Informative);

    // create handler object
    GUILayout_xmlHandler handler(name_prefix, callback, userdata);

	// do parse (which uses handler to create actual data)
	try
	{
        System::getSingleton().getXMLParser()->parseXMLFile(handler,
            filename, GUILayoutSchemaName, resourceGroup.empty() ? d_defaultResourceGroup : resourceGroup);
	}
	catch(...)
	{
        Logger::getSingleton().logEvent("WindowManager::loadWindowLayout - loading of layout from file '" + filename +"' failed.", Errors);
        throw;
	}

    // log the completion of loading
    Logger::getSingleton().logEvent("---- Successfully completed loading of GUI layout from '" + filename + "' ----", Standard);

	return handler.getLayoutRootWindow();
}

Window* WindowManager::loadWindowLayout( const String& filename, bool generateRandomPrefix )
{
	//We really just use the bool to get rid of ambiguity with the other loadWindowLayout. There is no difference between
	//calling this loadWindowLayout and setting GRP to false, and calling the other one with no argument
	if(generateRandomPrefix)
		return loadWindowLayout(filename,generateUniqueWindowPrefix());

		return loadWindowLayout(filename);
}
bool WindowManager::isDeadPoolEmpty(void) const
{
    return d_deathrow.empty();
}

void WindowManager::cleanDeadPool(void)
{
    WindowVector::reverse_iterator curr = d_deathrow.rbegin();
    for (; curr != d_deathrow.rend(); ++curr)
    {
// in debug mode, log what gets cleaned from the dead pool (insane level)
#if defined(DEBUG) || defined (_DEBUG)
        CEGUI_LOGINSANE("Window '" + (*curr)->getName() + "' about to be finally destroyed from dead pool.");
#endif

        WindowFactory* factory = WindowFactoryManager::getSingleton().getFactory((*curr)->getType());
        factory->destroyWindow(*curr);
    }

    // all done here, so clear all pointers from dead pool
    d_deathrow.clear();
}

void WindowManager::writeWindowLayoutToStream(const Window& window, OutStream& out_stream, bool writeParent) const
{

    XMLSerializer xml(out_stream);
    // output GUILayout start element
    xml.openTag("GUILayout");
    // see if we need the parent attribute to be written
    if ((window.getParent() != 0) && writeParent)
    {
        xml.attribute("Parent", window.getParent()->getName());
    }
    // write windows
    window.writeXMLToStream(xml);
    // write closing GUILayout element
    xml.closeTag();
}

void WindowManager::writeWindowLayoutToStream(const String& window, OutStream& out_stream, bool writeParent) const
{
    writeWindowLayoutToStream(*getWindow(window), out_stream, writeParent);
}

String WindowManager::generateUniqueWindowName()
{
    // build name
    std::ostringstream uidname;
    uidname << GeneratedWindowNameBase.c_str() << d_uid_counter;

    // update counter for next time
    unsigned long old_uid = d_uid_counter;
    ++d_uid_counter;

    // log if we ever wrap-around (which should be pretty unlikely)
    if (d_uid_counter < old_uid)
        Logger::getSingleton().logEvent("UID counter for generated window names has wrapped around - the fun shall now commence!");

    // return generated name as a CEGUI::String.
    return String(uidname.str());
}

CEGUI::String WindowManager::generateUniqueWindowPrefix()
{
	std::ostringstream prefix;
	prefix << d_uid_counter << "_";

	// update counter for next time
	unsigned long old_uid = d_uid_counter;
	++d_uid_counter;

	// log if we ever wrap-around (which should be pretty unlikely)
	if (d_uid_counter < old_uid)
		Logger::getSingleton().logEvent("UID counter for generated window names has wrapped around - the fun shall now commence!");

	//return generated prefix
	return String(prefix.str());

}

void WindowManager::renameWindow(const String& window, const String& new_name)
{
    renameWindow(getWindow(window), new_name);
}

void WindowManager::renameWindow(Window* window, const String& new_name)
{
    if (window)
    {
        WindowRegistry::iterator pos = d_windowRegistry.find(window->getName());

        if (pos != d_windowRegistry.end())
        {
            // erase old window name from registry
            d_windowRegistry.erase(pos);

            try
            {
                // attempt to rename the window
                window->rename(new_name);
            }
            // rename fails if target name already exists
            catch (AlreadyExistsException&)
            {
                // re-add window to registry under it's old name
                d_windowRegistry[window->getName()] = window;
                // rethrow exception.
                throw;
            }

            // add window to registry under new name
            d_windowRegistry[new_name] = window;
        }
    }
}

/*************************************************************************
	Return a WindowManager::WindowIterator object to iterate over the
	currently defined Windows.
*************************************************************************/
WindowManager::WindowIterator WindowManager::getIterator(void) const
{
	return WindowIterator(d_windowRegistry.begin(), d_windowRegistry.end());
}

/*************************************************************************
    Outputs the names of ALL existing windows to log (DEBUG function).
*************************************************************************/
void WindowManager::DEBUG_dumpWindowNames(String zone)
{
    Logger::getSingleton().logEvent("WINDOW NAMES DUMP (" + zone + ")");
    Logger::getSingleton().logEvent("-----------------");
    CEGUI::WindowManager::WindowIterator windowIt = getIterator();
    while (!windowIt.isAtEnd())
    {
        Logger::getSingleton().logEvent("Window : " + windowIt.getCurrentValue()->getName());
        ++windowIt;
    }
    Logger::getSingleton().logEvent("-----------------");
}

//----------------------------------------------------------------------------//
void WindowManager::lock()
{
    ++d_lockCount;
}

//----------------------------------------------------------------------------//
void WindowManager::unlock()
{
    if (d_lockCount > 0)
        --d_lockCount;
}

//----------------------------------------------------------------------------//
bool WindowManager::isLocked() const
{
    return d_lockCount != 0;
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section
<commit_msg>Forgot to include the EventNamespace for global event set support of WindowManager events (not that it's important in this case).<commit_after>/***********************************************************************
	filename: 	CEGUIWindowManager.cpp
	created:	21/2/2004
	author:		Paul D Turner

	purpose:	Implements the WindowManager class
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   Permission is hereby granted, free of charge, to any person obtaining
 *   a copy of this software and associated documentation files (the
 *   "Software"), to deal in the Software without restriction, including
 *   without limitation the rights to use, copy, modify, merge, publish,
 *   distribute, sublicense, and/or sell copies of the Software, and to
 *   permit persons to whom the Software is furnished to do so, subject to
 *   the following conditions:
 *
 *   The above copyright notice and this permission notice shall be
 *   included in all copies or substantial portions of the Software.
 *
 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 *   OTHER DEALINGS IN THE SOFTWARE.
 ***************************************************************************/
#include "CEGUIWindowManager.h"
#include "CEGUIWindowFactoryManager.h"
#include "CEGUIWindowFactory.h"
#include "CEGUIWindow.h"
#include "CEGUIExceptions.h"
#include "CEGUIGUILayout_xmlHandler.h"
#include "CEGUIXMLParser.h"
#include <iostream>
#include <sstream>

// Start of CEGUI namespace section
namespace CEGUI
{
/*************************************************************************
	Static Data Definitions
*************************************************************************/
// singleton instance pointer
template<> WindowManager* Singleton<WindowManager>::ms_Singleton	= 0;
// default resource group
String WindowManager::d_defaultResourceGroup;

/*************************************************************************
	Definition of constant data for WindowManager
*************************************************************************/
// Declared in WindowManager
const char	WindowManager::GUILayoutSchemaName[]	= "GUILayout.xsd";
const String WindowManager::GeneratedWindowNameBase("__cewin_uid_");
const String WindowManager::EventNamespace("WindowManager");
const String WindowManager::EventWindowCreated("WindowCreated");
const String WindowManager::EventWindowDestroyed("WindowDestroyed");

/*************************************************************************
    Constructor
*************************************************************************/
WindowManager::WindowManager(void) :
    d_uid_counter(0),
    d_lockCount(0)
{
    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(this));
    Logger::getSingleton().logEvent(
        "CEGUI::WindowManager singleton created " + String(addr_buff));
}

/*************************************************************************
	Destructor
*************************************************************************/
WindowManager::~WindowManager(void)
{
	destroyAllWindows();
    cleanDeadPool();

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(this));
    Logger::getSingleton().logEvent(
        "CEGUI::WindowManager singleton destroyed " + String(addr_buff));
}

/*************************************************************************
	Create a new window of the specified type
*************************************************************************/
Window* WindowManager::createWindow( const String& type, const String& name /*= ""*/, const String& prefix /*= ""*/ )
{
    // only allow creation of Window objects if we are in unlocked state
    if (isLocked())
        throw InvalidRequestException("WindowManager::createWindow - "
                                      "WindowManager is in the locked state.");

    // Make sure that a non-empty name gets passed to the factory
    String finalName(prefix + name);
    // Still empty?
    if (finalName.empty())
    {
        finalName = generateUniqueWindowName();
    }

	if (isWindowPresent(finalName))
	{
		throw AlreadyExistsException("WindowManager::createWindow - A Window object with the name '" + finalName +"' already exists within the system.");
	}

    WindowFactoryManager& wfMgr = WindowFactoryManager::getSingleton();
    WindowFactory* factory = wfMgr.getFactory(type);

    Window* newWindow = factory->createWindow(finalName);
	newWindow->setPrefix(prefix);

    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(newWindow));
    Logger::getSingleton().logEvent("Window '" + finalName +"' of type '" +
        type + "' has been created. " + addr_buff, Informative);

    // see if we need to assign a look to this window
    if (wfMgr.isFalagardMappedType(type))
    {
        const WindowFactoryManager::FalagardWindowMapping& fwm = wfMgr.getFalagardMappingForType(type);
        // this was a mapped type, so assign a look to the window so it can finalise
        // its initialisation
        newWindow->d_falagardType = type;
        newWindow->setWindowRenderer(fwm.d_rendererType);
        newWindow->setLookNFeel(fwm.d_lookName);
    }

	d_windowRegistry[finalName] = newWindow;

    // fire event to notify interested parites about the new window.
    WindowEventArgs args(newWindow);
    fireEvent(EventWindowCreated, args, EventNamespace);

	return newWindow;
}

/*************************************************************************
	Destroy the given window by pointer
*************************************************************************/
void WindowManager::destroyWindow(Window* window)
{
	if (window)
	{
		// this is done because the name is used for the log after the window is destroyed,
		// if we just did getName() we would get a const ref to the Window's internal name
		// string which is destroyed along with the window so wouldn't exist when the log tried
		// to use it (as I soon discovered).
		String name = window->getName();

		destroyWindow(name);
	}

}

/*************************************************************************
	Destroy the given window by name
*************************************************************************/
void WindowManager::destroyWindow(const String& window)
{
	WindowRegistry::iterator wndpos = d_windowRegistry.find(window);

	if (wndpos != d_windowRegistry.end())
	{
        Window* wnd = wndpos->second;

        // remove entry from the WindowRegistry.
        d_windowRegistry.erase(wndpos);

        // do 'safe' part of cleanup
        wnd->destroy();

        // add window to dead pool
        d_deathrow.push_back(wnd);

        // notify system object of the window destruction
        System::getSingleton().notifyWindowDestroyed(wnd);

        char addr_buff[32];
        sprintf(addr_buff, "(%p)", static_cast<void*>(wnd));
        Logger::getSingleton().logEvent("Window '" + window + "' has been "
            "added to dead pool. " + addr_buff, Informative);

        // fire event to notify interested parites about window destruction.
        // TODO: Perhaps this should fire first, so window is still usable?
        WindowEventArgs args(wnd);
        fireEvent(EventWindowDestroyed, args, EventNamespace);
	}

}

/*************************************************************************
	Return a pointer to the named window
*************************************************************************/
Window* WindowManager::getWindow(const String& name) const
{
	WindowRegistry::const_iterator pos = d_windowRegistry.find(name);

	if (pos == d_windowRegistry.end())
	{
		throw UnknownObjectException("WindowManager::getWindow - A Window object with the name '" + name +"' does not exist within the system");
	}

	return pos->second;
}

/*************************************************************************
	Return true if a window with the given name is present
*************************************************************************/
bool WindowManager::isWindowPresent(const String& name) const
{
	return (d_windowRegistry.find(name) != d_windowRegistry.end());
}

/*************************************************************************
	Destroy all Window objects
*************************************************************************/
void WindowManager::destroyAllWindows(void)
{
	String window_name;
	while (!d_windowRegistry.empty())
	{
		window_name = d_windowRegistry.begin()->first;
		destroyWindow(window_name);
	}

}

/*************************************************************************
	Creates a set of windows (a Gui layout) from the information in the
	specified XML file.
*************************************************************************/
Window* WindowManager::loadWindowLayout(const String& filename, const String& name_prefix, const String& resourceGroup, PropertyCallback* callback, void* userdata)
{
	if (filename.empty())
	{
		throw InvalidRequestException("WindowManager::loadWindowLayout - Filename supplied for gui-layout loading must be valid.");
	}

	// log the fact we are about to load a layout
	Logger::getSingleton().logEvent("---- Beginning loading of GUI layout from '" + filename + "' ----", Informative);

    // create handler object
    GUILayout_xmlHandler handler(name_prefix, callback, userdata);

	// do parse (which uses handler to create actual data)
	try
	{
        System::getSingleton().getXMLParser()->parseXMLFile(handler,
            filename, GUILayoutSchemaName, resourceGroup.empty() ? d_defaultResourceGroup : resourceGroup);
	}
	catch(...)
	{
        Logger::getSingleton().logEvent("WindowManager::loadWindowLayout - loading of layout from file '" + filename +"' failed.", Errors);
        throw;
	}

    // log the completion of loading
    Logger::getSingleton().logEvent("---- Successfully completed loading of GUI layout from '" + filename + "' ----", Standard);

	return handler.getLayoutRootWindow();
}

Window* WindowManager::loadWindowLayout( const String& filename, bool generateRandomPrefix )
{
	//We really just use the bool to get rid of ambiguity with the other loadWindowLayout. There is no difference between
	//calling this loadWindowLayout and setting GRP to false, and calling the other one with no argument
	if(generateRandomPrefix)
		return loadWindowLayout(filename,generateUniqueWindowPrefix());

		return loadWindowLayout(filename);
}
bool WindowManager::isDeadPoolEmpty(void) const
{
    return d_deathrow.empty();
}

void WindowManager::cleanDeadPool(void)
{
    WindowVector::reverse_iterator curr = d_deathrow.rbegin();
    for (; curr != d_deathrow.rend(); ++curr)
    {
// in debug mode, log what gets cleaned from the dead pool (insane level)
#if defined(DEBUG) || defined (_DEBUG)
        CEGUI_LOGINSANE("Window '" + (*curr)->getName() + "' about to be finally destroyed from dead pool.");
#endif

        WindowFactory* factory = WindowFactoryManager::getSingleton().getFactory((*curr)->getType());
        factory->destroyWindow(*curr);
    }

    // all done here, so clear all pointers from dead pool
    d_deathrow.clear();
}

void WindowManager::writeWindowLayoutToStream(const Window& window, OutStream& out_stream, bool writeParent) const
{

    XMLSerializer xml(out_stream);
    // output GUILayout start element
    xml.openTag("GUILayout");
    // see if we need the parent attribute to be written
    if ((window.getParent() != 0) && writeParent)
    {
        xml.attribute("Parent", window.getParent()->getName());
    }
    // write windows
    window.writeXMLToStream(xml);
    // write closing GUILayout element
    xml.closeTag();
}

void WindowManager::writeWindowLayoutToStream(const String& window, OutStream& out_stream, bool writeParent) const
{
    writeWindowLayoutToStream(*getWindow(window), out_stream, writeParent);
}

String WindowManager::generateUniqueWindowName()
{
    // build name
    std::ostringstream uidname;
    uidname << GeneratedWindowNameBase.c_str() << d_uid_counter;

    // update counter for next time
    unsigned long old_uid = d_uid_counter;
    ++d_uid_counter;

    // log if we ever wrap-around (which should be pretty unlikely)
    if (d_uid_counter < old_uid)
        Logger::getSingleton().logEvent("UID counter for generated window names has wrapped around - the fun shall now commence!");

    // return generated name as a CEGUI::String.
    return String(uidname.str());
}

CEGUI::String WindowManager::generateUniqueWindowPrefix()
{
	std::ostringstream prefix;
	prefix << d_uid_counter << "_";

	// update counter for next time
	unsigned long old_uid = d_uid_counter;
	++d_uid_counter;

	// log if we ever wrap-around (which should be pretty unlikely)
	if (d_uid_counter < old_uid)
		Logger::getSingleton().logEvent("UID counter for generated window names has wrapped around - the fun shall now commence!");

	//return generated prefix
	return String(prefix.str());

}

void WindowManager::renameWindow(const String& window, const String& new_name)
{
    renameWindow(getWindow(window), new_name);
}

void WindowManager::renameWindow(Window* window, const String& new_name)
{
    if (window)
    {
        WindowRegistry::iterator pos = d_windowRegistry.find(window->getName());

        if (pos != d_windowRegistry.end())
        {
            // erase old window name from registry
            d_windowRegistry.erase(pos);

            try
            {
                // attempt to rename the window
                window->rename(new_name);
            }
            // rename fails if target name already exists
            catch (AlreadyExistsException&)
            {
                // re-add window to registry under it's old name
                d_windowRegistry[window->getName()] = window;
                // rethrow exception.
                throw;
            }

            // add window to registry under new name
            d_windowRegistry[new_name] = window;
        }
    }
}

/*************************************************************************
	Return a WindowManager::WindowIterator object to iterate over the
	currently defined Windows.
*************************************************************************/
WindowManager::WindowIterator WindowManager::getIterator(void) const
{
	return WindowIterator(d_windowRegistry.begin(), d_windowRegistry.end());
}

/*************************************************************************
    Outputs the names of ALL existing windows to log (DEBUG function).
*************************************************************************/
void WindowManager::DEBUG_dumpWindowNames(String zone)
{
    Logger::getSingleton().logEvent("WINDOW NAMES DUMP (" + zone + ")");
    Logger::getSingleton().logEvent("-----------------");
    CEGUI::WindowManager::WindowIterator windowIt = getIterator();
    while (!windowIt.isAtEnd())
    {
        Logger::getSingleton().logEvent("Window : " + windowIt.getCurrentValue()->getName());
        ++windowIt;
    }
    Logger::getSingleton().logEvent("-----------------");
}

//----------------------------------------------------------------------------//
void WindowManager::lock()
{
    ++d_lockCount;
}

//----------------------------------------------------------------------------//
void WindowManager::unlock()
{
    if (d_lockCount > 0)
        --d_lockCount;
}

//----------------------------------------------------------------------------//
bool WindowManager::isLocked() const
{
    return d_lockCount != 0;
}

//----------------------------------------------------------------------------//

} // End of  CEGUI namespace section
<|endoftext|>