<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include <mitkTestFixture.h>
#include <mitkTestingMacros.h>

#include <mitkIRESTManager.h>
#include <mitkIRESTObserver.h>
#include <mitkRESTClient.h>

#include <usGetModuleContext.h>
#include <usModuleContext.h>
#include <usServiceReference.h>

#include <vtkDebugLeaks.h>

class mitkRESTClientTestSuite : public mitk::TestFixture, mitk::IRESTObserver
{
  CPPUNIT_TEST_SUITE(mitkRESTClientTestSuite);
    // MITK_TEST(GetRequestValidURI_ReturnsExpectedJSON); GET requests do not support content yet?
    MITK_TEST(MultipleGetRequestValidURI_AllTasksFinish);
    MITK_TEST(PutRequestValidURI_ReturnsExpectedJSON);
    MITK_TEST(PostRequestValidURI_ReturnsExpectedJSON);
    MITK_TEST(GetRequestInvalidURI_ThrowsException);
    MITK_TEST(PutRequestInvalidURI_ThrowsException);
    MITK_TEST(PostRequestInvalidURI_ThrowsException);
  CPPUNIT_TEST_SUITE_END();

public:
  mitk::IRESTManager *m_Service;
  web::json::value m_Data;

  web::json::value Notify(const web::uri &, const web::json::value &) override
  {
    return m_Data;
  }

  /**
   * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used
   * members for a new test case. (If the members are not used in a test, the method does not need to be called).
   */
  void setUp() override
  {
    m_Data = web::json::value();
    m_Data[_XPLATSTR("userId")] = web::json::value(1);
    m_Data[_XPLATSTR("id")] = web::json::value(1);
    m_Data[_XPLATSTR("title")] = web::json::value(U("this is a title"));
    m_Data[_XPLATSTR("body")] = web::json::value(U("this is a body"));

    us::ServiceReference<mitk::IRESTManager> serviceRef =
      us::GetModuleContext()->GetServiceReference<mitk::IRESTManager>();
    if (serviceRef)
    {
      m_Service = us::GetModuleContext()->GetService(serviceRef);
    }

    if (!m_Service)
    {
      CPPUNIT_FAIL("Getting Service in setUp() failed");
    }

    m_Service->ReceiveRequest(_XPLATSTR("http://localhost:8080/clienttest"), this);
  }

  void tearDown() override
  {
    m_Service->HandleDeleteObserver(this);
  }

  void GetRequestValidURI_ReturnsExpectedJSON()
  {
    web::json::value result;

    m_Service->SendRequest(_XPLATSTR("http://localhost:8080/clienttest"))
      .then([&](pplx::task<web::json::value> resultTask) {
        try
        {
          result = resultTask.get();
        }
        catch (const mitk::Exception &exception)
        {
          MITK_ERROR << exception.what();
          return;
        }
      })
      .wait();

    CPPUNIT_ASSERT_MESSAGE("Result is the expected JSON value", result == m_Data);
  }

  void MultipleGetRequestValidURI_AllTasksFinish()
  {
    int count = 0;

      // Create multiple tasks e.g. as shown below
    std::vector<pplx::task<void>> tasks;
    for (int i = 0; i < 20; ++i)
    {
      pplx::task<void> singleTask =
        m_Service->SendRequest(_XPLATSTR("http://localhost:8080/clienttest"))
          .then([&](pplx::task<web::json::value> resultTask) {
            // Do something when a single task is done
            try
            {
              resultTask.get();
              count +=1;
            }
            catch (const mitk::Exception &exception)
            {
              MITK_ERROR << exception.what();
              return;
            }
          });
      tasks.emplace_back(singleTask);
    }
      // Create a joinTask which includes all tasks you've created
      auto joinTask = pplx::when_all(begin(tasks), end(tasks));
      // Run asynchonously
      joinTask.then([&](pplx::task<void> resultTask) {
        // Do something when all tasks are finished
        try
        {
          resultTask.get();
          count += 1;
        }
        catch (const mitk::Exception &exception)
        {
          MITK_ERROR << exception.what();
          return;
        }
      }).wait();

    CPPUNIT_ASSERT_MESSAGE("Multiple Requests", 21 == count);
  }

  void PutRequestValidURI_ReturnsExpectedJSON()
  {
    // optional: link might get invalid or content is changed
    web::json::value result;

    m_Service
      ->SendRequest(_XPLATSTR("https://jsonplaceholder.typicode.com/posts/1"), mitk::IRESTManager::RequestType::Put, &m_Data)
      .then([&](pplx::task<web::json::value> resultTask) {
        try
        {
          result = resultTask.get();
        }
        catch (const mitk::Exception &exception)
        {
          MITK_ERROR << exception.what();
          return;
        }
      })
      .wait();

    CPPUNIT_ASSERT_MESSAGE(
      "Result is the expected JSON value, check if the link is still valid since this is an optional test",
      result == m_Data);
  }

  void PostRequestValidURI_ReturnsExpectedJSON()
  {
    // optional: link might get invalid or content is changed
    web::json::value result;
    web::json::value data;

    data[_XPLATSTR("userId")] = m_Data[_XPLATSTR("userId")];
    data[_XPLATSTR("title")] = m_Data[_XPLATSTR("title")];
    data[_XPLATSTR("body")] = m_Data[_XPLATSTR("body")];

    m_Service->SendRequest(_XPLATSTR("https://jsonplaceholder.typicode.com/posts"), mitk::IRESTManager::RequestType::Post, &data)
      .then([&](pplx::task<web::json::value> resultTask) {
        try
        {
          result = resultTask.get();
        }
        catch (const mitk::Exception &exception)
        {
          MITK_ERROR << exception.what();
          return;
        }
      })
      .wait();

    data[_XPLATSTR("id")] = web::json::value(101);
    CPPUNIT_ASSERT_MESSAGE(
      "Result is the expected JSON value, check if the link is still valid since this is an optional test",
      result == data);
  }

  void GetException()
  {
    //Method which makes a get request to an invalid uri
    web::json::value result;

    m_Service->SendRequest(_XPLATSTR("http://localhost:1234/invalid"))
      .then([&](pplx::task<web::json::value> resultTask) { result = resultTask.get(); })
      .wait();
  }
  void GetRequestInvalidURI_ThrowsException() { CPPUNIT_ASSERT_THROW(GetException(), mitk::Exception); }

  void PutException()
  {
    //Method which makes a put request to an invalid uri
    web::json::value result;

    m_Service->SendRequest(_XPLATSTR("http://localhost:1234/invalid"), mitk::IRESTManager::RequestType::Put, &m_Data)
      .then([&](pplx::task<web::json::value> resultTask) {
          result = resultTask.get();})
      .wait();
  }
  void PutRequestInvalidURI_ThrowsException()
  {
    CPPUNIT_ASSERT_THROW(PutException(), mitk::Exception);
  }

  void PostException()
  {
    //Method which makes a post request to an invalid uri
    web::json::value result;

    m_Service->SendRequest(_XPLATSTR("http://localhost:1234/invalid"), mitk::IRESTManager::RequestType::Post, &m_Data)
      .then([&](pplx::task<web::json::value> resultTask) {
          result = resultTask.get();
      })
      .wait();
  }
  void PostRequestInvalidURI_ThrowsException()
  {
    CPPUNIT_ASSERT_THROW(PostException(), mitk::Exception);
  }
};

MITK_TEST_SUITE_REGISTRATION(mitkRESTClient)
<commit_msg>Deactivate tests to external URIs<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include <mitkTestFixture.h>
#include <mitkTestingMacros.h>

#include <mitkIRESTManager.h>
#include <mitkIRESTObserver.h>
#include <mitkRESTClient.h>

#include <usGetModuleContext.h>
#include <usModuleContext.h>
#include <usServiceReference.h>

#include <vtkDebugLeaks.h>

class mitkRESTClientTestSuite : public mitk::TestFixture, mitk::IRESTObserver
{
  CPPUNIT_TEST_SUITE(mitkRESTClientTestSuite);
    // MITK_TEST(GetRequestValidURI_ReturnsExpectedJSON); GET requests do not support content yet?
    MITK_TEST(MultipleGetRequestValidURI_AllTasksFinish);
    // MITK_TEST(PutRequestValidURI_ReturnsExpectedJSON); Does not work reliably on dart clients
    // MITK_TEST(PostRequestValidURI_ReturnsExpectedJSON);              -- " --
    MITK_TEST(GetRequestInvalidURI_ThrowsException);
    MITK_TEST(PutRequestInvalidURI_ThrowsException);
    MITK_TEST(PostRequestInvalidURI_ThrowsException);
  CPPUNIT_TEST_SUITE_END();

public:
  mitk::IRESTManager *m_Service;
  web::json::value m_Data;

  web::json::value Notify(const web::uri &, const web::json::value &) override
  {
    return m_Data;
  }

  /**
   * @brief Setup Always call this method before each Test-case to ensure correct and new intialization of the used
   * members for a new test case. (If the members are not used in a test, the method does not need to be called).
   */
  void setUp() override
  {
    m_Data = web::json::value();
    m_Data[_XPLATSTR("userId")] = web::json::value(1);
    m_Data[_XPLATSTR("id")] = web::json::value(1);
    m_Data[_XPLATSTR("title")] = web::json::value(U("this is a title"));
    m_Data[_XPLATSTR("body")] = web::json::value(U("this is a body"));

    us::ServiceReference<mitk::IRESTManager> serviceRef =
      us::GetModuleContext()->GetServiceReference<mitk::IRESTManager>();
    if (serviceRef)
    {
      m_Service = us::GetModuleContext()->GetService(serviceRef);
    }

    if (!m_Service)
    {
      CPPUNIT_FAIL("Getting Service in setUp() failed");
    }

    m_Service->ReceiveRequest(_XPLATSTR("http://localhost:8080/clienttest"), this);
  }

  void tearDown() override
  {
    m_Service->HandleDeleteObserver(this);
  }

  void GetRequestValidURI_ReturnsExpectedJSON()
  {
    web::json::value result;

    m_Service->SendRequest(_XPLATSTR("http://localhost:8080/clienttest"))
      .then([&](pplx::task<web::json::value> resultTask) {
        try
        {
          result = resultTask.get();
        }
        catch (const mitk::Exception &exception)
        {
          MITK_ERROR << exception.what();
          return;
        }
      })
      .wait();

    CPPUNIT_ASSERT_MESSAGE("Result is the expected JSON value", result == m_Data);
  }

  void MultipleGetRequestValidURI_AllTasksFinish()
  {
    int count = 0;

      // Create multiple tasks e.g. as shown below
    std::vector<pplx::task<void>> tasks;
    for (int i = 0; i < 20; ++i)
    {
      pplx::task<void> singleTask =
        m_Service->SendRequest(_XPLATSTR("http://localhost:8080/clienttest"))
          .then([&](pplx::task<web::json::value> resultTask) {
            // Do something when a single task is done
            try
            {
              resultTask.get();
              count +=1;
            }
            catch (const mitk::Exception &exception)
            {
              MITK_ERROR << exception.what();
              return;
            }
          });
      tasks.emplace_back(singleTask);
    }
      // Create a joinTask which includes all tasks you've created
      auto joinTask = pplx::when_all(begin(tasks), end(tasks));
      // Run asynchonously
      joinTask.then([&](pplx::task<void> resultTask) {
        // Do something when all tasks are finished
        try
        {
          resultTask.get();
          count += 1;
        }
        catch (const mitk::Exception &exception)
        {
          MITK_ERROR << exception.what();
          return;
        }
      }).wait();

    CPPUNIT_ASSERT_MESSAGE("Multiple Requests", 21 == count);
  }

