<commit_before>// Copyright (c) 2017 Emilian Cioca
#include "Jewel3D/Precompiled.h"
#include "Entity.h"
#include "Name.h"
#include "Jewel3D/Application/Logging.h"
#include "Jewel3D/Rendering/Material.h"

#include <algorithm>

namespace Jwl
{
	namespace detail
	{
		std::unordered_map<unsigned, std::vector<Entity*>> entityIndex;
		std::unordered_map<unsigned, std::vector<ComponentBase*>> componentIndex;
	}

	ComponentBase::ComponentBase(Entity& _owner, unsigned _componentId)
		: owner(_owner)
		, componentId(_componentId)
	{
	}

	ComponentBase& ComponentBase::operator=(const ComponentBase& other)
	{
		ASSERT(componentId == other.componentId, "Assignment operator between incompatible components.");
		// The owner reference is left untouched.
		return *this;
	}

	bool ComponentBase::IsEnabled() const
	{
		return isEnabled && owner.IsEnabled();
	}

	bool ComponentBase::IsComponentEnabled() const
	{
		return isEnabled;
	}

	unsigned ComponentBase::GenerateID()
	{
		static unsigned counter = 1;
		return counter++;
	}

	Entity::Entity(std::string name)
	{
		Add<Name>(std::move(name));
	}

	Entity::Entity(const Transform& pose)
		: Transform(pose)
	{
	}

	Entity::~Entity()
	{
		RemoveAllComponents();
		RemoveAllTags();
	}

	Entity::Ptr Entity::Duplicate() const
	{
		auto newEntity = MakeNew();

		newEntity->Transform::operator=(*this);
		newEntity->Hierarchy<Entity>::operator=(*this);

		/* Copy all tags */
		for (auto tag : this->tags)
		{
			newEntity->Tag(tag);
		}

		/* Copy all components */
		// The material is always copied first in order to have the Shader Variants updated from
		// any of the new components initializing.
		auto material = this->Try<Material>();
		if (material)
		{
			static_cast<const ComponentBase*>(material)->Copy(*newEntity);
		}

		// Mirror all components to the other entity.
		for (auto comp : this->components)
		{
			// Material component has already been copied over.
			if (comp == material)
				continue;

			comp->Copy(*newEntity);
		}

		if (!this->IsEnabled())
		{
			newEntity->Disable();
		}

		return newEntity;
	}

	void Entity::CopyComponent(const ComponentBase& source)
	{
		source.Copy(*this);
	}

	void Entity::RemoveAllComponents()
	{
		unsigned i = components.size();

		// This loop safely removes all components even if they remove others during destruction.
		while (i-- != 0)
		{
			if (i < components.size())
			{
				auto comp = components[i];
				components.erase(components.begin() + i);

				if (comp->IsEnabled())
				{
					Unindex(*comp);
				}

				delete comp;
			}
		}
	}

	void Entity::RemoveAllTags()
	{
		if (IsEnabled())
		{
			for (auto tag : tags)
			{
				UnindexTag(tag);
			}
		}

		tags.clear();
	}

	void Entity::Enable()
	{
		if (isEnabled)
		{
			return;
		}

		// Re-Index all active components.
		for (auto comp : components)
		{
			if (comp->IsComponentEnabled())
			{
				Index(*comp);
				comp->OnEnable();
			}
		}

		// Re-Index all tags.
		for (auto tag : tags)
		{
			IndexTag(tag);
		}

		isEnabled = true;
	}

	void Entity::Disable()
	{
		if (!isEnabled)
		{
			return;
		}

		// UnIndex all active components.
		for (auto comp : components)
		{
			if (comp->IsComponentEnabled())
			{
				Unindex(*comp);
				comp->OnDisable();
			}
		}

		// UnIndex all tags.
		for (auto tag : tags)
		{
			UnindexTag(tag);
		}

		isEnabled = false;
	}

	bool Entity::IsEnabled() const
	{
		return isEnabled;
	}

	Entity::Ptr Entity::CreateChild()
	{
		auto child = Entity::MakeNew();
		AddChild(child);

		return child;
	}

	void Entity::Tag(unsigned tagId)
	{
		if (IsEnabled())
		{
			IndexTag(tagId);
		}

		tags.push_back(tagId);
	}

	void Entity::RemoveTag(unsigned tagId)
	{
		if (IsEnabled())
		{
			UnindexTag(tagId);
		}

		auto itr = std::find(tags.begin(), tags.end(), tagId);
		*itr = tags.back();
		tags.pop_back();
	}

	void Entity::IndexTag(unsigned tagId)
	{
		// Adjust [id, entity] index.
		auto& table = detail::entityIndex[tagId];
		table.insert(std::lower_bound(table.begin(), table.end(), this), this);
	}

	void Entity::UnindexTag(unsigned tagId)
	{
		// Adjust [id, entity] index.
		auto& table = detail::entityIndex[tagId];
		table.erase(std::lower_bound(table.begin(), table.end(), this));
	}

	void Entity::Index(ComponentBase& comp)
	{
		// Adjust [id, entity] index.
		IndexTag(comp.componentId);

		// Adjust [id, component] index.
		detail::componentIndex[comp.componentId].push_back(&comp);
	}

	void Entity::Unindex(ComponentBase& comp)
	{
		// Adjust [id, entity] index.
		UnindexTag(comp.componentId);

		// Adjust [id, component] index.
		auto& componentTable = detail::componentIndex[comp.componentId];
		auto itr = std::find(componentTable.begin(), componentTable.end(), &comp);
		*itr = componentTable.back();
		componentTable.pop_back();
	}

	mat4 Entity::GetWorldTransform() const
	{
		mat4 transform(rotation, position, scale);

		if (auto parentEntity = GetParent())
		{
			transform = parentEntity->GetWorldTransform() * transform;
		}

		return transform;
	}

	quat Entity::GetWorldRotation() const
	{
		quat result = rotation;

		if (auto parentEntity = GetParent())
		{
			result = parentEntity->GetWorldRotation() * result;
		}

		return result;
	}

	void Entity::LookAt(const vec3& pos, const vec3& target, const vec3& up)
	{
		// Passthrough to get around C++ name-hiding.
		Transform::LookAt(pos, target, up);
	}

	void Entity::LookAt(const Entity& target, const vec3& up)
	{
		ASSERT(this != &target, "Transform cannot look at itself.");

		vec3 targetPos = target.GetWorldTransform().GetTranslation();

		// If we have a parent, we are not in world-space.
		// We must resolve for the target position in local-space.
		if (auto parentEntity = GetParent())
		{
			targetPos = vec3(parentEntity->GetWorldTransform() * vec4(targetPos, 1.0f));
		}

		LookAt(position, targetPos, up);
	}
}
<commit_msg>Fixed RemoveTag() crashing if the tag did not exist on the Entity<commit_after>// Copyright (c) 2017 Emilian Cioca
#include "Jewel3D/Precompiled.h"
#include "Entity.h"
#include "Name.h"
#include "Jewel3D/Application/Logging.h"
#include "Jewel3D/Rendering/Material.h"

#include <algorithm>

namespace Jwl
{
	namespace detail
	{
		std::unordered_map<unsigned, std::vector<Entity*>> entityIndex;
		std::unordered_map<unsigned, std::vector<ComponentBase*>> componentIndex;
	}

	ComponentBase::ComponentBase(Entity& _owner, unsigned _componentId)
		: owner(_owner)
		, componentId(_componentId)
	{
	}

	ComponentBase& ComponentBase::operator=(const ComponentBase& other)
	{
		ASSERT(componentId == other.componentId, "Assignment operator between incompatible components.");
		// The owner reference is left untouched.
		return *this;
	}

	bool ComponentBase::IsEnabled() const
	{
		return isEnabled && owner.IsEnabled();
	}

	bool ComponentBase::IsComponentEnabled() const
	{
		return isEnabled;
	}

	unsigned ComponentBase::GenerateID()
	{
		static unsigned counter = 1;
		return counter++;
	}

	Entity::Entity(std::string name)
	{
		Add<Name>(std::move(name));
	}

	Entity::Entity(const Transform& pose)
		: Transform(pose)
	{
	}

	Entity::~Entity()
	{
		RemoveAllComponents();
		RemoveAllTags();
	}

	Entity::Ptr Entity::Duplicate() const
	{
		auto newEntity = MakeNew();

		newEntity->Transform::operator=(*this);
		newEntity->Hierarchy<Entity>::operator=(*this);

		/* Copy all tags */
		for (auto tag : this->tags)
		{
			newEntity->Tag(tag);
		}

		/* Copy all components */
		// The material is always copied first in order to have the Shader Variants updated from
		// any of the new components initializing.
		auto material = this->Try<Material>();
		if (material)
		{
			static_cast<const ComponentBase*>(material)->Copy(*newEntity);
		}

		// Mirror all components to the other entity.
		for (auto comp : this->components)
		{
			// Material component has already been copied over.
			if (comp == material)
				continue;

			comp->Copy(*newEntity);
		}

		if (!this->IsEnabled())
		{
			newEntity->Disable();
		}

		return newEntity;
	}

	void Entity::CopyComponent(const ComponentBase& source)
	{
		source.Copy(*this);
	}

	void Entity::RemoveAllComponents()
	{
		unsigned i = components.size();

		// This loop safely removes all components even if they remove others during destruction.
		while (i-- != 0)
		{
			if (i < components.size())
			{
				auto comp = components[i];
				components.erase(components.begin() + i);

				if (comp->IsEnabled())
				{
					Unindex(*comp);
				}

				delete comp;
			}
		}
	}

	void Entity::RemoveAllTags()
	{
		if (IsEnabled())
		{
			for (auto tag : tags)
			{
				UnindexTag(tag);
			}
		}

		tags.clear();
	}

	void Entity::Enable()
	{
		if (isEnabled)
		{
			return;
		}

		// Re-Index all active components.
		for (auto comp : components)
		{
			if (comp->IsComponentEnabled())
			{
				Index(*comp);
				comp->OnEnable();
			}
		}

		// Re-Index all tags.
		for (auto tag : tags)
		{
			IndexTag(tag);
		}

		isEnabled = true;
	}

	void Entity::Disable()
	{
		if (!isEnabled)
		{
			return;
		}

		// UnIndex all active components.
		for (auto comp : components)
		{
			if (comp->IsComponentEnabled())
			{
				Unindex(*comp);
				comp->OnDisable();
			}
		}

		// UnIndex all tags.
		for (auto tag : tags)
		{
			UnindexTag(tag);
		}

		isEnabled = false;
	}

	bool Entity::IsEnabled() const
	{
		return isEnabled;
	}

	Entity::Ptr Entity::CreateChild()
	{
		auto child = Entity::MakeNew();
		AddChild(child);

		return child;
	}

	void Entity::Tag(unsigned tagId)
	{
		if (IsEnabled())
		{
			IndexTag(tagId);
		}

		tags.push_back(tagId);
	}

	void Entity::RemoveTag(unsigned tagId)
	{
		auto itr = std::find(tags.begin(), tags.end(), tagId);
		if (itr == tags.end())
			return;

		*itr = tags.back();
		tags.pop_back();

		if (IsEnabled())
		{
			UnindexTag(tagId);
		}
	}

