<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 "configuration_loader.h"

#include <fstream>
#include <strings.h>
#include <sstream>
#include <map>
#include <sys/stat.h>
#include <rapidxml/rapidxml.hpp>
#include <rapidxml/rapidxml_utils.hpp>

namespace hdfs {

/*
 * ConfigurationLoader class
 */

#if defined(WIN32) || defined(_WIN32)
static const char kFileSeparator = '\\';
#else
static const char kFileSeparator = '/';
#endif

static const char kSearchPathSeparator = ':';

bool is_valid_bool(const std::string& raw) {
  if (raw.empty()) {
    return false;
  }

  if (!strcasecmp(raw.c_str(), "true")) {
    return true;
  }
  if (!strcasecmp(raw.c_str(), "false")) {
    return true;
  }
  return false;
}

bool str_to_bool(const std::string& raw) {
  if (!strcasecmp(raw.c_str(), "true")) {
    return true;
  }

  return false;
}

void ConfigurationLoader::SetDefaultSearchPath() {
  //TODO: Use HADOOP_CONF_DIR when we get environment subs with HDFS-9385
  AddToSearchPath("./");
  AddToSearchPath("/etc/hadoop/");
}

void ConfigurationLoader::ClearSearchPath()
{
  search_path_.clear();
}

void ConfigurationLoader::SetSearchPath(const std::string & searchPath)
{
  search_path_.clear();

  std::vector<std::string> paths;
  std::string::size_type start = 0;
  std::string::size_type end = searchPath.find(kSearchPathSeparator);

  while (end != std::string::npos) {
     paths.push_back(searchPath.substr(start, end-start));
     start = ++end;
     end = searchPath.find(kSearchPathSeparator, start);
  }
  paths.push_back(searchPath.substr(start, searchPath.length()));

  for (auto path: paths) {
    AddToSearchPath(path);
  }

}

void ConfigurationLoader::AddToSearchPath(const std::string & searchPath)
{
  if (searchPath.empty())
    return;

  if (searchPath.back() != kFileSeparator) {
    std::string pathWithSlash(searchPath);
    pathWithSlash += kFileSeparator;
    search_path_.push_back(pathWithSlash);
  } else {
    search_path_.push_back(searchPath);
  }
}

std::string ConfigurationLoader::GetSearchPath()
{
  std::stringstream result;
  bool first = true;
  for(std::string item: search_path_) {
    if (!first) {
      result << kSearchPathSeparator;
    }

    result << item;
    first = false;
  }

  return result.str();
}

bool ConfigurationLoader::UpdateMapWithFile(ConfigMap & map, const std::string & path) const
{
  if (path.front() == kFileSeparator) { // Absolute path
    std::ifstream stream(path, std::ifstream::in);
    if ( stream.is_open() ) {
      return UpdateMapWithStream(map, stream);
    } else {
      return false;
    }
  } else { // Use search path
    for(auto dir: search_path_) {
      std::ifstream stream(dir + path);
      if ( stream.is_open() ) {
        if (UpdateMapWithStream(map, stream))
          return true;
      }
    }
  }

  return false;
}

bool ConfigurationLoader::UpdateMapWithStream(ConfigMap & map,
                                              std::istream & stream) {
  std::streampos start = stream.tellg();
  stream.seekg(0, std::ios::end);
  std::streampos end = stream.tellg();
  stream.seekg(start, std::ios::beg);

  int length = end - start;

  if (length <= 0 || start == -1 || end == -1)
    return false;

  std::vector<char> raw_bytes((int64_t)length + 1);
  stream.read(&raw_bytes[0], length);
  raw_bytes[length] = 0;

  return UpdateMapWithBytes(map, raw_bytes);
}

bool ConfigurationLoader::UpdateMapWithString(ConfigMap & map,
                                                   const std::string &xml_data) {
  if (xml_data.size() == 0) {
    return false;
  }

  std::vector<char> raw_bytes(xml_data.begin(), xml_data.end());
  raw_bytes.push_back('\0');

  bool success = UpdateMapWithBytes(map, raw_bytes);

  if (success) {
    return true;
  } else {
    return false;
  }
}

bool ConfigurationLoader::UpdateMapWithBytes(ConfigMap& map,
                                                 std::vector<char>& raw_bytes) {
  rapidxml::xml_document<> dom;
  dom.parse<rapidxml::parse_trim_whitespace>(&raw_bytes[0]);

  /* File must contain a single <configuration> stanza */
  auto config_node = dom.first_node("configuration", 0, false);
  if (!config_node) {
    return false;
  }

  /* Walk all of the <property> nodes, ignoring the rest */
  for (auto property_node = config_node->first_node("property", 0, false);
       property_node;
       property_node = property_node->next_sibling("property", 0, false)) {
    auto name_node = property_node->first_node("name", 0, false);
    auto value_node = property_node->first_node("value", 0, false);

    if (name_node && value_node) {
      std::string final_value;
      auto final_node = property_node->first_node("final", 0, false);
      if (final_node) {
        final_value = final_node->value();
      }
      UpdateMapWithValue(map, name_node->value(), value_node->value(), final_value);
    }

    auto name_attr = property_node->first_attribute("name", 0, false);
    auto value_attr = property_node->first_attribute("value", 0, false);

    if (name_attr && value_attr) {
      std::string final_value;
      auto final_attr = property_node->first_attribute("final", 0, false);
      if (final_attr) {
        final_value = final_attr->value();
      }
      UpdateMapWithValue(map, name_attr->value(), value_attr->value(), final_value);
    }
  }

  return true;
}

bool ConfigurationLoader::UpdateMapWithValue(ConfigMap& map,
                                             const std::string& key, const std::string& value,
                                             const std::string& final_text)
{
  std::string caseFixedKey = Configuration::fixCase(key);
  auto mapValue = map.find(caseFixedKey);
  if (mapValue != map.end() && mapValue->second.final) {
    return false;
  }

  bool final_value = false;
  if (is_valid_bool(final_text)) {
    final_value = str_to_bool(final_text);
  }

  map[caseFixedKey].value = value;
  map[caseFixedKey].final = final_value;
  return true;
}

}<commit_msg>HDFS-9791: libhdfs+_+: ConfigurationLoader throws parse_exception on invalid input.  Contributed by Bob Hansen.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 "configuration_loader.h"

#include <fstream>
#include <strings.h>
#include <sstream>
#include <map>
#include <sys/stat.h>
#include <rapidxml/rapidxml.hpp>
#include <rapidxml/rapidxml_utils.hpp>

namespace hdfs {

/*
 * ConfigurationLoader class
 */

#if defined(WIN32) || defined(_WIN32)
static const char kFileSeparator = '\\';
#else
static const char kFileSeparator = '/';
#endif

static const char kSearchPathSeparator = ':';

bool is_valid_bool(const std::string& raw) {
  if (raw.empty()) {
    return false;
  }

  if (!strcasecmp(raw.c_str(), "true")) {
    return true;
  }
  if (!strcasecmp(raw.c_str(), "false")) {
    return true;
  }
  return false;
}

bool str_to_bool(const std::string& raw) {
  if (!strcasecmp(raw.c_str(), "true")) {
    return true;
  }

  return false;
}

void ConfigurationLoader::SetDefaultSearchPath() {
  //TODO: Use HADOOP_CONF_DIR when we get environment subs with HDFS-9385
  AddToSearchPath("./");
  AddToSearchPath("/etc/hadoop/");
}

void ConfigurationLoader::ClearSearchPath()
{
  search_path_.clear();
}

void ConfigurationLoader::SetSearchPath(const std::string & searchPath)
{
  search_path_.clear();

  std::vector<std::string> paths;
  std::string::size_type start = 0;
  std::string::size_type end = searchPath.find(kSearchPathSeparator);

  while (end != std::string::npos) {
     paths.push_back(searchPath.substr(start, end-start));
     start = ++end;
     end = searchPath.find(kSearchPathSeparator, start);
  }
  paths.push_back(searchPath.substr(start, searchPath.length()));

  for (auto path: paths) {
    AddToSearchPath(path);
  }

}

void ConfigurationLoader::AddToSearchPath(const std::string & searchPath)
{
  if (searchPath.empty())
    return;

  if (searchPath.back() != kFileSeparator) {
    std::string pathWithSlash(searchPath);
    pathWithSlash += kFileSeparator;
    search_path_.push_back(pathWithSlash);
  } else {
    search_path_.push_back(searchPath);
  }
}

std::string ConfigurationLoader::GetSearchPath()
{
  std::stringstream result;
  bool first = true;
  for(std::string item: search_path_) {
    if (!first) {
      result << kSearchPathSeparator;
    }

    result << item;
    first = false;
  }

  return result.str();
}

bool ConfigurationLoader::UpdateMapWithFile(ConfigMap & map, const std::string & path) const
{
  if (path.front() == kFileSeparator) { // Absolute path
    std::ifstream stream(path, std::ifstream::in);
    if ( stream.is_open() ) {
      return UpdateMapWithStream(map, stream);
    } else {
      return false;
    }
  } else { // Use search path
    for(auto dir: search_path_) {
      std::ifstream stream(dir + path);
      if ( stream.is_open() ) {
        if (UpdateMapWithStream(map, stream))
          return true;
      }
    }
  }

  return false;
}

bool ConfigurationLoader::UpdateMapWithStream(ConfigMap & map,
                                              std::istream & stream) {
  std::streampos start = stream.tellg();
  stream.seekg(0, std::ios::end);
  std::streampos end = stream.tellg();
  stream.seekg(start, std::ios::beg);

  int length = end - start;

  if (length <= 0 || start == -1 || end == -1)
    return false;

  std::vector<char> raw_bytes((int64_t)length + 1);
  stream.read(&raw_bytes[0], length);
  raw_bytes[length] = 0;

  return UpdateMapWithBytes(map, raw_bytes);
}

bool ConfigurationLoader::UpdateMapWithString(ConfigMap & map,
                                                   const std::string &xml_data) {
  if (xml_data.size() == 0) {
    return false;
  }

  std::vector<char> raw_bytes(xml_data.begin(), xml_data.end());
  raw_bytes.push_back('\0');

  bool success = UpdateMapWithBytes(map, raw_bytes);

  if (success) {
    return true;
  } else {
    return false;
  }
}

bool ConfigurationLoader::UpdateMapWithBytes(ConfigMap& map,
                                                 std::vector<char>& raw_bytes) {
  try {
    rapidxml::xml_document<> dom;
    dom.parse<rapidxml::parse_trim_whitespace>(&raw_bytes[0]);

    /* File must contain a single <configuration> stanza */
    auto config_node = dom.first_node("configuration", 0, false);
    if (!config_node) {
      return false;
    }

    /* Walk all of the <property> nodes, ignoring the rest */
    for (auto property_node = config_node->first_node("property", 0, false);
         property_node;
         property_node = property_node->next_sibling("property", 0, false)) {
      auto name_node = property_node->first_node("name", 0, false);
      auto value_node = property_node->first_node("value", 0, false);

      if (name_node && value_node) {
        std::string final_value;
        auto final_node = property_node->first_node("final", 0, false);
        if (final_node) {
          final_value = final_node->value();
        }
        UpdateMapWithValue(map, name_node->value(), value_node->value(), final_value);
      }

      auto name_attr = property_node->first_attribute("name", 0, false);
      auto value_attr = property_node->first_attribute("value", 0, false);

      if (name_attr && value_attr) {
        std::string final_value;
        auto final_attr = property_node->first_attribute("final", 0, false);
        if (final_attr) {
          final_value = final_attr->value();
        }
        UpdateMapWithValue(map, name_attr->value(), value_attr->value(), final_value);
      }
    }

    return true;
  } catch (const rapidxml::parse_error &e) {
    // TODO: Capture the result in a Status object
    return false;
  }
}

bool ConfigurationLoader::UpdateMapWithValue(ConfigMap& map,
                                             const std::string& key, const std::string& value,
                                             const std::string& final_text)
{
  std::string caseFixedKey = Configuration::fixCase(key);
  auto mapValue = map.find(caseFixedKey);
  if (mapValue != map.end() && mapValue->second.final) {
    return false;
  }

  bool final_value = false;
  if (is_valid_bool(final_text)) {
    final_value = str_to_bool(final_text);
  }

  map[caseFixedKey].value = value;
  map[caseFixedKey].final = final_value;
  return true;
}

}<|endoftext|>


