<commit_before>#include "login_service.h"
#include <inttypes.h>
#include <curl/curl.h>
#include <sails/base/time_t.h>
#include <sails/crypto/md5.h>
#include <sails/base/string.h>
#include <sails/base/json.hpp>
#include <sails/log/logging.h>
#include <string>
#include "login_config.h"
#include "sails/base/util.h"

namespace sails {

log::Logger loginLog(log::Logger::LOG_LEVEL_DEBUG,
                     "./log/login.log", log::Logger::SPLIT_DAY);

LoginConfig config;

void LoginServiceImpl::login(::google::protobuf::RpcController* controller,
                             const ::sails::LoginRequest* request,
                             ::sails::LoginResponse* response,
                             ::google::protobuf::Closure* done) {
  if (request != NULL && response != NULL) {
    LoginResponse_ResultCode result_code =
        LoginResponse_ResultCode::LoginResponse_ResultCode_LOGIN_OTHER_ERR;
    if (login_check(request)) {  // check username and password
      // get room info
      int roomid = request->roomid();
      response->set_roomid(request->roomid());
      if (roomid > 0 && roomid < 1000) {
        RoomInfo room_info;
        memset(&room_info, 0, sizeof(RoomInfo));
        if ( get_room_info(roomid, &room_info) ) {
          response->set_ip(room_info.ip);
          response->set_port(room_info.port);
          if (room_info.usercount >= config.max_player()) {
            result_code = LoginResponse_ResultCode_LOGIN_ROOM_FULL;
          } else {
            // post session
            std::string session = get_session();
            response->set_session(session);

            if (report_session(session, request->username(), &room_info)) {
              result_code = LoginResponse_ResultCode_LOGIN_SUCCESS;
            } else {
              result_code = LoginResponse_ResultCode_LOGIN_ADD_SESSION_FAIL;
            }
          }
        } else {
          result_code = LoginResponse_ResultCode_LOGIN_GET_ROOM_FAIL;
        }
      } else {
        loginLog.error("roomid is %d and invalid", roomid);
      }
    } else {
      result_code = LoginResponse_ResultCode_LOGIN_CHECK_FAIL;
    }

    response->set_code(result_code);
  }
}

void LoginServiceImpl::logout(::google::protobuf::RpcController* controller,
                              const ::sails::LogoutRequest* request,
                              ::sails::LogoutResponse* response,
                              ::google::protobuf::Closure* done) {
  if (request != NULL && response != NULL) {
    std::string session = request->session();
    if (session.length() > 0) {
      if (delete_session(session)) {
        response->set_code(LogoutResponse_ResultCode_LOGOUT_SUCCESS);
        return;
      }
    }
  }
  response->set_code(LogoutResponse_ResultCode_LOGOUT_ERR);
}

size_t read_callback(void *buffer, size_t size, size_t nmemb, void *userp) {
  struct ptr_string *data = (struct ptr_string*)userp;
  size_t new_len = data->len + size*nmemb;
  char *ptr = reinterpret_cast<char*>(malloc(new_len+1));
  memcpy(ptr, data->ptr, data->len);
  memcpy(ptr+data->len, buffer, size*nmemb);
  free(data->ptr);
  data->ptr = ptr;
  data->len = new_len;
  data->ptr[new_len] = '\0';
  return size*nmemb;
}

bool login_check(const LoginRequest *request) {
  char signstr[500] = {'\0'};
  std::string strsignMd5;
  char time_str[100] = {'\0'};
  memset(time_str, 0, 100);
  base::TimeT::time_str(time_str, 100);
  snprintf(signstr, sizeof(signstr), "%s%s%s%s",
          request->username().c_str(), request->ticket().c_str(),
           time_str, config.get_login_key().c_str());
  strsignMd5 = crypto::MD5(signstr).toString();

  std::string password(request->ticket());
  char password_encoding[1000];
  memset(password_encoding, '\0', 1000);

  std::string url;
  if (config.is_test()) {
    url = config.get_login_test_url();
  } else {
    url = config.get_login_url();
  }
  char param[500] = {'\0'};
  if (config.is_test()) {
    snprintf(param, sizeof(param), "model=netgame&action=authuser&uid=%s&"
            "ticket=%s&time=%s&sign=%s&line=10",
            request->username().c_str(),
             base::url_encode(password.c_str(), password_encoding,
                              sizeof(password_encoding)),
            time_str, strsignMd5.c_str());

  } else {
    snprintf(param, sizeof(param), "model=netgame&action=authuser&uid=%s&"
             "ticket=%s&time=%s&sign=%s",
             request->username().c_str(),
             base::url_encode(password.c_str(), password_encoding,
                              sizeof(password_encoding)),
             time_str, strsignMd5.c_str());
  }

  std::string result;
  if ( post_message(url.c_str(), param, result) ) {
    // parser json data
    json root = json::parse(result);
    if ( !root["status"].empty() ) {
      int status = root["status"];
      if (status == 1) {
        return true;
      }
    }
  }
  return false;
}

std::string get_session() {
  // gen session
  char temp_str[100] = {'\0'};
  snprintf(temp_str, sizeof(temp_str), "%" PRIu64 "", sails::base::GetUID());
  std::string session = crypto::MD5(temp_str).toString();

  return session;
}

bool get_room_info(int roomid, RoomInfo *info) {
  std::string url = config.get_store_api_url()+"/room";
  char param[40] = {'\0'};
  snprintf(param, sizeof(param), "method=CHECK&id=%d", roomid);
  std::string result;

  if ( post_message(url.c_str(), param, result) ) {
    loginLog.debug("get room infor:%s", result.c_str());
    json root = json::parse(result);
    if ( !root["status"].empty() ) {
      int status = root["status"];
      if (status == 0) {  // call right
        if (!root["message"]["ip"].empty() &&
            !root["message"]["port"].empty() &&
            !root["message"]["usercount"].empty() ) {
          std::string ip = root["message"]["ip"];
          strncpy(info->ip, ip.c_str(), ip.length());
          loginLog.debug("ip:%s", ip.c_str());
          std::string portstr = root["message"]["port"];
          int port = atoi(portstr.c_str());
          info->port = port;
          loginLog.debug("port:%d", port);

          std::string usercountstr = root["message"]["usercount"];
          int usercount = atoi(usercountstr.c_str());
          info->usercount = usercount;
          loginLog.debug("usercount:%d", usercount);

          return true;
        }
      }
    }
  }
  return false;
}

bool report_session(std::string session, std::string user, RoomInfo* room) {
  std::string url = config.get_store_api_url()+"/session";
  char param[200] = {'\0'};
  snprintf(param, sizeof(param),
           "method=ADD&ip=%s&port=%d&session=%s&username=%s",
          room->ip, room->port, session.c_str(), user.c_str());
  std::string result;

  if (post_message(url.c_str(), param, result)) {
    loginLog.debug("report session result:%s", result.c_str());
    json root = json::parse(result);
    if ( !root["status"].empty() ) {
      int status = root["status"];
      if (status == 0) {  // call right
        return true;
      }
    }
  }
  return false;
}

bool delete_session(std::string session) {
  std::string url = config.get_store_api_url()+"/session";
  char param[200] = {'\0'};
  snprintf(param, sizeof(param), "method=REMOVE&session=%s", session.c_str());
  std::string result;

  if (post_message(url.c_str(), param, result)) {
    loginLog.debug("delete session result:%s", result.c_str());
    json root = json::parse(result);
    if ( !root["status"].empty() ) {
      int status = root["status"];
      if (status == 0) {  // call right
        return true;
      }
    }
  }
  return false;
}

bool post_message(const char* url, const char* data, std::string &result) {
  bool ret = false;
  curl_global_init(CURL_GLOBAL_ALL);
  CURL *curl = curl_easy_init();
  if (curl != NULL) {
    struct ptr_string login_result;
    login_result.len = 0;
    login_result.ptr = NULL;

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, read_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &login_result);

    CURLcode res;
    res = curl_easy_perform(curl);
    if (res == CURLE_OK) {
      result += std::string(login_result.ptr, login_result.len);
      ret = true;
    } else {
      loginLog.error("post url:%s", url);
    }

    if (login_result.len > 0 && login_result.ptr != NULL) {
      login_result.len = 0;
      free(login_result.ptr);
      login_result.ptr = NULL;
    }
  }

  curl_easy_cleanup(curl);
  curl_global_cleanup();
  return ret;
}

}  // namespace sails
<commit_msg>udpate<commit_after>// Copyright (C) 2015 sails Authors.
// All rights reserved.
//
// Official git repository and contact information can be found at
// https://github.com/sails/sails and http://www.sailsxu.com/.
//
// Filename: login_service.cc
//
// Author: sailsxu <sailsxu@gmail.com>
// Created: 2015-12-25 14:48:09

#include "login_service.h"
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <curl/curl.h>
#include <sails/base/time_t.h>
#include <sails/crypto/md5.h>
#include <sails/base/string.h>
#include <sails/base/json.hpp>
#include <sails/log/logging.h>
#include <string>
#include "login_config.h"
#include "sails/base/util.h"