  void PutRequestValidURI_ReturnsExpectedJSON()
  {
    // optional: link might get invalid or content is changed
    web::json::value result;

    m_Service
      ->SendRequest(_XPLATSTR("https://jsonplaceholder.typicode.com/posts/1"), mitk::IRESTManager::RequestType::Put, &m_Data)
      .then([&](pplx::task<web::json::value> resultTask) {
        try
        {
          result = resultTask.get();
        }
        catch (const mitk::Exception &exception)
        {
          MITK_ERROR << exception.what();
          return;
        }
      })
      .wait();

    CPPUNIT_ASSERT_MESSAGE(
      "Result is the expected JSON value, check if the link is still valid since this is an optional test",
      result == m_Data);
  }

  void PostRequestValidURI_ReturnsExpectedJSON()
  {
    // optional: link might get invalid or content is changed
    web::json::value result;
    web::json::value data;

    data[_XPLATSTR("userId")] = m_Data[_XPLATSTR("userId")];
    data[_XPLATSTR("title")] = m_Data[_XPLATSTR("title")];
    data[_XPLATSTR("body")] = m_Data[_XPLATSTR("body")];

    m_Service->SendRequest(_XPLATSTR("https://jsonplaceholder.typicode.com/posts"), mitk::IRESTManager::RequestType::Post, &data)
      .then([&](pplx::task<web::json::value> resultTask) {
        try
        {
          result = resultTask.get();
        }
        catch (const mitk::Exception &exception)
        {
          MITK_ERROR << exception.what();
          return;
        }
      })
      .wait();

    data[_XPLATSTR("id")] = web::json::value(101);
    CPPUNIT_ASSERT_MESSAGE(
      "Result is the expected JSON value, check if the link is still valid since this is an optional test",
      result == data);
  }

  void GetException()
  {
    //Method which makes a get request to an invalid uri
    web::json::value result;

    m_Service->SendRequest(_XPLATSTR("http://localhost:1234/invalid"))
      .then([&](pplx::task<web::json::value> resultTask) { result = resultTask.get(); })
      .wait();
  }
  void GetRequestInvalidURI_ThrowsException() { CPPUNIT_ASSERT_THROW(GetException(), mitk::Exception); }

  void PutException()
  {
    //Method which makes a put request to an invalid uri
    web::json::value result;

    m_Service->SendRequest(_XPLATSTR("http://localhost:1234/invalid"), mitk::IRESTManager::RequestType::Put, &m_Data)
      .then([&](pplx::task<web::json::value> resultTask) {
          result = resultTask.get();})
      .wait();
  }
  void PutRequestInvalidURI_ThrowsException()
  {
    CPPUNIT_ASSERT_THROW(PutException(), mitk::Exception);
  }

  void PostException()
  {
    //Method which makes a post request to an invalid uri
    web::json::value result;

    m_Service->SendRequest(_XPLATSTR("http://localhost:1234/invalid"), mitk::IRESTManager::RequestType::Post, &m_Data)
      .then([&](pplx::task<web::json::value> resultTask) {
          result = resultTask.get();
      })
      .wait();
  }
  void PostRequestInvalidURI_ThrowsException()
  {
    CPPUNIT_ASSERT_THROW(PostException(), mitk::Exception);
  }
};

MITK_TEST_SUITE_REGISTRATION(mitkRESTClient)
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName			:    NFCChatModule.h
//    @Author           :    LvSheng.Huang
//    @Date             :    2016-12-18
//    @Module           :    NFCChatModule
//    @Desc             :

#include "NFCChatModule.h"
#include "NFComm/NFMessageDefine/NFProtocolDefine.hpp"
#include "NFComm/NFPluginModule/NFIEventModule.h"

bool NFCChatModule::Init()
{
	return true;
}

bool NFCChatModule::AfterInit()
{
	m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>();
	m_pClassModule = pPluginManager->FindModule<NFIClassModule>();
	m_pElementModule = pPluginManager->FindModule<NFIElementModule>();
	m_pLogModule = pPluginManager->FindModule<NFILogModule>();
	m_pEventModule = pPluginManager->FindModule<NFIEventModule>();
	m_pSceneAOIModule = pPluginManager->FindModule<NFISceneAOIModule>();
	m_pGameServerNet_ServerModule = pPluginManager->FindModule<NFIGameServerNet_ServerModule>();
    m_pNetClientModule = pPluginManager->FindModule<NFIGameServerToWorldModule>();

	m_pNetModule->AddReceiveCallBack(NFMsg::EGMI_REQ_CHAT, this, &NFCChatModule::OnClienChatProcess);

	return true;
}

bool NFCChatModule::Shut()
{

	return true;
}

bool NFCChatModule::Execute()
{
	return true;
}

void NFCChatModule::OnClienChatProcess(const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
{
	CLIENT_MSG_PROCESS(nSockIndex, nMsgID, msg, nLen, NFMsg::ReqAckPlayerChat);

	switch (xMsg.chat_type())
	{
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_WORLD:
	{
		m_pNetModule->SendMsgPBToAllClient(NFMsg::EGMI_ACK_CHAT, xMsg);
	}
	break;
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_GUILD:
	{
		NFGUID xGuildID = m_pKernelModule->GetPropertyObject(nPlayerID, NFrame::Player::GuildID());
		if (!xGuildID.IsNull())
		{
		}
	}
	break;
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_PRIVATE:
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_TEAM:
	{
		if (xMsg.has_target_id())
		{
			NFGUID xTargetID = NFINetModule::PBToNF(xMsg.target_id());
			if (!xTargetID.IsNull())
			{
			}
		}
	}
	break;
	default:
		break;;
	}
}<commit_msg>fixed crash problem when you forget to get the net module<commit_after>// -------------------------------------------------------------------------
//    @FileName			:    NFCChatModule.h
//    @Author           :    LvSheng.Huang
//    @Date             :    2016-12-18
//    @Module           :    NFCChatModule
//    @Desc             :
// -------------------------------------------------------------------------

#include "NFCChatModule.h"
#include "NFComm/NFMessageDefine/NFProtocolDefine.hpp"
#include "NFComm/NFPluginModule/NFIEventModule.h"

bool NFCChatModule::Init()
{
	m_pNetModule = pPluginManager->FindModule<NFINetModule>();
	m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>();
	m_pClassModule = pPluginManager->FindModule<NFIClassModule>();
	m_pElementModule = pPluginManager->FindModule<NFIElementModule>();
	m_pLogModule = pPluginManager->FindModule<NFILogModule>();
	m_pEventModule = pPluginManager->FindModule<NFIEventModule>();
	m_pSceneAOIModule = pPluginManager->FindModule<NFISceneAOIModule>();
	m_pGameServerNet_ServerModule = pPluginManager->FindModule<NFIGameServerNet_ServerModule>();
	m_pNetClientModule = pPluginManager->FindModule<NFIGameServerToWorldModule>();

	return true;
}

bool NFCChatModule::AfterInit()
{
	m_pNetModule->AddReceiveCallBack(NFMsg::EGMI_REQ_CHAT, this, &NFCChatModule::OnClienChatProcess);

	return true;
}

bool NFCChatModule::Shut()
{

	return true;
}

bool NFCChatModule::Execute()
{
	return true;
}

void NFCChatModule::OnClienChatProcess(const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
{
	CLIENT_MSG_PROCESS(nSockIndex, nMsgID, msg, nLen, NFMsg::ReqAckPlayerChat);

	switch (xMsg.chat_type())
	{
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_WORLD:
	{
		m_pNetModule->SendMsgPBToAllClient(NFMsg::EGMI_ACK_CHAT, xMsg);
	}
	break;
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_GUILD:
	{
		NFGUID xGuildID = m_pKernelModule->GetPropertyObject(nPlayerID, NFrame::Player::GuildID());
		if (!xGuildID.IsNull())
		{
		}
	}
	break;
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_PRIVATE:
	case NFMsg::ReqAckPlayerChat_EGameChatType::ReqAckPlayerChat_EGameChatType_EGCT_TEAM:
	{
		if (xMsg.has_target_id())
		{
			NFGUID xTargetID = NFINetModule::PBToNF(xMsg.target_id());
			if (!xTargetID.IsNull())
			{
			}
		}
	}
	break;
	default:
		break;;
	}
}<|endoftext|>


<commit_before>// Copyright 2016 Google Inc. All rights reserved.
//
// 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.

#include "mocks/fplbase_mocks.h"

#include "fplbase/asset_manager.h"
#include "fplbase/async_loader.h"
#include "fplbase/input.h"
#include "fplbase/mesh.h"
#include "fplbase/renderer.h"
#include "fplbase/shader.h"
#include "fplbase/utilities.h"

#define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_PNG
#include "stb_image.h"

// STB_image to resize PNG glyph.
#define STB_IMAGE_RESIZE_IMPLEMENTATION
// Disable warnings in STB_image_resize.
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4100)  // Disable 'unused reference' warning.
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif /* _MSC_VER */
#include "stb_image_resize.h"
// Pop warning status.
#ifdef _MSC_VER
#pragma warning(pop)
#else
#pragma GCC diagnostic pop
#endif

namespace fplbase {

void LogError(const char* fmt, va_list args) {
  FplbaseMocks::get_mocks().LogError(fmt, args);
}

Texture* AssetManager::FindTexture(const char* filename) {
  return FplbaseMocks::get_mocks().FindTexture(filename);
}

// Unused functions to satisfy the linker.

// asset_manager.h
AssetManager::AssetManager(Renderer& renderer) : renderer_(renderer) {}
void AssetManager::ClearAllAssets() {}
Shader* AssetManager::LoadShader(const char*) { return nullptr; }

// async_loader.h
AsyncLoader::AsyncLoader() {}
AsyncLoader::~AsyncLoader() {}

// input.h
Button fake_button_to_return;
Button& InputSystem::GetButton(int) { return fake_button_to_return; }
void InputSystem::StartTextInput() {}
void InputSystem::StopTextInput() {}
double InputSystem::Time() const { return 0.0; }
void InputSystem::SetTextInputRect(const mathfu::vec4&) {}
const std::vector<TextInputEvent>* InputSystem::GetTextInputEvents() {
  return nullptr;
}

// mesh.h
void Mesh::RenderArray(Primitive, int, const Attribute*, int, const void*,
                       const unsigned short*) {}
void Mesh::RenderAAQuadAlongX(const mathfu::vec3&, const mathfu::vec3&,
                              const mathfu::vec2&, const mathfu::vec2&) {}
void Mesh::RenderAAQuadAlongXNinePatch(const mathfu::vec3&, const mathfu::vec3&,
                                       const mathfu::vec2i&,
                                       const mathfu::vec4&) {}

// renderer.h
Renderer::Renderer() {}
Renderer::~Renderer() {}
void Renderer::SetBlendMode(BlendMode) {}
void Renderer::DepthTest(bool) {}
void Renderer::ScissorOn(const mathfu::vec2i&, const mathfu::vec2i&) {}
void Renderer::ScissorOff() {}

// shader.h
void Shader::Set(const Renderer&) const {}
void Shader::SetUniform(UniformHandle, const float*, size_t) {}
UniformHandle Shader::FindUniform(const char*) { return 0; }

// texture.h
void Texture::Delete() {}
void Texture::Load() {}
void Texture::Finalize() {}
void Texture::LoadFromMemory(const uint8_t*, const mathfu::vec2i&,
                             TextureFormat) {}
void Texture::Set(size_t) {}
void Texture::Set(size_t) const {}
void Texture::UpdateTexture(TextureFormat, int, int, int, int, const void*) {}

// utilities.h
void LogInfo(const char*, va_list) {}
void LogInfo(LogCategory, const char*, va_list) {}
void LogError(LogCategory, const char*, va_list) {}
void LogError(const char*, ...) {}
void LogInfo(const char*, ...) {}
void LogInfo(LogCategory, const char*, ...) {}
void LogError(LogCategory, const char*, ...) {}
bool LoadFile(const char*, std::string*) { return false; }
bool LoeadWithIncludes(const char*, std::string*, std::string*) {
  return false;
}

}  // fplbase
<commit_msg>fixed fplbase/test/mocks fplbase_mocks.cpp file<commit_after>// Copyright 2016 Google Inc. All rights reserved.
//
// 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.

#include "mocks/fplbase_mocks.h"

#include "fplbase/asset_manager.h"
#include "fplbase/async_loader.h"
#include "fplbase/input.h"
#include "fplbase/mesh.h"
#include "fplbase/renderer.h"
#include "fplbase/shader.h"
#include "fplbase/utilities.h"

#define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_PNG
#include "stb_image.h"

// STB_image to resize PNG glyph.
#define STB_IMAGE_RESIZE_IMPLEMENTATION
// Disable warnings in STB_image_resize.
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4100)  // Disable 'unused reference' warning.
#else
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif /* _MSC_VER */
#include "stb_image_resize.h"
// Pop warning status.
#ifdef _MSC_VER
#pragma warning(pop)
#else
#pragma GCC diagnostic pop
#endif