<commit_before>/*
 * ImageDesignSessionImplementation.cpp
 *
 *  Created on: Feb 2, 2011
 *      Author: Polonel
 */

#include "engine/engine.h"
#include "ImageDesignSession.h"
#include "server/zone/ZoneServer.h"
#include "server/zone/packets/object/ImageDesignMessage.h"
#include "server/zone/packets/object/ImageDesignRejectMessageCallback.h"
#include "server/zone/managers/skill/SkillManager.h"
#include "server/zone/managers/skill/imagedesign/ImageDesignManager.h"
#include "server/zone/managers/player/PlayerManager.h"
#include "server/zone/objects/scene/variables/CustomizationVariables.h"
#include "server/zone/ZoneServer.h"

#include "server/zone/objects/player/events/ImageDesignTimeoutEvent.h"

void ImageDesignSessionImplementation::initializeTransientMembers() {
	FacadeImplementation::initializeTransientMembers();

	if (idTimeoutEvent == NULL) {
		idTimeoutEvent = new ImageDesignTimeoutEvent(_this);
		idTimeoutEvent->schedule(1000);
	} else {
		idTimeoutEvent->reschedule(1000);
	}
}

void ImageDesignSessionImplementation::startImageDesign(CreatureObject* designer, CreatureObject* targetPlayer) {
	uint64 tentID = 0; // Equals False, that controls if you can stat migrate or not (only in a Salon).

	ManagedReference<SceneObject*> obj = designer->getParentRecursively(SceneObjectType::SALONBUILDING);

	if (obj != NULL) // If they are in a salon, enable the tickmark for stat migration.
		tentID = obj->getObjectID();

	designer->addActiveSession(SessionFacadeType::IMAGEDESIGN, _this);

	String hairTemplate;

	TangibleObject* targetHair = dynamic_cast<TangibleObject*>(targetPlayer->getSlottedObject("hair"));

	ImageDesignStartMessage* msg = new ImageDesignStartMessage(designer, designer, targetPlayer, tentID, hairTemplate);
	designer->sendMessage(msg);

	if (designer != targetPlayer) {
		targetPlayer->addActiveSession(SessionFacadeType::IMAGEDESIGN, _this);

		ImageDesignStartMessage* msg2 = new ImageDesignStartMessage(targetPlayer, designer, targetPlayer, tentID, hairTemplate);
		targetPlayer->sendMessage(msg2);
	}

	designerCreature = designer;
	targetCreature = targetPlayer;

	idTimeoutEvent = new ImageDesignTimeoutEvent(_this);
}

void ImageDesignSessionImplementation::updateImageDesign(CreatureObject* updater, uint64 designer, uint64 targetPlayer, uint64 tent, int type, const ImageDesignData& data) {
	ManagedReference<SceneObject*> strongReferenceTarget = targetCreature.get();
	ManagedReference<SceneObject*> strongReferenceDesigner = designerCreature.get();

	if (strongReferenceTarget == NULL || strongReferenceDesigner == NULL)
		return;

	Locker locker(designerCreature);
	Locker clocker(targetCreature, designerCreature);

	imageDesignData = data;

	CreatureObject* targetObject = NULL;

	if (updater == designerCreature)
		targetObject = targetCreature;
	else
		targetObject = designerCreature;

	ImageDesignChangeMessage* message = new ImageDesignChangeMessage(targetObject->getObjectID(), designer, targetPlayer, tent, type);

	imageDesignData.insertToMessage(message);

	bool commitChanges = false;

	if (imageDesignData.isAcceptedByDesigner()) {
		commitChanges = true;

		if (designerCreature != targetCreature && !imageDesignData.isAcceptedByTarget()) {
			commitChanges = false;

			if (!idTimeoutEvent->isScheduled())
				idTimeoutEvent->schedule(120000); //2 minutes
		} else {
			commitChanges = doPayment();
		}
	}

	//System::out << h << endl;
	if (commitChanges) {
		//TODO: set XP Values

		int xpGranted = 50; // Minimum Image Design XP granted (base amount).

		String hairTemplate = imageDesignData.getHairTemplate();

		VectorMap<String, float>* bodyAttributes = imageDesignData.getBodyAttributesMap();
		VectorMap<String, uint32>* colorAttributes = imageDesignData.getColorAttributesMap();

		imageDesignManager = designerCreature->getZoneServer()->getSkillManager()->getImageDesignManager();

		if (type == 1)
			hairObject = imageDesignManager->createHairObject(designerCreature, targetCreature, imageDesignData.getHairTemplate(), imageDesignData.getHairCustomizationString());
		else
			hairObject = dynamic_cast<TangibleObject*>(targetCreature->getSlottedObject("hair"));

		for (int i = 0; i < bodyAttributes->size(); ++i) {
			VectorMapEntry<String, float>* entry = &bodyAttributes->elementAt(i);
			imageDesignManager->updateCustomization(designerCreature, entry->getKey(), entry->getValue(), targetCreature);
			xpGranted += 25;
		}

		for (int i = 0; i < colorAttributes->size(); ++i) {
			VectorMapEntry<String, uint32>* entry = &colorAttributes->elementAt(i);
			imageDesignManager->updateColorCustomization(designerCreature, entry->getKey(), entry->getValue(), hairObject, targetCreature);
			xpGranted += 25;
		}

		imageDesignManager->updateHairObject(targetCreature, hairObject);

		// Drop the Session for both the designer and the targetCreature;
		designerCreature->dropActiveSession(SessionFacadeType::IMAGEDESIGN);
		targetCreature->dropActiveSession(SessionFacadeType::IMAGEDESIGN);

		// Award XP.
		PlayerManager* playerManager = designerCreature->getZoneServer()->getPlayerManager();

		if (playerManager != NULL && designerCreature != targetCreature)
			playerManager->awardExperience(designerCreature, "imagedesigner", xpGranted, true);

		if (idTimeoutEvent->isScheduled())
			dequeueIdTimeoutEvent();
	}

	targetObject->sendMessage(message);
}

int ImageDesignSessionImplementation::doPayment() {
	int targetCash = targetCreature->getCashCredits();

	uint32 requiredPayment = imageDesignData.getRequiredPayment();

	// The client should pervent this, but in case it doesn't
	if (targetCash < requiredPayment) {
		targetCreature->sendSystemMessage("You do not have enough cash to pay the required payment.");
		designerCreature->sendSystemMessage("Target does not have enough cash for the required payment.");

		cancelSession();

		return 0;
	}

	targetCreature->subtractCashCredits(requiredPayment);
	designerCreature->addCashCredits(requiredPayment);

	return 1;

}