namespace sails {

log::Logger loginLog(log::Logger::LOG_LEVEL_DEBUG,
                     "./log/login.log", log::Logger::SPLIT_DAY);

LoginConfig config;

void LoginServiceImpl::login(::google::protobuf::RpcController* controller,
                             const ::sails::LoginRequest* request,
                             ::sails::LoginResponse* response,
                             ::google::protobuf::Closure* done) {
  if (request != NULL && response != NULL) {
    LoginResponse_ResultCode result_code =
        LoginResponse_ResultCode::LoginResponse_ResultCode_LOGIN_OTHER_ERR;
    if (login_check(request)) {  // check username and password
      // get room info
      int roomid = request->roomid();
      response->set_roomid(request->roomid());
      if (roomid > 0 && roomid < 1000) {
        RoomInfo room_info;
        memset(&room_info, 0, sizeof(RoomInfo));
        if ( get_room_info(roomid, &room_info) ) {
          response->set_ip(room_info.ip);
          response->set_port(room_info.port);
          if (room_info.usercount >= config.max_player()) {
            result_code = LoginResponse_ResultCode_LOGIN_ROOM_FULL;
          } else {
            // post session
            std::string session = get_session();
            response->set_session(session);

            if (report_session(session, request->username(), &room_info)) {
              result_code = LoginResponse_ResultCode_LOGIN_SUCCESS;
            } else {
              result_code = LoginResponse_ResultCode_LOGIN_ADD_SESSION_FAIL;
            }
          }
        } else {
          result_code = LoginResponse_ResultCode_LOGIN_GET_ROOM_FAIL;
        }
      } else {
        loginLog.error("roomid is %d and invalid", roomid);
      }
    } else {
      result_code = LoginResponse_ResultCode_LOGIN_CHECK_FAIL;
    }

    response->set_code(result_code);
  }
}

void LoginServiceImpl::logout(::google::protobuf::RpcController* controller,
                              const ::sails::LogoutRequest* request,
                              ::sails::LogoutResponse* response,
                              ::google::protobuf::Closure* done) {
  if (request != NULL && response != NULL) {
    std::string session = request->session();
    if (session.length() > 0) {
      if (delete_session(session)) {
        response->set_code(LogoutResponse_ResultCode_LOGOUT_SUCCESS);
        return;
      }
    }
  }
  response->set_code(LogoutResponse_ResultCode_LOGOUT_ERR);
}

size_t read_callback(void *buffer, size_t size, size_t nmemb, void *userp) {
  struct ptr_string *data = (struct ptr_string*)userp;
  size_t new_len = data->len + size*nmemb;
  char *ptr = reinterpret_cast<char*>(malloc(new_len+1));
  memcpy(ptr, data->ptr, data->len);
  memcpy(ptr+data->len, buffer, size*nmemb);
  free(data->ptr);
  data->ptr = ptr;
  data->len = new_len;
  data->ptr[new_len] = '\0';
  return size*nmemb;
}

bool login_check(const LoginRequest *request) {
  char signstr[500] = {'\0'};
  std::string strsignMd5;
  char time_str[100] = {'\0'};
  memset(time_str, 0, 100);
  base::TimeT::time_str(time_str, 100);
  snprintf(signstr, sizeof(signstr), "%s%s%s%s",
          request->username().c_str(), request->ticket().c_str(),
           time_str, config.get_login_key().c_str());
  strsignMd5 = crypto::MD5(signstr).toString();

  std::string password(request->ticket());
  char password_encoding[1000];
  memset(password_encoding, '\0', 1000);

  std::string url;
  if (config.is_test()) {
    url = config.get_login_test_url();
  } else {
    url = config.get_login_url();
  }
  char param[500] = {'\0'};
  if (config.is_test()) {
    snprintf(param, sizeof(param), "model=netgame&action=authuser&uid=%s&"
            "ticket=%s&time=%s&sign=%s&line=10",
            request->username().c_str(),
             base::url_encode(password.c_str(), password_encoding,
                              sizeof(password_encoding)),
            time_str, strsignMd5.c_str());

  } else {
    snprintf(param, sizeof(param), "model=netgame&action=authuser&uid=%s&"
             "ticket=%s&time=%s&sign=%s",
             request->username().c_str(),
             base::url_encode(password.c_str(), password_encoding,
                              sizeof(password_encoding)),
             time_str, strsignMd5.c_str());
  }

  std::string result;
  if ( post_message(url.c_str(), param, result) ) {
    // parser json data
    json root = json::parse(result);
    if ( !root["status"].empty() ) {
      int status = root["status"];
      if (status == 1) {
        return true;
      }
    }
  }
  return false;
}

std::string get_session() {
  // gen session
  char temp_str[100] = {'\0'};
  snprintf(temp_str, sizeof(temp_str), "%" PRIu64 "", sails::base::GetUID());
  std::string session = crypto::MD5(temp_str).toString();

  return session;
}

bool get_room_info(int roomid, RoomInfo *info) {
  std::string url = config.get_store_api_url()+"/room";
  char param[40] = {'\0'};
  snprintf(param, sizeof(param), "method=CHECK&id=%d", roomid);
  std::string result;

  if ( post_message(url.c_str(), param, result) ) {
    loginLog.debug("get room infor:%s", result.c_str());
    json root = json::parse(result);
    if ( !root["status"].empty() ) {
      int status = root["status"];
      if (status == 0) {  // call right
        if (!root["message"]["ip"].empty() &&
            !root["message"]["port"].empty() &&
            !root["message"]["usercount"].empty() ) {
          std::string ip = root["message"]["ip"];
          strncpy(info->ip, ip.c_str(), ip.length());
          loginLog.debug("ip:%s", ip.c_str());
          std::string portstr = root["message"]["port"];
          int port = atoi(portstr.c_str());
          info->port = port;
          loginLog.debug("port:%d", port);

          std::string usercountstr = root["message"]["usercount"];
          int usercount = atoi(usercountstr.c_str());
          info->usercount = usercount;
          loginLog.debug("usercount:%d", usercount);

          return true;
        }
      }
    }
  }
  return false;
}

bool report_session(std::string session, std::string user, RoomInfo* room) {
  std::string url = config.get_store_api_url()+"/session";
  char param[200] = {'\0'};
  snprintf(param, sizeof(param),
           "method=ADD&ip=%s&port=%d&session=%s&username=%s",
          room->ip, room->port, session.c_str(), user.c_str());
  std::string result;

  if (post_message(url.c_str(), param, result)) {
    loginLog.debug("report session result:%s", result.c_str());
    json root = json::parse(result);
    if ( !root["status"].empty() ) {
      int status = root["status"];
      if (status == 0) {  // call right
        return true;
      }
    }
  }
  return false;
}

bool delete_session(std::string session) {
  std::string url = config.get_store_api_url()+"/session";
  char param[200] = {'\0'};
  snprintf(param, sizeof(param), "method=REMOVE&session=%s", session.c_str());
  std::string result;

  if (post_message(url.c_str(), param, result)) {
    loginLog.debug("delete session result:%s", result.c_str());
    json root = json::parse(result);
    if ( !root["status"].empty() ) {
      int status = root["status"];
      if (status == 0) {  // call right
        return true;
      }
    }
  }
  return false;
}

bool post_message(const char* url, const char* data, std::string &result) {
  bool ret = false;
  curl_global_init(CURL_GLOBAL_ALL);
  CURL *curl = curl_easy_init();
  if (curl != NULL) {
    struct ptr_string login_result;
    login_result.len = 0;
    login_result.ptr = NULL;

    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, read_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &login_result);

    CURLcode res;
    res = curl_easy_perform(curl);
    if (res == CURLE_OK) {
      result += std::string(login_result.ptr, login_result.len);
      ret = true;
    } else {
      loginLog.error("post url:%s", url);
    }

    if (login_result.len > 0 && login_result.ptr != NULL) {
      login_result.len = 0;
      free(login_result.ptr);
      login_result.ptr = NULL;
    }
  }

  curl_easy_cleanup(curl);
  curl_global_cleanup();
  return ret;
}

}  // namespace sails
<|endoftext|>


<commit_before>// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp

#pragma once

#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
#define NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP

#include <Nazara/Graphics/CullingList.hpp>
#include <Nazara/Graphics/InstancedRenderable.hpp>
#include <Nazara/Utility/Node.hpp>
#include <NDK/Component.hpp>
#include <unordered_map>

namespace Ndk
{
	class GraphicsComponent;

	using GraphicsComponentCullingList = Nz::CullingList<GraphicsComponent>;
	using GraphicsComponentHandle = Nz::ObjectHandle<GraphicsComponent>;

	class NDK_API GraphicsComponent : public Component<GraphicsComponent>, public Nz::HandledObject<GraphicsComponent>
	{
		friend class RenderSystem;

		public:
			using RenderableList = std::vector<Nz::InstancedRenderableRef>;

			GraphicsComponent() = default;
			inline GraphicsComponent(const GraphicsComponent& graphicsComponent);
			~GraphicsComponent() = default;

			inline void AddToCullingList(GraphicsComponentCullingList* cullingList) const;
			void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const;

			inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0);
			void Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder = 0);

			inline void Clear();

			inline void Detach(const Nz::InstancedRenderable* renderable);

			inline bool DoesRequireRealTimeReflections() const;

			inline void EnsureBoundingVolumeUpdate() const;
			inline void EnsureTransformMatrixUpdate() const;

			inline void GetAttachedRenderables(RenderableList* renderables) const;
			inline std::size_t GetAttachedRenderableCount() const;

			inline const Nz::BoundingVolumef& GetBoundingVolume() const;

			inline void RemoveFromCullingList(GraphicsComponentCullingList* cullingList) const;

			static ComponentIndex componentIndex;

		private:
			struct Renderable;

			void ConnectInstancedRenderableSignals(Renderable& renderable);

			inline void InvalidateBoundingVolume() const;
			void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, std::size_t index);
			void InvalidateRenderableMaterial(const Nz::InstancedRenderable* renderable, std::size_t skinIndex, std::size_t matIndex, const Nz::MaterialRef& newMat);
			inline void InvalidateRenderables();
			void InvalidateReflectionMap();
			inline void InvalidateTransformMatrix();

			void RegisterMaterial(Nz::Material* material, std::size_t count = 1);

			void OnAttached() override;
			void OnComponentAttached(BaseComponent& component) override;
			void OnComponentDetached(BaseComponent& component) override;
			void OnDetached() override;

			void OnInstancedRenderableResetMaterials(const Nz::InstancedRenderable* renderable, std::size_t newMaterialCount);
			void OnInstancedRenderableSkinChange(const Nz::InstancedRenderable* renderable, std::size_t newSkinIndex);
			void OnMaterialReflectionChange(const Nz::Material* material, Nz::ReflectionMode reflectionMode);
			void OnNodeInvalidated(const Nz::Node* node);

			void UnregisterMaterial(Nz::Material* material);

			void UpdateBoundingVolume() const;
			void UpdateTransformMatrix() const;

			NazaraSlot(Nz::Node, OnNodeInvalidation, m_nodeInvalidationSlot);

			struct MaterialEntry
			{
				NazaraSlot(Nz::Material, OnMaterialReflectionChange, reflectionModelChangeSlot);

				std::size_t renderableCounter;
			};

			struct Renderable
			{
				Renderable(const Nz::Matrix4f& transformMatrix) :
				data(transformMatrix),
				dataUpdated(false)
				{
				}

				Renderable(const Renderable&) = delete;
				Renderable(Renderable&& rhs) noexcept = default;

				~Renderable()
				{
					// Disconnect release slot before releasing instanced renderable reference
					renderableReleaseSlot.Disconnect();
				}

				Renderable& operator=(const Renderable&) = delete;
				Renderable& operator=(Renderable&& r) noexcept = default;

				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateBoundingVolume, renderableBoundingVolumeInvalidationSlot);
				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableDataInvalidationSlot);
				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateMaterial, renderableMaterialInvalidationSlot);
				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableRelease, renderableReleaseSlot);
				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableResetMaterials, renderableResetMaterialsSlot);
				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableSkinChange, renderableSkinChangeSlot);

				mutable Nz::InstancedRenderable::InstanceData data;
				Nz::InstancedRenderableRef renderable;
				mutable bool dataUpdated;
			};

			using VolumeCullingListEntry = GraphicsComponentCullingList::VolumeEntry;

			struct VolumeCullingEntry
			{
				VolumeCullingListEntry listEntry;

				NazaraSlot(GraphicsComponentCullingList, OnCullingListRelease, cullingListReleaseSlot);
			};

			std::size_t m_reflectiveMaterialCount;
			mutable std::vector<VolumeCullingEntry> m_volumeCullingEntries;
			std::vector<Renderable> m_renderables;
			std::unordered_map<const Nz::Material*, MaterialEntry> m_materialEntries;
			mutable Nz::BoundingVolumef m_boundingVolume;
			mutable Nz::Matrix4f m_transformMatrix;
			Nz::TextureRef m_reflectionMap;
			mutable bool m_boundingVolumeUpdated;
			mutable bool m_transformMatrixUpdated;
			unsigned int m_reflectionMapSize;
	};
}

#include <NDK/Components/GraphicsComponent.inl>

#endif // NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
#endif // NDK_SERVER
<commit_msg>Fix compilation<commit_after>// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp

#pragma once

#ifndef NDK_SERVER
#ifndef NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
#define NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP

#include <Nazara/Graphics/CullingList.hpp>
#include <Nazara/Graphics/InstancedRenderable.hpp>
#include <Nazara/Utility/Node.hpp>
#include <NDK/Component.hpp>
#include <unordered_map>

namespace Ndk
{
	class GraphicsComponent;

	using GraphicsComponentCullingList = Nz::CullingList<GraphicsComponent>;
	using GraphicsComponentHandle = Nz::ObjectHandle<GraphicsComponent>;

	class NDK_API GraphicsComponent : public Component<GraphicsComponent>, public Nz::HandledObject<GraphicsComponent>
	{
		friend class RenderSystem;

		public:
			using RenderableList = std::vector<Nz::InstancedRenderableRef>;

			GraphicsComponent() = default;
			inline GraphicsComponent(const GraphicsComponent& graphicsComponent);
			~GraphicsComponent() = default;

			inline void AddToCullingList(GraphicsComponentCullingList* cullingList) const;
			void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const;

			inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0);
			void Attach(Nz::InstancedRenderableRef renderable, const Nz::Matrix4f& localMatrix, int renderOrder = 0);

			inline void Clear();

			inline void Detach(const Nz::InstancedRenderable* renderable);

			inline bool DoesRequireRealTimeReflections() const;

			inline void EnsureBoundingVolumeUpdate() const;
			inline void EnsureTransformMatrixUpdate() const;

			inline void GetAttachedRenderables(RenderableList* renderables) const;
			inline std::size_t GetAttachedRenderableCount() const;

			inline const Nz::BoundingVolumef& GetBoundingVolume() const;