namespace fplbase {

void LogError(const char* fmt, va_list args) {
  FplbaseMocks::get_mocks().LogError(fmt, args);
}

Texture* AssetManager::FindTexture(const char* filename) {
  return FplbaseMocks::get_mocks().FindTexture(filename);
}

// Unused functions to satisfy the linker.

// asset_manager.h
AssetManager::AssetManager(Renderer& renderer) : renderer_(renderer) {}
void AssetManager::ClearAllAssets() {}
Shader* AssetManager::LoadShader(const char*) { return nullptr; }

// async_loader.h
AsyncLoader::AsyncLoader() {}
AsyncLoader::~AsyncLoader() {}
void AsyncLoader::Stop() {}

// input.h
Button fake_button_to_return;
Button& InputSystem::GetButton(int) { return fake_button_to_return; }
void InputSystem::StartTextInput() {}
void InputSystem::StopTextInput() {}
double InputSystem::Time() const { return 0.0; }
void InputSystem::SetTextInputRect(const mathfu::vec4&) {}
const std::vector<TextInputEvent>* InputSystem::GetTextInputEvents() {
  return nullptr;
}

// mesh.h
void Mesh::RenderArray(Primitive, int, const Attribute*, int, const void*,
                       const unsigned short*) {}
void Mesh::RenderAAQuadAlongX(const mathfu::vec3&, const mathfu::vec3&,
                              const mathfu::vec2&, const mathfu::vec2&) {}
void Mesh::RenderAAQuadAlongXNinePatch(const mathfu::vec3&, const mathfu::vec3&,
                                       const mathfu::vec2i&,
                                       const mathfu::vec4&) {}

// renderer.h
Renderer::Renderer() {}
Renderer::~Renderer() {}
void Renderer::SetBlendMode(BlendMode) {}
void Renderer::DepthTest(bool) {}
void Renderer::ScissorOn(const mathfu::vec2i&, const mathfu::vec2i&) {}
void Renderer::ScissorOff() {}

// shader.h
void Shader::Set(const Renderer&) const {}
void Shader::SetUniform(UniformHandle, const float*, size_t) {}
UniformHandle Shader::FindUniform(const char*) { return 0; }

// texture.h
void Texture::Delete() {}
void Texture::Load() {}
void Texture::Finalize() {}
void Texture::LoadFromMemory(const uint8_t*, const mathfu::vec2i&,
                             TextureFormat) {}
void Texture::Set(size_t) {}
void Texture::Set(size_t) const {}
void Texture::UpdateTexture(TextureFormat, int, int, int, int, const void*) {}

// utilities.h
void LogInfo(const char*, va_list) {}
void LogInfo(LogCategory, const char*, va_list) {}
void LogError(LogCategory, const char*, va_list) {}
void LogError(const char*, ...) {}
void LogInfo(const char*, ...) {}
void LogInfo(LogCategory, const char*, ...) {}
void LogError(LogCategory, const char*, ...) {}
bool LoadFile(const char*, std::string*) { return false; }
bool LoeadWithIncludes(const char*, std::string*, std::string*) {
  return false;
}

}  // fplbase
<|endoftext|>


<commit_before>#include <array>
#include <string>
#include <iostream>
#include <vector>
#include <memory>
#include <map>
#include <conio.h>
#include <dpmi.h>
#include <go32.h>
#include <sys/movedata.h>
#include <pc.h>
#include <sys/farptr.h>
#include <bios.h>
#include <sys/nearptr.h>

#include <cstdlib>
#include <cstdio>
#include <functional>
#include <cmath>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
#include <memory>
#include <iostream>
#include <map>
#include <array>
#include <iostream>

#include <conio.h>

#include "Vipper/Vipper.h"
#include "NativeBitmap.h"
#include "CDOSRenderer.h"

//
// Created by monty on 06/10/16.
//
#include <memory>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>

#include "NativeBitmap.h"

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

namespace RunTheWorld {

  std::vector<char> readToBuffer(FILE *fileDescriptor) {
    const unsigned N = 1024;
    std::vector<char> total;
    while (true) {
      char buffer[N];
      size_t read = fread((void *) &buffer[0], 1, N, fileDescriptor);
      if (read) {
	for (int c = 0; c < read; ++c) {
	  total.push_back(buffer[c]);
	}
      }
      if (read < N) {
	break;
      }
    }

    return total;
  }

  std::vector<char> loadBinaryFileFromPath(const std::string &path) {
    FILE *fd;

    fd = fopen(path.c_str(), "rb");

    if (fd == nullptr) {
      exit(0);
    }

    std::vector<char> toReturn = readToBuffer(fd);
    fclose(fd);

    return toReturn;
  }

    Vipper::IRenderer::BitmapId CDOSRenderer::loadBitmap( std::string path ) {
      auto id = mSprites.size() + 1;

      std::cout << "loading " << path << std::endl;

      auto buffer = loadBinaryFileFromPath( path );
      int xSize;
      int ySize;
      int components;

      auto image = stbi_load_from_memory((const stbi_uc *) buffer.data(), buffer.size(), &xSize, &ySize, &components, 0 );
      auto rawData = new int[ xSize * ySize ];
      std::memcpy( rawData, image, xSize * ySize * 4 );
      stbi_image_free(image);
      mSprites[ id ] = std::make_shared<odb::NativeBitmap>( path, xSize, ySize, rawData );
      return id;
    }

    Vipper::IRenderer::SoundId CDOSRenderer::loadSound( std::string path ) {
      return 0;
    }

    Vipper::IRenderer::FontId CDOSRenderer::loadFont( std::string path, int sizeInPt ) {
      return 0;
    }

  void CDOSRenderer::fill(float x0, float x1, float y0, float x2, float x3, float y1, std::array<int, 4> shade ) {

        float fromY = std::min( y0, y1 );
        float toY = std::max( y0, y1 );
        float deltaY = toY - fromY;

        float ratiox0x2 = 1.0f;
        float ratiox1x3 = 1.0f;

        if ( toY - fromY > 0.0f  ) {
            ratiox0x2 = ( x0 - x2 ) / deltaY;
            ratiox1x3 = ( x1 - x3 ) / deltaY;
        }

        float x = x0;
        float fx = x1;

        for ( int line = toY; line >= fromY; line--) {
            x -= ratiox0x2;
            fx -= ratiox1x3;
	    drawSquare( (int)x, line, (int)fx, line + 1, shade );
        }
    }

    void CDOSRenderer::drawSquare( int x1, int y1, int x2, int y2, std::array<int,4> colour ) {
      int _x0 = x1 / 2;
      int _x1 = x2 / 2;
      int _y0 = (y1 * 200) / 480;
      int _y1 = (y2 * 200 ) / 480;

      int pixel = colour[ 3 ];
      pixel += colour[ 2 ] << 8;
      pixel += colour[ 1 ] << 8;

      for ( int y = _y0; y < _y1; ++y ) {
	for ( int x = _x0; x < _x1; ++x ) {

	  if ( x < 0 || x >= 320 || y < 0 || y >= 200 ) {
	    continue;
	  }

	  mBuffer[ (320 * y ) + x ] = pixel;
	}
      }
    };

    void CDOSRenderer::drawTextAt( int x, int y, std::string text, std::array<int, 4> colour, Vipper::IRenderer::FontId id ) {

      int offset = 0;
      int start = ( ((y * 25) / 200 ) * 80 ) + ((x * 80 ) / 320 );

      for ( char letter : text ) {
	mTextBuffer[ start + offset ] = letter;
	offset++;
      }
    };

  void CDOSRenderer::drawBitmapAt( int dx, int dy, int w, int h, const IRenderer::BitmapId id ) {
      auto bitmap = mSprites[ id ];
      auto data = bitmap->getPixelData();

      int x = 0;
      int y = 0;
      for ( int sy = 0; sy < bitmap->getHeight(); ++sy ) {
	for ( int sx = 0; sx < bitmap->getWidth(); ++sx ) {

	  x = (sx + dx) / 2;
	  y = ((sy + dy) * 200 ) / 480;

	  if ( x < 0 || x >= 320 || y < 0 || y >= 200 ) {
	    continue;
	  }

	  auto pixel = data + ( sy * bitmap->getWidth() ) + sx;
	  auto colour = *pixel;

	  if ( (colour & 0xFF000000 ) < 254 ) {
	    continue;
	  }

	  mBuffer[ (320 * y ) + x ] = colour;
	  sx++;
	}
	sy++;
      }
  };

  void CDOSRenderer::playSound( const IRenderer::SoundId& id ) {
  };

  CDOSRenderer::CDOSRenderer() {
    __dpmi_regs reg;

    reg.x.ax = 0x13;
    __dpmi_int(0x10, &reg);

    outp(0x03c8, 0);

    for ( int r = 0; r < 4; ++r ) {
      for ( int g = 0; g < 4; ++g ) {
	for ( int b = 0; b < 4; ++b ) {
	  outp(0x03c9, (r * (85) ) );
	  outp(0x03c9, (g * (85) ) );
	  outp(0x03c9, (b * (85) ) );
	}
      }
    }

  }

  void CDOSRenderer::shutdown() {

  }