void ImageDesignSessionImplementation::cancelImageDesign(uint64 designer, uint64 targetPlayer, uint64 tent, int type, const ImageDesignData& data) {
	if (targetCreature == NULL || designerCreature == NULL)
		return;

	Locker locker(designerCreature);
	Locker clocker(targetCreature, designerCreature);

	imageDesignData = data;

	ImageDesignRejectMessage* message = new ImageDesignRejectMessage(targetCreature->getObjectID(), designer, targetPlayer,tent, type);
	imageDesignData.insertToMessage(message);
	targetCreature->sendMessage(message);

	ImageDesignRejectMessage* msg2 = new ImageDesignRejectMessage(designerCreature->getObjectID(), designer, targetPlayer,tent, type);
	imageDesignData.insertToMessage(msg2);
	designerCreature->sendMessage(msg2);

	//TODO: Needs research.

	cancelSession();
}
<commit_msg>[fixed] id hair color defaulting to brown sometimes<commit_after>/*
 * ImageDesignSessionImplementation.cpp
 *
 *  Created on: Feb 2, 2011
 *      Author: Polonel
 */

#include "engine/engine.h"
#include "ImageDesignSession.h"
#include "server/zone/ZoneServer.h"
#include "server/zone/packets/object/ImageDesignMessage.h"
#include "server/zone/packets/object/ImageDesignRejectMessageCallback.h"
#include "server/zone/managers/skill/SkillManager.h"
#include "server/zone/managers/skill/imagedesign/ImageDesignManager.h"
#include "server/zone/managers/player/PlayerManager.h"
#include "server/zone/objects/scene/variables/CustomizationVariables.h"
#include "server/zone/ZoneServer.h"

#include "server/zone/objects/player/events/ImageDesignTimeoutEvent.h"

void ImageDesignSessionImplementation::initializeTransientMembers() {
	FacadeImplementation::initializeTransientMembers();

	if (idTimeoutEvent == NULL) {
		idTimeoutEvent = new ImageDesignTimeoutEvent(_this);
		idTimeoutEvent->schedule(1000);
	} else {
		idTimeoutEvent->reschedule(1000);
	}
}

void ImageDesignSessionImplementation::startImageDesign(CreatureObject* designer, CreatureObject* targetPlayer) {
	uint64 tentID = 0; // Equals False, that controls if you can stat migrate or not (only in a Salon).

	ManagedReference<SceneObject*> obj = designer->getParentRecursively(SceneObjectType::SALONBUILDING);

	if (obj != NULL) // If they are in a salon, enable the tickmark for stat migration.
		tentID = obj->getObjectID();

	designer->addActiveSession(SessionFacadeType::IMAGEDESIGN, _this);

	String hairTemplate;

	TangibleObject* targetHair = dynamic_cast<TangibleObject*>(targetPlayer->getSlottedObject("hair"));

	ImageDesignStartMessage* msg = new ImageDesignStartMessage(designer, designer, targetPlayer, tentID, hairTemplate);
	designer->sendMessage(msg);

	if (designer != targetPlayer) {
		targetPlayer->addActiveSession(SessionFacadeType::IMAGEDESIGN, _this);

		ImageDesignStartMessage* msg2 = new ImageDesignStartMessage(targetPlayer, designer, targetPlayer, tentID, hairTemplate);
		targetPlayer->sendMessage(msg2);
	}

	designerCreature = designer;
	targetCreature = targetPlayer;

	idTimeoutEvent = new ImageDesignTimeoutEvent(_this);
}

void ImageDesignSessionImplementation::updateImageDesign(CreatureObject* updater, uint64 designer, uint64 targetPlayer, uint64 tent, int type, const ImageDesignData& data) {
	ManagedReference<SceneObject*> strongReferenceTarget = targetCreature.get();
	ManagedReference<SceneObject*> strongReferenceDesigner = designerCreature.get();

	if (strongReferenceTarget == NULL || strongReferenceDesigner == NULL)
		return;

	Locker locker(designerCreature);
	Locker clocker(targetCreature, designerCreature);

	imageDesignData = data;

	CreatureObject* targetObject = NULL;

	if (updater == designerCreature)
		targetObject = targetCreature;
	else
		targetObject = designerCreature;

	ImageDesignChangeMessage* message = new ImageDesignChangeMessage(targetObject->getObjectID(), designer, targetPlayer, tent, type);

	imageDesignData.insertToMessage(message);

	bool commitChanges = false;

	if (imageDesignData.isAcceptedByDesigner()) {
		commitChanges = true;

		if (designerCreature != targetCreature && !imageDesignData.isAcceptedByTarget()) {
			commitChanges = false;

			if (!idTimeoutEvent->isScheduled())
				idTimeoutEvent->schedule(120000); //2 minutes
		} else {
			commitChanges = doPayment();
		}
	}

	//System::out << h << endl;
	if (commitChanges) {
		//TODO: set XP Values

		int xpGranted = 50; // Minimum Image Design XP granted (base amount).

		String hairTemplate = imageDesignData.getHairTemplate();

		VectorMap<String, float>* bodyAttributes = imageDesignData.getBodyAttributesMap();
		VectorMap<String, uint32>* colorAttributes = imageDesignData.getColorAttributesMap();

		imageDesignManager = designerCreature->getZoneServer()->getSkillManager()->getImageDesignManager();

		hairObject = dynamic_cast<TangibleObject*>(targetCreature->getSlottedObject("hair"));

		if (type == 1) {
			String oldCustomization;

			if (hairObject != NULL)
				hairObject->getCustomizationString(oldCustomization);

			hairObject = imageDesignManager->createHairObject(designerCreature, targetCreature, imageDesignData.getHairTemplate(), imageDesignData.getHairCustomizationString());

			if (hairObject != NULL)
				hairObject->setCustomizationString(oldCustomization);
		}

		for (int i = 0; i < bodyAttributes->size(); ++i) {
			VectorMapEntry<String, float>* entry = &bodyAttributes->elementAt(i);
			imageDesignManager->updateCustomization(designerCreature, entry->getKey(), entry->getValue(), targetCreature);
			xpGranted += 25;
		}

		for (int i = 0; i < colorAttributes->size(); ++i) {
			VectorMapEntry<String, uint32>* entry = &colorAttributes->elementAt(i);
			imageDesignManager->updateColorCustomization(designerCreature, entry->getKey(), entry->getValue(), hairObject, targetCreature);
			xpGranted += 25;
		}

		imageDesignManager->updateHairObject(targetCreature, hairObject);

		// Drop the Session for both the designer and the targetCreature;
		designerCreature->dropActiveSession(SessionFacadeType::IMAGEDESIGN);
		targetCreature->dropActiveSession(SessionFacadeType::IMAGEDESIGN);

		// Award XP.
		PlayerManager* playerManager = designerCreature->getZoneServer()->getPlayerManager();

		if (playerManager != NULL && designerCreature != targetCreature)
			playerManager->awardExperience(designerCreature, "imagedesigner", xpGranted, true);

		if (idTimeoutEvent->isScheduled())
			dequeueIdTimeoutEvent();
	}

	targetObject->sendMessage(message);
}

int ImageDesignSessionImplementation::doPayment() {
	int targetCash = targetCreature->getCashCredits();

	uint32 requiredPayment = imageDesignData.getRequiredPayment();

	// The client should pervent this, but in case it doesn't
	if (targetCash < requiredPayment) {
		targetCreature->sendSystemMessage("You do not have enough cash to pay the required payment.");
		designerCreature->sendSystemMessage("Target does not have enough cash for the required payment.");

		cancelSession();

		return 0;
	}

	targetCreature->subtractCashCredits(requiredPayment);
	designerCreature->addCashCredits(requiredPayment);

	return 1;

}

void ImageDesignSessionImplementation::cancelImageDesign(uint64 designer, uint64 targetPlayer, uint64 tent, int type, const ImageDesignData& data) {
	if (targetCreature == NULL || designerCreature == NULL)
		return;

	Locker locker(designerCreature);
	Locker clocker(targetCreature, designerCreature);

	imageDesignData = data;

	ImageDesignRejectMessage* message = new ImageDesignRejectMessage(targetCreature->getObjectID(), designer, targetPlayer,tent, type);
	imageDesignData.insertToMessage(message);
	targetCreature->sendMessage(message);

	ImageDesignRejectMessage* msg2 = new ImageDesignRejectMessage(designerCreature->getObjectID(), designer, targetPlayer,tent, type);
	imageDesignData.insertToMessage(msg2);
	designerCreature->sendMessage(msg2);

	//TODO: Needs research.

	cancelSession();
}
<|endoftext|>