			inline void RemoveFromCullingList(GraphicsComponentCullingList* cullingList) const;

			static ComponentIndex componentIndex;

		private:
			struct Renderable;

			void ConnectInstancedRenderableSignals(Renderable& renderable);

			inline void InvalidateBoundingVolume() const;
			void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, std::size_t index);
			void InvalidateRenderableMaterial(const Nz::InstancedRenderable* renderable, std::size_t skinIndex, std::size_t matIndex, const Nz::MaterialRef& newMat);
			inline void InvalidateRenderables();
			void InvalidateReflectionMap();
			inline void InvalidateTransformMatrix();

			void RegisterMaterial(Nz::Material* material, std::size_t count = 1);

			void OnAttached() override;
			void OnComponentAttached(BaseComponent& component) override;
			void OnComponentDetached(BaseComponent& component) override;
			void OnDetached() override;

			void OnInstancedRenderableResetMaterials(const Nz::InstancedRenderable* renderable, std::size_t newMaterialCount);
			void OnInstancedRenderableSkinChange(const Nz::InstancedRenderable* renderable, std::size_t newSkinIndex);
			void OnMaterialReflectionChange(const Nz::Material* material, Nz::ReflectionMode reflectionMode);
			void OnNodeInvalidated(const Nz::Node* node);

			void UnregisterMaterial(Nz::Material* material);

			void UpdateBoundingVolume() const;
			void UpdateTransformMatrix() const;

			NazaraSlot(Nz::Node, OnNodeInvalidation, m_nodeInvalidationSlot);

			struct MaterialEntry
			{
				NazaraSlot(Nz::Material, OnMaterialReflectionModeChange, reflectionModelChangeSlot);

				std::size_t renderableCounter;
			};

			struct Renderable
			{
				Renderable(const Nz::Matrix4f& transformMatrix) :
				data(transformMatrix),
				dataUpdated(false)
				{
				}

				Renderable(const Renderable&) = delete;
				Renderable(Renderable&& rhs) noexcept = default;

				~Renderable()
				{
					// Disconnect release slot before releasing instanced renderable reference
					renderableReleaseSlot.Disconnect();
				}

				Renderable& operator=(const Renderable&) = delete;
				Renderable& operator=(Renderable&& r) noexcept = default;

				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateBoundingVolume, renderableBoundingVolumeInvalidationSlot);
				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableDataInvalidationSlot);
				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateMaterial, renderableMaterialInvalidationSlot);
				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableRelease, renderableReleaseSlot);
				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableResetMaterials, renderableResetMaterialsSlot);
				NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableSkinChange, renderableSkinChangeSlot);

				mutable Nz::InstancedRenderable::InstanceData data;
				Nz::InstancedRenderableRef renderable;
				mutable bool dataUpdated;
			};

			using VolumeCullingListEntry = GraphicsComponentCullingList::VolumeEntry;

			struct VolumeCullingEntry
			{
				VolumeCullingListEntry listEntry;

				NazaraSlot(GraphicsComponentCullingList, OnCullingListRelease, cullingListReleaseSlot);
			};

			std::size_t m_reflectiveMaterialCount;
			mutable std::vector<VolumeCullingEntry> m_volumeCullingEntries;
			std::vector<Renderable> m_renderables;
			std::unordered_map<const Nz::Material*, MaterialEntry> m_materialEntries;
			mutable Nz::BoundingVolumef m_boundingVolume;
			mutable Nz::Matrix4f m_transformMatrix;
			Nz::TextureRef m_reflectionMap;
			mutable bool m_boundingVolumeUpdated;
			mutable bool m_transformMatrixUpdated;
			unsigned int m_reflectionMapSize;
	};
}

#include <NDK/Components/GraphicsComponent.inl>

#endif // NDK_COMPONENTS_GRAPHICSCOMPONENT_HPP
#endif // NDK_SERVER
<|endoftext|>


<commit_before>//===- IntegerDivision.cpp - Unit tests for the integer division code -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"
#include "llvm/BasicBlock.h"
#include "llvm/GlobalValue.h"
#include "llvm/Function.h"
#include "llvm/IRBuilder.h"
#include "llvm/Module.h"
#include "llvm/Transforms/Utils/IntegerDivision.h"

using namespace llvm;

namespace {

TEST(IntegerDivision, SDiv) {
  LLVMContext &C(getGlobalContext());
  Module M("test division", C);
  IRBuilder<> Builder(C);

  SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
  Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
                                                   ArgTys, false),
                                 GlobalValue::ExternalLinkage, "F", &M);
  assert(F->getArgumentList().size() == 2);

  BasicBlock *BB = BasicBlock::Create(C, "", F);
  Builder.SetInsertPoint(BB);

  Function::arg_iterator AI = F->arg_begin();
  Value *A = AI++;
  Value *B = AI++;

  Value *Div = Builder.CreateSDiv(A, B);
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::SDiv);

  Value *Ret = Builder.CreateRet(Div);

  expandDivision(cast<BinaryOperator>(Div));
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);

  Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
  EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::Sub);

  Builder.SetInsertPoint(BB->end());
}

TEST(IntegerDivision, UDiv) {
  LLVMContext &C(getGlobalContext());
  Module M("test division", C);
  IRBuilder<> Builder(C);

  SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
  Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
                                                   ArgTys, false),
                                 GlobalValue::ExternalLinkage, "F", &M);
  assert(F->getArgumentList().size() == 2);

  BasicBlock *BB = BasicBlock::Create(C, "", F);
  Builder.SetInsertPoint(BB);

  Function::arg_iterator AI = F->arg_begin();
  Value *A = AI++;
  Value *B = AI++;

  Value *Div = Builder.CreateUDiv(A, B);
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::UDiv);

  Value *Ret = Builder.CreateRet(Div);

  expandDivision(cast<BinaryOperator>(Div));
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);

  Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
  EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::PHI);

  Builder.SetInsertPoint(BB->end());
}

TEST(IntegerDivision, SRem) {
  LLVMContext &C(getGlobalContext());
  Module M("test remainder", C);
  IRBuilder<> Builder(C);

  SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
  Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
                                                   ArgTys, false),
                                 GlobalValue::ExternalLinkage, "F", &M);
  assert(F->getArgumentList().size() == 2);

  BasicBlock *BB = BasicBlock::Create(C, "", F);
  Builder.SetInsertPoint(BB);

  Function::arg_iterator AI = F->arg_begin();
  Value *A = AI++;
  Value *B = AI++;

  Value *Rem = Builder.CreateSRem(A, B);
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::SRem);

  Value *Ret = Builder.CreateRet(Rem);

  expandRemainder(cast<BinaryOperator>(Rem));
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);

  Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
  EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);

  Builder.SetInsertPoint(BB->end());
}

TEST(IntegerDivision, URem) {
  LLVMContext &C(getGlobalContext());
  Module M("test remainder", C);
  IRBuilder<> Builder(C);

  SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
  Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
                                                   ArgTys, false),
                                 GlobalValue::ExternalLinkage, "F", &M);
  assert(F->getArgumentList().size() == 2);

  BasicBlock *BB = BasicBlock::Create(C, "", F);
  Builder.SetInsertPoint(BB);

  Function::arg_iterator AI = F->arg_begin();
  Value *A = AI++;
  Value *B = AI++;

  Value *Rem = Builder.CreateURem(A, B);
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::URem);

  Value *Ret = Builder.CreateRet(Rem);

  expandRemainder(cast<BinaryOperator>(Rem));
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);

  Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
  EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);

  Builder.SetInsertPoint(BB->end());
}

}
<commit_msg>Remove unneeded and invalid SetInsertPoint calls from unittest.<commit_after>//===- IntegerDivision.cpp - Unit tests for the integer division code -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "gtest/gtest.h"
#include "llvm/BasicBlock.h"
#include "llvm/GlobalValue.h"
#include "llvm/Function.h"
#include "llvm/IRBuilder.h"
#include "llvm/Module.h"
#include "llvm/Transforms/Utils/IntegerDivision.h"

using namespace llvm;

namespace {

TEST(IntegerDivision, SDiv) {
  LLVMContext &C(getGlobalContext());
  Module M("test division", C);
  IRBuilder<> Builder(C);

  SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
  Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
                                                   ArgTys, false),
                                 GlobalValue::ExternalLinkage, "F", &M);
  assert(F->getArgumentList().size() == 2);

  BasicBlock *BB = BasicBlock::Create(C, "", F);
  Builder.SetInsertPoint(BB);

  Function::arg_iterator AI = F->arg_begin();
  Value *A = AI++;
  Value *B = AI++;

  Value *Div = Builder.CreateSDiv(A, B);
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::SDiv);

  Value *Ret = Builder.CreateRet(Div);

  expandDivision(cast<BinaryOperator>(Div));
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);

  Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
  EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::Sub);
}

TEST(IntegerDivision, UDiv) {
  LLVMContext &C(getGlobalContext());
  Module M("test division", C);
  IRBuilder<> Builder(C);

  SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
  Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
                                                   ArgTys, false),
                                 GlobalValue::ExternalLinkage, "F", &M);
  assert(F->getArgumentList().size() == 2);

  BasicBlock *BB = BasicBlock::Create(C, "", F);
  Builder.SetInsertPoint(BB);

  Function::arg_iterator AI = F->arg_begin();
  Value *A = AI++;
  Value *B = AI++;

  Value *Div = Builder.CreateUDiv(A, B);
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::UDiv);

  Value *Ret = Builder.CreateRet(Div);

  expandDivision(cast<BinaryOperator>(Div));
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);

  Instruction* Quotient = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
  EXPECT_TRUE(Quotient && Quotient->getOpcode() == Instruction::PHI);
}

TEST(IntegerDivision, SRem) {
  LLVMContext &C(getGlobalContext());
  Module M("test remainder", C);
  IRBuilder<> Builder(C);

  SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
  Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
                                                   ArgTys, false),
                                 GlobalValue::ExternalLinkage, "F", &M);
  assert(F->getArgumentList().size() == 2);

  BasicBlock *BB = BasicBlock::Create(C, "", F);
  Builder.SetInsertPoint(BB);

  Function::arg_iterator AI = F->arg_begin();
  Value *A = AI++;
  Value *B = AI++;

  Value *Rem = Builder.CreateSRem(A, B);
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::SRem);

  Value *Ret = Builder.CreateRet(Rem);

  expandRemainder(cast<BinaryOperator>(Rem));
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::AShr);

  Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
  EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
}

TEST(IntegerDivision, URem) {
  LLVMContext &C(getGlobalContext());
  Module M("test remainder", C);
  IRBuilder<> Builder(C);

  SmallVector<Type*, 2> ArgTys(2, Builder.getInt32Ty());
  Function *F = Function::Create(FunctionType::get(Builder.getInt32Ty(),
                                                   ArgTys, false),
                                 GlobalValue::ExternalLinkage, "F", &M);
  assert(F->getArgumentList().size() == 2);

  BasicBlock *BB = BasicBlock::Create(C, "", F);
  Builder.SetInsertPoint(BB);

  Function::arg_iterator AI = F->arg_begin();
  Value *A = AI++;
  Value *B = AI++;

  Value *Rem = Builder.CreateURem(A, B);
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::URem);

  Value *Ret = Builder.CreateRet(Rem);

  expandRemainder(cast<BinaryOperator>(Rem));
  EXPECT_TRUE(BB->front().getOpcode() == Instruction::ICmp);

  Instruction* Remainder = dyn_cast<Instruction>(cast<User>(Ret)->getOperand(0));
  EXPECT_TRUE(Remainder && Remainder->getOpcode() == Instruction::Sub);
}

}
<|endoftext|>