  void CDOSRenderer::update() {

    while ( kbhit() ) {
      switch ( getch() ) {
      case 'a':
	dispatchKeyDownToListeners(Vipper::ECommand::kLeft);
	dispatchKeyUpToListeners(Vipper::ECommand::kLeft);
	break;
      case 'd':
	dispatchKeyDownToListeners(Vipper::ECommand::kRight);
	dispatchKeyUpToListeners(Vipper::ECommand::kRight);
	break;

      case 'w':
	dispatchKeyDownToListeners(Vipper::ECommand::kUp);
	dispatchKeyUpToListeners(Vipper::ECommand::kUp);
	break;

      case 's':
	dispatchKeyDownToListeners(Vipper::ECommand::kDown);
	dispatchKeyUpToListeners(Vipper::ECommand::kDown);
	break;
      case 'z':
	dispatchKeyDownToListeners(Vipper::ECommand::kFire1);
	dispatchKeyUpToListeners(Vipper::ECommand::kFire1);
	break;
      default:
	break;
      }
    }
  }

  unsigned char getPaletteEntry( int origin ) {
    unsigned char shade = 0;
    shade += (((((origin & 0x0000FF)      ) * 4  ) / 255 ) ) << 4;
    shade += (((((origin & 0x00FF00) >> 8 ) * 4  ) / 255 ) ) << 2;
    shade += (((((origin & 0xFF0000) >> 16) * 4  ) / 255 ) ) << 0;
    return shade;
  }

  void CDOSRenderer::render() {

    int offset = 0;

    unsigned char buffer[ 320 * 200 ];
    int origin = -1;
    int lastOrigin = 1;
    unsigned char shade;

    for (int y = 0; y < 200; ++y) {
      for (int x = 0; x < 320; ++x) {

	offset = (y * 320) + x;
	origin = mBuffer[offset];

	if ( origin != lastOrigin ) {
	  shade = getPaletteEntry( origin );
	}

	lastOrigin = origin;

	buffer[ ( y * 320 ) + x ] = shade;
      }
    }

    dosmemput(buffer, 64000, 0xa0000);
    return;

    for ( int y = 0; y < 25; ++y ) {
      for ( int x = 0; x < 80; ++x ) {
	char c = ( mTextBuffer[ ( y * 80 ) + x ] );

	if ( c != ' ' ) {
	  gotoxy( x + 1, y + 1);
	  std::cout << c;
	}
      }
    }
    std::cout.flush();
    std::fill( std::begin( mTextBuffer), std::end( mTextBuffer ), ' ' );

  }
}
<commit_msg>Fix palette translation caching<commit_after>#include <array>
#include <string>
#include <iostream>
#include <vector>
#include <memory>
#include <map>
#include <conio.h>
#include <dpmi.h>
#include <go32.h>
#include <sys/movedata.h>
#include <pc.h>
#include <sys/farptr.h>
#include <bios.h>
#include <sys/nearptr.h>

#include <cstdlib>
#include <cstdio>
#include <functional>
#include <cmath>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstring>
#include <memory>
#include <iostream>
#include <map>
#include <array>
#include <iostream>

#include <conio.h>

#include "Vipper/Vipper.h"
#include "NativeBitmap.h"
#include "CDOSRenderer.h"

//
// Created by monty on 06/10/16.
//
#include <memory>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>

#include "NativeBitmap.h"

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

namespace RunTheWorld {

  std::vector<char> readToBuffer(FILE *fileDescriptor) {
    const unsigned N = 1024;
    std::vector<char> total;
    while (true) {
      char buffer[N];
      size_t read = fread((void *) &buffer[0], 1, N, fileDescriptor);
      if (read) {
	for (int c = 0; c < read; ++c) {
	  total.push_back(buffer[c]);
	}
      }
      if (read < N) {
	break;
      }
    }

    return total;
  }

  std::vector<char> loadBinaryFileFromPath(const std::string &path) {
    FILE *fd;

    fd = fopen(path.c_str(), "rb");

    if (fd == nullptr) {
      exit(0);
    }

    std::vector<char> toReturn = readToBuffer(fd);
    fclose(fd);

    return toReturn;
  }

    Vipper::IRenderer::BitmapId CDOSRenderer::loadBitmap( std::string path ) {
      auto id = mSprites.size() + 1;

      std::cout << "loading " << path << std::endl;

      auto buffer = loadBinaryFileFromPath( path );
      int xSize;
      int ySize;
      int components;

      auto image = stbi_load_from_memory((const stbi_uc *) buffer.data(), buffer.size(), &xSize, &ySize, &components, 0 );
      auto rawData = new int[ xSize * ySize ];
      std::memcpy( rawData, image, xSize * ySize * 4 );
      stbi_image_free(image);
      mSprites[ id ] = std::make_shared<odb::NativeBitmap>( path, xSize, ySize, rawData );
      return id;
    }

    Vipper::IRenderer::SoundId CDOSRenderer::loadSound( std::string path ) {
      return 0;
    }

    Vipper::IRenderer::FontId CDOSRenderer::loadFont( std::string path, int sizeInPt ) {
      return 0;
    }

  void CDOSRenderer::fill(float x0, float x1, float y0, float x2, float x3, float y1, std::array<int, 4> shade ) {

        float fromY = std::min( y0, y1 );
        float toY = std::max( y0, y1 );
        float deltaY = toY - fromY;

        float ratiox0x2 = 1.0f;
        float ratiox1x3 = 1.0f;

        if ( toY - fromY > 0.0f  ) {
            ratiox0x2 = ( x0 - x2 ) / deltaY;
            ratiox1x3 = ( x1 - x3 ) / deltaY;
        }

        float x = x0;
        float fx = x1;

        for ( int line = toY; line >= fromY; line--) {
            x -= ratiox0x2;
            fx -= ratiox1x3;
	    drawSquare( (int)x, line, (int)fx, line + 1, shade );
        }
    }

    void CDOSRenderer::drawSquare( int x1, int y1, int x2, int y2, std::array<int,4> colour ) {
      int _x0 = x1 / 2;
      int _x1 = x2 / 2;
      int _y0 = (y1 * 200) / 480;
      int _y1 = (y2 * 200 ) / 480;

      int pixel = colour[ 3 ];
      pixel += colour[ 2 ] << 8;
      pixel += colour[ 1 ] << 8;

      for ( int y = _y0; y < _y1; ++y ) {
	for ( int x = _x0; x < _x1; ++x ) {

	  if ( x < 0 || x >= 320 || y < 0 || y >= 200 ) {
	    continue;
	  }

	  mBuffer[ (320 * y ) + x ] = pixel;
	}
      }
    };

    void CDOSRenderer::drawTextAt( int x, int y, std::string text, std::array<int, 4> colour, Vipper::IRenderer::FontId id ) {

      int offset = 0;
      int start = ( ((y * 25) / 200 ) * 80 ) + ((x * 80 ) / 320 );

      for ( char letter : text ) {
	mTextBuffer[ start + offset ] = letter;
	offset++;
      }
    };

  void CDOSRenderer::drawBitmapAt( int dx, int dy, int w, int h, const IRenderer::BitmapId id ) {
      auto bitmap = mSprites[ id ];
      auto data = bitmap->getPixelData();

      int x = 0;
      int y = 0;
      for ( int sy = 0; sy < bitmap->getHeight(); ++sy ) {
	for ( int sx = 0; sx < bitmap->getWidth(); ++sx ) {

	  x = (sx + dx) / 2;
	  y = ((sy + dy) * 200 ) / 480;

	  if ( x < 0 || x >= 320 || y < 0 || y >= 200 ) {
	    continue;
	  }

	  auto pixel = data + ( sy * bitmap->getWidth() ) + sx;
	  auto colour = *pixel;

	  if ( (colour & 0xFF000000 ) < 254 ) {
	    continue;
	  }

	  mBuffer[ (320 * y ) + x ] = colour;
	  sx++;
	}
	sy++;
      }
  };

  void CDOSRenderer::playSound( const IRenderer::SoundId& id ) {
  };

  CDOSRenderer::CDOSRenderer() {
    __dpmi_regs reg;

    reg.x.ax = 0x13;
    __dpmi_int(0x10, &reg);

    outp(0x03c8, 0);

    for ( int r = 0; r < 4; ++r ) {
      for ( int g = 0; g < 4; ++g ) {
	for ( int b = 0; b < 4; ++b ) {
	  outp(0x03c9, (r * (85) ) );
	  outp(0x03c9, (g * (85) ) );
	  outp(0x03c9, (b * (85) ) );
	}
      }
    }

  }

  void CDOSRenderer::shutdown() {

  }

  void CDOSRenderer::update() {

    while ( kbhit() ) {
      switch ( getch() ) {
      case 'a':
	dispatchKeyDownToListeners(Vipper::ECommand::kLeft);
	dispatchKeyUpToListeners(Vipper::ECommand::kLeft);
	break;
      case 'd':
	dispatchKeyDownToListeners(Vipper::ECommand::kRight);
	dispatchKeyUpToListeners(Vipper::ECommand::kRight);
	break;

      case 'w':
	dispatchKeyDownToListeners(Vipper::ECommand::kUp);
	dispatchKeyUpToListeners(Vipper::ECommand::kUp);
	break;

      case 's':
	dispatchKeyDownToListeners(Vipper::ECommand::kDown);
	dispatchKeyUpToListeners(Vipper::ECommand::kDown);
	break;
      case 'z':
	dispatchKeyDownToListeners(Vipper::ECommand::kFire1);
	dispatchKeyUpToListeners(Vipper::ECommand::kFire1);
	break;
      default:
	break;
      }
    }
  }

  unsigned char getPaletteEntry( int origin ) {
    unsigned char shade = 0;
    shade += (((((origin & 0x0000FF)      ) * 4  ) / 255 ) ) << 4;
    shade += (((((origin & 0x00FF00) >> 8 ) * 4  ) / 255 ) ) << 2;
    shade += (((((origin & 0xFF0000) >> 16) * 4  ) / 255 ) ) << 0;
    return shade;
  }

  void CDOSRenderer::render() {

    int offset = 0;

    unsigned char buffer[ 320 * 200 ];
    int origin = 0;
    int lastOrigin = -1;
    unsigned char shade;

    for (int y = 0; y < 200; ++y) {
      for (int x = 0; x < 320; ++x) {

	offset = (y * 320) + x;
	origin = mBuffer[offset];

	if ( origin != lastOrigin ) {
	  shade = getPaletteEntry( origin );
	}

	lastOrigin = origin;

	buffer[ ( y * 320 ) + x ] = shade;
      }
    }

    dosmemput(buffer, 64000, 0xa0000);
    return;

    for ( int y = 0; y < 25; ++y ) {
      for ( int x = 0; x < 80; ++x ) {
	char c = ( mTextBuffer[ ( y * 80 ) + x ] );

	if ( c != ' ' ) {
	  gotoxy( x + 1, y + 1);
	  std::cout << c;
	}
      }
    }
    std::cout.flush();
    std::fill( std::begin( mTextBuffer), std::end( mTextBuffer ), ' ' );

  }
}
<|endoftext|>


<commit_before>//
// Class AliRsnCutEventUtils
//
// This cut implementation checks the quality of event primary vertex.
// Some functions currently work only with ESD events (not AOD).
//
// authors: F. Bellini (fbellini@cern.ch)
// contributors: A. Knospe (aknospe@cern.ch)

#include "AliRsnCutEventUtils.h"
#include "AliAnalysisUtils.h"
#include <AliHeader.h>
#include <AliAODMCHeader.h>
#include <AliGenDPMjetEventHeader.h>

ClassImp(AliRsnCutEventUtils)