	void Entity::IndexTag(unsigned tagId)
	{
		// Adjust [id, entity] index.
		auto& table = detail::entityIndex[tagId];
		table.insert(std::lower_bound(table.begin(), table.end(), this), this);
	}

	void Entity::UnindexTag(unsigned tagId)
	{
		// Adjust [id, entity] index.
		auto& table = detail::entityIndex[tagId];
		table.erase(std::lower_bound(table.begin(), table.end(), this));
	}

	void Entity::Index(ComponentBase& comp)
	{
		// Adjust [id, entity] index.
		IndexTag(comp.componentId);

		// Adjust [id, component] index.
		detail::componentIndex[comp.componentId].push_back(&comp);
	}

	void Entity::Unindex(ComponentBase& comp)
	{
		// Adjust [id, entity] index.
		UnindexTag(comp.componentId);

		// Adjust [id, component] index.
		auto& componentTable = detail::componentIndex[comp.componentId];
		auto itr = std::find(componentTable.begin(), componentTable.end(), &comp);
		*itr = componentTable.back();
		componentTable.pop_back();
	}

	mat4 Entity::GetWorldTransform() const
	{
		mat4 transform(rotation, position, scale);

		if (auto parentEntity = GetParent())
		{
			transform = parentEntity->GetWorldTransform() * transform;
		}

		return transform;
	}

	quat Entity::GetWorldRotation() const
	{
		quat result = rotation;

		if (auto parentEntity = GetParent())
		{
			result = parentEntity->GetWorldRotation() * result;
		}

		return result;
	}

	void Entity::LookAt(const vec3& pos, const vec3& target, const vec3& up)
	{
		// Passthrough to get around C++ name-hiding.
		Transform::LookAt(pos, target, up);
	}

	void Entity::LookAt(const Entity& target, const vec3& up)
	{
		ASSERT(this != &target, "Transform cannot look at itself.");

		vec3 targetPos = target.GetWorldTransform().GetTranslation();

		// If we have a parent, we are not in world-space.
		// We must resolve for the target position in local-space.
		if (auto parentEntity = GetParent())
		{
			targetPos = vec3(parentEntity->GetWorldTransform() * vec4(targetPos, 1.0f));
		}

		LookAt(position, targetPos, up);
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "client_handler.h"
#include <stdio.h>
#include <sstream>
#include <string>
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "cefclient.h"
#include "resource_util.h"
#include "string_util.h"
#include "appshell/appshell_extensions.h"
#include "appshell/command_callbacks.h"

// Custom menu command Ids.
enum client_menu_ids {
  CLIENT_ID_SHOW_DEVTOOLS   = MENU_ID_USER_FIRST,
};

ClientHandler::BrowserWindowMap ClientHandler::browser_window_map_;

ClientHandler::ClientHandler()
  : m_MainHwnd(NULL),
    m_BrowserId(0),
    m_EditHwnd(NULL),
    m_BackHwnd(NULL),
    m_ForwardHwnd(NULL),
    m_StopHwnd(NULL),
    m_ReloadHwnd(NULL),
    m_bFormElementHasFocus(false),
    m_quitting(false) {
  callbackId = 0;
  CreateProcessMessageDelegates(process_message_delegates_);
  CreateRequestDelegates(request_delegates_);
}

ClientHandler::~ClientHandler() {
}

bool ClientHandler::OnProcessMessageReceived(
    CefRefPtr<CefBrowser> browser,
    CefProcessId source_process,
    CefRefPtr<CefProcessMessage> message) {
  bool handled = false;

  // Check for callbacks first
  if (message->GetName() == "executeCommandCallback") {
    int32 commandId = message->GetArgumentList()->GetInt(0);
    bool result = message->GetArgumentList()->GetBool(1);

    CefRefPtr<CommandCallback> callback = command_callback_map_[commandId];
    callback->CommandComplete(result);
    command_callback_map_.erase(commandId);

    handled = true;
  }

  // Execute delegate callbacks.
  ProcessMessageDelegateSet::iterator it = process_message_delegates_.begin();
  for (; it != process_message_delegates_.end() && !handled; ++it) {
    handled = (*it)->OnProcessMessageReceived(this, browser, source_process,
                                              message);
  }

  return handled;
}

void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  AutoLock lock_scope(this);
  if (!m_Browser.get())   {
    // We need to keep the main child window, but not popup windows
    m_Browser = browser;
    m_BrowserId = browser->GetIdentifier();
  } else {
    // Call the platform-specific code to hook up popup windows
    PopupCreated(browser);
  }

  browser_window_map_[browser->GetHost()->GetWindowHandle()] = browser;
}

bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  if (m_BrowserId == browser->GetIdentifier()) {
    // Since the main window contains the browser window, we need to close
    // the parent window instead of the browser window.
    CloseMainWindow();

    // Return true here so that we can skip closing the browser window
    // in this pass. (It will be destroyed due to the call to close
    // the parent above.)
    return true;
  }

  // A popup browser window is not contained in another window, so we can let
  // these windows close by themselves.
  return false;
}

void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  if (CanCloseBrowser(browser)) {
    if (m_BrowserId == browser->GetIdentifier()) {
      // Free the browser pointer so that the browser can be destroyed
      m_Browser = NULL;
	} else if (browser->IsPopup()) {
      // Remove the record for DevTools popup windows.
      std::set<std::string>::iterator it =
          m_OpenDevToolsURLs.find(browser->GetMainFrame()->GetURL());
      if (it != m_OpenDevToolsURLs.end())
        m_OpenDevToolsURLs.erase(it);
	}

    browser_window_map_.erase(browser->GetHost()->GetWindowHandle());
  }

  if (m_quitting) {
    DispatchCloseToNextBrowser();
  }
}

void ClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame) {
  REQUIRE_UI_THREAD();

  if (m_BrowserId == browser->GetIdentifier() && frame->IsMain()) {
    // We've just started loading a page
    SetLoading(true);
  }
}

void ClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
                              CefRefPtr<CefFrame> frame,
                              int httpStatusCode) {
  REQUIRE_UI_THREAD();

  if (m_BrowserId == browser->GetIdentifier() && frame->IsMain()) {
    // We've just finished loading a page
    SetLoading(false);
  }
}

void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame,
                                ErrorCode errorCode,
                                const CefString& errorText,
                                const CefString& failedUrl) {
  REQUIRE_UI_THREAD();

  // Display a load error message.
  std::stringstream ss;
  ss << "
Failed to load URL " << std::string(failedUrl) <<
        " with error " << std::string(errorText) << " (" << errorCode <<
        ").
";
  frame->LoadString(ss.str(), failedUrl);
}

CefRefPtr<CefResourceHandler> ClientHandler::GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) {
  CefRefPtr<CefResourceHandler> handler;

  // Execute delegate callbacks.
  RequestDelegateSet::iterator it = request_delegates_.begin();
  for (; it != request_delegates_.end() && !handler.get(); ++it)
    handler = (*it)->GetResourceHandler(this, browser, frame, request);

  return handler;
}

void ClientHandler::OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                                         bool isLoading,
                                         bool canGoBack,
                                         bool canGoForward) {
  REQUIRE_UI_THREAD();
  SetLoading(isLoading);
  SetNavState(canGoBack, canGoForward);
}

bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
                                     const CefString& message,
                                     const CefString& source,
                                     int line) {
  // Don't write the message to a console.log file. Instead, we'll just
  // return false here so the message gets written to the console (output window
  // in xcode, or console window in dev tools)

/*
  REQUIRE_UI_THREAD();

  bool first_message;
  std::string logFile;

  {
    AutoLock lock_scope(this);

    first_message = m_LogFile.empty();
    if (first_message) {
      std::stringstream ss;
      ss << AppGetWorkingDirectory();
#if defined(OS_WIN)
      ss << "\\";
#else
      ss << "/";
#endif
      ss << "console.log";
      m_LogFile = ss.str();
    }
    logFile = m_LogFile;
  }

  FILE* file = fopen(logFile.c_str(), "a");
  if (file) {
    std::stringstream ss;
    ss << "Message: " << std::string(message) << "\r\nSource: " <<
        std::string(source) << "\r\nLine: " << line <<
        "\r\n-----------------------\r\n";
    fputs(ss.str().c_str(), file);
    fclose(file);

    if (first_message)
      SendNotification(NOTIFY_CONSOLE_MESSAGE);
  }
*/
  return false;
}

void ClientHandler::OnRequestGeolocationPermission(
      CefRefPtr<CefBrowser> browser,
      const CefString& requesting_url,
      int request_id,
      CefRefPtr<CefGeolocationCallback> callback) {
  // Allow geolocation access from all websites.
  callback->Continue(true);
}

void ClientHandler::OnBeforeContextMenu(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    CefRefPtr<CefContextMenuParams> params,
    CefRefPtr<CefMenuModel> model) {
  if ((params->GetTypeFlags() & (CM_TYPEFLAG_PAGE | CM_TYPEFLAG_FRAME)) != 0) {
    // Add a separator if the menu already has items.
    if (model->GetCount() > 0)
      model->AddSeparator();

    // Add a "Show DevTools" item to all context menus.
    model->AddItem(CLIENT_ID_SHOW_DEVTOOLS, "&Show DevTools");

    CefString devtools_url = browser->GetHost()->GetDevToolsURL(true);
    if (devtools_url.empty() ||
        m_OpenDevToolsURLs.find(devtools_url) != m_OpenDevToolsURLs.end()) {
      // Disable the menu option if DevTools isn't enabled or if a window is
      // already open for the current URL.
      model->SetEnabled(CLIENT_ID_SHOW_DEVTOOLS, false);
    }
  }
}

bool ClientHandler::OnContextMenuCommand(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    CefRefPtr<CefContextMenuParams> params,
    int command_id,
    EventFlags event_flags) {
  switch (command_id) {
    case CLIENT_ID_SHOW_DEVTOOLS:
      ShowDevTools(browser);
      return true;
    default:  // Allow default handling, if any.
      return false;
  }
}

void ClientHandler::SetMainHwnd(CefWindowHandle hwnd) {
  AutoLock lock_scope(this);
  m_MainHwnd = hwnd;
}

void ClientHandler::SetEditHwnd(CefWindowHandle hwnd) {
  AutoLock lock_scope(this);
  m_EditHwnd = hwnd;
}

void ClientHandler::SetButtonHwnds(CefWindowHandle backHwnd,
                                   CefWindowHandle forwardHwnd,
                                   CefWindowHandle reloadHwnd,
                                   CefWindowHandle stopHwnd) {
  AutoLock lock_scope(this);
  m_BackHwnd = backHwnd;
  m_ForwardHwnd = forwardHwnd;
  m_ReloadHwnd = reloadHwnd;
  m_StopHwnd = stopHwnd;
}

std::string ClientHandler::GetLogFile() {
  AutoLock lock_scope(this);
  return m_LogFile;
}

void ClientHandler::SetLastDownloadFile(const std::string& fileName) {
  AutoLock lock_scope(this);
  m_LastDownloadFile = fileName;
}

std::string ClientHandler::GetLastDownloadFile() {
  AutoLock lock_scope(this);
  return m_LastDownloadFile;
}