<commit_before>/*
 * Molch, an implementation of the axolotl ratchet based on libsodium
 *
 * ISC License
 *
 * Copyright (C) 2015-2016 1984not Security GmbH
 * Author: Max Bruckner (FSMaxB)
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef LIB_HEADER_AND_MESSAGE_KEY_STORE_H
#define LIB_HEADER_AND_MESSAGE_KEY_STORE_H

#include <sodium.h>
#include <vector>
#include <ostream>

#include "constants.h"
#include "buffer.hpp"
#include "return-status.hpp"
#include "sodium-wrappers.hpp"
#include "protobuf.hpp"
#include "key.hpp"
#include "time.hpp"

namespace Molch {
	class HeaderAndMessageKey {
	private:
		void fill(const HeaderKey& header_key, const MessageKey& message_key, const seconds expiration_date) noexcept;

		HeaderAndMessageKey& copy(const HeaderAndMessageKey& node) noexcept;
		HeaderAndMessageKey& move(HeaderAndMessageKey&& node) noexcept;

		MessageKey message_key;
		HeaderKey header_key;
		seconds expiration_date{0};

	public:
		HeaderAndMessageKey() = default;
		HeaderAndMessageKey(const HeaderKey& header_key, const MessageKey& message_key);
		HeaderAndMessageKey(const HeaderKey& header_key, const MessageKey& message_key, const seconds expiration_date);
		/* copy and move constructors */
		HeaderAndMessageKey(const HeaderAndMessageKey& node) noexcept;
		HeaderAndMessageKey(HeaderAndMessageKey&& node) noexcept;
		HeaderAndMessageKey(const ProtobufCKeyBundle& key_bundle);

		/* copy and move assignment operators */
		HeaderAndMessageKey& operator=(const HeaderAndMessageKey& node) noexcept;
		HeaderAndMessageKey& operator=(HeaderAndMessageKey&& node) noexcept;

		const MessageKey& messageKey() const noexcept;
		const HeaderKey& headerKey() const noexcept;
		seconds expirationDate() const noexcept;

		ProtobufCKeyBundle* exportProtobuf(Arena& arena) const;

		std::ostream& print(std::ostream& stream) const;
	};

	static constexpr size_t header_and_message_store_maximum_keys{1000};
	static constexpr seconds header_and_message_store_maximum_age{1_months};

	//header of the key store
	class HeaderAndMessageKeyStore {
	private:
		//Vector of Header and message keys, sorted in ascending order by expiration date
		std::vector<HeaderAndMessageKey,SodiumAllocator<HeaderAndMessageKey>> key_storage;

	public:
		HeaderAndMessageKeyStore() = default;
		//! Import a header_and_message_keystore form a Protobuf-C struct.
		/*
		 * \param key_bundles An array of Protobuf-C key-bundles to import from.
		 */
		HeaderAndMessageKeyStore(const span<ProtobufCKeyBundle*> key_bundles);

		const HeaderAndMessageKey& operator[](size_t index) const;
		void add(const HeaderAndMessageKeyStore& keystore);
		void add(const HeaderKey& header_key, const MessageKey& message_key);
		void add(const HeaderAndMessageKey& key);
		void remove(size_t index);
		void clear();

		void removeOutdatedAndTrimSize();

		const std::vector<HeaderAndMessageKey,SodiumAllocator<HeaderAndMessageKey>>& keys() const;

		//! Export a header_and_message_keystore as Protobuf-C struct.
		span<ProtobufCKeyBundle*> exportProtobuf(Arena& arena) const;

		std::ostream& print(std::ostream& stream) const;
	};
}
#endif
<commit_msg>HeaderAndMessageKeyStore: Remove operator[]<commit_after>/*
 * Molch, an implementation of the axolotl ratchet based on libsodium
 *
 * ISC License
 *
 * Copyright (C) 2015-2016 1984not Security GmbH
 * Author: Max Bruckner (FSMaxB)
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef LIB_HEADER_AND_MESSAGE_KEY_STORE_H
#define LIB_HEADER_AND_MESSAGE_KEY_STORE_H

#include <sodium.h>
#include <vector>
#include <ostream>

#include "constants.h"
#include "buffer.hpp"
#include "return-status.hpp"
#include "sodium-wrappers.hpp"
#include "protobuf.hpp"
#include "key.hpp"
#include "time.hpp"

namespace Molch {
	class HeaderAndMessageKey {
	private:
		void fill(const HeaderKey& header_key, const MessageKey& message_key, const seconds expiration_date) noexcept;

		HeaderAndMessageKey& copy(const HeaderAndMessageKey& node) noexcept;
		HeaderAndMessageKey& move(HeaderAndMessageKey&& node) noexcept;

		MessageKey message_key;
		HeaderKey header_key;
		seconds expiration_date{0};

	public:
		HeaderAndMessageKey() = default;
		HeaderAndMessageKey(const HeaderKey& header_key, const MessageKey& message_key);
		HeaderAndMessageKey(const HeaderKey& header_key, const MessageKey& message_key, const seconds expiration_date);
		/* copy and move constructors */
		HeaderAndMessageKey(const HeaderAndMessageKey& node) noexcept;
		HeaderAndMessageKey(HeaderAndMessageKey&& node) noexcept;
		HeaderAndMessageKey(const ProtobufCKeyBundle& key_bundle);

		/* copy and move assignment operators */
		HeaderAndMessageKey& operator=(const HeaderAndMessageKey& node) noexcept;
		HeaderAndMessageKey& operator=(HeaderAndMessageKey&& node) noexcept;

		const MessageKey& messageKey() const noexcept;
		const HeaderKey& headerKey() const noexcept;
		seconds expirationDate() const noexcept;

		ProtobufCKeyBundle* exportProtobuf(Arena& arena) const;

		std::ostream& print(std::ostream& stream) const;
	};

	static constexpr size_t header_and_message_store_maximum_keys{1000};
	static constexpr seconds header_and_message_store_maximum_age{1_months};

	//header of the key store
	class HeaderAndMessageKeyStore {
	private:
		//Vector of Header and message keys, sorted in ascending order by expiration date
		std::vector<HeaderAndMessageKey,SodiumAllocator<HeaderAndMessageKey>> key_storage;

	public:
		HeaderAndMessageKeyStore() = default;
		//! Import a header_and_message_keystore form a Protobuf-C struct.
		/*
		 * \param key_bundles An array of Protobuf-C key-bundles to import from.
		 */
		HeaderAndMessageKeyStore(const span<ProtobufCKeyBundle*> key_bundles);

		//const HeaderAndMessageKey& operator[](size_t index) const;
		void add(const HeaderAndMessageKeyStore& keystore);
		void add(const HeaderKey& header_key, const MessageKey& message_key);
		void add(const HeaderAndMessageKey& key);
		void remove(size_t index);
		void clear();

		void removeOutdatedAndTrimSize();

		const std::vector<HeaderAndMessageKey,SodiumAllocator<HeaderAndMessageKey>>& keys() const;

		//! Export a header_and_message_keystore as Protobuf-C struct.
		span<ProtobufCKeyBundle*> exportProtobuf(Arena& arena) const;

		std::ostream& print(std::ostream& stream) const;
	};
}
#endif
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright © 2019 Ruben Van Boxem
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 **/

#ifndef SKUI_CSS_PROPERTY_ANIMATION_H
#define SKUI_CSS_PROPERTY_ANIMATION_H

#include "css/property.h++"
#include "css/time.h++"
#include "css/timing_function.h++"

#include <core/string.h++>

#include <iosfwd>

namespace skui::css
{
  enum class animation_direction : std::uint8_t
  {
    normal,
    reverse,
    alternate,
    alternate_reverse
  };
  enum class fill_mode : std::uint8_t
  {
    none,
    forwards,
    backwards,
    both
  };
  enum class play_state : std::uint8_t
  {
    running,
    paused
  };

  struct infinite_t final {} constexpr infinite;
  constexpr bool operator==(const infinite_t&, const infinite_t&) { return true; }

  struct animation final
  {
    animation() = default;
    animation(const animation&) = default;
    animation(animation&&) = default;
    explicit animation(initial_t);
    explicit animation(inherit_t);
    animation& operator=(initial_t);
    animation& operator=(inherit_t);
    animation& operator=(const animation&) = default;
    animation& operator=(animation&&) = default;

    property<core::string> name;
    property<time> duration;
    property<css::timing_function> timing_function;
    property<time> delay;
    property<std::uint64_t, infinite_t> iteration_count;
    property<animation_direction> direction;
    property<css::fill_mode> fill_mode;
    property<css::play_state> play_state;
  };

  inline animation::animation(initial_t)
    : name{initial}
    , duration{initial}
    , timing_function{initial}
    , delay{initial}
    , iteration_count{initial}
    , direction{initial}
    , fill_mode{initial}
    , play_state(initial)
  {}

  inline animation::animation(inherit_t)
    : name{inherit}
    , duration{inherit}
    , timing_function{inherit}
    , delay{inherit}
    , iteration_count{inherit}
    , direction{inherit}
    , fill_mode{inherit}
    , play_state{inherit}
  {}

  inline animation& animation::operator=(initial_t)
  {
    *this = animation{initial};
    return *this;
  }

  inline animation& animation::operator=(inherit_t)
  {
    *this = animation{inherit};
    return *this;
  }

  constexpr bool operator==(const animation& lhs, const animation& rhs)
  {
    return lhs.name == rhs.name
        && lhs.duration == rhs.duration
        && lhs.timing_function == rhs.timing_function
        && lhs.delay == rhs.delay
        && lhs.iteration_count == rhs.iteration_count
        && lhs.direction == rhs.direction
        && lhs.fill_mode == rhs.fill_mode
        && lhs.play_state == rhs.play_state;
  }
}
#endif
<commit_msg>Add explicitly defaulted constructor to satisfy rules of N.<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright © 2019 Ruben Van Boxem
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 **/

#ifndef SKUI_CSS_PROPERTY_ANIMATION_H
#define SKUI_CSS_PROPERTY_ANIMATION_H

#include "css/property.h++"
#include "css/time.h++"
#include "css/timing_function.h++"

#include <core/string.h++>

#include <iosfwd>

namespace skui::css
{
  enum class animation_direction : std::uint8_t
  {
    normal,
    reverse,
    alternate,
    alternate_reverse
  };
  enum class fill_mode : std::uint8_t
  {
    none,
    forwards,
    backwards,
    both
  };
  enum class play_state : std::uint8_t
  {
    running,
    paused
  };

  struct infinite_t final {} constexpr infinite;
  constexpr bool operator==(const infinite_t&, const infinite_t&) { return true; }

  struct animation final
  {
    animation() = default;
    animation(const animation&) = default;
    animation(animation&&) = default;
    ~animation() = default;
    explicit animation(initial_t);
    explicit animation(inherit_t);
    animation& operator=(initial_t);
    animation& operator=(inherit_t);
    animation& operator=(const animation&) = default;
    animation& operator=(animation&&) = default;

    property<core::string> name;
    property<time> duration;
    property<css::timing_function> timing_function;
    property<time> delay;
    property<std::uint64_t, infinite_t> iteration_count;
    property<animation_direction> direction;
    property<css::fill_mode> fill_mode;
    property<css::play_state> play_state;
  };