//_________________________________________________________________________________________________
AliRsnCutEventUtils::AliRsnCutEventUtils(const char *name, Bool_t rmFirstEvInChunck, Bool_t checkPileUppA2013) :
AliRsnCut(name, AliRsnCut::kEvent),
  fIsRmFirstEvInChunck(rmFirstEvInChunck),
  fCheckPileUppA2013(checkPileUppA2013),
  fUseMVPlpSelection(kFALSE),
  fMinPlpContribMV(5),
  fMinPlpContribSPD(5),
  fUseVertexSelection2013pA(kFALSE),
  fUseVertexSelection2013pAspectra(kFALSE),
  fMaxVtxZ(10.0),
  fFilterNSDeventsDPMJETpA2013(kFALSE),
  fCheckIncompleteDAQ(kFALSE),
  fCheckPastFuture(kFALSE),
  fPastFutureFirstBit(79),
  fPastFutureNBits(11),
  fCheckSPDClusterVsTrackletBG(kFALSE),
  fASPDCvsTCut(-9999.0),
  fBSPDCvsTCut(-9999.0),
  fUtils(0x0)
{
  //
  // Main constructor.
  //If the rmFirstEvInChunck flag is kTRUE, it removed the first event in chunk
  //
  //If the checkPileUp flag is kTRUE, it removes the events from pile-up
  //- to be used for pA 2013, for other periods the rejection of pileup is implemented
  //ad an additional cut in the primary vertex

}

//_________________________________________________________________________________________________
AliRsnCutEventUtils::AliRsnCutEventUtils(const AliRsnCutEventUtils &copy) :
  AliRsnCut(copy),
  fIsRmFirstEvInChunck(copy.fIsRmFirstEvInChunck),
  fCheckPileUppA2013(copy.fCheckPileUppA2013),
  fUseMVPlpSelection(copy.fUseMVPlpSelection),
  fMinPlpContribMV(copy.fMinPlpContribMV),
  fMinPlpContribSPD(copy.fMinPlpContribSPD),
  fUseVertexSelection2013pA(copy.fUseVertexSelection2013pA),
  fUseVertexSelection2013pAspectra(copy.fUseVertexSelection2013pAspectra),
  fMaxVtxZ(copy.fMaxVtxZ),
  fFilterNSDeventsDPMJETpA2013(copy.fFilterNSDeventsDPMJETpA2013),
  fCheckIncompleteDAQ(copy.fCheckIncompleteDAQ),
  fCheckPastFuture(copy.fCheckPastFuture),
  fPastFutureFirstBit(copy.fPastFutureFirstBit),
  fPastFutureNBits(copy.fPastFutureNBits),
  fCheckSPDClusterVsTrackletBG(copy.fCheckSPDClusterVsTrackletBG),
  fASPDCvsTCut(copy.fASPDCvsTCut),
  fBSPDCvsTCut(copy.fBSPDCvsTCut),
  fUtils(copy.fUtils)
{
  //
  // Copy constructor.
  //
}

//-------------------------------------------------------------------------------------------------
AliRsnCutEventUtils &AliRsnCutEventUtils::operator=(const AliRsnCutEventUtils &copy)
{
  //
  // Assignment operator.
  // Works like copy constructor.
  //
  AliRsnCut::operator=(copy);
  if (this == &copy)
    return *this;

  fIsRmFirstEvInChunck=copy.fIsRmFirstEvInChunck;
  fCheckPileUppA2013=copy.fCheckPileUppA2013;
  fUseMVPlpSelection=copy.fUseMVPlpSelection;
  fMinPlpContribMV=copy.fMinPlpContribMV;
  fMinPlpContribSPD=copy.fMinPlpContribSPD;
  fUseVertexSelection2013pA=copy.fUseVertexSelection2013pA;
  fUseVertexSelection2013pAspectra=copy.fUseVertexSelection2013pAspectra;
  fMaxVtxZ=copy.fMaxVtxZ;
  fFilterNSDeventsDPMJETpA2013=copy.fFilterNSDeventsDPMJETpA2013;
  fCheckIncompleteDAQ=copy.fCheckIncompleteDAQ;
  fCheckPastFuture=copy.fCheckPastFuture;
  fPastFutureFirstBit=copy.fPastFutureFirstBit;
  fPastFutureNBits=copy.fPastFutureNBits;
  fCheckSPDClusterVsTrackletBG=copy.fCheckSPDClusterVsTrackletBG;
  fASPDCvsTCut=copy.fASPDCvsTCut;
  fBSPDCvsTCut=copy.fBSPDCvsTCut;
  fUtils=copy.fUtils;

  return (*this);
}
//_________________________________________________________________________________________________
Bool_t AliRsnCutEventUtils::IsSelected(TObject *object)
{
//
// Cut checker
//
   // coherence check
   // which also fills data member objects
   if (!TargetOK(object)) return kFALSE;
   // retrieve event

   AliVEvent *vevt = dynamic_cast<AliVEvent *>(fEvent->GetRef());
   //set cuts in analysis utils
   fUtils = new AliAnalysisUtils();
   fUtils->SetUseMVPlpSelection(fUseMVPlpSelection);
   fUtils->SetMinPlpContribMV(fMinPlpContribMV);
   fUtils->SetMinPlpContribSPD(fMinPlpContribSPD);
   fUtils->SetMaxVtxZ(fMaxVtxZ);
   if(fASPDCvsTCut>-9990.0) fUtils->SetASPDCvsTCut(fASPDCvsTCut);
   if(fBSPDCvsTCut>-9990.0) fUtils->SetBSPDCvsTCut(fBSPDCvsTCut);

   Bool_t accept = kTRUE;
   //remove first event in chunk
   if ((fIsRmFirstEvInChunck) && (fUtils->IsFirstEventInChunk(vevt))) accept = kFALSE;

   //apply vertex selection - for 2013 pPb data
   if ((fUseVertexSelection2013pAspectra) && (!IsVertexSelected2013pAIDspectra(vevt))) accept = kFALSE;

   //apply vertex selection - for 2013 pPb data
   if((fUseVertexSelection2013pA) && (!fUtils->IsVertexSelected2013pA(vevt))) accept = kFALSE;

   // pile-up check
   if ((fCheckPileUppA2013) && (fUtils->IsPileUpEvent(vevt))) accept = kFALSE;

   //check if DAQ is incomplete
   if(fCheckIncompleteDAQ && IsIncompleteDAQ()) return kFALSE;

   //past/future protection
   if(fCheckPastFuture && FailsPastFuture()) return kFALSE;

   //check correlation between number of SPD clusters and number of tracklets
   if(fCheckSPDClusterVsTrackletBG && IsSPDClusterVsTrackletBG(vevt)) return kFALSE;

   //apply filter for NSD events in DPMJET MC for pA
   if (fFilterNSDeventsDPMJETpA2013){
     //Adaptation of snippet received from David D. Chinellato on 07/09/2015 +
     // this: http://svnweb.cern.ch/world/wsvn/AliRoot/trunk/PWGLF/SPECTRA/ChargedHadrons/dNdPt/AlidNdPtHelper.cxx?rev=61295
     AliGenDPMjetEventHeader* dpmHeader;

     if (fEvent->IsAOD()){
       AliAODEvent *aodEvt = (AliAODEvent*)(fEvent->GetRef());
       AliAODMCHeader *aodMCheader = (AliAODMCHeader*)aodEvt->GetList()->FindObject(AliAODMCHeader::StdBranchName());
       if (!aodMCheader) {
	 AliError("MC header branch in AOD not found!\n");
	 return kFALSE;
       }
       dpmHeader = dynamic_cast<AliGenDPMjetEventHeader*>(aodMCheader->GetCocktailHeader(0));
     }
     else if (fEvent->IsESD()) {
       AliMCEvent *mcEvt = (AliMCEvent*)(fEvent->GetRefMC());
       if (!mcEvt) {
	 AliError("MC header branch in AOD not found!\n");
	 return kFALSE;
       }
       AliHeader * header = mcEvt->Header();
       dpmHeader = dynamic_cast<AliGenDPMjetEventHeader*>(header->GenEventHeader());
       if (!dpmHeader) {
	 AliError("Invalid DPMJET event header.");
	 return kFALSE;
       }
     } else
       return kFALSE;

     Int_t nsd1 = 0;
     Int_t nsd2 = 0;
     Int_t ndd  = 0;
     dpmHeader->GetNDiffractive(nsd1, nsd2, ndd);
     if ( ((dpmHeader->ProjectileParticipants()==nsd1) && (ndd==0)) ||
	  ((dpmHeader->ProjectileParticipants()==nsd2) && (ndd==0))  ) {
       AliInfo("fFilterNSDeventsDPMJETpA2013 rejected a non-NSD event!");
       accept = kFALSE;
     }
     else  accept = kTRUE;
   }

   return accept;
}

Bool_t AliRsnCutEventUtils::IsVertexSelected2013pAIDspectra(AliVEvent *event)
{
  // Check whether the event is of AOD or ESD type
  AliAODEvent *aod = 0x0;
  AliESDEvent *esd = 0x0;
  aod = dynamic_cast<AliAODEvent*>(event);
  esd = dynamic_cast<AliESDEvent*>(event);

  Bool_t fisAOD = kFALSE;
  if(aod) {
    fisAOD = kTRUE;
  } else {
    fisAOD = kFALSE;
    if(!esd) {
      AliFatal("Event is neither of AOD nor ESD type");
      return kFALSE;
    }
  }

  //Roberto's PV selection criteria, implemented 17th April 2013 on ESDs
  //fbellini modifications for usage with both ESDs and AODs
   /* vertex selection */

  Bool_t accept = kFALSE;
  const AliVVertex *vertex = fisAOD ?
    dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex()) :
    dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertex()) ;

  if (vertex->GetNContributors() < 1) {
    vertex = fisAOD ?
      dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertexSPD()) :
      dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexSPD()) ;
    if (vertex->GetNContributors() < 1) accept = kFALSE;
    else accept = kTRUE;
    Double_t cov[6]={0};
    vertex->GetCovarianceMatrix(cov);
    Double_t zRes = TMath::Sqrt(cov[5]);
    if (vertex->IsFromVertexerZ() && (zRes>0.25)) accept = kFALSE;
  }
  else accept = kTRUE;

  Float_t zvtx = vertex->GetZ();
  if (TMath::Abs(zvtx) > fMaxVtxZ) accept = kFALSE;
  return accept;
}

Bool_t AliRsnCutEventUtils::IsIncompleteDAQ(){
  if(!fEvent) return kFALSE;
  AliAODEvent* aodEvt=0;
  Bool_t isAOD=fEvent->IsAOD();
  if(isAOD) aodEvt=(AliAODEvent*)(fEvent->GetRef());

  AliESDEvent* esdEvt=0;
  Bool_t isESD=fEvent->IsESD();
  if(isESD) esdEvt=(AliESDEvent*)(fEvent->GetRef());

  if(isAOD && aodEvt && aodEvt->IsIncompleteDAQ()) return kTRUE;
  else if(isESD && esdEvt && esdEvt->IsIncompleteDAQ()) return kTRUE;
  return kFALSE;
}

Bool_t AliRsnCutEventUtils::FailsPastFuture(){
  if(!fEvent) return kFALSE;//this function has not been tested

  AliESDEvent* esdEvt=0;
  Bool_t isESD=fEvent->IsESD();
  if(isESD) esdEvt=(AliESDEvent*)(fEvent->GetRef());
  else return kFALSE;
  if(!esdEvt) return kFALSE;

  TBits b=esdEvt->GetHeader()->GetIRInt1InteractionMap();
  for(Int_t i=fPastFutureFirstBit;i<fPastFutureFirstBit+fPastFutureNBits;i++) if(b.TestBitNumber(i)) return kTRUE;
  return kFALSE;
}