<commit_before>/* * This file is part of meego-im-framework *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

// Input method overlay window

#include "mimpluginmanager.h"
#include "mimapplication.h"
#include "mimdummyinputcontext.h"
#include "minputcontextglibdbusconnection.h"
#include "mimpluginsproxywidget.h"

#ifdef Q_WS_X11
#include "mimxapplication.h"
#include "mimremotewindow.h"
#include "mimrotationanimation.h"
#include "mpassthruwindow.h"
#endif

#ifdef Q_WS_QPA
#include "mimqpaplatform.h"
#endif

#include <QApplication>
#include <QtDebug>
#include <QWidget>
#include <QGraphicsView>
#include <QPalette>
#include <QCommonStyle>
#include <stdlib.h>

using namespace std::tr1;

namespace {
    void disableMInputContextPlugin()
    {
        // prevent loading of minputcontext because we don't need it and starting
        // it might trigger starting of this service by the d-bus. not nice if that is
        // already happening :)
        if (-1 == unsetenv("QT_IM_MODULE")) {
            qWarning("meego-im-uiserver: unable to unset QT_IM_MODULE.");
        }

        // TODO: Check if hardwiring the QStyle can be removed at a later stage.
        QApplication::setStyle(new QCommonStyle);
    }
}

int main(int argc, char **argv)
{
    // QT_IM_MODULE, MApplication and QtMaemo5Style all try to load
    // MInputContext, which is fine for the application. For the passthrough
    // server itself, we absolutely need to prevent that.
    disableMInputContextPlugin();

#ifdef Q_WS_X11
    MImXApplication app(argc, argv);
#else
    MIMApplication app(argc, argv);
#endif
    // Set a dummy input context so that Qt does not create a default input
    // context (qimsw-multi) which is expensive and not required by
    // meego-im-uiserver.
    app.setInputContext(new MIMDummyInputContext);

    qDebug() << (app.selfComposited() ? "Use self composition" : "Use system compositor");

    // DBus Input Context Connection
    shared_ptr<MInputContextConnection> icConnection(new MInputContextGlibDBusConnection);

#ifdef Q_WS_X11
    QObject::connect(icConnection.get(), SIGNAL(focusChanged(WId)),
                     &app, SLOT(setTransientHint(WId)));

    // Rotation Animation
    MImRotationAnimation *rotationAnimation =
            new MImRotationAnimation(app.pluginsProxyWidget(), app.passThruWindow(), &app);

    QObject::connect(icConnection.get(), SIGNAL(appOrientationAboutToChange(int)),
            rotationAnimation, SLOT(appOrientationAboutToChange(int)));
    QObject::connect(icConnection.get(), SIGNAL(appOrientationChanged(int)),
            rotationAnimation, SLOT(appOrientationChangeFinished(int)));

    QWidget *pluginsProxyWidget = app.pluginsProxyWidget();
#endif

#ifdef Q_WS_QPA
    QWidget *pluginsProxyWidget = new MImPluginsProxyWidget;

    std::auto_ptr<MImQPAPlatform> platform(new MImQPAPlatform(pluginsProxyWidget));
#endif

    // PluginManager
    MIMPluginManager *pluginManager = new MIMPluginManager(icConnection,
                                                           pluginsProxyWidget);

#ifdef Q_WS_X11
    // hide active plugins when remote input window is gone or iconified.
    QObject::connect(&app, SIGNAL(remoteWindowGone()),
                     pluginManager, SLOT(hideActivePlugins()));

    QObject::connect(pluginManager, SIGNAL(regionUpdated(const QRegion &)),
                     app.passThruWindow(), SLOT(inputPassthrough(const QRegion &)));

    QObject::connect(pluginManager, SIGNAL(pluginLoaded()),
                     &app, SLOT(configureWidgetsForCompositing()));

    // Configure widgets loaded during MIMPluginManager construction
    app.configureWidgetsForCompositing();
#endif

#ifdef Q_WS_QPA
    QObject::connect(pluginManager, SIGNAL(regionUpdated(const QRegion &)),
                     platform.get(), SLOT(inputPassthrough(const QRegion &)));
#endif

    return app.exec();
}

<commit_msg>Cleanup main and add more comments<commit_after>/* * This file is part of meego-im-framework *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

// Input method overlay window

#include "mimpluginmanager.h"
#include "mimapplication.h"
#include "mimdummyinputcontext.h"
#include "minputcontextglibdbusconnection.h"
#include "mimpluginsproxywidget.h"

#if defined(Q_WS_X11)
#include "mimxapplication.h"
#include "mimremotewindow.h"
#include "mimrotationanimation.h"
#include "mpassthruwindow.h"
#elif defined(Q_WS_QPA)
#include "mimqpaplatform.h"
#endif

#include <QApplication>
#include <QtDebug>
#include <QWidget>
#include <QGraphicsView>
#include <QPalette>
#include <QCommonStyle>
#include <stdlib.h>

using namespace std::tr1;

namespace {
    void disableMInputContextPlugin()
    {
        // prevent loading of minputcontext because we don't need it and starting
        // it might trigger starting of this service by the d-bus. not nice if that is
        // already happening :)
        if (-1 == unsetenv("QT_IM_MODULE")) {
            qWarning("meego-im-uiserver: unable to unset QT_IM_MODULE.");
        }

        // TODO: Check if hardwiring the QStyle can be removed at a later stage.
        QApplication::setStyle(new QCommonStyle);
    }
}

int main(int argc, char **argv)
{
    // QT_IM_MODULE, MApplication and QtMaemo5Style all try to load
    // MInputContext, which is fine for the application. For the passthrough
    // server itself, we absolutely need to prevent that.
    disableMInputContextPlugin();

#if defined(Q_WS_X11)
    MImXApplication app(argc, argv);
#else
    MIMApplication app(argc, argv);
#endif

    // Set a dummy input context so that Qt does not create a default input
    // context (qimsw-multi) which is expensive and not required by
    // meego-im-uiserver.
    app.setInputContext(new MIMDummyInputContext);

    qDebug() << (app.selfComposited() ? "Use self composition" : "Use system compositor");

    // DBus Input Context Connection
    shared_ptr<MInputContextConnection> icConnection(new MInputContextGlibDBusConnection);

#if defined(Q_WS_X11)
    // For X11 the toplevel window is a MPassThruWindow (managed by MImXApplication. It
    // contains a MImPluginsProxyWidget as container for all plugin widgets and a
    // MImRotationAnimation, which is used to display the rotation animation. MImXApplication
    // also manages MImRemoteWindows representing the current application window.

    QObject::connect(icConnection.get(), SIGNAL(focusChanged(WId)),
                     &app, SLOT(setTransientHint(WId)));

    // Widget for showing a rotation animation inside the toplevel MPassThruWindow instead
    // of the MImPluginsProxyWidget when the device is rotating.
    MImRotationAnimation *rotationAnimation = new MImRotationAnimation(app.pluginsProxyWidget(),
                                                                       app.passThruWindow(), &app);
    QObject::connect(icConnection.get(), SIGNAL(appOrientationAboutToChange(int)),
                     rotationAnimation, SLOT(appOrientationAboutToChange(int)));
    QObject::connect(icConnection.get(), SIGNAL(appOrientationChanged(int)),
                     rotationAnimation, SLOT(appOrientationChangeFinished(int)));

    // Container for all plugin widgets
    QWidget *pluginsProxyWidget = app.pluginsProxyWidget();

    // Manager for loading and handling all plugins
    MIMPluginManager *pluginManager = new MIMPluginManager(icConnection,
                                                           pluginsProxyWidget);

    // Hide active plugins when the application window is gone or iconified.
    QObject::connect(&app, SIGNAL(remoteWindowGone()),
                     pluginManager, SLOT(hideActivePlugins()));

    // Handle changed used area by plugins
    QObject::connect(pluginManager, SIGNAL(regionUpdated(const QRegion &)),
                     app.passThruWindow(), SLOT(inputPassthrough(const QRegion &)));

    // Configure widgets for self compositing after loading
    QObject::connect(pluginManager, SIGNAL(pluginLoaded()),
                     &app, SLOT(configureWidgetsForCompositing()));

    // Configure widgets loaded during MIMPluginManager construction
    app.configureWidgetsForCompositing();

#elif defined(Q_WS_QPA)
    // For QPA the toplevel window is a MImPluginsProxyWidget containing all plugin
    // widgets. The MImQPAPlatform is used to show/hide that toplevel window when
    // required.

    std::auto_ptr<QWidget> pluginsProxyWidget(new MImPluginsProxyWidget);

    std::auto_ptr<MImQPAPlatform> platform(new MImQPAPlatform(pluginsProxyWidget.get()));

    MIMPluginManager *pluginManager = new MIMPluginManager(icConnection,
                                                           pluginsProxyWidget.get());

    QObject::connect(pluginManager, SIGNAL(regionUpdated(const QRegion &)),
                     platform.get(), SLOT(inputPassthrough(const QRegion &)));
#endif

    return app.exec();
}

<|endoftext|>


<commit_before>#include "AssetManager.hpp"

namespace swift
{
	AssetManager::AssetManager()
	{
		smooth = false;
	}

	AssetManager::~AssetManager()
	{
		for(auto& t : textures)
			delete t.second;

		//for(auto& s : skeletons)
		//	delete s.second;

		for(auto& s : soundBuffers)
			delete s.second;

		for(auto& m : music)
			delete m.second;

		for(auto& f : fonts)
			delete f.second;

		for(auto& s : scripts)
			delete s.second;
	}

	bool AssetManager::loadResourceFolder(const std::string& folder)
	{
		DIR* dir = nullptr;
		struct dirent* entry = nullptr;

		dir = opendir(folder.c_str());

		// error handling
		if(dir == nullptr)
		{
			log << "Unable to open resource folder: " << folder << "\n";
			return false;
		}

		while((entry = readdir(dir)))
		{
			if(entry == nullptr)
			{
				log << "Unable to read resource folder: " << folder << "\n";
				return false;
			}

			// if the entry is a directory, but is not the current or parent directory
			if(entry->d_type == DT_DIR && !(std::string(entry->d_name).compare(".") == 0 || std::string(entry->d_name).compare("..") == 0))
			{
				loadResourceFolder(folder + '/' + std::string(entry->d_name));	// recursive on child directory
			}
			// entry is a file
			else if(entry->d_type == DT_REG)
			{
				loadResource(folder + '/' + std::string(entry->d_name));
			}
		}

		closedir(dir);

		return true;
	}

	bool AssetManager::loadMod(const Mod& mod)
	{
		bool returnVar = true;

		for(auto &f : mod.getFiles())
		{
			bool temp = true;
			temp = loadResource(f);
			if(temp == false)
			{
				log << "ERROR: In " << mod.getName() << ", could not load " << f << '\n';
				returnVar = false;
			}
		}

		return returnVar;
	}

	void AssetManager::clean()
	{
		textures.clear();
		//skeletons.clear();
		soundBuffers.clear();
		music.clear();
		fonts.clear();
		scripts.clear();
	}

	void AssetManager::setSmooth(bool s)
	{
		smooth = s;
		for(auto &t : textures)
		{
			t.second->setSmooth(smooth);
		}
	}

	sf::Texture& AssetManager::getTexture(const std::string& n)
	{
		return *textures.find(n)->second;
	}

	/*Bitmask& AssetManager::getBitmask(const std::string& n)
	{
		return *bitmasks.find(n)->second;
	}*/

	/*Skeleton& AssetManager::getSkeleton(const std::string& n)
	{
		return *skeletons.find(n)->second;
	}*/

	sf::SoundBuffer& AssetManager::getSoundBuffer(const std::string& n)
	{
		return *soundBuffers.find(n)->second;
	}

	sf::Music& AssetManager::getSong(const std::string& n)
	{
		return *music.find(n)->second;
	}

	sf::Font& AssetManager::getFont(const std::string& n)
	{
		return *fonts.find(n)->second;
	}

	Script& AssetManager::getScript(const std::string& n)
	{
		return *scripts.find(n)->second;
	}

	bool AssetManager::loadResource(const std::string& file)
	{
		// this if chain checks what folder the file is in
		if(file.find("/textures/") != std::string::npos)
		{
			textures.emplace(file, new sf::Texture());

			if(!textures[file]->loadFromFile(file))
			{
				log << "Unable to load " << file << " as a texture.\n";
				textures.erase(file);
				return false;
			}
			textures[file]->setSmooth(smooth);

			log << "Texture:\t" << file << '\n';
		}
		else if(file.find("/skeletons/") != std::string::npos)
		{
			// create a skeleton
		}
		else if(file.find("/sounds/") != std::string::npos)
		{
			soundBuffers.emplace(file, new sf::SoundBuffer());

			if(!soundBuffers[file]->loadFromFile(file))
			{
				log << "Unable to load " << file << " as a sound.\n";
				soundBuffers.erase(file);
				return false;
			}

			log << "Sound:\t" << file << '\n';
		}
		else if(file.find("/music/") != std::string::npos)
		{
			music.emplace(file, new sf::Music());

			if(!music[file]->openFromFile(file))
			{
				log << "Unable to open " << file << " as a music file.\n";
				music.erase(file);
				return false;
			}

			log << "Music:\t" << file << '\n';
		}
		else if(file.find("/fonts/") != std::string::npos)
		{
			fonts.emplace(file, new sf::Font());

			if(!fonts[file]->loadFromFile(file))
			{
				log << "Unable to load " << file << " as a font.\n";
				fonts.erase(file);
				return false;
			}

			log << "Font:\t" << file << '\n';
		}
		else if(file.find("/scripts/") != std::string::npos)
		{
			scripts.emplace(file, new Script());

			if(!scripts[file]->loadFromFile(file))
			{
				log << "Unable to load " << file << " as a script.\n";
				scripts.erase(file);
				return false;
			}

			log << "Script:\t" << file << '\n';
		}
		else if(file.find(".txt") != std::string::npos)
		{
			// ignore *.txt files, but don't throw a warning/error
			log << "Ignoring " << file << '\n';
		}
		else
		{
			log << "WARNING: " << file << " is an unknown resource type.\n";
			return false;
		}
		return true;
	}
}
<commit_msg>Fixed a possible memory leak when a resource was unable to be loaded<commit_after>#include "AssetManager.hpp"