  inline animation::animation(initial_t)
    : name{initial}
    , duration{initial}
    , timing_function{initial}
    , delay{initial}
    , iteration_count{initial}
    , direction{initial}
    , fill_mode{initial}
    , play_state(initial)
  {}

  inline animation::animation(inherit_t)
    : name{inherit}
    , duration{inherit}
    , timing_function{inherit}
    , delay{inherit}
    , iteration_count{inherit}
    , direction{inherit}
    , fill_mode{inherit}
    , play_state{inherit}
  {}

  inline animation& animation::operator=(initial_t)
  {
    *this = animation{initial};
    return *this;
  }

  inline animation& animation::operator=(inherit_t)
  {
    *this = animation{inherit};
    return *this;
  }

  constexpr bool operator==(const animation& lhs, const animation& rhs)
  {
    return lhs.name == rhs.name
        && lhs.duration == rhs.duration
        && lhs.timing_function == rhs.timing_function
        && lhs.delay == rhs.delay
        && lhs.iteration_count == rhs.iteration_count
        && lhs.direction == rhs.direction
        && lhs.fill_mode == rhs.fill_mode
        && lhs.play_state == rhs.play_state;
  }
}
#endif
<|endoftext|>


<commit_before>/* -*- C++ -*-; c-basic-offset: 4; indent-tabs-mode: nil */
/*
 * Test suite for Processor class.
 *
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */

#include <boost/test/unit_test.hpp>
#include <opflex/comms/comms-internal.hpp>
#include <opflex/logging/internal/logging.hpp>
#include <cstdlib>

using opflex::comms::comms_passive_listener;
using opflex::comms::comms_active_connection;
using namespace opflex::comms::internal;

BOOST_AUTO_TEST_SUITE(asynchronous_sockets)

/**
 * A fixture for communications tests
 */
class CommsFixture {
  private:
    uv_idle_t  * idler;
    uv_timer_t * timer;

  protected:
    CommsFixture()
        :
            idler((typeof(idler))malloc(sizeof(*idler))),
            timer((typeof(timer))malloc(sizeof(*timer))) {

        LOG(INFO) << "\n\n\n\n\n\n\n\n";

        LOG(DEBUG) << "idler = " << idler;
        LOG(DEBUG) << "timer = " << timer;
        idler->data = timer->data = this;

        int rc = opflex::comms::initCommunicationLoop(uv_default_loop());

        BOOST_CHECK(!rc);

        for (size_t i=0; i < Peer::LoopData::TOTAL_STATES; ++i) {
            BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                        Peer::LoopData::PeerState(i))
                    ->size(), 0);
        }

        uv_idle_init(uv_default_loop(), idler);
        uv_idle_start(idler, check_peer_db_cb);

        uv_timer_init(uv_default_loop(), timer);
        uv_timer_start(timer, timeout_cb, 1800, 0);
        uv_unref((uv_handle_t*) timer);

    }

    struct PeerDisposer {
        void operator()(Peer *peer)
        {
            LOG(DEBUG) << peer << " destroy() with intent of deleting";
            peer->destroy();
        }
    };

    void cleanup() {

        LOG(DEBUG);

        uv_timer_stop(timer);
        uv_idle_stop(idler);

        for (size_t i=0; i < Peer::LoopData::TOTAL_STATES; ++i) {
            Peer::LoopData::getPeerList(uv_default_loop(),
                        Peer::LoopData::PeerState(i))
                ->clear_and_dispose(PeerDisposer());

        }

        uv_idle_start(idler, wait_for_zero_peers_cb);

    }

    ~CommsFixture() {

        uv_close((uv_handle_t *)timer, (uv_close_cb)free);
        uv_close((uv_handle_t *)idler, (uv_close_cb)free);

        opflex::comms::finiCommunicationLoop(uv_default_loop());

        LOG(INFO) << "\n\n\n\n\n\n\n\n";

    }

    typedef void (*pc)(void);

    static size_t required_final_peers;
    static pc required_post_conditions;
    static bool expect_timeout;

    static size_t count_final_peers() {

        static std::string oldDbgLog;
        std::stringstream dbgLog;
        std::string newDbgLog;

        size_t final_peers = 0;

        size_t m;
        if((m=Peer::LoopData::getPeerList(
                    uv_default_loop(),
                    internal::Peer::LoopData::ONLINE)->size())) {
            final_peers += m;
            dbgLog << " online: " << m;
        }
        if((m=Peer::LoopData::getPeerList(
                    uv_default_loop(),
                    internal::Peer::LoopData::RETRY_TO_CONNECT)->size())) {
            final_peers += m;
            dbgLog << " retry-connecting: " << m;
        }
        if((m=Peer::LoopData::getPeerList(
                    uv_default_loop(),
                    internal::Peer::LoopData::ATTEMPTING_TO_CONNECT)->size())) {
            /* this is not a "final" state, from a test's perspective */
            dbgLog << " attempting: " << m;
        }
        if((m=Peer::LoopData::getPeerList(
                    uv_default_loop(),
                    internal::Peer::LoopData::RETRY_TO_LISTEN)->size())) {
            final_peers += m;
            dbgLog << " retry-listening: " << m;
        }
        if((m=Peer::LoopData::getPeerList(
                    uv_default_loop(),
                    internal::Peer::LoopData::LISTENING)->size())) {
            final_peers += m;
            dbgLog << " listening: " << m;
        }

        dbgLog << " TOTAL FINAL: " << final_peers << "\0";

        newDbgLog = dbgLog.str();

        if (oldDbgLog != newDbgLog) {
            oldDbgLog = newDbgLog;

            LOG(DEBUG) << newDbgLog;
        }

        return final_peers;
    }

    static void wait_for_zero_peers_cb(uv_idle_t * handle) {

        static size_t old_count;
        size_t count = Peer::getCounter();

        if (count) {
            if (old_count != count) {
                LOG(DEBUG) << count << " peers left";
            }
            old_count = count;
            return;
        }
        LOG(DEBUG) << "no peers left";

        uv_idle_stop(handle);
        uv_stop(uv_default_loop());

    }

    static void check_peer_db_cb(uv_idle_t * handle) {

        /* check all easily reachable peers' invariants */
        for (size_t i=0; i < Peer::LoopData::TOTAL_STATES; ++i) {
            Peer::List * pL = Peer::LoopData::getPeerList(uv_default_loop(),
                        Peer::LoopData::PeerState(i));

            for(Peer::List::iterator it = pL->begin(); it != pL->end(); ++it) {
                it->__checkInvariants();
            }
        }

        if (count_final_peers() < required_final_peers) {
            return;
        }

        (*required_post_conditions)();

        reinterpret_cast<CommsFixture*>(handle->data)->cleanup();

    }

    static void timeout_cb(uv_timer_t * handle) {

        LOG(DEBUG);

        if (!expect_timeout) {
            BOOST_CHECK(!"the test has timed out");
        }

        (*required_post_conditions)();

        reinterpret_cast<CommsFixture*>(handle->data)->cleanup();

    }

    void loop_until_final(size_t final_peers, pc post_conditions, bool timeout = false) {

        LOG(DEBUG);

        required_final_peers = final_peers;
        required_post_conditions = post_conditions;
        expect_timeout = timeout;

        uv_run(uv_default_loop(), UV_RUN_DEFAULT);

    }

};

size_t CommsFixture::required_final_peers;
CommsFixture::pc CommsFixture::required_post_conditions;
bool CommsFixture::expect_timeout;

BOOST_FIXTURE_TEST_CASE( test_initialization, CommsFixture ) {

    LOG(DEBUG);

}

void pc_successful_connect(void) {

    LOG(DEBUG);

    /* empty */
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::RETRY_TO_CONNECT)
            ->size(), 0);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::RETRY_TO_LISTEN)
            ->size(), 0);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::ATTEMPTING_TO_CONNECT)
            ->size(), 0);

    /* non-empty */
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::ONLINE)
            ->size(), 2);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::LISTENING)
            ->size(), 1);

}

class DoNothingOnConnect {
  public:
    void operator()(opflex::comms::internal::CommunicationPeer * p) {
        LOG(INFO) << "chill out, we just had a" << (
                p->passive_ ? " pass" : "n act"
            ) << "ive connection";
    }
};

opflex::comms::internal::ConnectionHandler doNothingOnConnect = DoNothingOnConnect();

class StartPingingOnConnect {
  public:
    void operator()(opflex::comms::internal::CommunicationPeer * p) {
        p->startKeepAlive();
    }
};

opflex::comms::internal::ConnectionHandler startPingingOnConnect = StartPingingOnConnect();

BOOST_FIXTURE_TEST_CASE( test_ipv4, CommsFixture ) {

    LOG(DEBUG);

    int rc;

    rc = comms_passive_listener(doNothingOnConnect, "127.0.0.1", 65535);

    BOOST_CHECK_EQUAL(rc, 0);

    rc = comms_active_connection(doNothingOnConnect, "localhost", "65535");

    BOOST_CHECK_EQUAL(rc, 0);

    loop_until_final(3, pc_successful_connect);

}

BOOST_FIXTURE_TEST_CASE( test_ipv6, CommsFixture ) {

    LOG(DEBUG);

    int rc;

    rc = comms_passive_listener(doNothingOnConnect, "::1", 65534);

    BOOST_CHECK_EQUAL(rc, 0);

    rc = comms_active_connection(doNothingOnConnect, "localhost", "65534");

    BOOST_CHECK_EQUAL(rc, 0);

    loop_until_final(3, pc_successful_connect);

}