void ClientHandler::ShowDevTools(CefRefPtr<CefBrowser> browser) {
  std::string devtools_url = browser->GetHost()->GetDevToolsURL(true);
  if (!devtools_url.empty() &&
      m_OpenDevToolsURLs.find(devtools_url) == m_OpenDevToolsURLs.end()) {
    m_OpenDevToolsURLs.insert(devtools_url);
    browser->GetMainFrame()->ExecuteJavaScript(
        "window.open('" +  devtools_url + "');", "about:blank", 0);
  }
}

bool ClientHandler::SendJSCommand(CefRefPtr<CefBrowser> browser, const CefString& commandName, CefRefPtr<CommandCallback> callback)
{
  CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create("executeCommand");
  message->GetArgumentList()->SetString(0, commandName);

  if (callback) {
    callbackId++;
    command_callback_map_[callbackId] = callback;
    message->GetArgumentList()->SetInt(1, callbackId);
  }

  return browser->SendProcessMessage(PID_RENDERER, message);
}

void ClientHandler::SendOpenFileCommand(CefRefPtr<CefBrowser> browser, const CefString &filename) {
  std::string filenameStr(filename);
  // FIXME: Use SendJSCommand once it supports parameters
  std::string cmd = "require('command/CommandManager').execute('file.open',{fullPath:'" + filenameStr + "'})";
  browser->GetMainFrame()->ExecuteJavaScript(CefString(cmd.c_str()),
                                browser->GetMainFrame()->GetURL(), 0);
}

void ClientHandler::DispatchCloseToNextBrowser()
{
  // If the inner loop iterates thru all browsers and there's still at least one
  // left (i.e. the first browser that was skipped), then re-start loop
  while (browser_window_map_.size() > 0)
  {
    // Close the main window last. On Windows, closing the main window exits the
    // application, so make sure all other windows get a crack at saving changes first.
    bool skipMainWindow = (browser_window_map_.size() > 1);

    BrowserWindowMap::const_iterator i;
    for (i = browser_window_map_.begin(); i != browser_window_map_.end(); i++)
    {
      CefRefPtr<CefBrowser> browser = i->second;
      if (skipMainWindow && browser && browser->GetIdentifier() == m_BrowserId) {
        continue;
      }

      // Bring the window to the front before sending the command
      BringBrowserWindowToFront(browser);

      // This call initiates a quit sequence. We will continue to close browser windows
      // unless AbortQuit() is called.
      m_quitting = true;
      CefRefPtr<CommandCallback> callback = new CloseWindowCommandCallback(browser);

      if (SendJSCommand(browser, FILE_CLOSE_WINDOW, callback)) {
        // JS Command successfully sent, so we're done
        return;
      }

      // Sending JS command to browser failed, so remove it from queue, continue to next browser
      browser_window_map_.erase(i->first);
    }
  }
}

void ClientHandler::AbortQuit()
{
	m_quitting = false;

	// Notify all browsers that quit was aborted
	BrowserWindowMap::const_iterator i, last = browser_window_map_.end();
	for (i = browser_window_map_.begin(); i != last; i++)
	{
		CefRefPtr<CefBrowser> browser = i->second;
		SendJSCommand(browser, APP_ABORT_QUIT);
	}
}

// static
void ClientHandler::CreateProcessMessageDelegates(
      ProcessMessageDelegateSet& delegates) {
	appshell_extensions::CreateProcessMessageDelegates(delegates);
}

// static
void ClientHandler::CreateRequestDelegates(RequestDelegateSet& delegates) {
}
<commit_msg>Use file.addToWorkingSet instead of file.open<commit_after>// Copyright (c) 2011 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

#include "client_handler.h"
#include <stdio.h>
#include <sstream>
#include <string>
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/wrapper/cef_stream_resource_handler.h"
#include "cefclient.h"
#include "resource_util.h"
#include "string_util.h"
#include "appshell/appshell_extensions.h"
#include "appshell/command_callbacks.h"

// Custom menu command Ids.
enum client_menu_ids {
  CLIENT_ID_SHOW_DEVTOOLS   = MENU_ID_USER_FIRST,
};

ClientHandler::BrowserWindowMap ClientHandler::browser_window_map_;

ClientHandler::ClientHandler()
  : m_MainHwnd(NULL),
    m_BrowserId(0),
    m_EditHwnd(NULL),
    m_BackHwnd(NULL),
    m_ForwardHwnd(NULL),
    m_StopHwnd(NULL),
    m_ReloadHwnd(NULL),
    m_bFormElementHasFocus(false),
    m_quitting(false) {
  callbackId = 0;
  CreateProcessMessageDelegates(process_message_delegates_);
  CreateRequestDelegates(request_delegates_);
}

ClientHandler::~ClientHandler() {
}

bool ClientHandler::OnProcessMessageReceived(
    CefRefPtr<CefBrowser> browser,
    CefProcessId source_process,
    CefRefPtr<CefProcessMessage> message) {
  bool handled = false;

  // Check for callbacks first
  if (message->GetName() == "executeCommandCallback") {
    int32 commandId = message->GetArgumentList()->GetInt(0);
    bool result = message->GetArgumentList()->GetBool(1);

    CefRefPtr<CommandCallback> callback = command_callback_map_[commandId];
    callback->CommandComplete(result);
    command_callback_map_.erase(commandId);

    handled = true;
  }

  // Execute delegate callbacks.
  ProcessMessageDelegateSet::iterator it = process_message_delegates_.begin();
  for (; it != process_message_delegates_.end() && !handled; ++it) {
    handled = (*it)->OnProcessMessageReceived(this, browser, source_process,
                                              message);
  }

  return handled;
}

void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  AutoLock lock_scope(this);
  if (!m_Browser.get())   {
    // We need to keep the main child window, but not popup windows
    m_Browser = browser;
    m_BrowserId = browser->GetIdentifier();
  } else {
    // Call the platform-specific code to hook up popup windows
    PopupCreated(browser);
  }

  browser_window_map_[browser->GetHost()->GetWindowHandle()] = browser;
}

bool ClientHandler::DoClose(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  if (m_BrowserId == browser->GetIdentifier()) {
    // Since the main window contains the browser window, we need to close
    // the parent window instead of the browser window.
    CloseMainWindow();

    // Return true here so that we can skip closing the browser window
    // in this pass. (It will be destroyed due to the call to close
    // the parent above.)
    return true;
  }

  // A popup browser window is not contained in another window, so we can let
  // these windows close by themselves.
  return false;
}

void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
  REQUIRE_UI_THREAD();

  if (CanCloseBrowser(browser)) {
    if (m_BrowserId == browser->GetIdentifier()) {
      // Free the browser pointer so that the browser can be destroyed
      m_Browser = NULL;
	} else if (browser->IsPopup()) {
      // Remove the record for DevTools popup windows.
      std::set<std::string>::iterator it =
          m_OpenDevToolsURLs.find(browser->GetMainFrame()->GetURL());
      if (it != m_OpenDevToolsURLs.end())
        m_OpenDevToolsURLs.erase(it);
	}

    browser_window_map_.erase(browser->GetHost()->GetWindowHandle());
  }

  if (m_quitting) {
    DispatchCloseToNextBrowser();
  }
}

void ClientHandler::OnLoadStart(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame) {
  REQUIRE_UI_THREAD();

  if (m_BrowserId == browser->GetIdentifier() && frame->IsMain()) {
    // We've just started loading a page
    SetLoading(true);
  }
}

void ClientHandler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
                              CefRefPtr<CefFrame> frame,
                              int httpStatusCode) {
  REQUIRE_UI_THREAD();

  if (m_BrowserId == browser->GetIdentifier() && frame->IsMain()) {
    // We've just finished loading a page
    SetLoading(false);
  }
}

void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
                                CefRefPtr<CefFrame> frame,
                                ErrorCode errorCode,
                                const CefString& errorText,
                                const CefString& failedUrl) {
  REQUIRE_UI_THREAD();

  // Display a load error message.
  std::stringstream ss;
  ss << "
Failed to load URL " << std::string(failedUrl) <<
        " with error " << std::string(errorText) << " (" << errorCode <<
        ").
";
  frame->LoadString(ss.str(), failedUrl);
}

CefRefPtr<CefResourceHandler> ClientHandler::GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request) {
  CefRefPtr<CefResourceHandler> handler;

  // Execute delegate callbacks.
  RequestDelegateSet::iterator it = request_delegates_.begin();
  for (; it != request_delegates_.end() && !handler.get(); ++it)
    handler = (*it)->GetResourceHandler(this, browser, frame, request);

  return handler;
}

void ClientHandler::OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
                                         bool isLoading,
                                         bool canGoBack,
                                         bool canGoForward) {
  REQUIRE_UI_THREAD();
  SetLoading(isLoading);
  SetNavState(canGoBack, canGoForward);
}

bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
                                     const CefString& message,
                                     const CefString& source,
                                     int line) {
  // Don't write the message to a console.log file. Instead, we'll just
  // return false here so the message gets written to the console (output window
  // in xcode, or console window in dev tools)

/*
  REQUIRE_UI_THREAD();

  bool first_message;
  std::string logFile;

  {
    AutoLock lock_scope(this);

    first_message = m_LogFile.empty();
    if (first_message) {
      std::stringstream ss;
      ss << AppGetWorkingDirectory();
#if defined(OS_WIN)
      ss << "\\";
#else
      ss << "/";
#endif
      ss << "console.log";
      m_LogFile = ss.str();
    }
    logFile = m_LogFile;
  }

  FILE* file = fopen(logFile.c_str(), "a");
  if (file) {
    std::stringstream ss;
    ss << "Message: " << std::string(message) << "\r\nSource: " <<
        std::string(source) << "\r\nLine: " << line <<
        "\r\n-----------------------\r\n";
    fputs(ss.str().c_str(), file);
    fclose(file);

    if (first_message)
      SendNotification(NOTIFY_CONSOLE_MESSAGE);
  }
*/
  return false;
}

void ClientHandler::OnRequestGeolocationPermission(
      CefRefPtr<CefBrowser> browser,
      const CefString& requesting_url,
      int request_id,
      CefRefPtr<CefGeolocationCallback> callback) {
  // Allow geolocation access from all websites.
  callback->Continue(true);
}

void ClientHandler::OnBeforeContextMenu(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    CefRefPtr<CefContextMenuParams> params,
    CefRefPtr<CefMenuModel> model) {
  if ((params->GetTypeFlags() & (CM_TYPEFLAG_PAGE | CM_TYPEFLAG_FRAME)) != 0) {
    // Add a separator if the menu already has items.
    if (model->GetCount() > 0)
      model->AddSeparator();

    // Add a "Show DevTools" item to all context menus.
    model->AddItem(CLIENT_ID_SHOW_DEVTOOLS, "&Show DevTools");

    CefString devtools_url = browser->GetHost()->GetDevToolsURL(true);
    if (devtools_url.empty() ||
        m_OpenDevToolsURLs.find(devtools_url) != m_OpenDevToolsURLs.end()) {
      // Disable the menu option if DevTools isn't enabled or if a window is
      // already open for the current URL.
      model->SetEnabled(CLIENT_ID_SHOW_DEVTOOLS, false);
    }
  }
}