Bool_t AliRsnCutEventUtils::IsSPDClusterVsTrackletBG(AliVEvent* vevt){
  if(!fEvent || !fUtils) return kFALSE;
  if(!vevt) vevt = dynamic_cast<AliVEvent *>(fEvent->GetRef());
  if(!vevt) return kFALSE;
  return fUtils->IsSPDClusterVsTrackletBG(vevt);
}
<commit_msg> implemented dynamic casts for the IsIncompleteDAQ check<commit_after>//
// Class AliRsnCutEventUtils
//
// This cut implementation checks the quality of event primary vertex.
// Some functions currently work only with ESD events (not AOD).
//
// authors: Martin Vala (martin.vala@cern.ch)
//          Alberto Pulvirenti (alberto.pulvirenti@ct.infn.it)
//

#include "AliRsnCutEventUtils.h"
#include "AliAnalysisUtils.h"
#include <AliHeader.h>
#include <AliAODMCHeader.h>
#include <AliGenDPMjetEventHeader.h>

ClassImp(AliRsnCutEventUtils)

//_________________________________________________________________________________________________
AliRsnCutEventUtils::AliRsnCutEventUtils(const char *name, Bool_t rmFirstEvInChunck, Bool_t checkPileUppA2013) :
AliRsnCut(name, AliRsnCut::kEvent),
  fIsRmFirstEvInChunck(rmFirstEvInChunck),
  fCheckPileUppA2013(checkPileUppA2013),
  fUseMVPlpSelection(kFALSE),
  fMinPlpContribMV(5),
  fMinPlpContribSPD(5),
  fUseVertexSelection2013pA(kFALSE),
  fUseVertexSelection2013pAspectra(kFALSE),
  fMaxVtxZ(10.0),
  fFilterNSDeventsDPMJETpA2013(kFALSE),
  fCheckIncompleteDAQ(kFALSE),
  fCheckPastFuture(kFALSE),
  fPastFutureFirstBit(79),
  fPastFutureNBits(11),
  fCheckSPDClusterVsTrackletBG(kFALSE),
  fASPDCvsTCut(-9999.0),
  fBSPDCvsTCut(-9999.0),
  fUtils(0x0)
{
  //
  // Main constructor.
  //If the rmFirstEvInChunck flag is kTRUE, it removed the first event in chunk
  //
  //If the checkPileUp flag is kTRUE, it removes the events from pile-up
  //- to be used for pA 2013, for other periods the rejection of pileup is implemented
  //ad an additional cut in the primary vertex

}

//_________________________________________________________________________________________________
AliRsnCutEventUtils::AliRsnCutEventUtils(const AliRsnCutEventUtils &copy) :
  AliRsnCut(copy),
  fIsRmFirstEvInChunck(copy.fIsRmFirstEvInChunck),
  fCheckPileUppA2013(copy.fCheckPileUppA2013),
  fUseMVPlpSelection(copy.fUseMVPlpSelection),
  fMinPlpContribMV(copy.fMinPlpContribMV),
  fMinPlpContribSPD(copy.fMinPlpContribSPD),
  fUseVertexSelection2013pA(copy.fUseVertexSelection2013pA),
  fUseVertexSelection2013pAspectra(copy.fUseVertexSelection2013pAspectra),
  fMaxVtxZ(copy.fMaxVtxZ),
  fFilterNSDeventsDPMJETpA2013(copy.fFilterNSDeventsDPMJETpA2013),
  fCheckIncompleteDAQ(copy.fCheckIncompleteDAQ),
  fCheckPastFuture(copy.fCheckPastFuture),
  fPastFutureFirstBit(copy.fPastFutureFirstBit),
  fPastFutureNBits(copy.fPastFutureNBits),
  fCheckSPDClusterVsTrackletBG(copy.fCheckSPDClusterVsTrackletBG),
  fASPDCvsTCut(copy.fASPDCvsTCut),
  fBSPDCvsTCut(copy.fBSPDCvsTCut),
  fUtils(copy.fUtils)
{
  //
  // Copy constructor.
  //
}

//-------------------------------------------------------------------------------------------------
AliRsnCutEventUtils &AliRsnCutEventUtils::operator=(const AliRsnCutEventUtils &copy)
{
  //
  // Assignment operator.
  // Works like copy constructor.
  //
  AliRsnCut::operator=(copy);
  if (this == &copy)
    return *this;

  fIsRmFirstEvInChunck=copy.fIsRmFirstEvInChunck;
  fCheckPileUppA2013=copy.fCheckPileUppA2013;
  fUseMVPlpSelection=copy.fUseMVPlpSelection;
  fMinPlpContribMV=copy.fMinPlpContribMV;
  fMinPlpContribSPD=copy.fMinPlpContribSPD;
  fUseVertexSelection2013pA=copy.fUseVertexSelection2013pA;
  fUseVertexSelection2013pAspectra=copy.fUseVertexSelection2013pAspectra;
  fMaxVtxZ=copy.fMaxVtxZ;
  fFilterNSDeventsDPMJETpA2013=copy.fFilterNSDeventsDPMJETpA2013;
  fCheckIncompleteDAQ=copy.fCheckIncompleteDAQ;
  fCheckPastFuture=copy.fCheckPastFuture;
  fPastFutureFirstBit=copy.fPastFutureFirstBit;
  fPastFutureNBits=copy.fPastFutureNBits;
  fCheckSPDClusterVsTrackletBG=copy.fCheckSPDClusterVsTrackletBG;
  fASPDCvsTCut=copy.fASPDCvsTCut;
  fBSPDCvsTCut=copy.fBSPDCvsTCut;
  fUtils=copy.fUtils;

  return (*this);
}
//_________________________________________________________________________________________________
Bool_t AliRsnCutEventUtils::IsSelected(TObject *object)
{
//
// Cut checker
//
   // coherence check
   // which also fills data member objects
   if (!TargetOK(object)) return kFALSE;
   // retrieve event

   AliVEvent *vevt = dynamic_cast<AliVEvent *>(fEvent->GetRef());
   //set cuts in analysis utils
   fUtils = new AliAnalysisUtils();
   fUtils->SetUseMVPlpSelection(fUseMVPlpSelection);
   fUtils->SetMinPlpContribMV(fMinPlpContribMV);
   fUtils->SetMinPlpContribSPD(fMinPlpContribSPD);
   fUtils->SetMaxVtxZ(fMaxVtxZ);
   if(fASPDCvsTCut>-9990.0) fUtils->SetASPDCvsTCut(fASPDCvsTCut);
   if(fBSPDCvsTCut>-9990.0) fUtils->SetBSPDCvsTCut(fBSPDCvsTCut);

   Bool_t accept = kTRUE;
   //remove first event in chunk
   if ((fIsRmFirstEvInChunck) && (fUtils->IsFirstEventInChunk(vevt))) accept = kFALSE;

   //apply vertex selection - for 2013 pPb data
   if ((fUseVertexSelection2013pAspectra) && (!IsVertexSelected2013pAIDspectra(vevt))) accept = kFALSE;

   //apply vertex selection - for 2013 pPb data
   if((fUseVertexSelection2013pA) && (!fUtils->IsVertexSelected2013pA(vevt))) accept = kFALSE;

   // pile-up check
   if ((fCheckPileUppA2013) && (fUtils->IsPileUpEvent(vevt))) accept = kFALSE;

   //check if DAQ is incomplete
   if(fCheckIncompleteDAQ && IsIncompleteDAQ()) return kFALSE;

   //past/future protection
   if(fCheckPastFuture && FailsPastFuture()) return kFALSE;

   //check correlation between number of SPD clusters and number of tracklets
   if(fCheckSPDClusterVsTrackletBG && IsSPDClusterVsTrackletBG(vevt)) return kFALSE;

   //apply filter for NSD events in DPMJET MC for pA
   if (fFilterNSDeventsDPMJETpA2013){
     //Adaptation of snippet received from David D. Chinellato on 07/09/2015 +
     // this: http://svnweb.cern.ch/world/wsvn/AliRoot/trunk/PWGLF/SPECTRA/ChargedHadrons/dNdPt/AlidNdPtHelper.cxx?rev=61295
     AliGenDPMjetEventHeader* dpmHeader;

     if (fEvent->IsAOD()){
       AliAODEvent *aodEvt = (AliAODEvent*)(fEvent->GetRef());
       AliAODMCHeader *aodMCheader = (AliAODMCHeader*)aodEvt->GetList()->FindObject(AliAODMCHeader::StdBranchName());
       if (!aodMCheader) {
	 AliError("MC header branch in AOD not found!\n");
	 return kFALSE;
       }
       dpmHeader = dynamic_cast<AliGenDPMjetEventHeader*>(aodMCheader->GetCocktailHeader(0));
     }
     else if (fEvent->IsESD()) {
       AliMCEvent *mcEvt = (AliMCEvent*)(fEvent->GetRefMC());
       if (!mcEvt) {
	 AliError("MC header branch in AOD not found!\n");
	 return kFALSE;
       }
       AliHeader * header = mcEvt->Header();
       dpmHeader = dynamic_cast<AliGenDPMjetEventHeader*>(header->GenEventHeader());
       if (!dpmHeader) {
	 AliError("Invalid DPMJET event header.");
	 return kFALSE;
       }
     } else
       return kFALSE;

     Int_t nsd1 = 0;
     Int_t nsd2 = 0;
     Int_t ndd  = 0;
     dpmHeader->GetNDiffractive(nsd1, nsd2, ndd);
     if ( ((dpmHeader->ProjectileParticipants()==nsd1) && (ndd==0)) ||
	  ((dpmHeader->ProjectileParticipants()==nsd2) && (ndd==0))  ) {
       AliInfo("fFilterNSDeventsDPMJETpA2013 rejected a non-NSD event!");
       accept = kFALSE;
     }
     else  accept = kTRUE;
   }

   return accept;
}

Bool_t AliRsnCutEventUtils::IsVertexSelected2013pAIDspectra(AliVEvent *event)
{
  // Check whether the event is of AOD or ESD type
  AliAODEvent *aod = 0x0;
  AliESDEvent *esd = 0x0;
  aod = dynamic_cast<AliAODEvent*>(event);
  esd = dynamic_cast<AliESDEvent*>(event);

  Bool_t fisAOD = kFALSE;
  if(aod) {
    fisAOD = kTRUE;
  } else {
    fisAOD = kFALSE;
    if(!esd) {
      AliFatal("Event is neither of AOD nor ESD type");
      return kFALSE;
    }
  }

  //Roberto's PV selection criteria, implemented 17th April 2013 on ESDs
  //fbellini modifications for usage with both ESDs and AODs
   /* vertex selection */

  Bool_t accept = kFALSE;
  const AliVVertex *vertex = fisAOD ?
    dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex()) :
    dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertex()) ;

  if (vertex->GetNContributors() < 1) {
    vertex = fisAOD ?
      dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertexSPD()) :
      dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexSPD()) ;
    if (vertex->GetNContributors() < 1) accept = kFALSE;
    else accept = kTRUE;
    Double_t cov[6]={0};
    vertex->GetCovarianceMatrix(cov);
    Double_t zRes = TMath::Sqrt(cov[5]);
    if (vertex->IsFromVertexerZ() && (zRes>0.25)) accept = kFALSE;
  }
  else accept = kTRUE;

  Float_t zvtx = vertex->GetZ();
  if (TMath::Abs(zvtx) > fMaxVtxZ) accept = kFALSE;
  return accept;
}