static void pc_non_existent(void) {

    LOG(DEBUG);

    /* non-empty */
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::RETRY_TO_CONNECT)
            ->size(), 1);

    /* empty */
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::RETRY_TO_LISTEN)
            ->size(), 0);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::ATTEMPTING_TO_CONNECT)
            ->size(), 0);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::ONLINE)
            ->size(), 0);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::LISTENING)
            ->size(), 0);

}

BOOST_FIXTURE_TEST_CASE( test_non_existent_host, CommsFixture ) {

    LOG(DEBUG);

    int rc = comms_active_connection(doNothingOnConnect, "non_existent_host.", "65533");

    BOOST_CHECK_EQUAL(rc, 0);

    loop_until_final(1, pc_non_existent);

}

BOOST_FIXTURE_TEST_CASE( test_non_existent_service, CommsFixture ) {

    LOG(DEBUG);

    int rc = comms_active_connection(doNothingOnConnect, "127.0.0.1", "65533");

    BOOST_CHECK_EQUAL(rc, 0);

    loop_until_final(1, pc_non_existent);

}

BOOST_FIXTURE_TEST_CASE( test_keepalive, CommsFixture ) {

    LOG(DEBUG);

    int rc;

    rc = comms_passive_listener(startPingingOnConnect, "::1", 65532);

    BOOST_CHECK_EQUAL(rc, 0);

    rc = comms_active_connection(startPingingOnConnect, "::1", "65532");

    BOOST_CHECK_EQUAL(rc, 0);

    loop_until_final(4, pc_successful_connect, true); // 4 is to cause a timeout

}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>always show testcase names in comms tests<commit_after>/* -*- C++ -*-; c-basic-offset: 4; indent-tabs-mode: nil */
/*
 * Test suite for Processor class.
 *
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */

#include <boost/test/unit_test.hpp>
#include <opflex/comms/comms-internal.hpp>
#include <opflex/logging/internal/logging.hpp>
#include <cstdlib>
#include <boost/test/unit_test_log.hpp>

#include <dlfcn.h>

using opflex::comms::comms_passive_listener;
using opflex::comms::comms_active_connection;
using namespace opflex::comms::internal;

BOOST_AUTO_TEST_SUITE(asynchronous_sockets)

struct CommsTests {
    CommsTests() {
        LOG(INFO) << "global setup\n";

        boost::unit_test::unit_test_log_t::instance().set_threshold_level(::boost::unit_test::log_successful_tests);
    }
    ~CommsTests() {
        LOG(INFO) << "global teardown\n";
    }
};

BOOST_GLOBAL_FIXTURE( CommsTests );

/**
 * A fixture for communications tests
 */
class CommsFixture {
  private:
    uv_idle_t  * idler;
    uv_timer_t * timer;

  protected:
    CommsFixture()
        :
            idler((typeof(idler))malloc(sizeof(*idler))),
            timer((typeof(timer))malloc(sizeof(*timer))) {

        LOG(INFO) << "\n\n\n\n\n\n\n\n";

        LOG(DEBUG) << "idler = " << idler;
        LOG(DEBUG) << "timer = " << timer;
        idler->data = timer->data = this;

        int rc = opflex::comms::initCommunicationLoop(uv_default_loop());

        BOOST_CHECK(!rc);

        for (size_t i=0; i < Peer::LoopData::TOTAL_STATES; ++i) {
            BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                        Peer::LoopData::PeerState(i))
                    ->size(), 0);
        }

        uv_idle_init(uv_default_loop(), idler);
        uv_idle_start(idler, check_peer_db_cb);

        uv_timer_init(uv_default_loop(), timer);
        uv_timer_start(timer, timeout_cb, 1800, 0);
        uv_unref((uv_handle_t*) timer);

    }

    struct PeerDisposer {
        void operator()(Peer *peer)
        {
            LOG(DEBUG) << peer << " destroy() with intent of deleting";
            peer->destroy();
        }
    };

    void cleanup() {

        LOG(DEBUG);

        uv_timer_stop(timer);
        uv_idle_stop(idler);

        for (size_t i=0; i < Peer::LoopData::TOTAL_STATES; ++i) {
            Peer::LoopData::getPeerList(uv_default_loop(),
                        Peer::LoopData::PeerState(i))
                ->clear_and_dispose(PeerDisposer());

        }

        uv_idle_start(idler, wait_for_zero_peers_cb);

    }

    ~CommsFixture() {

        uv_close((uv_handle_t *)timer, (uv_close_cb)free);
        uv_close((uv_handle_t *)idler, (uv_close_cb)free);

        opflex::comms::finiCommunicationLoop(uv_default_loop());

        LOG(INFO) << "\n\n\n\n\n\n\n\n";

    }

    typedef void (*pc)(void);

    static size_t required_final_peers;
    static pc required_post_conditions;
    static bool expect_timeout;

    static size_t count_final_peers() {

        static std::string oldDbgLog;
        std::stringstream dbgLog;
        std::string newDbgLog;

        size_t final_peers = 0;

        size_t m;
        if((m=Peer::LoopData::getPeerList(
                    uv_default_loop(),
                    internal::Peer::LoopData::ONLINE)->size())) {
            final_peers += m;
            dbgLog << " online: " << m;
        }
        if((m=Peer::LoopData::getPeerList(
                    uv_default_loop(),
                    internal::Peer::LoopData::RETRY_TO_CONNECT)->size())) {
            final_peers += m;
            dbgLog << " retry-connecting: " << m;
        }
        if((m=Peer::LoopData::getPeerList(
                    uv_default_loop(),
                    internal::Peer::LoopData::ATTEMPTING_TO_CONNECT)->size())) {
            /* this is not a "final" state, from a test's perspective */
            dbgLog << " attempting: " << m;
        }
        if((m=Peer::LoopData::getPeerList(
                    uv_default_loop(),
                    internal::Peer::LoopData::RETRY_TO_LISTEN)->size())) {
            final_peers += m;
            dbgLog << " retry-listening: " << m;
        }
        if((m=Peer::LoopData::getPeerList(
                    uv_default_loop(),
                    internal::Peer::LoopData::LISTENING)->size())) {
            final_peers += m;
            dbgLog << " listening: " << m;
        }

        dbgLog << " TOTAL FINAL: " << final_peers << "\0";

        newDbgLog = dbgLog.str();

        if (oldDbgLog != newDbgLog) {
            oldDbgLog = newDbgLog;

            LOG(DEBUG) << newDbgLog;
        }

        return final_peers;
    }

    static void wait_for_zero_peers_cb(uv_idle_t * handle) {

        static size_t old_count;
        size_t count = Peer::getCounter();

        if (count) {
            if (old_count != count) {
                LOG(DEBUG) << count << " peers left";
            }
            old_count = count;
            return;
        }
        LOG(DEBUG) << "no peers left";

        uv_idle_stop(handle);
        uv_stop(uv_default_loop());

    }

    static void check_peer_db_cb(uv_idle_t * handle) {

        /* check all easily reachable peers' invariants */
        for (size_t i=0; i < Peer::LoopData::TOTAL_STATES; ++i) {
            Peer::List * pL = Peer::LoopData::getPeerList(uv_default_loop(),
                        Peer::LoopData::PeerState(i));

            for(Peer::List::iterator it = pL->begin(); it != pL->end(); ++it) {
                it->__checkInvariants();
            }
        }

        if (count_final_peers() < required_final_peers) {
            return;
        }

        (*required_post_conditions)();

        reinterpret_cast<CommsFixture*>(handle->data)->cleanup();

    }

    static void timeout_cb(uv_timer_t * handle) {

        LOG(DEBUG);

        if (!expect_timeout) {
            BOOST_CHECK(!"the test has timed out");
        }

        (*required_post_conditions)();

        reinterpret_cast<CommsFixture*>(handle->data)->cleanup();

    }

    void loop_until_final(size_t final_peers, pc post_conditions, bool timeout = false) {

        LOG(DEBUG);

        required_final_peers = final_peers;
        required_post_conditions = post_conditions;
        expect_timeout = timeout;

        uv_run(uv_default_loop(), UV_RUN_DEFAULT);

    }

};

size_t CommsFixture::required_final_peers;
CommsFixture::pc CommsFixture::required_post_conditions;
bool CommsFixture::expect_timeout;

BOOST_FIXTURE_TEST_CASE( test_initialization, CommsFixture ) {

    LOG(DEBUG);

}

void pc_successful_connect(void) {

    LOG(DEBUG);

    /* empty */
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::RETRY_TO_CONNECT)
            ->size(), 0);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::RETRY_TO_LISTEN)
            ->size(), 0);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::ATTEMPTING_TO_CONNECT)
            ->size(), 0);

    /* non-empty */
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::ONLINE)
            ->size(), 2);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::LISTENING)
            ->size(), 1);

}

class DoNothingOnConnect {
  public:
    void operator()(opflex::comms::internal::CommunicationPeer * p) {
        LOG(INFO) << "chill out, we just had a" << (
                p->passive_ ? " pass" : "n act"
            ) << "ive connection";
    }
};

opflex::comms::internal::ConnectionHandler doNothingOnConnect = DoNothingOnConnect();

class StartPingingOnConnect {
  public:
    void operator()(opflex::comms::internal::CommunicationPeer * p) {
        p->startKeepAlive();
    }
};

opflex::comms::internal::ConnectionHandler startPingingOnConnect = StartPingingOnConnect();

BOOST_FIXTURE_TEST_CASE( test_ipv4, CommsFixture ) {

    LOG(DEBUG);

    int rc;

    rc = comms_passive_listener(doNothingOnConnect, "127.0.0.1", 65535);

    BOOST_CHECK_EQUAL(rc, 0);

    rc = comms_active_connection(doNothingOnConnect, "localhost", "65535");

    BOOST_CHECK_EQUAL(rc, 0);

    loop_until_final(3, pc_successful_connect);

}