namespace swift
{
	AssetManager::AssetManager()
	{
		smooth = false;
	}

	AssetManager::~AssetManager()
	{
		for(auto& t : textures)
			delete t.second;

		//for(auto& s : skeletons)
		//	delete s.second;

		for(auto& s : soundBuffers)
			delete s.second;

		for(auto& m : music)
			delete m.second;

		for(auto& f : fonts)
			delete f.second;

		for(auto& s : scripts)
			delete s.second;
	}

	bool AssetManager::loadResourceFolder(const std::string& folder)
	{
		DIR* dir = nullptr;
		struct dirent* entry = nullptr;

		dir = opendir(folder.c_str());

		// error handling
		if(dir == nullptr)
		{
			log << "Unable to open resource folder: " << folder << "\n";
			return false;
		}

		while((entry = readdir(dir)))
		{
			if(entry == nullptr)
			{
				log << "Unable to read resource folder: " << folder << "\n";
				return false;
			}

			// if the entry is a directory, but is not the current or parent directory
			if(entry->d_type == DT_DIR && !(std::string(entry->d_name).compare(".") == 0 || std::string(entry->d_name).compare("..") == 0))
			{
				loadResourceFolder(folder + '/' + std::string(entry->d_name));	// recursive on child directory
			}
			// entry is a file
			else if(entry->d_type == DT_REG)
			{
				loadResource(folder + '/' + std::string(entry->d_name));
			}
		}

		closedir(dir);

		return true;
	}

	bool AssetManager::loadMod(const Mod& mod)
	{
		bool returnVar = true;

		for(auto &f : mod.getFiles())
		{
			bool temp = true;
			temp = loadResource(f);
			if(temp == false)
			{
				log << "ERROR: In " << mod.getName() << ", could not load " << f << '\n';
				returnVar = false;
			}
		}

		return returnVar;
	}

	void AssetManager::clean()
	{
		textures.clear();
		//skeletons.clear();
		soundBuffers.clear();
		music.clear();
		fonts.clear();
		scripts.clear();
	}

	void AssetManager::setSmooth(bool s)
	{
		smooth = s;
		for(auto &t : textures)
		{
			t.second->setSmooth(smooth);
		}
	}

	sf::Texture& AssetManager::getTexture(const std::string& n)
	{
		return *textures.find(n)->second;
	}

	/*Bitmask& AssetManager::getBitmask(const std::string& n)
	{
		return *bitmasks.find(n)->second;
	}*/

	/*Skeleton& AssetManager::getSkeleton(const std::string& n)
	{
		return *skeletons.find(n)->second;
	}*/

	sf::SoundBuffer& AssetManager::getSoundBuffer(const std::string& n)
	{
		return *soundBuffers.find(n)->second;
	}

	sf::Music& AssetManager::getSong(const std::string& n)
	{
		return *music.find(n)->second;
	}

	sf::Font& AssetManager::getFont(const std::string& n)
	{
		return *fonts.find(n)->second;
	}

	Script& AssetManager::getScript(const std::string& n)
	{
		return *scripts.find(n)->second;
	}

	bool AssetManager::loadResource(const std::string& file)
	{
		// this if chain checks what folder the file is in
		if(file.find("/textures/") != std::string::npos)
		{
			textures.emplace(file, new sf::Texture());

			if(!textures[file]->loadFromFile(file))
			{
				log << "Unable to load " << file << " as a texture.\n";

				// delete new'd texture
				auto it = textures.end();
				it--;
				delete it->second;

				textures.erase(file);
				return false;
			}
			textures[file]->setSmooth(smooth);

			log << "Texture:\t" << file << '\n';
		}
		else if(file.find("/skeletons/") != std::string::npos)
		{
			// create a skeleton
		}
		else if(file.find("/sounds/") != std::string::npos)
		{
			soundBuffers.emplace(file, new sf::SoundBuffer());

			if(!soundBuffers[file]->loadFromFile(file))
			{
				log << "Unable to load " << file << " as a sound.\n";

				// delete new'd soundbuffer
				auto it = soundBuffers.end();
				it--;
				delete it->second;

				soundBuffers.erase(file);
				return false;
			}

			log << "Sound:\t" << file << '\n';
		}
		else if(file.find("/music/") != std::string::npos)
		{
			music.emplace(file, new sf::Music());

			if(!music[file]->openFromFile(file))
			{
				log << "Unable to open " << file << " as a music file.\n";

				// delete new'd music
				auto it = music.end();
				it--;
				delete it->second;

				music.erase(file);
				return false;
			}

			log << "Music:\t" << file << '\n';
		}
		else if(file.find("/fonts/") != std::string::npos)
		{
			fonts.emplace(file, new sf::Font());

			if(!fonts[file]->loadFromFile(file))
			{
				log << "Unable to load " << file << " as a font.\n";

				// delete new'd font
				auto it = fonts.end();
				it--;
				delete it->second;

				fonts.erase(file);
				return false;
			}

			log << "Font:\t" << file << '\n';
		}
		else if(file.find("/scripts/") != std::string::npos)
		{
			scripts.emplace(file, new Script());

			if(!scripts[file]->loadFromFile(file))
			{
				log << "Unable to load " << file << " as a script.\n";

				// delete new'd script
				auto it = scripts.end();
				it--;
				delete it->second;

				scripts.erase(file);
				return false;
			}

			log << "Script:\t" << file << '\n';
		}
		else if(file.find(".txt") != std::string::npos)
		{
			// ignore *.txt files, but don't throw a warning/error
			log << "Ignoring " << file << '\n';
		}
		else
		{
			log << "WARNING: " << file << " is an unknown resource type.\n";
			return false;
		}
		return true;
	}
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: typemanager.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: jsc $ $Date: 2005-09-09 13:50:40 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "unodevtools/typemanager.hxx"

#include <rtl/alloc.h>
#include <registry/reader.hxx>
#include <cppuhelper/bootstrap.hxx>

#include <com/sun/star/container/XSet.hpp>
#include <com/sun/star/reflection/XTypeDescription.hpp>

using namespace ::rtl;
using namespace ::cppu;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::registry;
using namespace ::com::sun::star::reflection;

namespace unodevtools {

static RTTypeClass mapTypeClass(TypeClass typeclass) {
    switch(typeclass) {
    case TypeClass_ENUM:
        return RT_TYPE_ENUM;
        break;
    case TypeClass_TYPEDEF:
        return RT_TYPE_TYPEDEF;
        break;
    case TypeClass_STRUCT:
        return RT_TYPE_STRUCT;
        break;
    case TypeClass_UNION:
        return RT_TYPE_UNION;
        break;
    case TypeClass_EXCEPTION:
        return RT_TYPE_EXCEPTION;
        break;
    case TypeClass_INTERFACE:
        return RT_TYPE_INTERFACE;
        break;
    case TypeClass_SERVICE:
        return RT_TYPE_SERVICE;
        break;
    case TypeClass_MODULE:
        return RT_TYPE_MODULE;
        break;
    case TypeClass_CONSTANTS:
        return RT_TYPE_CONSTANTS;
        break;
    case TypeClass_SINGLETON:
        return RT_TYPE_SINGLETON;
        break;
    }
    return RT_TYPE_INVALID;
}

UnoTypeManager::UnoTypeManager()
{
    m_pImpl = new UnoTypeManagerImpl();
    acquire();
}

UnoTypeManager::~UnoTypeManager()
{
    release();
}

void UnoTypeManager::release()
{
    if (0 == TypeManager::release())
        delete m_pImpl;
}

sal_Bool UnoTypeManager::init(
    const ::std::vector< ::rtl::OUString > registries)
{
    Reference< XComponentContext > xContext=
        defaultBootstrap_InitialComponentContext();

    if ( !xContext.is() ) {
        OUString msg(RTL_CONSTASCII_USTRINGPARAM(
            "internal UNO problem, can't create initial UNO component context"));
        throw RuntimeException( msg, Reference< XInterface >());
    }
    Any a = xContext->getValueByName(
        OUString(RTL_CONSTASCII_USTRINGPARAM(
            "/singletons/com.sun.star.reflection.theTypeDescriptionManager")));

    a >>= m_pImpl->m_tdmgr;

    if ( !m_pImpl->m_tdmgr.is() ) {
        OUString msg(RTL_CONSTASCII_USTRINGPARAM(
            "internal UNO problem, can't get TypeDescriptionManager"));
        throw RuntimeException( msg, Reference< XInterface >());
    }

    if ( !registries.empty() ) {

        Reference< XMultiComponentFactory > xServiceManager(
            xContext->getServiceManager() );
        if ( !xServiceManager.is() ) {
            OUString msg(RTL_CONSTASCII_USTRINGPARAM(
                             "internal UNO problem, can't get ServiceManager"));
            throw RuntimeException( msg, Reference< XInterface >());
        }

        Sequence<Any> seqArgs(registries.size());

        std::vector< OUString >::const_iterator iter = registries.begin();
        int i = 0;
        while (iter != registries.end()) {
            Reference< XSimpleRegistry > xReg(
                xServiceManager->createInstanceWithContext(
                    OUString(RTL_CONSTASCII_USTRINGPARAM(
                             "com.sun.star.registry.SimpleRegistry")),
                    xContext), UNO_QUERY);
            xReg->open(convertToFileUrl(
                           OUStringToOString(*iter, RTL_TEXTENCODING_UTF8)),
                           sal_True, sal_False);

            seqArgs[i++] = makeAny(xReg);
            iter++;
        }

        Reference< XHierarchicalNameAccess > xTDProvider(
            xServiceManager->createInstanceWithArgumentsAndContext(
                OUString(RTL_CONSTASCII_USTRINGPARAM(
                             "com.sun.star.reflection.TypeDescriptionProvider")),
                seqArgs, xContext),
            UNO_QUERY);
        if ( !xTDProvider.is() ) {
            OUString msg(RTL_CONSTASCII_USTRINGPARAM(
                             "internal UNO problem, can't create type local"
                             " type description provider"));
            throw RuntimeException( msg, Reference< XInterface >());
        }

        a = makeAny(xTDProvider);
        Reference< XSet > xSet(m_pImpl->m_tdmgr, UNO_QUERY);
        xSet->insert(a);
    }

    return sal_True;
}

sal_Bool UnoTypeManager::isValidType(const ::rtl::OString& name) const
{
    return m_pImpl->m_tdmgr->hasByHierarchicalName(
        OStringToOUString(name, RTL_TEXTENCODING_UTF8));
}

OString UnoTypeManager::getTypeName(RegistryKey& rTypeKey) const
{
    OString typeName = OUStringToOString(rTypeKey.getName(), RTL_TEXTENCODING_UTF8);
    static OString sBase("/UCR");
    if (typeName.indexOf(sBase) == 0)
        typeName = typeName.copy(typeName.indexOf('/', 1) + 1);
    else
        typeName = typeName.copy(1);

    return typeName;
}

// extern
void* getTypeBlob(Reference< XHierarchicalNameAccess > xTDmgr,
                  const OString& typeName, sal_uInt32* pBlob);

typereg::Reader UnoTypeManager::getTypeReader(
    const OString& name, sal_Bool * pIsExtraType ) const
{
    typereg::Reader reader;

    void* pBlob = NULL;
    sal_uInt32 blobsize = 0;

    if ( (pBlob = getTypeBlob(m_pImpl->m_tdmgr, name, &blobsize)) != NULL )
    {
        reader = typereg::Reader(pBlob, blobsize, sal_True, TYPEREG_VERSION_1);
    }

    if ( pBlob )
    {
        rtl_freeMemory(pBlob);
    }

    return reader;
}

typereg::Reader UnoTypeManager::getTypeReader(RegistryKey& rTypeKey) const
{
    typereg::Reader reader;

    if (rTypeKey.isValid())
    {
        RegValueType    valueType;
        sal_uInt32      valueSize;

        if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize))
        {
            sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
            if (!rTypeKey.getValue(OUString(), pBuffer))
            {
                reader = typereg::Reader(
                    pBuffer, valueSize, true, TYPEREG_VERSION_1);
            }
            rtl_freeMemory(pBuffer);
        }
    }
    return reader;
}