bool ClientHandler::OnContextMenuCommand(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    CefRefPtr<CefContextMenuParams> params,
    int command_id,
    EventFlags event_flags) {
  switch (command_id) {
    case CLIENT_ID_SHOW_DEVTOOLS:
      ShowDevTools(browser);
      return true;
    default:  // Allow default handling, if any.
      return false;
  }
}

void ClientHandler::SetMainHwnd(CefWindowHandle hwnd) {
  AutoLock lock_scope(this);
  m_MainHwnd = hwnd;
}

void ClientHandler::SetEditHwnd(CefWindowHandle hwnd) {
  AutoLock lock_scope(this);
  m_EditHwnd = hwnd;
}

void ClientHandler::SetButtonHwnds(CefWindowHandle backHwnd,
                                   CefWindowHandle forwardHwnd,
                                   CefWindowHandle reloadHwnd,
                                   CefWindowHandle stopHwnd) {
  AutoLock lock_scope(this);
  m_BackHwnd = backHwnd;
  m_ForwardHwnd = forwardHwnd;
  m_ReloadHwnd = reloadHwnd;
  m_StopHwnd = stopHwnd;
}

std::string ClientHandler::GetLogFile() {
  AutoLock lock_scope(this);
  return m_LogFile;
}

void ClientHandler::SetLastDownloadFile(const std::string& fileName) {
  AutoLock lock_scope(this);
  m_LastDownloadFile = fileName;
}

std::string ClientHandler::GetLastDownloadFile() {
  AutoLock lock_scope(this);
  return m_LastDownloadFile;
}

void ClientHandler::ShowDevTools(CefRefPtr<CefBrowser> browser) {
  std::string devtools_url = browser->GetHost()->GetDevToolsURL(true);
  if (!devtools_url.empty() &&
      m_OpenDevToolsURLs.find(devtools_url) == m_OpenDevToolsURLs.end()) {
    m_OpenDevToolsURLs.insert(devtools_url);
    browser->GetMainFrame()->ExecuteJavaScript(
        "window.open('" +  devtools_url + "');", "about:blank", 0);
  }
}

bool ClientHandler::SendJSCommand(CefRefPtr<CefBrowser> browser, const CefString& commandName, CefRefPtr<CommandCallback> callback)
{
  CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create("executeCommand");
  message->GetArgumentList()->SetString(0, commandName);

  if (callback) {
    callbackId++;
    command_callback_map_[callbackId] = callback;
    message->GetArgumentList()->SetInt(1, callbackId);
  }

  return browser->SendProcessMessage(PID_RENDERER, message);
}

void ClientHandler::SendOpenFileCommand(CefRefPtr<CefBrowser> browser, const CefString &filename) {
  std::string filenameStr(filename);
  // FIXME: Use SendJSCommand once it supports parameters
  std::string cmd = "require('command/CommandManager').execute('file.addToWorkingSet',{fullPath:'" + filenameStr + "'})";
  browser->GetMainFrame()->ExecuteJavaScript(CefString(cmd.c_str()),
                                browser->GetMainFrame()->GetURL(), 0);
}

void ClientHandler::DispatchCloseToNextBrowser()
{
  // If the inner loop iterates thru all browsers and there's still at least one
  // left (i.e. the first browser that was skipped), then re-start loop
  while (browser_window_map_.size() > 0)
  {
    // Close the main window last. On Windows, closing the main window exits the
    // application, so make sure all other windows get a crack at saving changes first.
    bool skipMainWindow = (browser_window_map_.size() > 1);

    BrowserWindowMap::const_iterator i;
    for (i = browser_window_map_.begin(); i != browser_window_map_.end(); i++)
    {
      CefRefPtr<CefBrowser> browser = i->second;
      if (skipMainWindow && browser && browser->GetIdentifier() == m_BrowserId) {
        continue;
      }

      // Bring the window to the front before sending the command
      BringBrowserWindowToFront(browser);

      // This call initiates a quit sequence. We will continue to close browser windows
      // unless AbortQuit() is called.
      m_quitting = true;
      CefRefPtr<CommandCallback> callback = new CloseWindowCommandCallback(browser);

      if (SendJSCommand(browser, FILE_CLOSE_WINDOW, callback)) {
        // JS Command successfully sent, so we're done
        return;
      }

      // Sending JS command to browser failed, so remove it from queue, continue to next browser
      browser_window_map_.erase(i->first);
    }
  }
}

void ClientHandler::AbortQuit()
{
	m_quitting = false;

	// Notify all browsers that quit was aborted
	BrowserWindowMap::const_iterator i, last = browser_window_map_.end();
	for (i = browser_window_map_.begin(); i != last; i++)
	{
		CefRefPtr<CefBrowser> browser = i->second;
		SendJSCommand(browser, APP_ABORT_QUIT);
	}
}

// static
void ClientHandler::CreateProcessMessageDelegates(
      ProcessMessageDelegateSet& delegates) {
	appshell_extensions::CreateProcessMessageDelegates(delegates);
}

// static
void ClientHandler::CreateRequestDelegates(RequestDelegateSet& delegates) {
}
<|endoftext|>


<commit_before>// $Id$

//**************************************************************************
//* This file is property of and copyright by the ALICE HLT Project        *
//* ALICE Experiment at CERN, All rights reserved.                         *
//*                                                                        *
//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
//*                  for The ALICE HLT Project.                            *
//*                                                                        *
//* Permission to use, copy, modify and distribute this software and its   *
//* documentation strictly for non-commercial purposes is hereby granted   *
//* without fee, provided that the above copyright notice appears in all   *
//* copies and that both the copyright notice and this permission notice   *
//* appear in the supporting documentation. The authors make no claims     *
//* about the suitability of this software for any purpose. It is          *
//* provided "as is" without express or implied warranty.                  *
//**************************************************************************

/** @file   AliHLTGlobalAgent.cxx
    @author Matthias Richter
    @date
    @brief  Agent of the libAliHLTGlobal library
*/

#include <cassert>
#include "AliHLTGlobalAgent.h"
#include "AliHLTConfigurationHandler.h"
#include "TObjString.h"
#include "TObjArray.h"
#include "AliHLTGlobalFlatEsdTestComponent.h"

// header files of library components
#include "AliHLTGlobalTrackMergerComponent.h"
#include "AliHLTGlobalCompareFlatComponent.h"
#include "AliHLTGlobalEsdToFlatConverterComponent.h"
#include "AliHLTGlobalFlatEsdConverterComponent.h"
#include "AliHLTGlobalEsdConverterComponent.h"
#include "AliHLTGlobalVertexerComponent.h"
#include "AliHLTGlobalOfflineVertexerComponent.h"
#include "AliHLTV0HistoComponent.h"
#include "AliHLTdNdPtAnalysisComponent.h"
#include "AliHLTdNdPtAnalysisMergerComponent.h"
#include "AliHLTGlobalVertexerHistoComponent.h"
#include "AliHLTGlobalHistoComponent.h"
#include "AliHLTGlobalHistoCollector.h"
#include "AliHLTGlobalDCSPublisherComponent.h"
#include "AliHLTMultiplicityCorrelationsComponent.h"
#include "AliHLTPrimaryVertexFinderComponent.h"
#include "AliHLTV0FinderComponent.h"
#include "AliHLTAnalysisManagerComponent.h"
#include "AliHLTAsyncTestComponent.h"
#include "AliHLTLumiRegComponent.h"
#include "AliHLTGlobalPromptRecoQAComponent.h"
#include "AliHLTRootObjectMergerComponent.h"
#include "AliHLTAsyncCalibrationComponent.h"
#include "AliHLTZeroComponent.h"
#ifdef ZMQ
#include "AliHLTZMQsink.h"
#include "AliHLTZMQsource.h"
#endif

// header file for preprocessor plugin
#include "AliHLTGlobalPreprocessor.h"

#define NOCOMPRESS

/** global instance for agent registration */
AliHLTGlobalAgent gAliHLTGlobalAgent;

/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTGlobalAgent)

AliHLTGlobalAgent::AliHLTGlobalAgent()
  :
  AliHLTModuleAgent("Global")
{
  // see header file for class documentation
  // or
  // refer to README to build package
  // or
  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
}

AliHLTGlobalAgent::~AliHLTGlobalAgent()
{
  // see header file for class documentation
}

int AliHLTGlobalAgent::RegisterComponents(AliHLTComponentHandler* pHandler) const
{
  // see header file for class documentation
  assert(pHandler);
  if (!pHandler) return -EINVAL;
  pHandler->AddComponent(new AliHLTGlobalEsdToFlatConverterComponent);
  pHandler->AddComponent(new AliHLTGlobalCompareFlatComponent);
  pHandler->AddComponent(new AliHLTGlobalFlatEsdTestComponent);
  pHandler->AddComponent(new AliHLTGlobalTrackMergerComponent);
  pHandler->AddComponent(new AliHLTGlobalFlatEsdConverterComponent);
  pHandler->AddComponent(new AliHLTGlobalEsdConverterComponent);
  pHandler->AddComponent(new AliHLTGlobalVertexerComponent);
  pHandler->AddComponent(new AliHLTGlobalOfflineVertexerComponent);
  pHandler->AddComponent(new AliHLTGlobalVertexerHistoComponent);
  pHandler->AddComponent(new AliHLTGlobalHistoComponent);
  pHandler->AddComponent(new AliHLTV0HistoComponent );
  //pHandler->AddComponent(new AliHLTdNdPtAnalysisComponent );
  //pHandler->AddComponent(new AliHLTdNdPtAnalysisMergerComponent );
  pHandler->AddComponent(new AliHLTMultiplicityCorrelationsComponent );
  pHandler->AddComponent(new AliHLTPrimaryVertexFinderComponent);
  pHandler->AddComponent(new AliHLTV0FinderComponent);
  pHandler->AddComponent(new AliHLTGlobalHistoCollector );
  pHandler->AddComponent(new AliHLTGlobalDCSPublisherComponent );
  pHandler->AddComponent(new AliHLTAnalysisManagerComponent);
  pHandler->AddComponent(new AliHLTAsyncTestComponent);
  pHandler->AddComponent(new AliHLTAsyncCalibrationComponent);
  pHandler->AddComponent(new AliHLTZeroComponent);
  pHandler->AddComponent(new AliHLTLumiRegComponent);
  pHandler->AddComponent(new AliHLTGlobalPromptRecoQAComponent);
  pHandler->AddComponent(new AliHLTRootObjectMergerComponent);
#ifdef ZMQ
  pHandler->AddComponent(new AliHLTZMQsink);
  pHandler->AddComponent(new AliHLTZMQsource);
#endif
  return 0;
}