Bool_t AliRsnCutEventUtils::IsIncompleteDAQ(){
  if(!fEvent) return kFALSE;
  AliAODEvent* aodEvt=0;
  Bool_t isAOD=fEvent->IsAOD();
  if(isAOD) aodEvt=dynamic_cast<AliAODEvent *>(fEvent->GetRef());

  AliESDEvent* esdEvt=0;
  Bool_t isESD=fEvent->IsESD();
  if(isESD) esdEvt=dynamic_cast<AliESDEvent *>(fEvent->GetRef());

  if(isAOD && aodEvt && aodEvt->IsIncompleteDAQ()) return kTRUE;
  else if(isESD && esdEvt && esdEvt->IsIncompleteDAQ()) return kTRUE;
  return kFALSE;
}

Bool_t AliRsnCutEventUtils::FailsPastFuture(){
  if(!fEvent) return kFALSE;//this function has not been tested

  AliESDEvent* esdEvt=0;
  Bool_t isESD=fEvent->IsESD();
  if(isESD) esdEvt=(AliESDEvent*)(fEvent->GetRef());
  else return kFALSE;
  if(!esdEvt) return kFALSE;

  TBits b=esdEvt->GetHeader()->GetIRInt1InteractionMap();
  for(Int_t i=fPastFutureFirstBit;i<fPastFutureFirstBit+fPastFutureNBits;i++) if(b.TestBitNumber(i)) return kTRUE;
  return kFALSE;
}

Bool_t AliRsnCutEventUtils::IsSPDClusterVsTrackletBG(AliVEvent* vevt){
  if(!fEvent || !fUtils) return kFALSE;
  if(!vevt) vevt = dynamic_cast<AliVEvent *>(fEvent->GetRef());
  if(!vevt) return kFALSE;
  return fUtils->IsSPDClusterVsTrackletBG(vevt);
}
<|endoftext|>


<commit_before>// SA:MP Profiler plugin
//
// Copyright (c) 2011 Zeex
//
// 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.

#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <numeric>

#include "amxprofiler.h"

#include "amx/amx.h"
#include "amx/amxdbg.h"

std::map<AMX*, AmxProfiler*> AmxProfiler::instances_;

AmxProfiler::AmxProfiler() {}

// Extracts the names of native functions from the native table.
static void GetNatives(AMX *amx, std::vector<AmxProfiler::Function> &names) {
    AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
    AMX_FUNCSTUBNT *natives = reinterpret_cast<AMX_FUNCSTUBNT*>(amx->base + hdr->natives);

    int numberOfNatives;
    amx_NumNatives(amx, &numberOfNatives);

    for (int i = 0; i < numberOfNatives; i++) {
        names.push_back(AmxProfiler::Function(natives[i].address,
            reinterpret_cast<char*>(amx->base + natives[i].nameofs)));
    }
}

// Extracts the names of public functions from the native table.
static void GetPublics(AMX *amx, std::vector<AmxProfiler::Function> &names) {
    AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
    AMX_FUNCSTUBNT *publics = reinterpret_cast<AMX_FUNCSTUBNT*>(amx->base + hdr->publics);

    int numberOfPublics;
    amx_NumPublics(amx, &numberOfPublics);

    for (int i = 0; i < numberOfPublics; i++) {
        names.push_back(AmxProfiler::Function(publics[i].address,
            reinterpret_cast<char*>(amx->base + publics[i].nameofs)));
    }
}

// Reads from a code section at a given location.
static inline cell ReadAmxCode(AMX *amx, cell where) {
    AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
    return *reinterpret_cast<cell*>(amx->base + hdr->cod + where);
}

// Comparison functiosn for different stats sorting modes
static bool ByCalls(const std::pair<cell, AmxPerformanceCounter> &op1,
                         const std::pair<cell, AmxPerformanceCounter> &op2) {
    return op1.second.GetCalls() > op2.second.GetCalls();
}

static bool ByTime(const std::pair<cell, AmxPerformanceCounter> &op1,
                        const std::pair<cell, AmxPerformanceCounter> &op2) {
    return op1.second.GetTime() > op2.second.GetTime();
}

static bool ByTimePerCall(const std::pair<cell, AmxPerformanceCounter> &op1,
                               const std::pair<cell, AmxPerformanceCounter> &op2) {
    return static_cast<double>(op1.second.GetTime()) / static_cast<double>(op1.second.GetCalls())
         > static_cast<double>(op2.second.GetTime()) / static_cast<double>(op2.second.GetCalls());
}

AmxProfiler::AmxProfiler(AMX *amx)
    : amx_(amx),
      debug_(amx->debug),
      callback_(amx->callback),
      active_(false),
      haveDbg_(false)
{
    // Since PrintStats is done in AmxUnload and amx->base is already freed before
    // AmxUnload gets called, therefore both native and public tables are not accessible,
    // from there, so they must be stored separately in some global place.
    GetNatives(amx, natives_);
    GetPublics(amx, publics_);
}

AmxProfiler::AmxProfiler(AMX *amx, AMX_DBG amxdbg)
    : amx_(amx),
      amxdbg_(amxdbg),
      debug_(amx->debug),
      callback_(amx->callback),
      active_(false),
      haveDbg_(true)
{
    GetNatives(amx, natives_);
    GetPublics(amx, publics_);
}

void AmxProfiler::Attach(AMX *amx) {
    AmxProfiler *prof = new AmxProfiler(amx);
    instances_[amx] = prof;
    prof->Activate();
}

void AmxProfiler::Attach(AMX *amx, AMX_DBG amxdbg) {
    AmxProfiler *prof = new AmxProfiler(amx, amxdbg);
    instances_[amx] = prof;
    prof->Activate();
}

void AmxProfiler::Detach(AMX *amx) {
    AmxProfiler *prof = AmxProfiler::Get(amx);
    if (prof != 0) {
        prof->Deactivate();
        delete prof;
    }
    instances_.erase(amx);
}

AmxProfiler *AmxProfiler::Get(AMX *amx) {
    std::map<AMX*, AmxProfiler*>::iterator it = instances_.find(amx);
    if (it != instances_.end()) {
        return it->second;
    }
    return 0;
}

static int AMXAPI Debug(AMX *amx) {
    return AmxProfiler::Get(amx)->Debug();
}

static int AMXAPI Callback(AMX *amx, cell index, cell *result, cell *params) {
    return AmxProfiler::Get(amx)->Callback(index, result, params);
}

void AmxProfiler::Activate() {
    if (!active_) {
        active_ = true;
        amx_SetDebugHook(amx_, ::Debug);
        amx_SetCallback(amx_, ::Callback);
    }
}

bool AmxProfiler::IsActive() const {
    return active_;
}

void AmxProfiler::Deactivate() {
    if (active_) {
        active_ = false;
        amx_SetDebugHook(amx_, debug_);
        amx_SetCallback(amx_, callback_);
    }
}

void AmxProfiler::ResetStats() {
    counters_.clear();
}

bool AmxProfiler::PrintStats(const std::string &filename, StatsPrintOrder order) {
    std::ofstream stream(filename.c_str());

    if (stream.is_open()) {
        std::vector<std::pair<cell, AmxPerformanceCounter> > stats(counters_.begin(),
                                                     counters_.end());
        switch (order) {
            case ORDER_BY_CALLS:
                std::sort(stats.begin(), stats.end(), ByCalls);
                break;
            case ORDER_BY_TIME:
                std::sort(stats.begin(), stats.end(), ByTime);
                break;
            case ORDER_BY_TIME_PER_CALL:
                std::sort(stats.begin(), stats.end(), ByTimePerCall);
                break;
            default:
                // leave as is
                break;
        }

        stream << "
\n"
               << "\t
\n"
               << "\t\tFunction	\n"
               << "\t\tCalls	\n"
               << "\t\tTime per call, µs	\n"
               << "\t\tOverall time, µs	\n"
               << "\t\tOverall time, %	\n"
               << "\t
\n";

        platformstl::int64_t totalTime = 0;

        for (std::vector<std::pair<cell, AmxPerformanceCounter> >::iterator it = stats.begin();
             it != stats.end(); ++it)
        {
            totalTime += it->second.GetTime();
        }

        for (std::vector<std::pair<cell, AmxPerformanceCounter> >::iterator it = stats.begin();
             it != stats.end(); ++it)
        {
            stream << "\t
\n";

            cell address = it->first;

            if (address <= 0) {
                stream << "\t\t" << natives_[-address].name() << "	\n";
            } else {
                const char *name = 0;
                if (haveDbg_ && dbg_LookupFunction(&amxdbg_, address, &name) == AMX_ERR_NONE) {
                    stream << "\t\t" << name << "	\n";
                } else {
                    for (std::vector<AmxProfiler::Function>::iterator pubIt = publics_.begin();
                         pubIt != publics_.end(); ++pubIt)
                    {
                        if (pubIt->address() == address)  {
                            stream << "\t\t" << pubIt->name() << "	\n";
                        }
                    }
                    // OK we tried all means but still don't know the name, so we just print the address.
                    stream << "\t\t" << std::hex << address << std::dec << "	\n";
                }
            }

            AmxPerformanceCounter &counter = it->second;

            stream << "\t\t" << counter.GetCalls() << "	\n"
                   << "\t\t" << std::fixed << std::setprecision(0)
                                 << static_cast<double>(counter.GetTime()) /
                                        static_cast<double>(counter.GetCalls()) << "	\n"
                   << "\t\t" << counter.GetTime() << "	\n"
                   << "\t\t" << std::setprecision(2)
                                 << static_cast<double>(counter.GetTime() * 100) /
                                        static_cast<double>(totalTime) << "	\n";
            stream << "\t
\n";
        }

        stream << "
\n";

        return true;
    }

    return false;
}

int AmxProfiler::Debug() {
    // Get previous stack frame.
    cell prevFrame = amx_->stp;
    if (!calls_.empty()) {
        prevFrame = calls_.top().frame();
    }

    // Check whether current frame is different.
    if (amx_->frm < prevFrame) {
        // Probably entered a function body (first BREAK after PROC).
        cell address = amx_->cip - 2*sizeof(cell);
        // Check if we have a PROC opcode behind.
        if (ReadAmxCode(amx_, address) == 46) {
            calls_.push(CallInfo(amx_->frm, address, false));
            if (active_) {
                counters_[address].Start();
            }
            //logprintf("==> %x | frame = %x", address, amx_->frm);
        }
    } else if (amx_->frm > prevFrame) {
        if (!calls_.top().entryPoint()) { // entry points are handled by Exec
            // Left the function
            cell address = calls_.top().address();
            if (active_) {
                counters_[address].Stop();
            }
            calls_.pop();
            //logprintf("<== %x | frame = %x", address, amx_->frm);
        }
    }

    if (debug_ != 0) {
        // Others could set their own debug hooks
        return debug_(amx_);
    }

    return AMX_ERR_NONE;
}