BOOST_FIXTURE_TEST_CASE( test_ipv6, CommsFixture ) {

    LOG(DEBUG);

    int rc;

    rc = comms_passive_listener(doNothingOnConnect, "::1", 65534);

    BOOST_CHECK_EQUAL(rc, 0);

    rc = comms_active_connection(doNothingOnConnect, "localhost", "65534");

    BOOST_CHECK_EQUAL(rc, 0);

    loop_until_final(3, pc_successful_connect);

}

static void pc_non_existent(void) {

    LOG(DEBUG);

    /* non-empty */
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::RETRY_TO_CONNECT)
            ->size(), 1);

    /* empty */
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::RETRY_TO_LISTEN)
            ->size(), 0);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::ATTEMPTING_TO_CONNECT)
            ->size(), 0);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::ONLINE)
            ->size(), 0);
    BOOST_CHECK_EQUAL(Peer::LoopData::getPeerList(uv_default_loop(),
                Peer::LoopData::LISTENING)
            ->size(), 0);

}

BOOST_FIXTURE_TEST_CASE( test_non_existent_host, CommsFixture ) {

    LOG(DEBUG);

    int rc = comms_active_connection(doNothingOnConnect, "non_existent_host.", "65533");

    BOOST_CHECK_EQUAL(rc, 0);

    loop_until_final(1, pc_non_existent);

}

BOOST_FIXTURE_TEST_CASE( test_non_existent_service, CommsFixture ) {

    LOG(DEBUG);

    int rc = comms_active_connection(doNothingOnConnect, "127.0.0.1", "65533");

    BOOST_CHECK_EQUAL(rc, 0);

    loop_until_final(1, pc_non_existent);

}

BOOST_FIXTURE_TEST_CASE( test_keepalive, CommsFixture ) {

    LOG(DEBUG);

    int rc;

    rc = comms_passive_listener(startPingingOnConnect, "::1", 65532);

    BOOST_CHECK_EQUAL(rc, 0);

    rc = comms_active_connection(startPingingOnConnect, "::1", "65532");

    BOOST_CHECK_EQUAL(rc, 0);

    loop_until_final(4, pc_successful_connect, true); // 4 is to cause a timeout

}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_FEM_KERNELS_HPP
#define MFEM_FEM_KERNELS_HPP

#include "../config/config.hpp"
#include "../linalg/dtensor.hpp"

namespace mfem
{

namespace kernels
{

/// Load B1d matrice into shared memory
template<int MD1, int MQ1>
MFEM_HOST_DEVICE inline void LoadB(const int D1D, const int Q1D,
                                   const ConstDeviceMatrix b,
                                   double sB[MQ1*MD1])
{
   const int tidz = MFEM_THREAD_ID(z);
   DeviceMatrix B(sB, MD1, MQ1);

   if (tidz == 0)
   {
      MFEM_FOREACH_THREAD(d,y,D1D)
      {
         MFEM_FOREACH_THREAD(q,x,Q1D)
         {
            B(d,q) = b(q,d);
         }
      }
   }
   MFEM_SYNC_THREAD;
}

/// Load 2D input scalar into shared memory, with comp
template<int MD1, int NBZ>
MFEM_HOST_DEVICE inline void LoadX(const int e, const int D1D, const int c,
                                   const DeviceTensor<4, const double> x,
                                   double sm[NBZ][MD1*MD1])
{
   const int tidz = MFEM_THREAD_ID(z);
   DeviceMatrix X(sm[tidz], MD1, MD1);

   MFEM_FOREACH_THREAD(dy,y,D1D)
   {
      MFEM_FOREACH_THREAD(dx,x,D1D)
      {
         X(dx,dy) = x(dx,dy,c,e);
      }
   }
   MFEM_SYNC_THREAD;
}

/// 2D Scalar Evaluation, 1/2
template<int MD1, int MQ1, int NBZ>
MFEM_HOST_DEVICE inline void EvalX(const int D1D, const int Q1D,
                                   const double sB[MQ1*MD1],
                                   const double sX[NBZ][MD1*MD1],
                                   double sDQ[NBZ][MD1*MQ1])
{
   const int tidz = MFEM_THREAD_ID(z);
   ConstDeviceMatrix B(sB, MD1, MQ1);
   ConstDeviceMatrix X(sX[tidz], MD1, MD1);
   DeviceMatrix DQ(sDQ[tidz], MQ1, MD1);

   MFEM_FOREACH_THREAD(dy,y,D1D)
   {
      MFEM_FOREACH_THREAD(qx,x,Q1D)
      {
         double u = 0.0;
         for (int dx = 0; dx < D1D; ++dx)
         {
            u += B(dx,qx) * X(dx,dy);
         }
         DQ(qx,dy) = u;
      }
   }
   MFEM_SYNC_THREAD;
}

/// 2D Scalar Evaluation, 2/2
template<int MD1, int MQ1, int NBZ>
MFEM_HOST_DEVICE inline void EvalY(const int D1D, const int Q1D,
                                   const double sB[MQ1*MD1],
                                   const double sDQ[NBZ][MD1*MQ1],
                                   double sQQ[NBZ][MQ1*MQ1])
{
   const int tidz = MFEM_THREAD_ID(z);
   ConstDeviceMatrix B(sB, MD1, MQ1);
   ConstDeviceMatrix DQ(sDQ[tidz], MQ1, MD1);
   DeviceMatrix QQ(sQQ[tidz], MQ1, MQ1);

   MFEM_FOREACH_THREAD(qy,y,Q1D)
   {
      MFEM_FOREACH_THREAD(qx,x,Q1D)
      {
         double u = 0.0;
         for (int dy = 0; dy < D1D; ++dy)
         {
            u += DQ(qx,dy) * B(dy,qy);
         }
         QQ(qx,qy) = u;
      }
   }
   MFEM_SYNC_THREAD;
}

/// Pull 2D Scalar Evaluation
template<int MQ1, int NBZ>
MFEM_HOST_DEVICE inline double PullEval(const int qx, const int qy,
                                      const double sQQ[NBZ][MQ1*MQ1])
{
   const int tidz = MFEM_THREAD_ID(z);
   ConstDeviceMatrix QQ(sQQ[tidz], MQ1, MQ1);

   return QQ(qx,qy);
}

/// Load 3D scalar input vector into shared memory, with comp
template<int MD1>
MFEM_HOST_DEVICE inline void LoadX(const int e, const int D1D, const int c,
                                   const DeviceTensor<5, const double> x,
                                   double sm[MD1*MD1*MD1])
{
   DeviceCube X(sm, MD1, MD1, MD1);

   MFEM_FOREACH_THREAD(dz,z,D1D)
   {
      MFEM_FOREACH_THREAD(dy,y,D1D)
      {
         MFEM_FOREACH_THREAD(dx,x,D1D)
         {
            X(dx,dy,dz) = x(dx,dy,dz,c,e);
         }
      }
   }
   MFEM_SYNC_THREAD;
}

/// 3D Scalar Evaluation, 1/3
template<int MD1, int MQ1>
MFEM_HOST_DEVICE inline void EvalX(const int D1D, const int Q1D,
                                   const double sB[MQ1*MD1],
                                   const double sDDD[MD1*MD1*MD1],
                                   double sDDQ[MD1*MD1*MQ1])
{
   ConstDeviceMatrix B(sB, MD1, MQ1);
   ConstDeviceCube Xx(sDDD, MD1, MD1, MD1);
   DeviceCube XxB(sDDQ, MQ1, MD1, MD1);

   MFEM_FOREACH_THREAD(dz,z,D1D)
   {
      MFEM_FOREACH_THREAD(dy,y,D1D)
      {
         MFEM_FOREACH_THREAD(qx,x,Q1D)
         {
            double u = 0.0;
            for (int dx = 0; dx < D1D; ++dx)
            {
               const double Bx = B(dx,qx);
               u += Bx * Xx(dx,dy,dz);
            }
            XxB(qx,dy,dz) = u;
         }
      }
   }
   MFEM_SYNC_THREAD;
}

/// 3D Scalar Evaluation, 2/3
template<int MD1, int MQ1>
MFEM_HOST_DEVICE inline void EvalY(const int D1D, const int Q1D,
                                   const double sB[MQ1*MD1],
                                   const double sDDQ[MD1*MD1*MQ1],
                                   double sDQQ[MD1*MQ1*MQ1])
{
   ConstDeviceMatrix B(sB, MD1, MQ1);
   ConstDeviceCube XxB(sDDQ, MQ1, MD1, MD1);
   DeviceCube XxBB(sDQQ, MQ1, MQ1, MD1);

   MFEM_FOREACH_THREAD(dz,z,D1D)
   {
      MFEM_FOREACH_THREAD(qy,y,Q1D)
      {
         MFEM_FOREACH_THREAD(qx,x,Q1D)
         {
            double u = 0.0;
            for (int dy = 0; dy < D1D; ++dy)
            {
               const double By = B(dy,qy);
               u += XxB(qx,dy,dz) * By;
            }
            XxBB(qx,qy,dz) = u;
         }
      }
   }
   MFEM_SYNC_THREAD;
}

/// 3D Scalar Evaluation, 3/3
template<int MD1, int MQ1>
MFEM_HOST_DEVICE inline void EvalZ(const int D1D, const int Q1D,
                                   const double sB[MQ1*MD1],
                                   const double sDQQ[MD1*MQ1*MQ1],
                                   double sQQQ[MQ1*MQ1*MQ1])
{
   ConstDeviceMatrix B(sB, MD1, MQ1);
   ConstDeviceCube XxBB(sDQQ, MQ1, MQ1, MD1);
   DeviceCube XxBBB(sQQQ, MQ1, MQ1, MQ1);

   MFEM_FOREACH_THREAD(qz,z,Q1D)
   {
      MFEM_FOREACH_THREAD(qy,y,Q1D)
      {
         MFEM_FOREACH_THREAD(qx,x,Q1D)
         {
            double u = 0.0;
            for (int dz = 0; dz < D1D; ++dz)
            {
               const double Bz = B(dz,qz);
               u += XxBB(qx,qy,dz) * Bz;
            }
            XxBBB(qx,qy,qz) = u;
         }
      }
   }
   MFEM_SYNC_THREAD;
}

/// Pull 3D Scalar Evaluation
template<int MQ1>
MFEM_HOST_DEVICE inline double PullEval(const int x, const int y, const int z,
                                      const double sQQQ[MQ1*MQ1*MQ1])
{
   ConstDeviceCube XxBBB(sQQQ, MQ1, MQ1, MQ1);
   return XxBBB(x,y,z);
}

} // namespace kernels

} // namespace mfem