int AliHLTGlobalAgent::CreateConfigurations(AliHLTConfigurationHandler* pHandler,
					    AliRawReader* /*rawReader*/,
					    AliRunLoader* /*runloader*/) const
{
  // see header file for class documentation
  if (!pHandler) return -EINVAL;
  TObjArray* pTokens=NULL;

  ///////////////////////////////////////////////////////////////////////////////////////////////////
  //
  // global vertexer component
  //
  // define the inputs
  TString vertexerInputs="TPC-globalmerger ITS-tracker";

  // check for the availibility
  pTokens=vertexerInputs.Tokenize(" ");
  vertexerInputs="";
  if (pTokens) {
    for (int n=0; n<pTokens->GetEntriesFast(); n++) {
      TString module=((TObjString*)pTokens->At(n))->GetString();
      if (pHandler->FindConfiguration(module.Data())) {
	vertexerInputs+=module;
	vertexerInputs+=" ";
      }
    }
    delete pTokens;
    pTokens=NULL;
  }
  cout<<endl<<"\n\nConfiguring inputs to global HLT Vertexer: "<<vertexerInputs.Data()<<endl<<endl;
  if (!vertexerInputs.IsNull()) {
    HLTInfo("\n\nConfiguring inputs to global HLT Vertexer: %s\n\n", vertexerInputs.Data());
    pHandler->CreateConfiguration("GLOBAL-vertexer","GlobalVertexer",vertexerInputs,"");
  } else {
    HLTWarning("\n\nNo inputs to global HLT Vertexer found\n\n");
  }

  /////////////////////////////////////////////////////////////////////////////////////
  //
  // assembly of the global ESD

  // define the inputs to the global ESD
  TString esdInputs="TPC-globalmerger TPC-mcTrackMarker ITS-tracker TPC-ClusterTransformation GLOBAL-vertexer ITS-SPD-vertexer TPC-dEdx VZERO-RECO ITS-SAPtracker";

  // check for the availibility
  pTokens=esdInputs.Tokenize(" ");
  esdInputs="";
  if (pTokens) {
    for (int n=0; n<pTokens->GetEntriesFast(); n++) {
      TString module=((TObjString*)pTokens->At(n))->GetString();
      if (pHandler->FindConfiguration(module.Data())) {
	esdInputs+=module;
	esdInputs+=" ";
      }
    }
    delete pTokens;
    pTokens=NULL;
  }

  if (esdInputs.Length()>0) {
    esdInputs+=" TPC-ClusterTransformation";
    HLTInfo("Configuring inputs to global HLT ESD: %s", esdInputs.Data());
  } else {
    HLTWarning("No inputs to global HLT ESD found");
  }
#ifdef NOCOMPRESS
  pHandler->CreateConfiguration("GLOBAL-flat-esd-converter", "GlobalFlatEsdConverter", esdInputs.Data(), "-object-compression=0");
  pHandler->CreateConfiguration("GLOBAL-esd-converter", "GlobalEsdConverter", esdInputs.Data(), "-object-compression=0");
  pHandler->CreateConfiguration("GLOBAL-esd-converter-friends", "GlobalEsdConverter", esdInputs.Data(), "-object-compression=0 -make-friends");
#endif

#ifndef NOCOMPRESS
  pHandler->CreateConfiguration("GLOBAL-flat-esd-converter", "GlobalFlatEsdConverter", esdInputs.Data(), "");
  pHandler->CreateConfiguration("GLOBAL-esd-converter", "GlobalEsdConverter", esdInputs.Data(), "");
  pHandler->CreateConfiguration("GLOBAL-esd-converter-friends", "GlobalEsdConverter", esdInputs.Data(), "-make-friends");
#endif
  pHandler->CreateConfiguration("GLOBAL-flat-esd-test", "GlobalFlatEsdTest", "GLOBAL-esd-converter GLOBAL-flat-esd-converter", "");
  pHandler->CreateConfiguration("esd-to-flat-conversion", "GlobalEsdToFlatConverter", "GLOBAL-esd-converter-friends", "");
  pHandler->CreateConfiguration("compare-flat", "GlobalCompareFlat", "GLOBAL-flat-esd-converter esd-to-flat-conversion", "");

  ///////////////////////////////////////////////////////////////////////////////////////////////////
  //
  // global histograms
  //
  TString vertexhistoInput="GLOBAL-vertexer ITS-SPD-vertexer";

  // check for the availibility
  pTokens=vertexhistoInput.Tokenize(" ");
  vertexhistoInput="";
  if (pTokens) {
    for (int n=0; n<pTokens->GetEntriesFast(); n++) {
      TString module=((TObjString*)pTokens->At(n))->GetString();
      if (pHandler->FindConfiguration(module.Data())) {
	vertexhistoInput+=module;
	vertexhistoInput+=" ";
      }
    }
    delete pTokens;
    pTokens=NULL;
  }

  if (!vertexhistoInput.IsNull()) {
    HLTInfo("Configuring inputs to global HLT Vertex histogram component: %s", vertexhistoInput.Data());
    pHandler->CreateConfiguration("GLOBAL-vertexhisto","GlobalVertexerHisto", vertexhistoInput.Data(),"");
  } else {
    HLTWarning("No inputs to global HLT Vertex histogram component found");
  }

  //pHandler->CreateConfiguration("GLOBAL-dNdPtAnalysis", "dNdPtAnalysis", "GLOBAL-esd-converter", "");

  pHandler->CreateConfiguration("GLOBAL-MultCorr", "MultiplicityCorrelations", "GLOBAL-esd-converter", "");

  return 0;
}

const char* AliHLTGlobalAgent::GetReconstructionChains(AliRawReader* /*rawReader*/,
						    AliRunLoader* runloader) const
{
  // see header file for class documentation
  if (runloader) {
    // reconstruction chains for AliRoot simulation
    // Note: run loader is only available while running embedded into
    // AliRoot simulation
    return "GLOBAL-esd-converter";
  }
  return NULL;
}

const char* AliHLTGlobalAgent::GetRequiredComponentLibraries() const
{
  // see header file for class documentation

  return "";
}

int AliHLTGlobalAgent::GetHandlerDescription(AliHLTComponentDataType /*dt*/,
					     AliHLTUInt32_t /*spec*/,
					     AliHLTOUTHandlerDesc& /*desc*/) const
{
  // see header file for class documentation

  return 0;
}

AliHLTOUTHandler* AliHLTGlobalAgent::GetOutputHandler(AliHLTComponentDataType /*dt*/,
						      AliHLTUInt32_t /*spec*/)
{
  // see header file for class documentation

  return NULL;
}

int AliHLTGlobalAgent::DeleteOutputHandler(AliHLTOUTHandler* pInstance)
{
  // see header file for class documentation
  if (pInstance==NULL) return -EINVAL;

  return 0;
}

AliHLTModulePreprocessor* AliHLTGlobalAgent::GetPreprocessor()
{
  // create the preprocessor plugin
  return new AliHLTGlobalPreprocessor;
}
<commit_msg>add a configuration of GLOBAL-esd-converter-schema with schema enabled<commit_after>// $Id$

//**************************************************************************
//* This file is property of and copyright by the ALICE HLT Project        *
//* ALICE Experiment at CERN, All rights reserved.                         *
//*                                                                        *
//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
//*                  for The ALICE HLT Project.                            *
//*                                                                        *
//* Permission to use, copy, modify and distribute this software and its   *
//* documentation strictly for non-commercial purposes is hereby granted   *
//* without fee, provided that the above copyright notice appears in all   *
//* copies and that both the copyright notice and this permission notice   *
//* appear in the supporting documentation. The authors make no claims     *
//* about the suitability of this software for any purpose. It is          *
//* provided "as is" without express or implied warranty.                  *
//**************************************************************************

/** @file   AliHLTGlobalAgent.cxx
    @author Matthias Richter
    @date
    @brief  Agent of the libAliHLTGlobal library
*/

#include <cassert>
#include "AliHLTGlobalAgent.h"
#include "AliHLTConfigurationHandler.h"
#include "TObjString.h"
#include "TObjArray.h"
#include "AliHLTGlobalFlatEsdTestComponent.h"

// header files of library components
#include "AliHLTGlobalTrackMergerComponent.h"
#include "AliHLTGlobalCompareFlatComponent.h"
#include "AliHLTGlobalEsdToFlatConverterComponent.h"
#include "AliHLTGlobalFlatEsdConverterComponent.h"
#include "AliHLTGlobalEsdConverterComponent.h"
#include "AliHLTGlobalVertexerComponent.h"
#include "AliHLTGlobalOfflineVertexerComponent.h"
#include "AliHLTV0HistoComponent.h"
#include "AliHLTdNdPtAnalysisComponent.h"
#include "AliHLTdNdPtAnalysisMergerComponent.h"
#include "AliHLTGlobalVertexerHistoComponent.h"
#include "AliHLTGlobalHistoComponent.h"
#include "AliHLTGlobalHistoCollector.h"
#include "AliHLTGlobalDCSPublisherComponent.h"
#include "AliHLTMultiplicityCorrelationsComponent.h"
#include "AliHLTPrimaryVertexFinderComponent.h"
#include "AliHLTV0FinderComponent.h"
#include "AliHLTAnalysisManagerComponent.h"
#include "AliHLTAsyncTestComponent.h"
#include "AliHLTLumiRegComponent.h"
#include "AliHLTGlobalPromptRecoQAComponent.h"
#include "AliHLTRootObjectMergerComponent.h"
#include "AliHLTAsyncCalibrationComponent.h"
#include "AliHLTZeroComponent.h"
#ifdef ZMQ
#include "AliHLTZMQsink.h"
#include "AliHLTZMQsource.h"
#endif

// header file for preprocessor plugin
#include "AliHLTGlobalPreprocessor.h"

#define NOCOMPRESS

/** global instance for agent registration */
AliHLTGlobalAgent gAliHLTGlobalAgent;

/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTGlobalAgent)

AliHLTGlobalAgent::AliHLTGlobalAgent()
  :
  AliHLTModuleAgent("Global")
{
  // see header file for class documentation
  // or
  // refer to README to build package
  // or
  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
}

AliHLTGlobalAgent::~AliHLTGlobalAgent()
{
  // see header file for class documentation
}

int AliHLTGlobalAgent::RegisterComponents(AliHLTComponentHandler* pHandler) const
{
  // see header file for class documentation
  assert(pHandler);
  if (!pHandler) return -EINVAL;
  pHandler->AddComponent(new AliHLTGlobalEsdToFlatConverterComponent);
  pHandler->AddComponent(new AliHLTGlobalCompareFlatComponent);
  pHandler->AddComponent(new AliHLTGlobalFlatEsdTestComponent);
  pHandler->AddComponent(new AliHLTGlobalTrackMergerComponent);
  pHandler->AddComponent(new AliHLTGlobalFlatEsdConverterComponent);
  pHandler->AddComponent(new AliHLTGlobalEsdConverterComponent);
  pHandler->AddComponent(new AliHLTGlobalVertexerComponent);
  pHandler->AddComponent(new AliHLTGlobalOfflineVertexerComponent);
  pHandler->AddComponent(new AliHLTGlobalVertexerHistoComponent);
  pHandler->AddComponent(new AliHLTGlobalHistoComponent);
  pHandler->AddComponent(new AliHLTV0HistoComponent );
  //pHandler->AddComponent(new AliHLTdNdPtAnalysisComponent );
  //pHandler->AddComponent(new AliHLTdNdPtAnalysisMergerComponent );
  pHandler->AddComponent(new AliHLTMultiplicityCorrelationsComponent );
  pHandler->AddComponent(new AliHLTPrimaryVertexFinderComponent);
  pHandler->AddComponent(new AliHLTV0FinderComponent);
  pHandler->AddComponent(new AliHLTGlobalHistoCollector );
  pHandler->AddComponent(new AliHLTGlobalDCSPublisherComponent );
  pHandler->AddComponent(new AliHLTAnalysisManagerComponent);
  pHandler->AddComponent(new AliHLTAsyncTestComponent);
  pHandler->AddComponent(new AliHLTAsyncCalibrationComponent);
  pHandler->AddComponent(new AliHLTZeroComponent);
  pHandler->AddComponent(new AliHLTLumiRegComponent);
  pHandler->AddComponent(new AliHLTGlobalPromptRecoQAComponent);
  pHandler->AddComponent(new AliHLTRootObjectMergerComponent);
#ifdef ZMQ
  pHandler->AddComponent(new AliHLTZMQsink);
  pHandler->AddComponent(new AliHLTZMQsource);
#endif
  return 0;
}