RTTypeClass UnoTypeManager::getTypeClass(const OString& name) const
{
    if (m_pImpl->m_t2TypeClass.count(name) > 0)
    {
        return m_pImpl->m_t2TypeClass[name];
    } else
    {
        Reference< XTypeDescription > xTD;
        Any a = m_pImpl->m_tdmgr->getByHierarchicalName(
            OStringToOUString(name, RTL_TEXTENCODING_UTF8));
        a >>= xTD;

        if ( xTD.is())
        {
            RTTypeClass tc = mapTypeClass(xTD->getTypeClass());
            if (tc != RT_TYPE_INVALID)
                m_pImpl->m_t2TypeClass[name] = tc;
            return tc;
        }
    }

    return RT_TYPE_INVALID;
}

RTTypeClass UnoTypeManager::getTypeClass(RegistryKey& rTypeKey) const
{
    OString name = getTypeName(rTypeKey);

    if (m_pImpl->m_t2TypeClass.count(name) > 0)
    {
        return m_pImpl->m_t2TypeClass[name];
    } else
    {
        if (rTypeKey.isValid())
        {
            RegValueType    valueType;
            sal_uInt32      valueSize;

            if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize))
            {
                sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
                if (!rTypeKey.getValue(OUString(), pBuffer))
                {
                    typereg::Reader reader(
                        pBuffer, valueSize, false, TYPEREG_VERSION_1);

                    RTTypeClass ret = reader.getTypeClass();

                    rtl_freeMemory(pBuffer);

                    m_pImpl->m_t2TypeClass[name] = ret;
                    return ret;
                }
                rtl_freeMemory(pBuffer);
            }
        }
    }

    return RT_TYPE_INVALID;
}

} // end of namespace unodevtools
<commit_msg>#i52208# correct error message<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: typemanager.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: jsc $ $Date: 2005-10-19 08:55:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "unodevtools/typemanager.hxx"

#include <rtl/alloc.h>
#include <registry/reader.hxx>
#include <cppuhelper/bootstrap.hxx>

#include <com/sun/star/container/XSet.hpp>
#include <com/sun/star/reflection/XTypeDescription.hpp>

using namespace ::rtl;
using namespace ::cppu;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::registry;
using namespace ::com::sun::star::reflection;

namespace unodevtools {

static RTTypeClass mapTypeClass(TypeClass typeclass) {
    switch(typeclass) {
    case TypeClass_ENUM:
        return RT_TYPE_ENUM;
        break;
    case TypeClass_TYPEDEF:
        return RT_TYPE_TYPEDEF;
        break;
    case TypeClass_STRUCT:
        return RT_TYPE_STRUCT;
        break;
    case TypeClass_UNION:
        return RT_TYPE_UNION;
        break;
    case TypeClass_EXCEPTION:
        return RT_TYPE_EXCEPTION;
        break;
    case TypeClass_INTERFACE:
        return RT_TYPE_INTERFACE;
        break;
    case TypeClass_SERVICE:
        return RT_TYPE_SERVICE;
        break;
    case TypeClass_MODULE:
        return RT_TYPE_MODULE;
        break;
    case TypeClass_CONSTANTS:
        return RT_TYPE_CONSTANTS;
        break;
    case TypeClass_SINGLETON:
        return RT_TYPE_SINGLETON;
        break;
    }
    return RT_TYPE_INVALID;
}

UnoTypeManager::UnoTypeManager()
{
    m_pImpl = new UnoTypeManagerImpl();
    acquire();
}

UnoTypeManager::~UnoTypeManager()
{
    release();
}

void UnoTypeManager::release()
{
    if (0 == TypeManager::release())
        delete m_pImpl;
}

sal_Bool UnoTypeManager::init(
    const ::std::vector< ::rtl::OUString > registries)
{
    Reference< XComponentContext > xContext=
        defaultBootstrap_InitialComponentContext();

    if ( !xContext.is() ) {
        OUString msg(RTL_CONSTASCII_USTRINGPARAM(
            "internal UNO problem, can't create initial UNO component context"));
        throw RuntimeException( msg, Reference< XInterface >());
    }
    Any a = xContext->getValueByName(
        OUString(RTL_CONSTASCII_USTRINGPARAM(
            "/singletons/com.sun.star.reflection.theTypeDescriptionManager")));

    a >>= m_pImpl->m_tdmgr;

    if ( !m_pImpl->m_tdmgr.is() ) {
        OUString msg(RTL_CONSTASCII_USTRINGPARAM(
            "internal UNO problem, can't get TypeDescriptionManager"));
        throw RuntimeException( msg, Reference< XInterface >());
    }

    if ( !registries.empty() ) {

        Reference< XMultiComponentFactory > xServiceManager(
            xContext->getServiceManager() );
        if ( !xServiceManager.is() ) {
            OUString msg(RTL_CONSTASCII_USTRINGPARAM(
                             "internal UNO problem, can't get ServiceManager"));
            throw RuntimeException( msg, Reference< XInterface >());
        }

        Sequence<Any> seqArgs(registries.size());

        std::vector< OUString >::const_iterator iter = registries.begin();
        int i = 0;
        while (iter != registries.end()) {
            Reference< XSimpleRegistry > xReg(
                xServiceManager->createInstanceWithContext(
                    OUString(RTL_CONSTASCII_USTRINGPARAM(
                             "com.sun.star.registry.SimpleRegistry")),
                    xContext), UNO_QUERY);
            xReg->open(convertToFileUrl(
                           OUStringToOString(*iter, RTL_TEXTENCODING_UTF8)),
                           sal_True, sal_False);

            seqArgs[i++] = makeAny(xReg);
            iter++;
        }

        Reference< XHierarchicalNameAccess > xTDProvider(
            xServiceManager->createInstanceWithArgumentsAndContext(
                OUString(RTL_CONSTASCII_USTRINGPARAM(
                             "com.sun.star.reflection.TypeDescriptionProvider")),
                seqArgs, xContext),
            UNO_QUERY);
        if ( !xTDProvider.is() ) {
            OUString msg(RTL_CONSTASCII_USTRINGPARAM(
                             "internal UNO problem, can't create local"
                             " type description provider"));
            throw RuntimeException( msg, Reference< XInterface >());
        }

        a = makeAny(xTDProvider);
        Reference< XSet > xSet(m_pImpl->m_tdmgr, UNO_QUERY);
        xSet->insert(a);
    }

    return sal_True;
}

sal_Bool UnoTypeManager::isValidType(const ::rtl::OString& name) const
{
    return m_pImpl->m_tdmgr->hasByHierarchicalName(
        OStringToOUString(name, RTL_TEXTENCODING_UTF8));
}

OString UnoTypeManager::getTypeName(RegistryKey& rTypeKey) const
{
    OString typeName = OUStringToOString(rTypeKey.getName(), RTL_TEXTENCODING_UTF8);
    static OString sBase("/UCR");
    if (typeName.indexOf(sBase) == 0)
        typeName = typeName.copy(typeName.indexOf('/', 1) + 1);
    else
        typeName = typeName.copy(1);

    return typeName;
}

// extern
void* getTypeBlob(Reference< XHierarchicalNameAccess > xTDmgr,
                  const OString& typeName, sal_uInt32* pBlob);

typereg::Reader UnoTypeManager::getTypeReader(
    const OString& name, sal_Bool * pIsExtraType ) const
{
    typereg::Reader reader;

    void* pBlob = NULL;
    sal_uInt32 blobsize = 0;

    if ( (pBlob = getTypeBlob(m_pImpl->m_tdmgr, name, &blobsize)) != NULL )
    {
        reader = typereg::Reader(pBlob, blobsize, sal_True, TYPEREG_VERSION_1);
    }

    if ( pBlob )
    {
        rtl_freeMemory(pBlob);
    }

    return reader;
}

typereg::Reader UnoTypeManager::getTypeReader(RegistryKey& rTypeKey) const
{
    typereg::Reader reader;

    if (rTypeKey.isValid())
    {
        RegValueType    valueType;
        sal_uInt32      valueSize;

        if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize))
        {
            sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
            if (!rTypeKey.getValue(OUString(), pBuffer))
            {
                reader = typereg::Reader(
                    pBuffer, valueSize, true, TYPEREG_VERSION_1);
            }
            rtl_freeMemory(pBuffer);
        }
    }
    return reader;
}

RTTypeClass UnoTypeManager::getTypeClass(const OString& name) const
{
    if (m_pImpl->m_t2TypeClass.count(name) > 0)
    {
        return m_pImpl->m_t2TypeClass[name];
    } else
    {
        Reference< XTypeDescription > xTD;
        Any a = m_pImpl->m_tdmgr->getByHierarchicalName(
            OStringToOUString(name, RTL_TEXTENCODING_UTF8));
        a >>= xTD;

        if ( xTD.is())
        {
            RTTypeClass tc = mapTypeClass(xTD->getTypeClass());
            if (tc != RT_TYPE_INVALID)
                m_pImpl->m_t2TypeClass[name] = tc;
            return tc;
        }
    }

    return RT_TYPE_INVALID;
}

RTTypeClass UnoTypeManager::getTypeClass(RegistryKey& rTypeKey) const
{
    OString name = getTypeName(rTypeKey);

    if (m_pImpl->m_t2TypeClass.count(name) > 0)
    {
        return m_pImpl->m_t2TypeClass[name];
    } else
    {
        if (rTypeKey.isValid())
        {
            RegValueType    valueType;
            sal_uInt32      valueSize;

            if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize))
            {
                sal_uInt8*  pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize);
                if (!rTypeKey.getValue(OUString(), pBuffer))
                {
                    typereg::Reader reader(
                        pBuffer, valueSize, false, TYPEREG_VERSION_1);

                    RTTypeClass ret = reader.getTypeClass();

                    rtl_freeMemory(pBuffer);

                    m_pImpl->m_t2TypeClass[name] = ret;
                    return ret;
                }
                rtl_freeMemory(pBuffer);
            }
        }
    }

    return RT_TYPE_INVALID;
}

} // end of namespace unodevtools
<|endoftext|>