#endif // MFEM_FEM_KERNELS_HPP
<commit_msg>Make style<commit_after>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#ifndef MFEM_FEM_KERNELS_HPP
#define MFEM_FEM_KERNELS_HPP

#include "../config/config.hpp"
#include "../linalg/dtensor.hpp"

namespace mfem
{

namespace kernels
{

/// Load B1d matrice into shared memory
template<int MD1, int MQ1>
MFEM_HOST_DEVICE inline void LoadB(const int D1D, const int Q1D,
                                   const ConstDeviceMatrix b,
                                   double sB[MQ1*MD1])
{
   const int tidz = MFEM_THREAD_ID(z);
   DeviceMatrix B(sB, MD1, MQ1);

   if (tidz == 0)
   {
      MFEM_FOREACH_THREAD(d,y,D1D)
      {
         MFEM_FOREACH_THREAD(q,x,Q1D)
         {
            B(d,q) = b(q,d);
         }
      }
   }
   MFEM_SYNC_THREAD;
}

/// Load 2D input scalar into shared memory, with comp
template<int MD1, int NBZ>
MFEM_HOST_DEVICE inline void LoadX(const int e, const int D1D, const int c,
                                   const DeviceTensor<4, const double> x,
                                   double sm[NBZ][MD1*MD1])
{
   const int tidz = MFEM_THREAD_ID(z);
   DeviceMatrix X(sm[tidz], MD1, MD1);

   MFEM_FOREACH_THREAD(dy,y,D1D)
   {
      MFEM_FOREACH_THREAD(dx,x,D1D)
      {
         X(dx,dy) = x(dx,dy,c,e);
      }
   }
   MFEM_SYNC_THREAD;
}

/// 2D Scalar Evaluation, 1/2
template<int MD1, int MQ1, int NBZ>
MFEM_HOST_DEVICE inline void EvalX(const int D1D, const int Q1D,
                                   const double sB[MQ1*MD1],
                                   const double sX[NBZ][MD1*MD1],
                                   double sDQ[NBZ][MD1*MQ1])
{
   const int tidz = MFEM_THREAD_ID(z);
   ConstDeviceMatrix B(sB, MD1, MQ1);
   ConstDeviceMatrix X(sX[tidz], MD1, MD1);
   DeviceMatrix DQ(sDQ[tidz], MQ1, MD1);

   MFEM_FOREACH_THREAD(dy,y,D1D)
   {
      MFEM_FOREACH_THREAD(qx,x,Q1D)
      {
         double u = 0.0;
         for (int dx = 0; dx < D1D; ++dx)
         {
            u += B(dx,qx) * X(dx,dy);
         }
         DQ(qx,dy) = u;
      }
   }
   MFEM_SYNC_THREAD;
}

/// 2D Scalar Evaluation, 2/2
template<int MD1, int MQ1, int NBZ>
MFEM_HOST_DEVICE inline void EvalY(const int D1D, const int Q1D,
                                   const double sB[MQ1*MD1],
                                   const double sDQ[NBZ][MD1*MQ1],
                                   double sQQ[NBZ][MQ1*MQ1])
{
   const int tidz = MFEM_THREAD_ID(z);
   ConstDeviceMatrix B(sB, MD1, MQ1);
   ConstDeviceMatrix DQ(sDQ[tidz], MQ1, MD1);
   DeviceMatrix QQ(sQQ[tidz], MQ1, MQ1);

   MFEM_FOREACH_THREAD(qy,y,Q1D)
   {
      MFEM_FOREACH_THREAD(qx,x,Q1D)
      {
         double u = 0.0;
         for (int dy = 0; dy < D1D; ++dy)
         {
            u += DQ(qx,dy) * B(dy,qy);
         }
         QQ(qx,qy) = u;
      }
   }
   MFEM_SYNC_THREAD;
}

/// Pull 2D Scalar Evaluation
template<int MQ1, int NBZ>
MFEM_HOST_DEVICE inline double PullEval(const int qx, const int qy,
                                        const double sQQ[NBZ][MQ1*MQ1])
{
   const int tidz = MFEM_THREAD_ID(z);
   ConstDeviceMatrix QQ(sQQ[tidz], MQ1, MQ1);

   return QQ(qx,qy);
}

/// Load 3D scalar input vector into shared memory, with comp
template<int MD1>
MFEM_HOST_DEVICE inline void LoadX(const int e, const int D1D, const int c,
                                   const DeviceTensor<5, const double> x,
                                   double sm[MD1*MD1*MD1])
{
   DeviceCube X(sm, MD1, MD1, MD1);

   MFEM_FOREACH_THREAD(dz,z,D1D)
   {
      MFEM_FOREACH_THREAD(dy,y,D1D)
      {
         MFEM_FOREACH_THREAD(dx,x,D1D)
         {
            X(dx,dy,dz) = x(dx,dy,dz,c,e);
         }
      }
   }
   MFEM_SYNC_THREAD;
}

/// 3D Scalar Evaluation, 1/3
template<int MD1, int MQ1>
MFEM_HOST_DEVICE inline void EvalX(const int D1D, const int Q1D,
                                   const double sB[MQ1*MD1],
                                   const double sDDD[MD1*MD1*MD1],
                                   double sDDQ[MD1*MD1*MQ1])
{
   ConstDeviceMatrix B(sB, MD1, MQ1);
   ConstDeviceCube Xx(sDDD, MD1, MD1, MD1);
   DeviceCube XxB(sDDQ, MQ1, MD1, MD1);

   MFEM_FOREACH_THREAD(dz,z,D1D)
   {
      MFEM_FOREACH_THREAD(dy,y,D1D)
      {
         MFEM_FOREACH_THREAD(qx,x,Q1D)
         {
            double u = 0.0;
            for (int dx = 0; dx < D1D; ++dx)
            {
               const double Bx = B(dx,qx);
               u += Bx * Xx(dx,dy,dz);
            }
            XxB(qx,dy,dz) = u;
         }
      }
   }
   MFEM_SYNC_THREAD;
}

/// 3D Scalar Evaluation, 2/3
template<int MD1, int MQ1>
MFEM_HOST_DEVICE inline void EvalY(const int D1D, const int Q1D,
                                   const double sB[MQ1*MD1],
                                   const double sDDQ[MD1*MD1*MQ1],
                                   double sDQQ[MD1*MQ1*MQ1])
{
   ConstDeviceMatrix B(sB, MD1, MQ1);
   ConstDeviceCube XxB(sDDQ, MQ1, MD1, MD1);
   DeviceCube XxBB(sDQQ, MQ1, MQ1, MD1);

   MFEM_FOREACH_THREAD(dz,z,D1D)
   {
      MFEM_FOREACH_THREAD(qy,y,Q1D)
      {
         MFEM_FOREACH_THREAD(qx,x,Q1D)
         {
            double u = 0.0;
            for (int dy = 0; dy < D1D; ++dy)
            {
               const double By = B(dy,qy);
               u += XxB(qx,dy,dz) * By;
            }
            XxBB(qx,qy,dz) = u;
         }
      }
   }
   MFEM_SYNC_THREAD;
}

/// 3D Scalar Evaluation, 3/3
template<int MD1, int MQ1>
MFEM_HOST_DEVICE inline void EvalZ(const int D1D, const int Q1D,
                                   const double sB[MQ1*MD1],
                                   const double sDQQ[MD1*MQ1*MQ1],
                                   double sQQQ[MQ1*MQ1*MQ1])
{
   ConstDeviceMatrix B(sB, MD1, MQ1);
   ConstDeviceCube XxBB(sDQQ, MQ1, MQ1, MD1);
   DeviceCube XxBBB(sQQQ, MQ1, MQ1, MQ1);

   MFEM_FOREACH_THREAD(qz,z,Q1D)
   {
      MFEM_FOREACH_THREAD(qy,y,Q1D)
      {
         MFEM_FOREACH_THREAD(qx,x,Q1D)
         {
            double u = 0.0;
            for (int dz = 0; dz < D1D; ++dz)
            {
               const double Bz = B(dz,qz);
               u += XxBB(qx,qy,dz) * Bz;
            }
            XxBBB(qx,qy,qz) = u;
         }
      }
   }
   MFEM_SYNC_THREAD;
}

/// Pull 3D Scalar Evaluation
template<int MQ1>
MFEM_HOST_DEVICE inline double PullEval(const int x, const int y, const int z,
                                        const double sQQQ[MQ1*MQ1*MQ1])
{
   ConstDeviceCube XxBBB(sQQQ, MQ1, MQ1, MQ1);
   return XxBBB(x,y,z);
}

} // namespace kernels

} // namespace mfem

#endif // MFEM_FEM_KERNELS_HPP
<|endoftext|>