int AliHLTGlobalAgent::CreateConfigurations(AliHLTConfigurationHandler* pHandler,
					    AliRawReader* /*rawReader*/,
					    AliRunLoader* /*runloader*/) const
{
  // see header file for class documentation
  if (!pHandler) return -EINVAL;
  TObjArray* pTokens=NULL;

  ///////////////////////////////////////////////////////////////////////////////////////////////////
  //
  // global vertexer component
  //
  // define the inputs
  TString vertexerInputs="TPC-globalmerger ITS-tracker";

  // check for the availibility
  pTokens=vertexerInputs.Tokenize(" ");
  vertexerInputs="";
  if (pTokens) {
    for (int n=0; n<pTokens->GetEntriesFast(); n++) {
      TString module=((TObjString*)pTokens->At(n))->GetString();
      if (pHandler->FindConfiguration(module.Data())) {
	vertexerInputs+=module;
	vertexerInputs+=" ";
      }
    }
    delete pTokens;
    pTokens=NULL;
  }
  cout<<endl<<"\n\nConfiguring inputs to global HLT Vertexer: "<<vertexerInputs.Data()<<endl<<endl;
  if (!vertexerInputs.IsNull()) {
    HLTInfo("\n\nConfiguring inputs to global HLT Vertexer: %s\n\n", vertexerInputs.Data());
    pHandler->CreateConfiguration("GLOBAL-vertexer","GlobalVertexer",vertexerInputs,"");
  } else {
    HLTWarning("\n\nNo inputs to global HLT Vertexer found\n\n");
  }

  /////////////////////////////////////////////////////////////////////////////////////
  //
  // assembly of the global ESD

  // define the inputs to the global ESD
  TString esdInputs="TPC-globalmerger TPC-mcTrackMarker ITS-tracker TPC-ClusterTransformation GLOBAL-vertexer ITS-SPD-vertexer TPC-dEdx VZERO-RECO ITS-SAPtracker";

  // check for the availibility
  pTokens=esdInputs.Tokenize(" ");
  esdInputs="";
  if (pTokens) {
    for (int n=0; n<pTokens->GetEntriesFast(); n++) {
      TString module=((TObjString*)pTokens->At(n))->GetString();
      if (pHandler->FindConfiguration(module.Data())) {
	esdInputs+=module;
	esdInputs+=" ";
      }
    }
    delete pTokens;
    pTokens=NULL;
  }

  if (esdInputs.Length()>0) {
    esdInputs+=" TPC-ClusterTransformation";
    HLTInfo("Configuring inputs to global HLT ESD: %s", esdInputs.Data());
  } else {
    HLTWarning("No inputs to global HLT ESD found");
  }
#ifdef NOCOMPRESS
  pHandler->CreateConfiguration("GLOBAL-flat-esd-converter", "GlobalFlatEsdConverter", esdInputs.Data(), "-object-compression=0");
  pHandler->CreateConfiguration("GLOBAL-esd-converter", "GlobalEsdConverter", esdInputs.Data(), "-object-compression=0");
  pHandler->CreateConfiguration("GLOBAL-esd-converter-friends", "GlobalEsdConverter", esdInputs.Data(), "-object-compression=0 -make-friends");
  pHandler->CreateConfiguration("GLOBAL-esd-converter-schema", "GlobalEsdConverter", esdInputs.Data(), "-object-compression=0 -schema");
#endif

#ifndef NOCOMPRESS
  pHandler->CreateConfiguration("GLOBAL-flat-esd-converter", "GlobalFlatEsdConverter", esdInputs.Data(), "");
  pHandler->CreateConfiguration("GLOBAL-esd-converter", "GlobalEsdConverter", esdInputs.Data(), "");
  pHandler->CreateConfiguration("GLOBAL-esd-converter-friends", "GlobalEsdConverter", esdInputs.Data(), "-make-friends");
#endif
  pHandler->CreateConfiguration("GLOBAL-flat-esd-test", "GlobalFlatEsdTest", "GLOBAL-esd-converter GLOBAL-flat-esd-converter", "");
  pHandler->CreateConfiguration("esd-to-flat-conversion", "GlobalEsdToFlatConverter", "GLOBAL-esd-converter-friends", "");
  pHandler->CreateConfiguration("compare-flat", "GlobalCompareFlat", "GLOBAL-flat-esd-converter esd-to-flat-conversion", "");

  ///////////////////////////////////////////////////////////////////////////////////////////////////
  //
  // global histograms
  //
  TString vertexhistoInput="GLOBAL-vertexer ITS-SPD-vertexer";

  // check for the availibility
  pTokens=vertexhistoInput.Tokenize(" ");
  vertexhistoInput="";
  if (pTokens) {
    for (int n=0; n<pTokens->GetEntriesFast(); n++) {
      TString module=((TObjString*)pTokens->At(n))->GetString();
      if (pHandler->FindConfiguration(module.Data())) {
	vertexhistoInput+=module;
	vertexhistoInput+=" ";
      }
    }
    delete pTokens;
    pTokens=NULL;
  }

  if (!vertexhistoInput.IsNull()) {
    HLTInfo("Configuring inputs to global HLT Vertex histogram component: %s", vertexhistoInput.Data());
    pHandler->CreateConfiguration("GLOBAL-vertexhisto","GlobalVertexerHisto", vertexhistoInput.Data(),"");
  } else {
    HLTWarning("No inputs to global HLT Vertex histogram component found");
  }

  //pHandler->CreateConfiguration("GLOBAL-dNdPtAnalysis", "dNdPtAnalysis", "GLOBAL-esd-converter", "");

  pHandler->CreateConfiguration("GLOBAL-MultCorr", "MultiplicityCorrelations", "GLOBAL-esd-converter", "");

  return 0;
}

const char* AliHLTGlobalAgent::GetReconstructionChains(AliRawReader* /*rawReader*/,
						    AliRunLoader* runloader) const
{
  // see header file for class documentation
  if (runloader) {
    // reconstruction chains for AliRoot simulation
    // Note: run loader is only available while running embedded into
    // AliRoot simulation
    return "GLOBAL-esd-converter";
  }
  return NULL;
}

const char* AliHLTGlobalAgent::GetRequiredComponentLibraries() const
{
  // see header file for class documentation

  return "";
}

int AliHLTGlobalAgent::GetHandlerDescription(AliHLTComponentDataType /*dt*/,
					     AliHLTUInt32_t /*spec*/,
					     AliHLTOUTHandlerDesc& /*desc*/) const
{
  // see header file for class documentation

  return 0;
}

AliHLTOUTHandler* AliHLTGlobalAgent::GetOutputHandler(AliHLTComponentDataType /*dt*/,
						      AliHLTUInt32_t /*spec*/)
{
  // see header file for class documentation

  return NULL;
}

int AliHLTGlobalAgent::DeleteOutputHandler(AliHLTOUTHandler* pInstance)
{
  // see header file for class documentation
  if (pInstance==NULL) return -EINVAL;

  return 0;
}