<commit_before>/*
 *  ti-pga2310
 *      An Arduino / Energia Library for control of a Texas Instruments
 *      PGA2310 Stereo Volume Control.
 *  github.com/kashev/ti-pga2310 - Kashev Dalmia - kashev.dalmia@gmail.com
 *
 *  PGA2310.cpp
 */

#include "PGA2310.h"

PGA2310::PGA2310 (uint8_t pinCS, uint8_t pinSDATA, uint8_t pinSCLK, uint8_t pinZCEN, uint8_t pinMUTE)
{
    _pinCS    = pinCS;
    _pinSDATA = pinSDATA;
    _pinSCLK  = pinSCLK;
    _pinZCEN  = pinZCEN;
    _pinMUTE  = pinMUTE;

    _hard_mute = 1;

}

PGA2310::PGA2310 (uint8_t pinCS, uint8_t pinSDATA, uint8_t pinSCLK, uint8_t pinZCEN)
{
    _pinCS    = pinCS;
    _pinSDATA = pinSDATA;
    _pinSCLK  = pinSCLK;
    _pinZCEN  = pinZCEN;

    _hard_mute = 0;
}

void
PGA2310::begin (void)
{
    pinMode(_pinCS,    OUTPUT);
    pinMode(_pinSDATA, OUTPUT);
    pinMode(_pinSCLK,  OUTPUT);
    pinMode(_pinZCEN,  OUTPUT);

    if (_hard_mute)
        pinMode(_pinMUTE, OUTPUT);
}

uint8_t
PGA2310::getLeftVolume (void)
{
    return _v_left;
}

uint8_t
PGA2310::getRightVolume (void)
{
    return _v_right;
}

void
PGA2310::SPIWrite (uint8_t byte)
{
    for (uint8_t i = 0; i < 8; i++, byte <<= 1)
    {
        digitalWrite(_pinSCLK, LOW);
        if (0x80 & byte)
            digitalWrite(_pinSDATA, HIGH);
        else
            digitalWrite(_pinSDATA, LOW);
        digitalWrite(_pinSCLK, HIGH);
    }
}

void
PGA2310::setVolume (uint8_t left, uint8_t right)
{
    digitalWrite(_pinCS, LOW);
    SPIWrite(right);
    SPIWrite(left);
    digitalWrite(_pinCS, HIGH);
}<commit_msg>properly save volumes when setting new volume.<commit_after>/*
 *  ti-pga2310
 *      An Arduino / Energia Library for control of a Texas Instruments
 *      PGA2310 Stereo Volume Control.
 *  github.com/kashev/ti-pga2310 - Kashev Dalmia - kashev.dalmia@gmail.com
 *
 *  PGA2310.cpp
 */

#include "PGA2310.h"

PGA2310::PGA2310 (uint8_t pinCS, uint8_t pinSDATA, uint8_t pinSCLK, uint8_t pinZCEN, uint8_t pinMUTE)
{
    _pinCS    = pinCS;
    _pinSDATA = pinSDATA;
    _pinSCLK  = pinSCLK;
    _pinZCEN  = pinZCEN;
    _pinMUTE  = pinMUTE;

    _hard_mute = 1;

}

PGA2310::PGA2310 (uint8_t pinCS, uint8_t pinSDATA, uint8_t pinSCLK, uint8_t pinZCEN)
{
    _pinCS    = pinCS;
    _pinSDATA = pinSDATA;
    _pinSCLK  = pinSCLK;
    _pinZCEN  = pinZCEN;

    _hard_mute = 0;
}

void
PGA2310::begin (void)
{
    pinMode(_pinCS,    OUTPUT);
    pinMode(_pinSDATA, OUTPUT);
    pinMode(_pinSCLK,  OUTPUT);
    pinMode(_pinZCEN,  OUTPUT);

    if (_hard_mute)
        pinMode(_pinMUTE, OUTPUT);
}

uint8_t
PGA2310::getLeftVolume (void)
{
    return _v_left;
}

uint8_t
PGA2310::getRightVolume (void)
{
    return _v_right;
}

void
PGA2310::SPIWrite (uint8_t byte)
{
    for (uint8_t i = 0; i < 8; i++, byte <<= 1)
    {
        digitalWrite(_pinSCLK, LOW);
        if (0x80 & byte)
            digitalWrite(_pinSDATA, HIGH);
        else
            digitalWrite(_pinSDATA, LOW);
        digitalWrite(_pinSCLK, HIGH);
    }
}

void
PGA2310::setVolume (uint8_t left, uint8_t right)
{
    digitalWrite(_pinCS, LOW);
    SPIWrite(right);
    SPIWrite(left);
    digitalWrite(_pinCS, HIGH);

    _pv_left = _v_left; _pv_right = _v_right;
    _v_left = left; _v_right = right;
}
<|endoftext|>


<commit_before>#pragma once

#include "FlareKeyBind.h"
#include "../../Flare.h"
#include "../Style/FlareStyleSet.h"

#define LOCTEXT_NAMESPACE "FlareKeyBind"

/*----------------------------------------------------
	Construct
----------------------------------------------------*/

void SFlareKeyBind::Construct(const FArguments& InArgs)
{
	// Setup
	bWaitingForKey = false;
	DefaultKey = InArgs._DefaultKey;
	OnKeyBindingChanged = InArgs._OnKeyBindingChanged;
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();

	// Parent constructor
	SButton::Construct(SButton::FArguments()
		.ButtonStyle(FCoreStyle::Get(), "NoBorder")
		.HAlign(HAlign_Fill)
		.VAlign(VAlign_Fill)
		.ContentPadding(FMargin(0))
		.DesiredSizeScale(FVector2D(1, 1))
		.ContentScale(FVector2D(1, 1))
		.ButtonColorAndOpacity(FLinearColor::White)
		.ForegroundColor(FCoreStyle::Get().GetSlateColor("InvertedForeground"))
	);

	// Layout
	ChildSlot
	[
		SNew(SBorder)
		.BorderImage(&Theme.ButtonBackground)
		.HAlign(HAlign_Center)
		.VAlign(VAlign_Center)
		[
			SAssignNew(KeyText, STextBlock)
			.TextStyle(&Theme.SmallFont)
		]
	];

	// Key data
	if (InArgs._Key.IsValid())
	{
		Key = InArgs._Key;
		KeyText->SetText(*Key == FKey() ? FString() : Key->ToString());
	}
}

/*----------------------------------------------------
	Interaction
----------------------------------------------------*/

void SFlareKeyBind::SetKey(FKey NewKey, bool bCanReset, bool bNotify)
{
	if (Key.IsValid())
	{
		FKey CurrentKey = *Key;
		if (NewKey == *Key && bCanReset)
		{
			NewKey = FKey();
		}

		*Key = NewKey;
		KeyText->SetText(NewKey == FKey() ? FString() : NewKey.ToString());
		bWaitingForKey = false;

		FSlateApplication::Get().GetPlatformApplication().Get()->Cursor->Show(true);
		FSlateApplication::Get().ClearKeyboardFocus(EKeyboardFocusCause::SetDirectly);

		if (bNotify)
		{
			OnKeyBindingChanged.ExecuteIfBound( CurrentKey , NewKey, this);
		}
	}
}

/*----------------------------------------------------
	Callbacks
----------------------------------------------------*/

FReply SFlareKeyBind::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
{
	if (bWaitingForKey && !InKeyEvent.GetKey().IsGamepadKey())
	{
		SetKey(InKeyEvent.GetKey());
		return FReply::Handled();
	}
	return FReply::Unhandled();
}

FReply SFlareKeyBind::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	if (bWaitingForKey && MouseEvent.GetEffectingButton() != EKeys::LeftMouseButton)
	{
		SetKey(MouseEvent.GetEffectingButton());
		return FReply::Handled();
	}

	else if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
	{
		// Get the center of the widget so we can lock our mouse there
		FSlateRect Rect = MyGeometry.GetClippingRect();
		WaitingMousePos.X = (Rect.Left + Rect.Right) * 0.5f;
		WaitingMousePos.Y = (Rect.Top + Rect.Bottom) * 0.5f;
		FSlateApplication::Get().GetPlatformApplication().Get()->Cursor->SetPosition(WaitingMousePos.X, WaitingMousePos.Y);

		KeyText->SetText(LOCTEXT("SFlareKeyBindPressAnyKey", "Press a key..."));
		bWaitingForKey = true;
		FSlateApplication::Get().GetPlatformApplication().Get()->Cursor->Show(false);
		return FReply::Handled();
	}
	return FReply::Unhandled();
}

FReply SFlareKeyBind::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	if (bWaitingForKey)
	{
		SetKey(MouseEvent.GetWheelDelta() > 0 ? EKeys::MouseScrollUp : EKeys::MouseScrollDown);
		return FReply::Handled();
	}

	return FReply::Unhandled();
}

int32 SFlareKeyBind::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
	// Make sure the mouse pointer doesn't leave the button
	if (bWaitingForKey)
	{
		FSlateApplication::Get().GetPlatformApplication().Get()->Cursor->SetPosition(WaitingMousePos.X, WaitingMousePos.Y);
	}

	return SButton::OnPaint(Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
}

FVector2D SFlareKeyBind::ComputeDesiredSize(float) const
{
	return FVector2D(200.0f, 46.0f);
}

#undef LOCTEXT_NAMESPACE

<commit_msg>#991 Fix joystick buttons unusable as bindings<commit_after>#pragma once

#include "FlareKeyBind.h"
#include "../../Flare.h"
#include "../Style/FlareStyleSet.h"

#define LOCTEXT_NAMESPACE "FlareKeyBind"

/*----------------------------------------------------
	Construct
----------------------------------------------------*/

void SFlareKeyBind::Construct(const FArguments& InArgs)
{
	// Setup
	bWaitingForKey = false;
	DefaultKey = InArgs._DefaultKey;
	OnKeyBindingChanged = InArgs._OnKeyBindingChanged;
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();

	// Parent constructor
	SButton::Construct(SButton::FArguments()
		.ButtonStyle(FCoreStyle::Get(), "NoBorder")
		.HAlign(HAlign_Fill)
		.VAlign(VAlign_Fill)
		.ContentPadding(FMargin(0))
		.DesiredSizeScale(FVector2D(1, 1))
		.ContentScale(FVector2D(1, 1))
		.ButtonColorAndOpacity(FLinearColor::White)
		.ForegroundColor(FCoreStyle::Get().GetSlateColor("InvertedForeground"))
	);

	// Layout
	ChildSlot
	[
		SNew(SBorder)
		.BorderImage(&Theme.ButtonBackground)
		.HAlign(HAlign_Center)
		.VAlign(VAlign_Center)
		[
			SAssignNew(KeyText, STextBlock)
			.TextStyle(&Theme.SmallFont)
		]
	];

	// Key data
	if (InArgs._Key.IsValid())
	{
		Key = InArgs._Key;
		KeyText->SetText(*Key == FKey() ? FString() : Key->ToString());
	}
}

/*----------------------------------------------------
	Interaction
----------------------------------------------------*/

void SFlareKeyBind::SetKey(FKey NewKey, bool bCanReset, bool bNotify)
{
	if (Key.IsValid())
	{
		FKey CurrentKey = *Key;
		if (NewKey == *Key && bCanReset)
		{
			NewKey = FKey();
		}

		*Key = NewKey;
		KeyText->SetText(NewKey == FKey() ? FString() : NewKey.ToString());
		bWaitingForKey = false;

		FSlateApplication::Get().GetPlatformApplication().Get()->Cursor->Show(true);
		FSlateApplication::Get().ClearKeyboardFocus(EKeyboardFocusCause::SetDirectly);

		if (bNotify)
		{
			OnKeyBindingChanged.ExecuteIfBound( CurrentKey , NewKey, this);
		}
	}
}

/*----------------------------------------------------
	Callbacks
----------------------------------------------------*/