int AmxProfiler::Callback(cell index, cell *result, cell *params) {
    // The default AMX callback (amx_Callback) can replace SYSREQ.C opcodes
    // with SYSREQ.D for better performance.
    amx_->sysreq_d = 0;

    if (active_) counters_[-index].Start();; // Notice negative index
    int error = callback_(amx_, index, result, params);
    if (active_) counters_[-index].Stop();

    return error;
}

int AmxProfiler::Exec(cell *retval, int index) {
    if (index >= 0 || index == AMX_EXEC_MAIN) {
        AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx_->base);
        cell address = 0;

        if (index == AMX_EXEC_MAIN) {
            address = hdr->cip;
        } else {
            AMX_FUNCSTUBNT *publics = reinterpret_cast<AMX_FUNCSTUBNT*>(amx_->base + hdr->publics);
            address = publics[index].address;
        }

        calls_.push(CallInfo(amx_->stk - 3*sizeof(cell), address, true));

        if (active_) counters_[address].Start();
        int error = amx_Exec(amx_, retval, index);
        if (active_) counters_[address].Stop();

        calls_.pop();

        return error;
    } else {
        return amx_Exec(amx_, retval, index);
    }
}

<commit_msg>Fix address shows even when public found<commit_after>// SA:MP Profiler plugin
//
// Copyright (c) 2011 Zeex
//
// 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.

#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <numeric>

#include "amxprofiler.h"

#include "amx/amx.h"
#include "amx/amxdbg.h"

std::map<AMX*, AmxProfiler*> AmxProfiler::instances_;

AmxProfiler::AmxProfiler() {}

// Extracts the names of native functions from the native table.
static void GetNatives(AMX *amx, std::vector<AmxProfiler::Function> &names) {
    AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
    AMX_FUNCSTUBNT *natives = reinterpret_cast<AMX_FUNCSTUBNT*>(amx->base + hdr->natives);

    int numberOfNatives;
    amx_NumNatives(amx, &numberOfNatives);

    for (int i = 0; i < numberOfNatives; i++) {
        names.push_back(AmxProfiler::Function(natives[i].address,
            reinterpret_cast<char*>(amx->base + natives[i].nameofs)));
    }
}

// Extracts the names of public functions from the native table.
static void GetPublics(AMX *amx, std::vector<AmxProfiler::Function> &names) {
    AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
    AMX_FUNCSTUBNT *publics = reinterpret_cast<AMX_FUNCSTUBNT*>(amx->base + hdr->publics);

    int numberOfPublics;
    amx_NumPublics(amx, &numberOfPublics);

    for (int i = 0; i < numberOfPublics; i++) {
        names.push_back(AmxProfiler::Function(publics[i].address,
            reinterpret_cast<char*>(amx->base + publics[i].nameofs)));
    }
}

// Reads from a code section at a given location.
static inline cell ReadAmxCode(AMX *amx, cell where) {
    AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx->base);
    return *reinterpret_cast<cell*>(amx->base + hdr->cod + where);
}

// Comparison functiosn for different stats sorting modes
static bool ByCalls(const std::pair<cell, AmxPerformanceCounter> &op1,
                         const std::pair<cell, AmxPerformanceCounter> &op2) {
    return op1.second.GetCalls() > op2.second.GetCalls();
}

static bool ByTime(const std::pair<cell, AmxPerformanceCounter> &op1,
                        const std::pair<cell, AmxPerformanceCounter> &op2) {
    return op1.second.GetTime() > op2.second.GetTime();
}

static bool ByTimePerCall(const std::pair<cell, AmxPerformanceCounter> &op1,
                               const std::pair<cell, AmxPerformanceCounter> &op2) {
    return static_cast<double>(op1.second.GetTime()) / static_cast<double>(op1.second.GetCalls())
         > static_cast<double>(op2.second.GetTime()) / static_cast<double>(op2.second.GetCalls());
}

AmxProfiler::AmxProfiler(AMX *amx)
    : amx_(amx),
      debug_(amx->debug),
      callback_(amx->callback),
      active_(false),
      haveDbg_(false)
{
    // Since PrintStats is done in AmxUnload and amx->base is already freed before
    // AmxUnload gets called, therefore both native and public tables are not accessible,
    // from there, so they must be stored separately in some global place.
    GetNatives(amx, natives_);
    GetPublics(amx, publics_);
}

AmxProfiler::AmxProfiler(AMX *amx, AMX_DBG amxdbg)
    : amx_(amx),
      amxdbg_(amxdbg),
      debug_(amx->debug),
      callback_(amx->callback),
      active_(false),
      haveDbg_(true)
{
    GetNatives(amx, natives_);
    GetPublics(amx, publics_);
}

void AmxProfiler::Attach(AMX *amx) {
    AmxProfiler *prof = new AmxProfiler(amx);
    instances_[amx] = prof;
    prof->Activate();
}

void AmxProfiler::Attach(AMX *amx, AMX_DBG amxdbg) {
    AmxProfiler *prof = new AmxProfiler(amx, amxdbg);
    instances_[amx] = prof;
    prof->Activate();
}

void AmxProfiler::Detach(AMX *amx) {
    AmxProfiler *prof = AmxProfiler::Get(amx);
    if (prof != 0) {
        prof->Deactivate();
        delete prof;
    }
    instances_.erase(amx);
}

AmxProfiler *AmxProfiler::Get(AMX *amx) {
    std::map<AMX*, AmxProfiler*>::iterator it = instances_.find(amx);
    if (it != instances_.end()) {
        return it->second;
    }
    return 0;
}

static int AMXAPI Debug(AMX *amx) {
    return AmxProfiler::Get(amx)->Debug();
}

static int AMXAPI Callback(AMX *amx, cell index, cell *result, cell *params) {
    return AmxProfiler::Get(amx)->Callback(index, result, params);
}

void AmxProfiler::Activate() {
    if (!active_) {
        active_ = true;
        amx_SetDebugHook(amx_, ::Debug);
        amx_SetCallback(amx_, ::Callback);
    }
}

bool AmxProfiler::IsActive() const {
    return active_;
}

void AmxProfiler::Deactivate() {
    if (active_) {
        active_ = false;
        amx_SetDebugHook(amx_, debug_);
        amx_SetCallback(amx_, callback_);
    }
}

void AmxProfiler::ResetStats() {
    counters_.clear();
}

bool AmxProfiler::PrintStats(const std::string &filename, StatsPrintOrder order) {
    std::ofstream stream(filename.c_str());

    if (stream.is_open()) {
        std::vector<std::pair<cell, AmxPerformanceCounter> > stats(counters_.begin(),
                                                     counters_.end());
        switch (order) {
            case ORDER_BY_CALLS:
                std::sort(stats.begin(), stats.end(), ByCalls);
                break;
            case ORDER_BY_TIME:
                std::sort(stats.begin(), stats.end(), ByTime);
                break;
            case ORDER_BY_TIME_PER_CALL:
                std::sort(stats.begin(), stats.end(), ByTimePerCall);
                break;
            default:
                // leave as is
                break;
        }

        stream << "
\n"
               << "\t
\n"
               << "\t\tFunction	\n"
               << "\t\tCalls	\n"
               << "\t\tTime per call, µs	\n"
               << "\t\tOverall time, µs	\n"
               << "\t\tOverall time, %	\n"
               << "\t
\n";

        platformstl::int64_t totalTime = 0;

        for (std::vector<std::pair<cell, AmxPerformanceCounter> >::iterator it = stats.begin();
             it != stats.end(); ++it)
        {
            totalTime += it->second.GetTime();
        }

        for (std::vector<std::pair<cell, AmxPerformanceCounter> >::iterator it = stats.begin();
             it != stats.end(); ++it)
        {
            stream << "\t
\n";

            cell address = it->first;

            if (address <= 0) {
                stream << "\t\t" << natives_[-address].name() << "	\n";
            } else {
                const char *name = 0;
                if (haveDbg_ && dbg_LookupFunction(&amxdbg_, address, &name) == AMX_ERR_NONE) {
                    stream << "\t\t" << name << "	\n";
                } else {
                    bool found = false;
                    for (std::vector<AmxProfiler::Function>::iterator pubIt = publics_.begin();
                         pubIt != publics_.end(); ++pubIt)
                    {
                        if (pubIt->address() == address)  {
                            stream << "\t\t" << pubIt->name() << "	\n";
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        // OK we tried all means but still don't know the name, so just print the address.
                        stream << "\t\t" << "0x" << std::hex << address << std::dec << "	\n";
                    }
                }
            }

            AmxPerformanceCounter &counter = it->second;

            stream << "\t\t" << counter.GetCalls() << "	\n"
                   << "\t\t" << std::fixed << std::setprecision(0)
                                 << static_cast<double>(counter.GetTime()) /
                                        static_cast<double>(counter.GetCalls()) << "	\n"
                   << "\t\t" << counter.GetTime() << "	\n"
                   << "\t\t" << std::setprecision(2)
                                 << static_cast<double>(counter.GetTime() * 100) /
                                        static_cast<double>(totalTime) << "	\n";
            stream << "\t
\n";
        }

        stream << "
\n";

        return true;
    }

    return false;
}

int AmxProfiler::Debug() {
    // Get previous stack frame.
    cell prevFrame = amx_->stp;
    if (!calls_.empty()) {
        prevFrame = calls_.top().frame();
    }

    // Check whether current frame is different.
    if (amx_->frm < prevFrame) {
        // Probably entered a function body (first BREAK after PROC).
        cell address = amx_->cip - 2*sizeof(cell);
        // Check if we have a PROC opcode behind.
        if (ReadAmxCode(amx_, address) == 46) {
            calls_.push(CallInfo(amx_->frm, address, false));
            if (active_) {
                counters_[address].Start();
            }
            //logprintf("==> %x | frame = %x", address, amx_->frm);
        }
    } else if (amx_->frm > prevFrame) {
        if (!calls_.top().entryPoint()) { // entry points are handled by Exec
            // Left the function
            cell address = calls_.top().address();
            if (active_) {
                counters_[address].Stop();
            }
            calls_.pop();
            //logprintf("<== %x | frame = %x", address, amx_->frm);
        }
    }

    if (debug_ != 0) {
        // Others could set their own debug hooks
        return debug_(amx_);
    }

    return AMX_ERR_NONE;
}

int AmxProfiler::Callback(cell index, cell *result, cell *params) {
    // The default AMX callback (amx_Callback) can replace SYSREQ.C opcodes
    // with SYSREQ.D for better performance.
    amx_->sysreq_d = 0;

    if (active_) counters_[-index].Start();; // Notice negative index
    int error = callback_(amx_, index, result, params);
    if (active_) counters_[-index].Stop();

    return error;
}

int AmxProfiler::Exec(cell *retval, int index) {
    if (index >= 0 || index == AMX_EXEC_MAIN) {
        AMX_HEADER *hdr = reinterpret_cast<AMX_HEADER*>(amx_->base);
        cell address = 0;

        if (index == AMX_EXEC_MAIN) {
            address = hdr->cip;
        } else {
            AMX_FUNCSTUBNT *publics = reinterpret_cast<AMX_FUNCSTUBNT*>(amx_->base + hdr->publics);
            address = publics[index].address;
        }

        calls_.push(CallInfo(amx_->stk - 3*sizeof(cell), address, true));

        if (active_) counters_[address].Start();
        int error = amx_Exec(amx_, retval, index);
        if (active_) counters_[address].Stop();

        calls_.pop();

        return error;
    } else {
        return amx_Exec(amx_, retval, index);
    }
}

<|endoftext|>