AliHLTModulePreprocessor* AliHLTGlobalAgent::GetPreprocessor()
{
  // create the preprocessor plugin
  return new AliHLTGlobalPreprocessor;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_dmi_clear_firs.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_io_dmi_clear_firs.C
/// @brief Clears I/O Firs
///-----------------------------------------------------------------------------
/// *HWP HWP Owner        : Chris Steffen <cwsteffen@us.ibm.com>
/// *HWP HWP Backup Owner : Gary Peterson <garyp@us.ibm.com>
/// *HWP FW Owner         : Jamie Knight <rjknight@us.ibm.com>
/// *HWP Team             : IO
/// *HWP Level            : 2
/// *HWP Consumed by      : FSP:HB
///-----------------------------------------------------------------------------
///
/// @verbatim
/// High-level procedure flow:
///
/// Clears I/O Xbus FIRs on the PHY Rx/Tx.
///
/// Clocks must be running.
///
/// @endverbatim
///----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//  Includes
//-----------------------------------------------------------------------------
#include <p9_io_dmi_clear_firs.H>
#include <p9_io_scom.H>
#include <p9_io_regs.H>

//-----------------------------------------------------------------------------
//  Definitions
//-----------------------------------------------------------------------------
fapi2::ReturnCode io_rx_fir_reset(
    const fapi2::Target < fapi2::TARGET_TYPE_DMI >& i_target);

fapi2::ReturnCode io_tx_fir_reset(
    const fapi2::Target < fapi2::TARGET_TYPE_DMI >& i_target);

/**
 * @brief Clears PHY Rx/Tx FIRs on the DMI(EDI+) specified target.  The FIRs
 *   are cleared by toggling a rx & tx fir reset bit.
 * @param[in] i_target         FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode p9_io_dmi_clear_firs(
    const fapi2::Target < fapi2::TARGET_TYPE_DMI >& i_target)
{
    FAPI_IMP("I/O Start DMI Clear FIRs");

    FAPI_TRY(io_tx_fir_reset(i_target), "Tx Reset Failed");

    FAPI_TRY(io_rx_fir_reset(i_target), "Rx Reset Failed");

fapi_try_exit:
    FAPI_IMP("I/O End DMI Clear FIRs");
    return fapi2::current_err;
}

/**
 * @brief This function resets the Rx Firs on a EDI+ DMI
 * @param[in] i_target       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_rx_fir_reset(
    const fapi2::Target < fapi2::TARGET_TYPE_DMI >& i_target)
{
    const uint8_t GRP3 = 3;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDIP_RX_FIR_RESET, i_target, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_target, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_target, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_target, GRP3, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief This function resets the Tx Firs on a EDI+ DMI
 * @param[in] i_target       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_tx_fir_reset(
    const fapi2::Target < fapi2::TARGET_TYPE_DMI >& i_target)
{
    const uint8_t GRP3 = 3;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDIP_TX_FIR_RESET, i_target, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_target, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_target, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_target, GRP3, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}
<commit_msg>DMI Linktraining and Centaur Dccal<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/io/p9_io_dmi_clear_firs.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file p9_io_dmi_clear_firs.C
/// @brief Clears I/O Firs
///-----------------------------------------------------------------------------
/// *HWP HWP Owner        : Chris Steffen <cwsteffen@us.ibm.com>
/// *HWP HWP Backup Owner : Gary Peterson <garyp@us.ibm.com>
/// *HWP FW Owner         : Jamie Knight <rjknight@us.ibm.com>
/// *HWP Team             : IO
/// *HWP Level            : 2
/// *HWP Consumed by      : FSP:HB
///-----------------------------------------------------------------------------
///
/// @verbatim
/// High-level procedure flow:
///
/// Clears I/O Xbus FIRs on the PHY Rx/Tx.
///
/// Clocks must be running.
///
/// @endverbatim
///----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
//  Includes
//-----------------------------------------------------------------------------
#include <p9_io_dmi_clear_firs.H>
#include <p9_io_scom.H>
#include <p9_io_regs.H>

//-----------------------------------------------------------------------------
//  Definitions
//-----------------------------------------------------------------------------
fapi2::ReturnCode io_dmi_proc_rx_fir_reset(const DMI_PROC_TGT& i_tgt);
fapi2::ReturnCode io_dmi_proc_tx_fir_reset(const DMI_PROC_TGT& i_tgt);

fapi2::ReturnCode io_dmi_cn_rx_fir_reset(const DMI_CN_TGT& i_tgt);
fapi2::ReturnCode io_dmi_cn_tx_fir_reset(const DMI_CN_TGT& i_tgt);

/**
 * @brief Clears PHY Rx/Tx FIRs on the DMI(EDI+) specified target.  The FIRs
 *   are cleared by toggling a rx & tx fir reset bit.
 * @param[in] i_tgt         FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode p9_io_dmi_proc_clear_firs(const DMI_PROC_TGT& i_tgt)
{
    FAPI_IMP("I/O Start DMI Proc Clear FIRs");

    FAPI_TRY(io_dmi_proc_tx_fir_reset(i_tgt), "Tx Reset Failed");

    FAPI_TRY(io_dmi_proc_rx_fir_reset(i_tgt), "Rx Reset Failed");

fapi_try_exit:
    FAPI_IMP("I/O End DMI Proc Clear FIRs");
    return fapi2::current_err;
}

/**
 * @brief This function resets the Rx Firs on a EDI+ DMI
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_proc_rx_fir_reset(const DMI_PROC_TGT& i_tgt)
{
    const uint8_t GRP3 = 3;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_RX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief This function resets the Tx Firs on a EDI+ DMI
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_proc_tx_fir_reset(const DMI_PROC_TGT& i_tgt)
{
    const uint8_t GRP3 = 3;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

    io::set (EDIP_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDIP_TX_FIR_RESET, i_tgt, GRP3, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief Clears PHY Rx/Tx FIRs on the DMI Centaur(EDI) specified target.  The FIRs
 *   are cleared by toggling a rx & tx fir reset bit.
 * @param[in] i_tgt         FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode p9_io_dmi_cn_clear_firs(const DMI_CN_TGT& i_tgt)
{
    FAPI_IMP("I/O Start DMI Proc Clear FIRs");

    FAPI_TRY(io_dmi_cn_tx_fir_reset(i_tgt), "Tx Reset Failed");

    FAPI_TRY(io_dmi_cn_rx_fir_reset(i_tgt), "Rx Reset Failed");

fapi_try_exit:
    FAPI_IMP("I/O End DMI Proc Clear FIRs");
    return fapi2::current_err;
}

/**
 * @brief This function resets the Rx Firs on a EDI DMI Centaur
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_cn_rx_fir_reset(const DMI_CN_TGT& i_tgt)
{
    const uint8_t GRP0 = 0;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_RX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_RX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_RX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}

/**
 * @brief This function resets the Tx Firs on a EDI DMI Centaur
 * @param[in] i_tgt       FAPI2 Target
 * @retval ReturnCode
 */
fapi2::ReturnCode io_dmi_cn_tx_fir_reset(const DMI_CN_TGT& i_tgt)
{
    const uint8_t GRP0 = 0;
    const uint8_t LN0 = 0;
    uint64_t l_data = 0;

    FAPI_TRY(io::read(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_TX_FIR_RESET, 1, l_data);
    FAPI_TRY(io::write(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

    io::set (EDI_TX_FIR_RESET, 0, l_data);
    FAPI_TRY(io::write(EDI_TX_FIR_RESET, i_tgt, GRP0, LN0, l_data));

fapi_try_exit:
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_homer.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file   p9_hcd_memmap_homer.H
/// @brief  defines region constants of homer.
///

// *HWP HWP Owner:        David Du   <daviddu@us.ibm.com>
// *HWP Backup HWP Owner: Greg Still <stillgs@us.ibm.com>
// *HWP FW Owner:         Prem S Jha <premjha2@in.ibm.com>
// *HWP Team:             PM
// *HWP Level:            2
// *HWP Consumed by:      PM:Hostboot:Phyp

#ifndef __P9_HCD_MEMMAP_HOMER_H__
#define __P9_HCD_MEMMAP_HOMER_H__

#include <p9_hcd_header_defs.H>
#include <p9_hcd_memmap_base.H>

// -------------------------------------------------------------------
// Note: There can be NO semicolons(";") at end of macros in this file
//       There can ONLY have HCD_CONST/HCD_CONST64 macros in this file
//--------------------------------------------------------------------

/// HOMER

HCD_CONST(HOMER_BASE_ADDR,                 0x80000000)

/// QPMR

HCD_CONST(HOMER_QPMR_BASE_ADDR,            (HOMER_BASE_ADDR + (QPMR_HOMER_OFFSET)))
HCD_CONST(HOMER_QPMR_HEADER_ADDR,          HOMER_QPMR_BASE_ADDR)
HCD_CONST(HOMER_SGPE_BOOT_LOADER_OFFSET_ADDR,
          (HOMER_QPMR_HEADER_ADDR + QPMR_BOOT_LOADER_OFFSET_BYTE))
HCD_CONST(HOMER_SGPE_BOOT_LOADER_LENGTH_ADDR,
          (HOMER_QPMR_HEADER_ADDR + QPMR_BOOT_LOADER_LENGTH_BYTE))
HCD_CONST(HOMER_SGPE_BOOT_COPIER_ADDR,
          (HOMER_QPMR_HEADER_ADDR + QPMR_HEADER_SIZE))
HCD_CONST(HOMER_AUX_BASE_ADDR, (HOMER_QPMR_BASE_ADDR + QPMR_AUX_OFFSET))

/// CPMR

HCD_CONST(HOMER_CPMR_BASE_ADDR,            (HOMER_BASE_ADDR + (CPMR_HOMER_OFFSET)))
HCD_CONST(HOMER_CPMR_HEADER_ADDR,          HOMER_CPMR_BASE_ADDR)
HCD_CONST(HOMER_CPMR_TRACE_ADDR,           (HOMER_CPMR_BASE_ADDR + CPMR_TRACE_REGION_OFFSET))
HCD_CONST(HOMER_CPMR_DEBUG_ADDR,           (HOMER_CPMR_BASE_ADDR + CPMR_DEBUG_REGION_OFFSET))

/// PPMR

HCD_CONST(HOMER_PPMR_BASE_ADDR,            (HOMER_BASE_ADDR + (PPMR_HOMER_OFFSET)))
HCD_CONST(HOMER_PPMR_HEADER_ADDR,          HOMER_PPMR_BASE_ADDR)
HCD_CONST(HOMER_PGPE_BOOT_LOADER_OFFSET_ADDR,
          (HOMER_PPMR_HEADER_ADDR + PPMR_BOOT_LOADER_OFFSET_BYTE))
HCD_CONST(HOMER_PGPE_BOOT_LOADER_LENGTH_ADDR,
          (HOMER_PPMR_HEADER_ADDR + PPMR_BOOT_LOADER_LENGTH_BYTE))
HCD_CONST(HOMER_PGPE_BOOT_COPIER_ADDR,
          (HOMER_PPMR_HEADER_ADDR + PPMR_HEADER_SIZE))

HCD_CONST(HOMER_OCC_PSTATE_PARAM_BLOCK_ADDR,
          (HOMER_PPMR_BASE_ADDR + OCC_PSTATE_PARAM_BLOCK_PPMR_OFFSET));
HCD_CONST(HOMER_PGPE_PSTATE_OUTPUT_TABLES_ADDR,
          (HOMER_PPMR_BASE_ADDR + PGPE_PSTATE_OUTPUT_TABLES_PPMR_OFFSET));
HCD_CONST(HOMER_OCC_WOF_TABLES_ADDR,
          (HOMER_PPMR_BASE_ADDR + OCC_WOF_TABLES_PPMR_OFFSET));

#endif /* __P9_HCD_MEMMAP_HOMER_H__ */
<commit_msg>Characterization Default Image<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/lib/p9_hcd_memmap_homer.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
///
/// @file   p9_hcd_memmap_homer.H
/// @brief  defines region constants of homer.
///

// *HWP HWP Owner:        David Du   <daviddu@us.ibm.com>
// *HWP Backup HWP Owner: Greg Still <stillgs@us.ibm.com>
// *HWP FW Owner:         Prem S Jha <premjha2@in.ibm.com>
// *HWP Team:             PM
// *HWP Level:            2
// *HWP Consumed by:      PM:Hostboot:Phyp

#ifndef __P9_HCD_MEMMAP_HOMER_H__
#define __P9_HCD_MEMMAP_HOMER_H__

#include <p9_hcd_header_defs.H>
#include <p9_hcd_memmap_base.H>

// -------------------------------------------------------------------
// Note: There can be NO semicolons(";") at end of macros in this file
//       There can ONLY have HCD_CONST/HCD_CONST64 macros in this file
//--------------------------------------------------------------------

/// HOMER

HCD_CONST(HOMER_BASE_ADDR,                 0x80000000)

/// QPMR

HCD_CONST(HOMER_QPMR_BASE_ADDR,            (HOMER_BASE_ADDR + (QPMR_HOMER_OFFSET)))
HCD_CONST(HOMER_QPMR_HEADER_ADDR,          HOMER_QPMR_BASE_ADDR)
HCD_CONST(HOMER_SGPE_BOOT_LOADER_OFFSET_ADDR,
          (HOMER_QPMR_HEADER_ADDR + QPMR_BOOT_LOADER_OFFSET_BYTE))
HCD_CONST(HOMER_SGPE_BOOT_LOADER_LENGTH_ADDR,
          (HOMER_QPMR_HEADER_ADDR + QPMR_BOOT_LOADER_LENGTH_BYTE))
HCD_CONST(HOMER_SGPE_BOOT_COPIER_ADDR,
          (HOMER_QPMR_HEADER_ADDR + QPMR_HEADER_SIZE))
HCD_CONST(HOMER_AUX_BASE_ADDR, (HOMER_QPMR_BASE_ADDR + QPMR_AUX_OFFSET))

/// CPMR

HCD_CONST(HOMER_CPMR_BASE_ADDR,            (HOMER_BASE_ADDR + (CPMR_HOMER_OFFSET)))
HCD_CONST(HOMER_CPMR_HEADER_ADDR,          HOMER_CPMR_BASE_ADDR)
HCD_CONST(HOMER_CPMR_TRACE_ADDR,           (HOMER_CPMR_BASE_ADDR + CPMR_TRACE_REGION_OFFSET))
HCD_CONST(HOMER_CPMR_DEBUG_ADDR,           (HOMER_CPMR_BASE_ADDR + CPMR_DEBUG_REGION_OFFSET))

/// PPMR

HCD_CONST(HOMER_PPMR_BASE_ADDR,            (HOMER_BASE_ADDR + (PPMR_HOMER_OFFSET)))
HCD_CONST(HOMER_PPMR_HEADER_ADDR,          HOMER_PPMR_BASE_ADDR)
HCD_CONST(HOMER_PGPE_BOOT_LOADER_OFFSET_ADDR,
          (HOMER_PPMR_HEADER_ADDR + PPMR_BOOT_LOADER_OFFSET_BYTE))
HCD_CONST(HOMER_PGPE_BOOT_LOADER_LENGTH_ADDR,
          (HOMER_PPMR_HEADER_ADDR + PPMR_BOOT_LOADER_LENGTH_BYTE))
HCD_CONST(HOMER_PGPE_BOOT_COPIER_ADDR,
          (HOMER_PPMR_HEADER_ADDR + PPMR_HEADER_SIZE))

HCD_CONST(HOMER_OCC_PSTATE_PARAM_BLOCK_ADDR,
          (HOMER_PPMR_BASE_ADDR + OCC_PSTATE_PARAM_BLOCK_PPMR_OFFSET))
HCD_CONST(HOMER_PGPE_PSTATE_OUTPUT_TABLES_ADDR,
          (HOMER_PPMR_BASE_ADDR + PGPE_PSTATE_OUTPUT_TABLES_PPMR_OFFSET))
HCD_CONST(HOMER_OCC_WOF_TABLES_ADDR,
          (HOMER_PPMR_BASE_ADDR + OCC_WOF_TABLES_PPMR_OFFSET))

#endif /* __P9_HCD_MEMMAP_HOMER_H__ */
<|endoftext|>


<commit_before>/*  Sirikata
 *  TriangulateFilter.cpp
 *
 *  Copyright (c) 2010, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "TriangulateFilter.hpp"

namespace Sirikata {
namespace Mesh {

Filter* TriangulateFilter::create(const String& args) {
    bool tri_strips = false;
    bool tri_fans = false;
    if (args.size() == 0) {
        tri_strips = true;
        tri_fans = true;
    }
    else {
        if (args == "tristrip")
            tri_strips = true;
        else if (args == "trifan")
            tri_fans = true;
        else if (args == "all") {
            tri_strips = true;
            tri_fans = true;
        }
    }

    return new TriangulateFilter(tri_strips, tri_fans);
}

TriangulateFilter::TriangulateFilter(bool tristrips, bool trifans)
 : mTriStrips(tristrips), mTriFans(trifans)
{
}

FilterDataPtr TriangulateFilter::apply(FilterDataPtr input) {
    for(FilterData::const_iterator md_it = input->begin(); md_it != input->end(); md_it++) {
        MeshdataPtr md = *md_it;

        // We just run through the primitives in each SubMeshGeometry and
        // transform each one as necessary
        for(SubMeshGeometryList::iterator sm_it = md->geometry.begin(); sm_it != md->geometry.end(); sm_it++) {
            SubMeshGeometry& smg = *sm_it;
            for(std::vector<SubMeshGeometry::Primitive>::iterator prim_it = smg.primitives.begin(); prim_it != smg.primitives.end(); prim_it++) {
                if (prim_it->primitiveType == SubMeshGeometry::Primitive::TRISTRIPS && mTriStrips) {
                    SubMeshGeometry::Primitive new_prim;
                    new_prim.primitiveType = SubMeshGeometry::Primitive::TRIANGLES;
                    new_prim.materialId = prim_it->materialId;

                    // Triangle strips have n triangles generated by n+2
                    // indices. Triangle n is defined by vertices n, n+1, n+2.
                    // This is simple enough, but we need to pay careful
                    // attention to winding order. From the GL Programming
                    // Guide:
                    //
                    //   GL_TRIANGLE_STRIP Draws a series of triangles
                    //   (three-sided polygons) using vertices v0, v1, v2, then
                    //   v2, v1, v3 (note the order), then v2, v3, v4, and so
                    //   on. The ordering is to ensure that the triangles are
                    //   all drawn with the same orientation so that the strip
                    //   can correctly form part of a surface.
                    //
                    // (This is what COLLADA and pretty much everybody else does,
                    // the GL Programming Guide just has a nicer explanation.)
                    //
                    // So our basic approach is to iterate and just track a
                    // flip-flopping winding order based on index, generating
                    // the different triplet for each winding order: 0, 1, 2 or
                    // 1, 0, 2.

                    for(int tri_idx = 0; tri_idx < prim_it->indices.size()-2; tri_idx++) {
                        if (tri_idx % 2 == 0) {
                            new_prim.indices.push_back( prim_it->indices[tri_idx] );
                            new_prim.indices.push_back( prim_it->indices[tri_idx+1] );
                            new_prim.indices.push_back( prim_it->indices[tri_idx+2] );
                        }
                        else {
                            new_prim.indices.push_back( prim_it->indices[tri_idx+1] );
                            new_prim.indices.push_back( prim_it->indices[tri_idx+0] );
                            new_prim.indices.push_back( prim_it->indices[tri_idx+2] );
                        }
                    }

                    *prim_it = new_prim;
                }
                else if (prim_it->primitiveType == SubMeshGeometry::Primitive::TRIFANS && mTriFans) {
                    SubMeshGeometry::Primitive new_prim;
                    new_prim.primitiveType = SubMeshGeometry::Primitive::TRIANGLES;
                    new_prim.materialId = prim_it->materialId;

                    // Triangle fans are pretty simple. They generate n
                    // triangles for n+2 vertices. Triangle n is formed by
                    // vertices 0, n+1, n+2, in that order.
                    for(int tri_idx = 0; tri_idx < prim_it->indices.size()-2; tri_idx++) {
                        new_prim.indices.push_back( prim_it->indices[0] );
                        new_prim.indices.push_back( prim_it->indices[tri_idx+1] );
                        new_prim.indices.push_back( prim_it->indices[tri_idx+2] );
                    }

                    *prim_it = new_prim;
                }
            }
        }
    }

    return input;
}

} // namespace Mesh
} // namespace Sirikata
<commit_msg>Change indexing in TriangulateFilter to avoid signed/unsigned bug when indices.size() == 0 for a primitive.<commit_after>/*  Sirikata
 *  TriangulateFilter.cpp
 *
 *  Copyright (c) 2010, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "TriangulateFilter.hpp"

namespace Sirikata {
namespace Mesh {

Filter* TriangulateFilter::create(const String& args) {
    bool tri_strips = false;
    bool tri_fans = false;
    if (args.size() == 0) {
        tri_strips = true;
        tri_fans = true;
    }
    else {
        if (args == "tristrip")
            tri_strips = true;
        else if (args == "trifan")
            tri_fans = true;
        else if (args == "all") {
            tri_strips = true;
            tri_fans = true;
        }
    }

    return new TriangulateFilter(tri_strips, tri_fans);
}

TriangulateFilter::TriangulateFilter(bool tristrips, bool trifans)
 : mTriStrips(tristrips), mTriFans(trifans)
{
}

FilterDataPtr TriangulateFilter::apply(FilterDataPtr input) {
    for(FilterData::const_iterator md_it = input->begin(); md_it != input->end(); md_it++) {
        MeshdataPtr md = *md_it;

        // We just run through the primitives in each SubMeshGeometry and
        // transform each one as necessary
        for(SubMeshGeometryList::iterator sm_it = md->geometry.begin(); sm_it != md->geometry.end(); sm_it++) {
            SubMeshGeometry& smg = *sm_it;
            for(std::vector<SubMeshGeometry::Primitive>::iterator prim_it = smg.primitives.begin(); prim_it != smg.primitives.end(); prim_it++) {
                if (prim_it->primitiveType == SubMeshGeometry::Primitive::TRISTRIPS && mTriStrips) {
                    SubMeshGeometry::Primitive new_prim;
                    new_prim.primitiveType = SubMeshGeometry::Primitive::TRIANGLES;
                    new_prim.materialId = prim_it->materialId;

                    // Triangle strips have n triangles generated by n+2
                    // indices. Triangle n is defined by vertices n, n+1, n+2.
                    // This is simple enough, but we need to pay careful
                    // attention to winding order. From the GL Programming
                    // Guide:
                    //
                    //   GL_TRIANGLE_STRIP Draws a series of triangles
                    //   (three-sided polygons) using vertices v0, v1, v2, then
                    //   v2, v1, v3 (note the order), then v2, v3, v4, and so
                    //   on. The ordering is to ensure that the triangles are
                    //   all drawn with the same orientation so that the strip
                    //   can correctly form part of a surface.
                    //
                    // (This is what COLLADA and pretty much everybody else does,
                    // the GL Programming Guide just has a nicer explanation.)
                    //
                    // So our basic approach is to iterate and just track a
                    // flip-flopping winding order based on index, generating
                    // the different triplet for each winding order: 0, 1, 2 or
                    // 1, 0, 2.

                    for(int tri_idx = 2; tri_idx < prim_it->indices.size(); tri_idx++) {
                        if (tri_idx % 2 == 0) {
                            new_prim.indices.push_back( prim_it->indices[tri_idx-2] );
                            new_prim.indices.push_back( prim_it->indices[tri_idx-1] );
                            new_prim.indices.push_back( prim_it->indices[tri_idx] );
                        }
                        else {
                            new_prim.indices.push_back( prim_it->indices[tri_idx-1] );
                            new_prim.indices.push_back( prim_it->indices[tri_idx-2] );
                            new_prim.indices.push_back( prim_it->indices[tri_idx] );
                        }
                    }

                    *prim_it = new_prim;
                }
                else if (prim_it->primitiveType == SubMeshGeometry::Primitive::TRIFANS && mTriFans) {
                    SubMeshGeometry::Primitive new_prim;
                    new_prim.primitiveType = SubMeshGeometry::Primitive::TRIANGLES;
                    new_prim.materialId = prim_it->materialId;

                    // Triangle fans are pretty simple. They generate n
                    // triangles for n+2 vertices. Triangle n is formed by
                    // vertices 0, n+1, n+2, in that order.
                    for(int tri_idx = 2; tri_idx < prim_it->indices.size(); tri_idx++) {
                        new_prim.indices.push_back( prim_it->indices[0] );
                        new_prim.indices.push_back( prim_it->indices[tri_idx-1] );
                        new_prim.indices.push_back( prim_it->indices[tri_idx] );
                    }

                    *prim_it = new_prim;
                }
            }
        }
    }

    return input;
}

} // namespace Mesh
} // namespace Sirikata
<|endoftext|>


<commit_before>#include <Windows.h>
#include <stdio.h>

int main(void) {
	printf("Hello");
	getchar();

	return 0;
}<commit_msg>add hello team<commit_after>#include <Windows.h>
#include <stdio.h>

int main(void) {
	printf("Hello team");
	getchar();

	return 0;
}<|endoftext|>