FReply SFlareKeyBind::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& InKeyEvent)
{
	bool IsJoystickKey = InKeyEvent.GetKey().GetDisplayName().ToString().StartsWith("Joystick");
	bool IsGamePadKey = InKeyEvent.GetKey().IsGamepadKey() && !IsJoystickKey;

	if (bWaitingForKey && !IsGamePadKey)
	{
		SetKey(InKeyEvent.GetKey());
		return FReply::Handled();
	}
	return FReply::Unhandled();
}

FReply SFlareKeyBind::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	if (bWaitingForKey && MouseEvent.GetEffectingButton() != EKeys::LeftMouseButton)
	{
		SetKey(MouseEvent.GetEffectingButton());
		return FReply::Handled();
	}

	else if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
	{
		// Get the center of the widget so we can lock our mouse there
		FSlateRect Rect = MyGeometry.GetClippingRect();
		WaitingMousePos.X = (Rect.Left + Rect.Right) * 0.5f;
		WaitingMousePos.Y = (Rect.Top + Rect.Bottom) * 0.5f;
		FSlateApplication::Get().GetPlatformApplication().Get()->Cursor->SetPosition(WaitingMousePos.X, WaitingMousePos.Y);

		KeyText->SetText(LOCTEXT("SFlareKeyBindPressAnyKey", "Press a key..."));
		bWaitingForKey = true;
		FSlateApplication::Get().GetPlatformApplication().Get()->Cursor->Show(false);
		return FReply::Handled();
	}
	return FReply::Unhandled();
}

FReply SFlareKeyBind::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
	if (bWaitingForKey)
	{
		SetKey(MouseEvent.GetWheelDelta() > 0 ? EKeys::MouseScrollUp : EKeys::MouseScrollDown);
		return FReply::Handled();
	}

	return FReply::Unhandled();
}

int32 SFlareKeyBind::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const
{
	// Make sure the mouse pointer doesn't leave the button
	if (bWaitingForKey)
	{
		FSlateApplication::Get().GetPlatformApplication().Get()->Cursor->SetPosition(WaitingMousePos.X, WaitingMousePos.Y);
	}

	return SButton::OnPaint(Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
}

FVector2D SFlareKeyBind::ComputeDesiredSize(float) const
{
	return FVector2D(200.0f, 46.0f);
}

#undef LOCTEXT_NAMESPACE

<|endoftext|>


<commit_before>// This code is based on Sabberstone project.
// Copyright (c) 2017-2019 SabberStone Team, darkfriend77 & rnilva
// RosettaStone is hearthstone simulator using C++ with reinforcement learning.
// Copyright (c) 2019 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

#include <Rosetta/Actions/Generic.hpp>
#include <Rosetta/Tasks/SimpleTasks/DamageTask.hpp>
#include <Rosetta/Tasks/SimpleTasks/DestroyTask.hpp>
#include <Rosetta/Tasks/SimpleTasks/IncludeTask.hpp>

namespace RosettaStone::SimpleTasks
{
DamageTask::DamageTask(EntityType entityType, std::size_t damage,
                       bool isSpellDamage)
    : ITask(entityType), m_damage(damage), m_isSpellDamage(isSpellDamage)
{
    // Do nothing
}

TaskID DamageTask::GetTaskID() const
{
    return TaskID::DAMAGE;
}

TaskStatus DamageTask::Impl(Player& player)
{
    auto entities =
        IncludeTask::GetEntities(m_entityType, player, m_source, m_target);

    for (auto& entity : entities)
    {
        auto character = dynamic_cast<Character*>(entity);
        Generic::TakeDamageToCharacter(
            m_source, character, static_cast<int>(m_damage), m_isSpellDamage);
    }

    for (auto& entity : entities)
    {
        if (entity->isDestroyed)
        {
            entity->Destroy();
        }
    }

    return TaskStatus::COMPLETE;
}
}  // namespace RosettaStone::SimpleTasks
<commit_msg>feat(card-impl): Delete code to call Destroy() method<commit_after>// This code is based on Sabberstone project.
// Copyright (c) 2017-2019 SabberStone Team, darkfriend77 & rnilva
// RosettaStone is hearthstone simulator using C++ with reinforcement learning.
// Copyright (c) 2019 Chris Ohk, Youngjoong Kim, SeungHyun Jeon

#include <Rosetta/Actions/Generic.hpp>
#include <Rosetta/Tasks/SimpleTasks/DamageTask.hpp>
#include <Rosetta/Tasks/SimpleTasks/DestroyTask.hpp>
#include <Rosetta/Tasks/SimpleTasks/IncludeTask.hpp>

namespace RosettaStone::SimpleTasks
{
DamageTask::DamageTask(EntityType entityType, std::size_t damage,
                       bool isSpellDamage)
    : ITask(entityType), m_damage(damage), m_isSpellDamage(isSpellDamage)
{
    // Do nothing
}

TaskID DamageTask::GetTaskID() const
{
    return TaskID::DAMAGE;
}

TaskStatus DamageTask::Impl(Player& player)
{
    auto entities =
        IncludeTask::GetEntities(m_entityType, player, m_source, m_target);

    for (auto& entity : entities)
    {
        auto character = dynamic_cast<Character*>(entity);
        Generic::TakeDamageToCharacter(
            m_source, character, static_cast<int>(m_damage), m_isSpellDamage);
    }

    return TaskStatus::COMPLETE;
}
}  // namespace RosettaStone::SimpleTasks
<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// 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 "SurgSim/Framework/TransferPropertiesBehavior.h"

#include <boost/thread/lock_guard.hpp>

namespace SurgSim
{
namespace Framework
{

TransferPropertiesBehavior::TransferPropertiesBehavior(const std::string& name) :
	SurgSim::Framework::Behavior(name),
	m_targetManager(MANAGER_TYPE_BEHAVIOR)
{

}

TransferPropertiesBehavior::~TransferPropertiesBehavior()
{

}

void TransferPropertiesBehavior::update(double dt)
{
	{
		boost::lock_guard<boost::mutex> lock(m_incomingMutex);
		m_connections.insert(m_connections.end(), m_incomingConnections.begin(), m_incomingConnections.end());
		m_incomingConnections.clear();
	}

	for (auto it = std::begin(m_connections); it != std::end(m_connections); ++it)
	{
		if (!it->first.accessible.expired() && !it->second.accessible.expired())
		{
			auto source = it->first.accessible.lock();
			auto target = it->second.accessible.lock();
			target->setValue(it->second.name, source->getValue(it->first.name));
		}
	}
}

bool TransferPropertiesBehavior::connect(
	std::shared_ptr<SurgSim::Framework::Accessible> sourceAccessible,
	const std::string& sourcePropertyName,
	std::shared_ptr<SurgSim::Framework::Accessible> targetAccessible,
	const std::string& targetPropertyName)
{
	SURGSIM_ASSERT(sourceAccessible != nullptr && targetAccessible != nullptr) <<
		"Accessibles cannot be nullptr";

	Property source = {sourceAccessible, sourcePropertyName};
	Property target = {targetAccessible, targetPropertyName};

	return connect(source, target);
}

bool TransferPropertiesBehavior::connect(const Property& source, const Property& target)
{
	// Early outs
	if (source.accessible.expired() || target.accessible.expired())
	{
		return false;
	}

	auto sharedSource = source.accessible.lock();
	auto sharedTarget = target.accessible.lock();

	SURGSIM_ASSERT(sharedSource != sharedTarget || source.name != target.name)
		<< "Cannot Read/Write with exactly the same property and object.";

	SURGSIM_ASSERT(sharedSource->isReadable(source.name))
		<< "Source does not have a readable property called <" << source.name << ">.";

	SURGSIM_ASSERT(sharedTarget->isWriteable(target.name))
		<< "Target does not have a readable property called <" << target.name << ">.";

	// \note HS-2013-nov-26 should also check matching types here

	auto entry = std::make_pair(source, target);

	boost::lock_guard<boost::mutex> lock(m_incomingMutex);
	m_incomingConnections.push_back(std::move(entry));

	return true;
}

bool TransferPropertiesBehavior::doInitialize()
{
	return true;
}

bool TransferPropertiesBehavior::doWakeUp()
{
	// Do an update step to initialize all the values
	update(0.0);
	return true;
}

void TransferPropertiesBehavior::setTargetManagerType(int managerType)
{
	SURGSIM_ASSERT(managerType > 0 && managerType < MANAGER_TYPE_COUNT) << "Invalid manager type.";
	SURGSIM_ASSERT(!isInitialized()) << "Cannot change the manager type after initialization.";
	m_targetManager = managerType;
}

int TransferPropertiesBehavior::getTargetManagerType() const
{
	return m_targetManager;
}

}
}
<commit_msg>Fix Comment<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013, SimQuest Solutions Inc.
//
// 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 "SurgSim/Framework/TransferPropertiesBehavior.h"

#include <boost/thread/lock_guard.hpp>

namespace SurgSim
{
namespace Framework
{

TransferPropertiesBehavior::TransferPropertiesBehavior(const std::string& name) :
	SurgSim::Framework::Behavior(name),
	m_targetManager(MANAGER_TYPE_BEHAVIOR)
{

}

TransferPropertiesBehavior::~TransferPropertiesBehavior()
{

}

void TransferPropertiesBehavior::update(double dt)
{
	{
		boost::lock_guard<boost::mutex> lock(m_incomingMutex);
		m_connections.insert(m_connections.end(), m_incomingConnections.begin(), m_incomingConnections.end());
		m_incomingConnections.clear();
	}

	for (auto it = std::begin(m_connections); it != std::end(m_connections); ++it)
	{
		if (!it->first.accessible.expired() && !it->second.accessible.expired())
		{
			auto source = it->first.accessible.lock();
			auto target = it->second.accessible.lock();
			target->setValue(it->second.name, source->getValue(it->first.name));
		}
	}
}

bool TransferPropertiesBehavior::connect(
	std::shared_ptr<SurgSim::Framework::Accessible> sourceAccessible,
	const std::string& sourcePropertyName,
	std::shared_ptr<SurgSim::Framework::Accessible> targetAccessible,
	const std::string& targetPropertyName)
{
	SURGSIM_ASSERT(sourceAccessible != nullptr && targetAccessible != nullptr) <<
		"Accessibles cannot be nullptr";

	Property source = {sourceAccessible, sourcePropertyName};
	Property target = {targetAccessible, targetPropertyName};

	return connect(source, target);
}

bool TransferPropertiesBehavior::connect(const Property& source, const Property& target)
{
	// Early outs
	if (source.accessible.expired() || target.accessible.expired())
	{
		return false;
	}

	auto sharedSource = source.accessible.lock();
	auto sharedTarget = target.accessible.lock();

	SURGSIM_ASSERT(sharedSource != sharedTarget || source.name != target.name)
		<< "Cannot Read/Write with exactly the same property and object.";

	SURGSIM_ASSERT(sharedSource->isReadable(source.name))
		<< "Source does not have a readable property called <" << source.name << ">.";

	SURGSIM_ASSERT(sharedTarget->isWriteable(target.name))
		<< "Target does not have a writeable property called <" << target.name << ">.";

	// \note HS-2013-nov-26 should also that the type of the output can be converted to the input

	auto entry = std::make_pair(source, target);

	boost::lock_guard<boost::mutex> lock(m_incomingMutex);
	m_incomingConnections.push_back(std::move(entry));

	return true;
}

bool TransferPropertiesBehavior::doInitialize()
{
	return true;
}

bool TransferPropertiesBehavior::doWakeUp()
{
	// Do an update step to initialize all the values
	update(0.0);
	return true;
}

void TransferPropertiesBehavior::setTargetManagerType(int managerType)
{
	SURGSIM_ASSERT(managerType > 0 && managerType < MANAGER_TYPE_COUNT) << "Invalid manager type.";
	SURGSIM_ASSERT(!isInitialized()) << "Cannot change the manager type after initialization.";
	m_targetManager = managerType;
}

int TransferPropertiesBehavior::getTargetManagerType() const
{
	return m_targetManager;
}

}
}
<|endoftext|>