<commit_before>#include "asset_browser_tabs.h"

#include "asset_editor_window.h"
#include "halley/tools/project/project.h"
#include "src/ui/editor_ui_factory.h"
#include "src/ui/project_window.h"

using namespace Halley;

AssetBrowserTabs::AssetBrowserTabs(EditorUIFactory& factory, Project& project, ProjectWindow& projectWindow)
	: UIWidget("asset_browser_tabs", {}, UISizer(UISizerType::Horizontal))
	, factory(factory)
	, project(project)
	, projectWindow(projectWindow)
{
	makeUI();
}

void AssetBrowserTabs::load(std::optional<AssetType> assetType, const String& name)
{
	openTab(assetType, name, true);
	saveTabs();
}

void AssetBrowserTabs::openTab(std::optional<AssetType> assetType, const String& name, bool selected)
{
	const String key = assetType ? (toString(assetType) + ":" + name) : name;

	const bool alreadyExists = tabs->setSelectedOptionId(key);
	if (alreadyExists) {
		return;
	}

	// Create tab
	auto tabContents = factory.makeUI("ui/halley/asset_browser_tab_contents");
	tabContents->setId("tabContents");
	populateTab(*tabContents, assetType, name, key);
	tabs->addItem(key, tabContents);

	// Create window
	auto window = std::make_shared<AssetEditorWindow>(factory, project, projectWindow);
	window->setAssetSrcMode(srcMode);
	window->loadAsset(name, assetType, true);
	windows.push_back(window);

	// Add to tabs
	pages->addPage()->add(window, 1);
	if (selected) {
		tabs->setSelectedOption(int(tabs->getCount()) - 1);
	}
}

void AssetBrowserTabs::closeTab(const String& key)
{
	const auto idx = tabs->tryGetItemId(key);
	if (idx != -1) {
		pages->removePage(idx);
		windows.erase(windows.begin() + idx);
		tabs->removeItem(key);
		saveTabs();
	}
}

void AssetBrowserTabs::populateTab(UIWidget& tab, std::optional<AssetType> assetType, const String& name, const String& key)
{
	Sprite icon;
	if (assetType) {
		icon = factory.makeAssetTypeIcon(assetType.value());
	} else {
		const auto type = project.getAssetImporter()->getImportAssetType(name, false);
		icon = factory.makeImportAssetTypeIcon(type);
	}
	auto label = LocalisedString::fromUserString(Path(name).getFilename().toString());
	tab.getWidgetAs<UIImage>("icon")->setSprite(icon);
	tab.getWidgetAs<UILabel>("label")->setText(std::move(label));
	tab.setHandle(UIEventType::ButtonClicked, "close", [=] (const UIEvent& event)
	{
		toClose.push_back(key);
	});
}

void AssetBrowserTabs::replaceAssetTab(const String& oldName, const String& newName)
{
	const auto idx = tabs->tryGetItemId(oldName);
	if (idx == -1) {
		return;
	}

	const auto contents = tabs->getItem(idx)->getWidget("tabContents");
	if (contents) {
		tabs->changeItemId(idx, newName);
		populateTab(*contents, {}, newName, newName);
		windows[idx]->loadAsset(newName, {}, true);
	}
}

void AssetBrowserTabs::refreshAssets()
{
	for (int i = 0; i < pages->getNumberOfPages(); ++i) {
		auto assetEditor = pages->getPage(i)->getWidgetAs<AssetEditorWindow>("assetEditorWindow");
		assetEditor->refreshAssets();
	}
}

void AssetBrowserTabs::setAssetSrcMode(bool srcMode)
{
	this->srcMode = srcMode;

	if (waitingLoad) {
		waitingLoad = false;
		loadTabs();
	}
}

void AssetBrowserTabs::update(Time t, bool moved)
{
	for (auto& key: toClose) {
		closeTab(key);
	}
	toClose.clear();

	int size = static_cast<int>(windows.size());
	for (int i = 0; i < size; ++i) {
		tabs->getItem(i)->getWidget("modified")->setActive(windows[i]->isModified());
	}
}

void AssetBrowserTabs::makeUI()
{
	add(factory.makeUI("ui/halley/asset_browser_tabs"), 1);
	tabs = getWidgetAs<UIList>("tabs");
	pages = getWidgetAs<UIPagedPane>("pages");

	setHandle(UIEventType::ListSelectionChanged, "tabs", [=] (const UIEvent& event)
	{
		pages->setPage(event.getIntData());
		saveTabs();
	});
}

void AssetBrowserTabs::saveTabs()
{
	ConfigNode::SequenceType tabIds;
	const auto n = tabs->getCount();
	for (int i = 0; i < n; ++i) {
		tabIds.push_back(ConfigNode(tabs->getItem(i)->getId()));
	}

	projectWindow.setSetting(EditorSettingType::Project, "tabsOpen", std::move(tabIds));
	projectWindow.setSetting(EditorSettingType::Project, "currentTab", ConfigNode(tabs->getSelectedOptionId()));
}

void AssetBrowserTabs::loadTabs()
{
	const auto& tabsOpen = projectWindow.getSetting(EditorSettingType::Project, "tabsOpen");
	if (tabsOpen.getType() == ConfigNodeType::Sequence) {
		for (const auto& tab: tabsOpen) {
			auto id = tab.asString();
			auto splitParts = id.split(':');
			if (splitParts.size() == 2) {
				openTab(fromString<AssetType>(splitParts[0]), splitParts[1], false);
			} else if (splitParts.size() == 1) {
				openTab({}, splitParts[0], false);
			}
		}
	}

	const auto curTab = projectWindow.getSetting(EditorSettingType::Project, "currentTab").asString("");
	tabs->setSelectedOptionId(curTab);
}
<commit_msg>Save tab persistence<commit_after>#include "asset_browser_tabs.h"

#include "asset_editor_window.h"
#include "halley/tools/project/project.h"
#include "src/ui/editor_ui_factory.h"
#include "src/ui/project_window.h"

using namespace Halley;

AssetBrowserTabs::AssetBrowserTabs(EditorUIFactory& factory, Project& project, ProjectWindow& projectWindow)
	: UIWidget("asset_browser_tabs", {}, UISizer(UISizerType::Horizontal))
	, factory(factory)
	, project(project)
	, projectWindow(projectWindow)
{
	makeUI();
}

void AssetBrowserTabs::load(std::optional<AssetType> assetType, const String& name)
{
	openTab(assetType, name, true);
	saveTabs();
}

void AssetBrowserTabs::openTab(std::optional<AssetType> assetType, const String& name, bool selected)
{
	const String key = assetType ? (toString(assetType) + ":" + name) : name;

	const bool alreadyExists = tabs->setSelectedOptionId(key);
	if (alreadyExists) {
		return;
	}

	// Create tab
	auto tabContents = factory.makeUI("ui/halley/asset_browser_tab_contents");
	tabContents->setId("tabContents");
	populateTab(*tabContents, assetType, name, key);
	tabs->addItem(key, tabContents);

	// Create window
	auto window = std::make_shared<AssetEditorWindow>(factory, project, projectWindow);
	window->setAssetSrcMode(srcMode);
	window->loadAsset(name, assetType, true);
	windows.push_back(window);

	// Add to tabs
	pages->addPage()->add(window, 1);
	if (selected) {
		tabs->setSelectedOption(int(tabs->getCount()) - 1);
	}
}

void AssetBrowserTabs::closeTab(const String& key)
{
	const auto idx = tabs->tryGetItemId(key);
	if (idx != -1) {
		pages->removePage(idx);
		windows.erase(windows.begin() + idx);
		tabs->removeItem(key);
		saveTabs();
	}
}

void AssetBrowserTabs::populateTab(UIWidget& tab, std::optional<AssetType> assetType, const String& name, const String& key)
{
	Sprite icon;
	if (assetType) {
		icon = factory.makeAssetTypeIcon(assetType.value());
	} else {
		const auto type = project.getAssetImporter()->getImportAssetType(name, false);
		icon = factory.makeImportAssetTypeIcon(type);
	}
	auto label = LocalisedString::fromUserString(Path(name).getFilename().toString());
	tab.getWidgetAs<UIImage>("icon")->setSprite(icon);
	tab.getWidgetAs<UILabel>("label")->setText(std::move(label));
	tab.setHandle(UIEventType::ButtonClicked, "close", [=] (const UIEvent& event)
	{
		toClose.push_back(key);
	});
}

void AssetBrowserTabs::replaceAssetTab(const String& oldName, const String& newName)
{
	const auto idx = tabs->tryGetItemId(oldName);
	if (idx == -1) {
		return;
	}

	const auto contents = tabs->getItem(idx)->getWidget("tabContents");
	if (contents) {
		tabs->changeItemId(idx, newName);
		populateTab(*contents, {}, newName, newName);
		windows[idx]->loadAsset(newName, {}, true);
		saveTabs();
	}
}

void AssetBrowserTabs::refreshAssets()
{
	for (int i = 0; i < pages->getNumberOfPages(); ++i) {
		auto assetEditor = pages->getPage(i)->getWidgetAs<AssetEditorWindow>("assetEditorWindow");
		assetEditor->refreshAssets();
	}
}

void AssetBrowserTabs::setAssetSrcMode(bool srcMode)
{
	this->srcMode = srcMode;

	if (waitingLoad) {
		waitingLoad = false;
		loadTabs();
	}
}

void AssetBrowserTabs::update(Time t, bool moved)
{
	for (auto& key: toClose) {
		closeTab(key);
	}
	toClose.clear();

	int size = static_cast<int>(windows.size());
	for (int i = 0; i < size; ++i) {
		tabs->getItem(i)->getWidget("modified")->setActive(windows[i]->isModified());
	}
}

void AssetBrowserTabs::makeUI()
{
	add(factory.makeUI("ui/halley/asset_browser_tabs"), 1);
	tabs = getWidgetAs<UIList>("tabs");
	pages = getWidgetAs<UIPagedPane>("pages");

	setHandle(UIEventType::ListSelectionChanged, "tabs", [=] (const UIEvent& event)
	{
		pages->setPage(event.getIntData());
		saveTabs();
	});
}

void AssetBrowserTabs::saveTabs()
{
	ConfigNode::SequenceType tabIds;
	const auto n = tabs->getCount();
	for (int i = 0; i < n; ++i) {
		tabIds.push_back(ConfigNode(tabs->getItem(i)->getId()));
	}

	projectWindow.setSetting(EditorSettingType::Project, "tabsOpen", std::move(tabIds));
	projectWindow.setSetting(EditorSettingType::Project, "currentTab", ConfigNode(tabs->getSelectedOptionId()));
}

void AssetBrowserTabs::loadTabs()
{
	const auto& tabsOpen = projectWindow.getSetting(EditorSettingType::Project, "tabsOpen");
	if (tabsOpen.getType() == ConfigNodeType::Sequence) {
		for (const auto& tab: tabsOpen) {
			auto id = tab.asString();
			auto splitParts = id.split(':');
			if (splitParts.size() == 2) {
				openTab(fromString<AssetType>(splitParts[0]), splitParts[1], false);
			} else if (splitParts.size() == 1) {
				openTab({}, splitParts[0], false);
			}
		}
	}

	const auto curTab = projectWindow.getSetting(EditorSettingType::Project, "currentTab").asString("");
	tabs->setSelectedOptionId(curTab);
}
<|endoftext|>


<commit_before>#pragma once

#include "JoystickService.hpp"

namespace JoystickLibrary
{
#ifdef _WIN32
    enum class Xbox360Button : int
    {
        A = 0,
        B = 1,
        X = 2,
        Y = 3,
        LB = 4,
        RB = 5,
        Back = 6,
        Start = 7,
        LeftThumbstick = 8,
        RightThumbstick = 9
    };
#else
    enum class Xbox360Button : int
    {
        A = BTN_SOUTH,
        B = BTN_EAST,
        X = BTN_NORTH,
        Y = BTN_WEST,
        LB = BTN_TR,
        RB = BTN_TL,
        Back = BTN_SELECT,
        Start = BTN_START,
        LeftThumbstick = BTN_THUMBL,
        RightThumbstick = BTN_THUMBR
    };
#endif

    class Xbox360Service : public JoystickService
    {
    public:
        const std::vector<JoystickDescriptor> XBOX_IDS {
            { 0x045E, 0x028E },	// Microsoft Xbox 360 Controller
            { 0x045E, 0x0291 },	// Microsoft Xbox 360 Wireless Controller
            { 0x0E6F, 0x0213 }	// Afterglow AX.1 for Xbox 360
        };

        const int NUMBER_BUTTONS = 11;

        static Xbox360Service& GetInstance()
        {
            static Xbox360Service instance;
            return instance;
        }

        Xbox360Service(Xbox360Service const&) = delete;
        void operator=(Xbox360Service const&) = delete;
        ~Xbox360Service();

        bool GetLeftX(int joystickID, int& leftX);
        bool GetLeftY(int joystickID, int& leftY);
        bool GetRightX(int joystickID, int& rightX);
        bool GetRightY(int joystickID, int& rightY);
        bool GetLeftTrigger(int joystickID, int& leftTrigger);
        bool GetRightTrigger(int joystickID, int& rightTrigger);
        bool GetDpad(int joystickID, POV& dpad);
        bool GetButton(int joystickID, Xbox360Button button, bool& buttonVal);
        bool GetButtons(int joystickID, std::map<Xbox360Button, bool>& buttons);

    protected:
        void OnDeviceChanged(DeviceStateChange ds);

    private:
        Xbox360Service();
    };
}

<commit_msg>added new xbox controller id<commit_after>#pragma once

#include "JoystickService.hpp"

namespace JoystickLibrary
{
#ifdef _WIN32
    enum class Xbox360Button : int
    {
        A = 0,
        B = 1,
        X = 2,
        Y = 3,
        LB = 4,
        RB = 5,
        Back = 6,
        Start = 7,
        LeftThumbstick = 8,
        RightThumbstick = 9
    };
#else
    enum class Xbox360Button : int
    {
        A = BTN_SOUTH,
        B = BTN_EAST,
        X = BTN_NORTH,
        Y = BTN_WEST,
        LB = BTN_TR,
        RB = BTN_TL,
        Back = BTN_SELECT,
        Start = BTN_START,
        LeftThumbstick = BTN_THUMBL,
        RightThumbstick = BTN_THUMBR
    };
#endif

    class Xbox360Service : public JoystickService
    {
    public:
        const std::vector<JoystickDescriptor> XBOX_IDS {
            { 0x045E, 0x028E },	// Microsoft Xbox 360 Controller
			{ 0x0E6F, 0x0401 },	// Microsoft Xbox 360 Controller
            { 0x045E, 0x0291 },	// Microsoft Xbox 360 Wireless Controller
            { 0x0E6F, 0x0213 }	// Afterglow AX.1 for Xbox 360
        };

        const int NUMBER_BUTTONS = 11;

        static Xbox360Service& GetInstance()
        {
            static Xbox360Service instance;
            return instance;
        }

        Xbox360Service(Xbox360Service const&) = delete;
        void operator=(Xbox360Service const&) = delete;
        ~Xbox360Service();

        bool GetLeftX(int joystickID, int& leftX);
        bool GetLeftY(int joystickID, int& leftY);
        bool GetRightX(int joystickID, int& rightX);
        bool GetRightY(int joystickID, int& rightY);
        bool GetLeftTrigger(int joystickID, int& leftTrigger);
        bool GetRightTrigger(int joystickID, int& rightTrigger);
        bool GetDpad(int joystickID, POV& dpad);
        bool GetButton(int joystickID, Xbox360Button button, bool& buttonVal);
        bool GetButtons(int joystickID, std::map<Xbox360Button, bool>& buttons);

    protected:
        void OnDeviceChanged(DeviceStateChange ds);

    private:
        Xbox360Service();
    };
}

<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 *
 * plan_executor.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/bridge/plan_executor.cpp
 *
 *-------------------------------------------------------------------------
 */

#include "plan_executor.h"
#include <cassert>

#include "backend/bridge/dml/mapper/mapper.h"
#include "backend/bridge/dml/tuple/tuple_transformer.h"
#include "backend/common/logger.h"
#include "backend/concurrency/transaction_manager.h"
#include "backend/executor/executors.h"
#include "backend/storage/tile_iterator.h"

#include "access/tupdesc.h"
#include "nodes/print.h"
#include "utils/memutils.h"

namespace peloton {
namespace bridge {

executor::AbstractExecutor *BuildExecutorTree(executor::AbstractExecutor *root,
                                              planner::AbstractPlanNode *plan,
                                              PlanState *planstate,
                                              concurrency::Transaction *txn);

void CleanExecutorTree(executor::AbstractExecutor *root);

/**
 * @brief Pretty print the plan tree.
 * @param The plan tree
 * @return none.
 */
void PlanExecutor::PrintPlan(const planner::AbstractPlanNode *plan, std::string prefix) {
  if(plan == nullptr)
    return;

  prefix += "  ";

  LOG_INFO("%s->Plan Type :: %d ", prefix.c_str(), plan->GetPlanNodeType());

  auto children = plan->GetChildren();

  for(auto child : children) {
    PrintPlan(child, prefix);
  }

}

/**
 * @brief Build the executor tree.
 * @param The current executor tree
 * @param The plan tree
 * @param Transation context
 * @return The updated executor tree.
 */
executor::AbstractExecutor *BuildExecutorTree(executor::AbstractExecutor *root,
                                              planner::AbstractPlanNode *plan,
                                              PlanState *planstate,
                                              concurrency::Transaction *txn) {
  // Base case
  if(plan == nullptr)
    return root;

  executor::AbstractExecutor *child_executor = nullptr;

  // TODO: Set params
  assert(planstate);
  assert(planstate->state);

  const ParamListInfo param_list = planstate->state->es_param_list_info;
  ValueArray params = PlanTransformer::BuildParams(param_list);

  executor::ExecutorContext *executor_context = new executor::ExecutorContext(txn,
                                                                              params);

  auto plan_node_type = plan->GetPlanNodeType();
  switch(plan_node_type) {
    case PLAN_NODE_TYPE_INVALID:
      LOG_ERROR("Invalid plan node type ");
      break;

    case PLAN_NODE_TYPE_SEQSCAN:
      child_executor = new executor::SeqScanExecutor(plan, executor_context);
      break;

    case PLAN_NODE_TYPE_INDEXSCAN:
      child_executor = new executor::IndexScanExecutor(plan, executor_context);
      break;

    case PLAN_NODE_TYPE_INSERT:
      child_executor = new executor::InsertExecutor(plan, executor_context);
      break;

    case PLAN_NODE_TYPE_DELETE:
      child_executor = new executor::DeleteExecutor(plan, executor_context);
      break;

    case PLAN_NODE_TYPE_UPDATE:
      child_executor = new executor::UpdateExecutor(plan, executor_context);
      break;

    case PLAN_NODE_TYPE_LIMIT:
      child_executor = new executor::LimitExecutor(plan);
      break;

    default:
      LOG_INFO("Unsupported plan node type : %d ", plan_node_type);
      break;
  }

  // Base case
  if(child_executor != nullptr) {
    if(root != nullptr)
      root->AddChild(child_executor);
    else
      root = child_executor;
  }

  // Recurse
  auto children = plan->GetChildren();
  for(auto child : children) {
    child_executor = BuildExecutorTree(child_executor, child, planstate, txn);
  }

  return root;
}

/**
 * @brief Clean up the executor tree.
 * @param The current executor tree
 * @return none.
 */
void CleanExecutorTree(executor::AbstractExecutor *root){
  if(root == nullptr)
    return;

  // Recurse
  auto children = root->GetChildren();
  for(auto child : children) {
    CleanExecutorTree(child);
  }

  // Cleanup self
  delete root;
}

/**
 * @brief Add a Materialization node if the root of the exector tree is seqscan or limit
 * @param the current executor tree
 * @return new root of the executor tree
 */
executor::AbstractExecutor *PlanExecutor::AddMaterialization(executor::AbstractExecutor *root) {
  if (root == nullptr) return root;
  auto type = root->GetRawNode()->GetPlanNodeType();
  executor::AbstractExecutor *new_root = root;

  switch (type) {
    case PLAN_NODE_TYPE_SEQSCAN:
    case PLAN_NODE_TYPE_INDEXSCAN:
      /* FALL THRU */
    case PLAN_NODE_TYPE_LIMIT:
      new_root = new executor::MaterializationExecutor(nullptr);
      new_root->AddChild(root);
      LOG_INFO("Added materialization, the original root executor type is %d", type);
      break;
    default:
      break;
  }

  return new_root;
}

/**
 * @brief Build a executor tree and execute it.
 * @return status of execution.
 */
bool PlanExecutor::ExecutePlan(planner::AbstractPlanNode *plan,
                               PlanState *planstate,
                               TupleDesc tuple_desc,
                               Peloton_Status *pstatus,
                               TransactionId txn_id) {

  assert(plan);

  bool status;
  bool single_statement_txn = false;
  MemoryContext oldContext;
  List *slots = NULL;

  auto& txn_manager = concurrency::TransactionManager::GetInstance();
  auto txn = txn_manager.GetPGTransaction(txn_id);
  // This happens for single statement queries in PG
  if(txn == nullptr) {
    single_statement_txn = true;
    txn = txn_manager.StartPGTransaction(txn_id);
  }
  assert(txn);

  LOG_TRACE("Building the executor tree");

  // Build the executor tree
  executor::AbstractExecutor *executor_tree = BuildExecutorTree(nullptr,
                                                                plan,
                                                                planstate,
                                                                txn);
  // Add materialization if the root if seqscan or limit
  executor_tree = AddMaterialization(executor_tree);

  LOG_TRACE("Initializing the executor tree");

  // Initialize the executor tree
  status = executor_tree->Init();

  // Abort and cleanup
  if(status == false) {
    txn_manager.AbortTransaction(txn);
    txn_manager.EndTransaction(txn);

    CleanExecutorTree(executor_tree);

    return false;
  }

  LOG_TRACE("Running the executor tree");

  // Execute the tree until we get result tiles from root node
  for(;;) {
    status = executor_tree->Execute();

    // Stop
    if(status == false) {
      break;
    }

    std::unique_ptr<executor::LogicalTile> tile(executor_tree->GetOutput());

    // FIXME Some executor just doesn't return tiles (e.g., Update).
    // Should we continue instead of break here?
    if(tile.get() == nullptr) {
      break;
    }

    // Get result base tile and iterate over it
    auto base_tile = tile.get()->GetBaseTile(0);
    assert(base_tile);
    storage::TileIterator tile_itr(base_tile);
    storage::Tuple tuple(base_tile->GetSchema());

    // Switch to TopSharedMemoryContext to construct list and slots
    oldContext = MemoryContextSwitchTo(TopSharedMemoryContext);

    // Go over tile and get result slots
    while (tile_itr.Next(tuple)) {
      //std::cout << tuple;
      auto slot = TupleTransformer::GetPostgresTuple(&tuple, tuple_desc);
      slots = lappend(slots, slot);
    }

    // Go back to previous context
    MemoryContextSwitchTo(oldContext);
  }

  pstatus->m_result_slots = slots;

  if(single_statement_txn == true) {
    // Commit
    try {
      txn_manager.CommitTransaction(txn);
      txn_manager.EndTransaction(txn);
    }
    catch(...){
      LOG_WARN("Could not commit transaction \n");
    }
  }

  // clean up
  CleanExecutorTree(executor_tree);

  return true;
}

}  // namespace bridge
}  // namespace peloton

<commit_msg>Add PlanTransformer support for other scan type as a child of Update<commit_after>/*-------------------------------------------------------------------------
 *
 * plan_executor.cpp
 * file description
 *
 * Copyright(c) 2015, CMU
 *
 * /peloton/src/backend/bridge/plan_executor.cpp
 *
 *-------------------------------------------------------------------------
 */

#include "plan_executor.h"
#include <cassert>

#include "backend/bridge/dml/mapper/mapper.h"
#include "backend/bridge/dml/tuple/tuple_transformer.h"
#include "backend/common/logger.h"
#include "backend/concurrency/transaction_manager.h"
#include "backend/executor/executors.h"
#include "backend/storage/tile_iterator.h"

#include "access/tupdesc.h"
#include "nodes/print.h"
#include "utils/memutils.h"

namespace peloton {
namespace bridge {

executor::AbstractExecutor *BuildExecutorTree(executor::AbstractExecutor *root,
                                              planner::AbstractPlanNode *plan,
                                              PlanState *planstate,
                                              concurrency::Transaction *txn);

void CleanExecutorTree(executor::AbstractExecutor *root);

/**
 * @brief Pretty print the plan tree.
 * @param The plan tree
 * @return none.
 */
void PlanExecutor::PrintPlan(const planner::AbstractPlanNode *plan, std::string prefix) {
  if(plan == nullptr)
    return;

  prefix += "  ";

  LOG_INFO("%s->Plan Type :: %d ", prefix.c_str(), plan->GetPlanNodeType());

  auto children = plan->GetChildren();

  for(auto child : children) {
    PrintPlan(child, prefix);
  }

}

/**
 * @brief Build the executor tree.
 * @param The current executor tree
 * @param The plan tree
 * @param Transation context
 * @return The updated executor tree.
 */
executor::AbstractExecutor *BuildExecutorTree(executor::AbstractExecutor *root,
                                              planner::AbstractPlanNode *plan,
                                              PlanState *planstate,
                                              concurrency::Transaction *txn) {
  // Base case
  if(plan == nullptr)
    return root;

  executor::AbstractExecutor *child_executor = nullptr;

  // TODO: Set params
  assert(planstate);
  assert(planstate->state);

  const ParamListInfo param_list = planstate->state->es_param_list_info;
  ValueArray params = PlanTransformer::BuildParams(param_list);

  executor::ExecutorContext *executor_context = new executor::ExecutorContext(txn,
                                                                              params);

  auto plan_node_type = plan->GetPlanNodeType();
  switch(plan_node_type) {
    case PLAN_NODE_TYPE_INVALID:
      LOG_ERROR("Invalid plan node type ");
      break;

    case PLAN_NODE_TYPE_SEQSCAN:
      child_executor = new executor::SeqScanExecutor(plan, executor_context);
      break;

    case PLAN_NODE_TYPE_INDEXSCAN:
      child_executor = new executor::IndexScanExecutor(plan, executor_context);
      break;

    case PLAN_NODE_TYPE_INSERT:
      child_executor = new executor::InsertExecutor(plan, executor_context);
      break;

    case PLAN_NODE_TYPE_DELETE:
      child_executor = new executor::DeleteExecutor(plan, executor_context);
      break;

    case PLAN_NODE_TYPE_UPDATE:
      child_executor = new executor::UpdateExecutor(plan, executor_context);
      break;

    case PLAN_NODE_TYPE_LIMIT:
      child_executor = new executor::LimitExecutor(plan);
      break;

    default:
      LOG_INFO("Unsupported plan node type : %d ", plan_node_type);
      break;
  }

  // Base case
  if(child_executor != nullptr) {
    if(root != nullptr)
      root->AddChild(child_executor);
    else
      root = child_executor;
  }

  // Recurse
  auto children = plan->GetChildren();
  for(auto child : children) {
    child_executor = BuildExecutorTree(child_executor, child, planstate, txn);
  }

  return root;
}

/**
 * @brief Clean up the executor tree.
 * @param The current executor tree
 * @return none.
 */
void CleanExecutorTree(executor::AbstractExecutor *root){
  if(root == nullptr)
    return;

  // Recurse
  auto children = root->GetChildren();
  for(auto child : children) {
    CleanExecutorTree(child);
  }

  // Cleanup self
  delete root;
}

/**
 * @brief Add a Materialization node if the root of the exector tree is seqscan or limit
 * @param the current executor tree
 * @return new root of the executor tree
 */
executor::AbstractExecutor *PlanExecutor::AddMaterialization(executor::AbstractExecutor *root) {
  if (root == nullptr) return root;
  auto type = root->GetRawNode()->GetPlanNodeType();
  executor::AbstractExecutor *new_root = root;

  switch (type) {
    case PLAN_NODE_TYPE_SEQSCAN:
    case PLAN_NODE_TYPE_INDEXSCAN:
      /* FALL THRU */
    case PLAN_NODE_TYPE_LIMIT:
      new_root = new executor::MaterializationExecutor(nullptr);
      new_root->AddChild(root);
      LOG_INFO("Added materialization, the original root executor type is %d", type);
      break;
    default:
      break;
  }

  return new_root;
}

/**
 * @brief Build a executor tree and execute it.
 * @return status of execution.
 */
bool PlanExecutor::ExecutePlan(planner::AbstractPlanNode *plan,
                               PlanState *planstate,
                               TupleDesc tuple_desc,
                               Peloton_Status *pstatus,
                               TransactionId txn_id) {

  assert(plan);
  assert(tuple_desc->tdrefcount == -1); // Should Not  be refcounting?

  bool status;
  bool single_statement_txn = false;
  MemoryContext oldContext;
  List *slots = NULL;

  auto& txn_manager = concurrency::TransactionManager::GetInstance();
  auto txn = txn_manager.GetPGTransaction(txn_id);
  // This happens for single statement queries in PG
  if(txn == nullptr) {
    single_statement_txn = true;
    txn = txn_manager.StartPGTransaction(txn_id);
  }
  assert(txn);

  LOG_TRACE("Building the executor tree");

  // Build the executor tree
  executor::AbstractExecutor *executor_tree = BuildExecutorTree(nullptr,
                                                                plan,
                                                                planstate,
                                                                txn);
  // Add materialization if the root if seqscan or limit
  executor_tree = AddMaterialization(executor_tree);

  LOG_TRACE("Initializing the executor tree");

  // Initialize the executor tree
  status = executor_tree->Init();

  // Abort and cleanup
  if(status == false) {
    txn_manager.AbortTransaction(txn);
    txn_manager.EndTransaction(txn);

    CleanExecutorTree(executor_tree);

    return false;
  }

  LOG_TRACE("Running the executor tree");

  // Execute the tree until we get result tiles from root node
  for(;;) {
    status = executor_tree->Execute();

    // Stop
    if(status == false) {
      break;
    }

    std::unique_ptr<executor::LogicalTile> tile(executor_tree->GetOutput());

    // FIXME Some executor just doesn't return tiles (e.g., Update).
    // Should we continue instead of break here?
    if(tile.get() == nullptr) {
      break;
    }

    // Get result base tile and iterate over it
    auto base_tile = tile.get()->GetBaseTile(0);
    assert(base_tile);
    storage::TileIterator tile_itr(base_tile);
    storage::Tuple tuple(base_tile->GetSchema());

    // Switch to TopSharedMemoryContext to construct list and slots
    oldContext = MemoryContextSwitchTo(TopSharedMemoryContext);

    // Go over tile and get result slots
    while (tile_itr.Next(tuple)) {
      //std::cout << tuple;
      auto slot = TupleTransformer::GetPostgresTuple(&tuple, tuple_desc);
      slots = lappend(slots, slot);
    }

    // Go back to previous context
    MemoryContextSwitchTo(oldContext);
  }

  pstatus->m_result_slots = slots;

  if(single_statement_txn == true) {
    // Commit
    try {
      txn_manager.CommitTransaction(txn);
      txn_manager.EndTransaction(txn);
    }
    catch(...){
      LOG_WARN("Could not commit transaction \n");
    }
  }

  // clean up
  CleanExecutorTree(executor_tree);

  return true;
}

}  // namespace bridge
}  // namespace peloton

<|endoftext|>


<commit_before>/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.
*/

#include <Hord/aux.hpp>
#include <Hord/utility.hpp>
#include <Hord/Log.hpp>
#include <Hord/IO/Defs.hpp>
#include <Hord/Object/Defs.hpp>
#include <Hord/Object/Unit.hpp>
#include <Hord/Object/Ops.hpp>
#include <Hord/Cmd/Object.hpp>

#include <exception>

#include <Hord/detail/gr_core.hpp>

namespace Hord {
namespace Cmd {
namespace Object {

#define HORD_SCOPE_CLASS Cmd::Object::SetParent

#define HORD_SCOPE_FUNC exec // pseudo
HORD_SCOPE_CLASS::exec_result_type
HORD_SCOPE_CLASS::operator()(
	Hord::Object::Unit& object,
	Hord::Object::ID const new_parent
) noexcept try {
	m_object_id = object.get_id();

	// TODO: Check for collision in parent children
	auto& datastore = get_datastore();
	if (object.get_id() == new_parent) {
		return commit_error("object cannot be a child of itself");
	} else if (object.get_parent() == new_parent) {
		// NB: Circumvents Object::set_parent() making the parent ID_NULL
		return commit_with(Cmd::Result::success_no_action);
	}
	bool const success = Hord::Object::set_parent(object, datastore, new_parent);
	auto const end = datastore.get_root_objects().end();
	auto const it = datastore.get_root_objects().find(object.get_id());
	if (object.get_parent().is_null()) {
		if (it == end) {
			datastore.get_root_objects().emplace(object.get_id());
		}
	} else if (it != end) {
		datastore.get_root_objects().erase(it);
	}
	if (success) {
		return commit();
	} else {
		return commit_error("Object::set_parent() failed");
	}
} catch (...) {
	notify_exception_current();
	return commit_error("unknown error");
}
#undef HORD_SCOPE_FUNC

#undef HORD_SCOPE_CLASS

} // namespace Object
} // namespace Cmd
} // namespace Hord
<commit_msg>Cmd::Object::SetParent: check for parent existence and slug collision.<commit_after>/**
@copyright MIT license; see @ref index or the accompanying LICENSE file.
*/

#include <Hord/aux.hpp>
#include <Hord/utility.hpp>
#include <Hord/Log.hpp>
#include <Hord/IO/Defs.hpp>
#include <Hord/Object/Defs.hpp>
#include <Hord/Object/Unit.hpp>
#include <Hord/Object/Ops.hpp>
#include <Hord/Cmd/Object.hpp>

#include <exception>

#include <Hord/detail/gr_core.hpp>

namespace Hord {
namespace Cmd {
namespace Object {

#define HORD_SCOPE_CLASS Cmd::Object::SetParent

#define HORD_SCOPE_FUNC exec // pseudo
HORD_SCOPE_CLASS::exec_result_type
HORD_SCOPE_CLASS::operator()(
	Hord::Object::Unit& object,
	Hord::Object::ID const new_parent
) noexcept try {
	m_object_id = object.get_id();

	auto& datastore = get_datastore();
	auto const* parent_obj = datastore.find_ptr(new_parent);
	if (object.get_id() == new_parent) {
		return commit_error("cannot parent object to itself");
	} else if (object.get_parent() == new_parent) {
		// NB: Circumvents Object::set_parent() making the parent ID_NULL
		return commit_with(Cmd::Result::success_no_action);
	} else if (!new_parent.is_null() && !parent_obj) {
		return commit_error("new parent does not exist");
	} else if (parent_obj) {
		auto const& parent_children = parent_obj ? parent_obj->get_children() : datastore.get_root_objects();
		for (auto child_id : parent_children) {
			auto child_obj = datastore.find_ptr(child_id);
			if (child_obj && object.get_slug() == child_obj->get_slug()) {
				return commit_error("slug would not be unique in new parent");
			}
		}
	}

	bool const success = Hord::Object::set_parent(object, datastore, new_parent);
	auto const end = datastore.get_root_objects().end();
	auto const it = datastore.get_root_objects().find(object.get_id());
	if (object.get_parent().is_null()) {
		if (it == end) {
			datastore.get_root_objects().emplace(object.get_id());
		}
	} else if (it != end) {
		datastore.get_root_objects().erase(it);
	}
	if (success) {
		return commit();
	} else {
		return commit_error("Object::set_parent() failed");
	}
} catch (...) {
	notify_exception_current();
	return commit_error("unknown error");
}
#undef HORD_SCOPE_FUNC

#undef HORD_SCOPE_CLASS

} // namespace Object
} // namespace Cmd
} // namespace Hord
<|endoftext|>


<commit_before>/// @file
/// @version 3.5
///
/// @section LICENSE
///
/// This program is free software; you can redistribute it and/or modify it under
/// the terms of the BSD license: http://opensource.org/licenses/BSD-3-Clause

#ifdef _WINRT_WINDOW
#include "pch.h"

#include <hltypes/hlog.h>
#include <hltypes/hstring.h>

#include "april.h"
#include "WinRT_XamlOverlay.xaml.h"

using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Markup;

// the textbox is manually created, because on some hardware the software keyboard won't appear if a static XAML textbox is used
#define XAML_TEXT_BOX "<TextBox \
	xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" \
	xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" \
	x:Name=\"keyboardTextbox\"\
	IsHitTestVisible=\"False\" \
	IsTextPredictionEnabled=\"False\" \
	Background=\"{x:Null}\" \
	BorderBrush=\"{x:Null}\" \
	Foreground=\"{x:Null}\" \
	Opacity=\"0\"/>"

namespace april
{
	static UIElement^ _loadFromXaml(chstr xaml)
	{
		hstr hXaml = xaml;
		if ((unsigned char)hXaml[0] == 0xEF && (unsigned char)hXaml[1] == 0xBB && (unsigned char)hXaml[2] == 0xBF) // remove BOM
		{
			hXaml = hXaml(3, -1);
		}
		return (UIElement^)XamlReader::Load(_HL_HSTR_TO_PSTR(hXaml));
	}

	WinRT_XamlOverlay::WinRT_XamlOverlay()
	{
		this->InitializeComponent();
		this->keyboardTextbox = nullptr;
		this->hideKeyboard();
	}

	void WinRT_XamlOverlay::showKeyboard()
	{
		this->hideKeyboard(); // this is required, because this method can be called from a touch-down event which will not display the keyboard the call after
		this->keyboardTextbox = (TextBox^)_loadFromXaml(XAML_TEXT_BOX);
		if (this->keyboardTextbox != nullptr)
		{
			this->Children->Append(this->keyboardTextbox);
			this->keyboardTextbox->Focus(FocusState::Programmatic);
		}
	}

	void WinRT_XamlOverlay::hideKeyboard()
	{
		if (this->Children->Size > 0)
		{
			this->Children->RemoveAt(0);
			this->keyboardTextbox = nullptr;
		}
	}

}
#endif
<commit_msg>- small WinRT fix<commit_after>/// @file
/// @version 3.5
///
/// @section LICENSE
///
/// This program is free software; you can redistribute it and/or modify it under
/// the terms of the BSD license: http://opensource.org/licenses/BSD-3-Clause

#ifdef _WINRT_WINDOW
#include "pch.h"

#include <hltypes/hlog.h>
#include <hltypes/hstring.h>

#include "april.h"
#include "WinRT_XamlOverlay.xaml.h"

using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Markup;

// the textbox is manually created, because on some hardware the software keyboard won't appear if a static XAML textbox is used
#define XAML_TEXT_BOX "<TextBox \
	xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" \
	xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" \
	x:Name=\"keyboardTextbox\" \
	IsHitTestVisible=\"False\" \
	IsTextPredictionEnabled=\"False\" \
	Background=\"{x:Null}\" \
	BorderBrush=\"{x:Null}\" \
	Foreground=\"{x:Null}\" \
	Opacity=\"0\"/>"

namespace april
{
	static UIElement^ _loadFromXaml(chstr xaml)
	{
		hstr hXaml = xaml;
		if ((unsigned char)hXaml[0] == 0xEF && (unsigned char)hXaml[1] == 0xBB && (unsigned char)hXaml[2] == 0xBF) // remove BOM
		{
			hXaml = hXaml(3, -1);
		}
		return (UIElement^)XamlReader::Load(_HL_HSTR_TO_PSTR(hXaml));
	}

	WinRT_XamlOverlay::WinRT_XamlOverlay()
	{
		this->InitializeComponent();
		this->keyboardTextbox = nullptr;
		this->hideKeyboard();
	}

	void WinRT_XamlOverlay::showKeyboard()
	{
		this->hideKeyboard(); // first destroy the already existing textbox
		this->keyboardTextbox = (TextBox^)_loadFromXaml(XAML_TEXT_BOX);
		if (this->keyboardTextbox != nullptr)
		{
			this->Children->Append(this->keyboardTextbox);
			this->keyboardTextbox->Focus(FocusState::Programmatic);
		}
	}

	void WinRT_XamlOverlay::hideKeyboard()
	{
		if (this->Children->Size > 0)
		{
			unsigned int index = -1;
			if (this->Children->IndexOf(this->keyboardTextbox, &index))
			{
				this->Children->RemoveAt(index);
			}
			this->keyboardTextbox = nullptr;
		}
	}

}
#endif
<|endoftext|>


<commit_before>/******************************************************************************
 *   Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
 *                                                                            *
 *   This file is part of the FreeCAD CAx development system.                 *
 *                                                                            *
 *   This library is free software; you can redistribute it and/or            *
 *   modify it under the terms of the GNU Library General Public              *
 *   License as published by the Free Software Foundation; either             *
 *   version 2 of the License, or (at your option) any later version.         *
 *                                                                            *
 *   This library  is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *   GNU Library General Public License for more details.                     *
 *                                                                            *
 *   You should have received a copy of the GNU Library General Public        *
 *   License along with this library; see the file COPYING.LIB. If not,       *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,            *
 *   Suite 330, Boston, MA  02111-1307, USA                                   *
 *                                                                            *
 ******************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <QPixmap>
# include <QDialog>
# include <QListIterator>
#endif

#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
#include <Gui/MainWindow.h>
#include <Gui/Document.h>
#include <Gui/ViewProviderOrigin.h>
#include <App/Document.h>
#include <Base/Tools.h>

#include "ui_TaskFeaturePick.h"
#include "TaskFeaturePick.h"

using namespace PartDesignGui;

const QString TaskFeaturePick::getFeatureStatusString(const featureStatus st)
{
    switch (st) {
        case validFeature: return tr("Valid");
        case invalidShape: return tr("Invalid shape");
        case noWire: return tr("No wire in sketch");
        case isUsed: return tr("Sketch already used by other feature");
        case otherBody: return tr("Sketch belongs to another Body feature");
        case basePlane: return tr("Base plane");
        case afterTip: return tr("Feature is located after the Tip feature");
    }

    return tr("");
}

TaskFeaturePick::TaskFeaturePick(std::vector<App::DocumentObject*>& objects,
                                     const std::vector<featureStatus>& status,
                                     QWidget* parent)
  : TaskBox(Gui::BitmapFactory().pixmap("edit-select-box"),
            QString::fromAscii("Select feature"), true, parent), ui(new Ui_TaskFeaturePick)
{

    proxy = new QWidget(this);
    ui->setupUi(proxy);

    connect(ui->checkReverse, SIGNAL(toggled(bool)), this, SLOT(onCheckReverse(bool)));
    connect(ui->checkOtherBody, SIGNAL(toggled(bool)), this, SLOT(onCheckOtherBody(bool)));
    connect(ui->checkOtherFeature, SIGNAL(toggled(bool)), this, SLOT(onCheckOtherFeature(bool)));
    connect(ui->radioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
    connect(ui->radioDependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
    connect(ui->radioXRef, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));

    ui->checkReverse->setChecked(false);
    ui->checkOtherBody->setChecked(true);
    ui->checkOtherBody->setEnabled(false); // TODO: implement
    ui->checkOtherFeature->setChecked(false);
    ui->checkOtherFeature->setEnabled(false); // TODO: implement
    ui->radioIndependent->setChecked(true);
    ui->radioIndependent->setEnabled(false);
    // These are not implemented yet
    ui->radioDependent->setEnabled(false);
    ui->radioXRef->setEnabled(false);

    auto guidoc = Gui::Application::Instance->activeDocument();
    auto origin_obj = App::GetApplication().getActiveDocument()->getObjectsOfType<App::Origin>();

    std::vector<featureStatus>::const_iterator st = status.begin();
    for (std::vector<App::DocumentObject*>::const_iterator o = objects.begin(); o != objects.end(); o++) {
        QListWidgetItem* item = new QListWidgetItem(QString::fromAscii((*o)->getNameInDocument()) +
                                                    QString::fromAscii(" (") + getFeatureStatusString(*st) + QString::fromAscii(")"));
        ui->listWidget->addItem(item);
        st++;

        //check if we need to set any origin in temporary visibility mode
        for(App::Origin* obj : origin_obj) {
            if(obj->hasObject(*o)) {
                Gui::ViewProviderOrigin* vpo = static_cast<Gui::ViewProviderOrigin*>(guidoc->getViewProvider(obj));
                if(!vpo->isTemporaryVisibilityMode())
                    vpo->setTemporaryVisibilityMode(true, guidoc);

                vpo->setTemporaryVisibility(*o, true);
                origins.push_back(vpo);
                break;
            }
        }
    }

    groupLayout()->addWidget(proxy);
    statuses = status;
    updateList();
}

TaskFeaturePick::~TaskFeaturePick()
{
    for(Gui::ViewProviderOrigin* vpo : origins)
        vpo->setTemporaryVisibilityMode(false, NULL);

}

void TaskFeaturePick::updateList()
{
    int index = 0;

    //get all origins in temporary mode

    for (std::vector<featureStatus>::const_iterator st = statuses.begin(); st != statuses.end(); st++) {
        QListWidgetItem* item = ui->listWidget->item(index);

        switch (*st) {
            case validFeature: item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); break;
            case invalidShape: item->setFlags(Qt::NoItemFlags); break;
            case noWire: item->setFlags(Qt::NoItemFlags); break;
            case isUsed: item->setFlags(ui->checkOtherFeature->isChecked() ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags); break;
            case otherBody: item->setFlags(ui->checkOtherBody->isChecked() ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags); break;
            case basePlane: item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); break;
            case afterTip: item->setFlags(Qt::NoItemFlags); break;
        }

        index++;
    }
}

void TaskFeaturePick::onCheckReverse(bool checked)
{
}

void TaskFeaturePick::onCheckOtherFeature(bool checked)
{
    ui->radioIndependent->setEnabled(checked);
    // TODO: Not implemented yet
    //ui->radioDependent->setEnabled(checked);
    //ui->radioXRef->setEnabled(checked);

    updateList();
}

void TaskFeaturePick::onCheckOtherBody(bool checked)
{
    ui->radioIndependent->setEnabled(checked);
    // TODO: Not implemented yet
    //ui->radioDependent->setEnabled(checked);
    //ui->radioXRef->setEnabled(checked);

    updateList();
}

void TaskFeaturePick::onUpdate(bool)
{
    updateList();
}

bool TaskFeaturePick::getReverse()
{
    return ui->checkReverse->isChecked();
}

std::vector<App::DocumentObject*> TaskFeaturePick::getFeatures() {

    features.clear();
    QListIterator<QListWidgetItem*> i(ui->listWidget->selectedItems());
    while (i.hasNext()) {
        QString t = i.next()->text();
        t = t.left(t.indexOf(QString::fromAscii("(")) - 1);
        features.push_back(t);
    }

    std::vector<App::DocumentObject*> result;

    for (std::vector<QString>::const_iterator s = features.begin(); s != features.end(); s++)
        result.push_back(App::GetApplication().getActiveDocument()->getObject(s->toAscii().data()));

    return result;
}

void TaskFeaturePick::onSelectionChanged(const Gui::SelectionChanges& msg)
{
    ui->listWidget->clearSelection();
    for(Gui::SelectionSingleton::SelObj obj :  Gui::Selection().getSelection()) {

        for(int row = 0; row < ui->listWidget->count(); row++) {

            QListWidgetItem *item = ui->listWidget->item(row);
            QString t = item->text();
            t = t.left(t.indexOf(QString::fromAscii("(")) - 1);
            if(t.compare(QString::fromAscii(obj.FeatName))==0) {
                ui->listWidget->setItemSelected(item, true);
            }
        }
    }

}

//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

TaskDlgFeaturePick::TaskDlgFeaturePick(std::vector<App::DocumentObject*> &objects,
                                        const std::vector<TaskFeaturePick::featureStatus> &status,
                                        boost::function<bool (std::vector<App::DocumentObject*>)> afunc,
                                        boost::function<void (std::vector<App::DocumentObject*>)> wfunc)
    : TaskDialog(), accepted(false)
{
    pick  = new TaskFeaturePick(objects, status);
    Content.push_back(pick);

    acceptFunction = afunc;
    workFunction = wfunc;
}

TaskDlgFeaturePick::~TaskDlgFeaturePick()
{
    //do the work now as before in accept() the dialog is still open, hence the work
    //function could not open annother dialog
    if(accepted)
        workFunction(pick->getFeatures());
}

//==== calls from the TaskView ===============================================================

void TaskDlgFeaturePick::open()
{

}

void TaskDlgFeaturePick::clicked(int)
{

}

bool TaskDlgFeaturePick::accept()
{
    accepted = acceptFunction(pick->getFeatures());

    return accepted;
}

bool TaskDlgFeaturePick::reject()
{
    accepted = false;
    return true;
}

#include "moc_TaskFeaturePick.cpp"
<commit_msg>assert before crashing<commit_after>/******************************************************************************
 *   Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
 *                                                                            *
 *   This file is part of the FreeCAD CAx development system.                 *
 *                                                                            *
 *   This library is free software; you can redistribute it and/or            *
 *   modify it under the terms of the GNU Library General Public              *
 *   License as published by the Free Software Foundation; either             *
 *   version 2 of the License, or (at your option) any later version.         *
 *                                                                            *
 *   This library  is distributed in the hope that it will be useful,         *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *   GNU Library General Public License for more details.                     *
 *                                                                            *
 *   You should have received a copy of the GNU Library General Public        *
 *   License along with this library; see the file COPYING.LIB. If not,       *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,            *
 *   Suite 330, Boston, MA  02111-1307, USA                                   *
 *                                                                            *
 ******************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <QPixmap>
# include <QDialog>
# include <QListIterator>
#endif

#include <Gui/Application.h>
#include <Gui/BitmapFactory.h>
#include <Gui/MainWindow.h>
#include <Gui/Document.h>
#include <Gui/ViewProviderOrigin.h>
#include <App/Document.h>
#include <Base/Tools.h>

#include "ui_TaskFeaturePick.h"
#include "TaskFeaturePick.h"

using namespace PartDesignGui;

const QString TaskFeaturePick::getFeatureStatusString(const featureStatus st)
{
    switch (st) {
        case validFeature: return tr("Valid");
        case invalidShape: return tr("Invalid shape");
        case noWire: return tr("No wire in sketch");
        case isUsed: return tr("Sketch already used by other feature");
        case otherBody: return tr("Sketch belongs to another Body feature");
        case basePlane: return tr("Base plane");
        case afterTip: return tr("Feature is located after the Tip feature");
    }

    return tr("");
}

TaskFeaturePick::TaskFeaturePick(std::vector<App::DocumentObject*>& objects,
                                     const std::vector<featureStatus>& status,
                                     QWidget* parent)
  : TaskBox(Gui::BitmapFactory().pixmap("edit-select-box"),
            QString::fromAscii("Select feature"), true, parent), ui(new Ui_TaskFeaturePick)
{

    proxy = new QWidget(this);
    ui->setupUi(proxy);

    connect(ui->checkReverse, SIGNAL(toggled(bool)), this, SLOT(onCheckReverse(bool)));
    connect(ui->checkOtherBody, SIGNAL(toggled(bool)), this, SLOT(onCheckOtherBody(bool)));
    connect(ui->checkOtherFeature, SIGNAL(toggled(bool)), this, SLOT(onCheckOtherFeature(bool)));
    connect(ui->radioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
    connect(ui->radioDependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
    connect(ui->radioXRef, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));

    ui->checkReverse->setChecked(false);
    ui->checkOtherBody->setChecked(true);
    ui->checkOtherBody->setEnabled(false); // TODO: implement
    ui->checkOtherFeature->setChecked(false);
    ui->checkOtherFeature->setEnabled(false); // TODO: implement
    ui->radioIndependent->setChecked(true);
    ui->radioIndependent->setEnabled(false);
    // These are not implemented yet
    ui->radioDependent->setEnabled(false);
    ui->radioXRef->setEnabled(false);

    auto guidoc = Gui::Application::Instance->activeDocument();
    auto origin_obj = App::GetApplication().getActiveDocument()->getObjectsOfType<App::Origin>();

    assert(status.size() == objects.size());
    std::vector<featureStatus>::const_iterator st = status.begin();
    for (std::vector<App::DocumentObject*>::const_iterator o = objects.begin(); o != objects.end(); o++) {
        QListWidgetItem* item = new QListWidgetItem(QString::fromAscii((*o)->getNameInDocument()) +
                                                    QString::fromAscii(" (") + getFeatureStatusString(*st) + QString::fromAscii(")"));
        ui->listWidget->addItem(item);
        st++;

        //check if we need to set any origin in temporary visibility mode
        for(App::Origin* obj : origin_obj) {
            if(obj->hasObject(*o)) {
                Gui::ViewProviderOrigin* vpo = static_cast<Gui::ViewProviderOrigin*>(guidoc->getViewProvider(obj));
                if(!vpo->isTemporaryVisibilityMode())
                    vpo->setTemporaryVisibilityMode(true, guidoc);

                vpo->setTemporaryVisibility(*o, true);
                origins.push_back(vpo);
                break;
            }
        }
    }

    groupLayout()->addWidget(proxy);
    statuses = status;
    updateList();
}

TaskFeaturePick::~TaskFeaturePick()
{
    for(Gui::ViewProviderOrigin* vpo : origins)
        vpo->setTemporaryVisibilityMode(false, NULL);

}

void TaskFeaturePick::updateList()
{
    int index = 0;

    //get all origins in temporary mode

    for (std::vector<featureStatus>::const_iterator st = statuses.begin(); st != statuses.end(); st++) {
        QListWidgetItem* item = ui->listWidget->item(index);

        switch (*st) {
            case validFeature: item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); break;
            case invalidShape: item->setFlags(Qt::NoItemFlags); break;
            case noWire: item->setFlags(Qt::NoItemFlags); break;
            case isUsed: item->setFlags(ui->checkOtherFeature->isChecked() ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags); break;
            case otherBody: item->setFlags(ui->checkOtherBody->isChecked() ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags); break;
            case basePlane: item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); break;
            case afterTip: item->setFlags(Qt::NoItemFlags); break;
        }

        index++;
    }
}

void TaskFeaturePick::onCheckReverse(bool checked)
{
}

void TaskFeaturePick::onCheckOtherFeature(bool checked)
{
    ui->radioIndependent->setEnabled(checked);
    // TODO: Not implemented yet
    //ui->radioDependent->setEnabled(checked);
    //ui->radioXRef->setEnabled(checked);

    updateList();
}

void TaskFeaturePick::onCheckOtherBody(bool checked)
{
    ui->radioIndependent->setEnabled(checked);
    // TODO: Not implemented yet
    //ui->radioDependent->setEnabled(checked);
    //ui->radioXRef->setEnabled(checked);

    updateList();
}

void TaskFeaturePick::onUpdate(bool)
{
    updateList();
}

bool TaskFeaturePick::getReverse()
{
    return ui->checkReverse->isChecked();
}

std::vector<App::DocumentObject*> TaskFeaturePick::getFeatures() {

    features.clear();
    QListIterator<QListWidgetItem*> i(ui->listWidget->selectedItems());
    while (i.hasNext()) {
        QString t = i.next()->text();
        t = t.left(t.indexOf(QString::fromAscii("(")) - 1);
        features.push_back(t);
    }

    std::vector<App::DocumentObject*> result;

    for (std::vector<QString>::const_iterator s = features.begin(); s != features.end(); s++)
        result.push_back(App::GetApplication().getActiveDocument()->getObject(s->toAscii().data()));

    return result;
}

void TaskFeaturePick::onSelectionChanged(const Gui::SelectionChanges& msg)
{
    ui->listWidget->clearSelection();
    for(Gui::SelectionSingleton::SelObj obj :  Gui::Selection().getSelection()) {

        for(int row = 0; row < ui->listWidget->count(); row++) {

            QListWidgetItem *item = ui->listWidget->item(row);
            QString t = item->text();
            t = t.left(t.indexOf(QString::fromAscii("(")) - 1);
            if(t.compare(QString::fromAscii(obj.FeatName))==0) {
                ui->listWidget->setItemSelected(item, true);
            }
        }
    }

}

//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

TaskDlgFeaturePick::TaskDlgFeaturePick(std::vector<App::DocumentObject*> &objects,
                                        const std::vector<TaskFeaturePick::featureStatus> &status,
                                        boost::function<bool (std::vector<App::DocumentObject*>)> afunc,
                                        boost::function<void (std::vector<App::DocumentObject*>)> wfunc)
    : TaskDialog(), accepted(false)
{
    pick  = new TaskFeaturePick(objects, status);
    Content.push_back(pick);

    acceptFunction = afunc;
    workFunction = wfunc;
}

TaskDlgFeaturePick::~TaskDlgFeaturePick()
{
    //do the work now as before in accept() the dialog is still open, hence the work
    //function could not open annother dialog
    if(accepted)
        workFunction(pick->getFeatures());
}

//==== calls from the TaskView ===============================================================

void TaskDlgFeaturePick::open()
{

}

void TaskDlgFeaturePick::clicked(int)
{

}

bool TaskDlgFeaturePick::accept()
{
    accepted = acceptFunction(pick->getFeatures());

    return accepted;
}

bool TaskDlgFeaturePick::reject()
{
    accepted = false;
    return true;
}

#include "moc_TaskFeaturePick.cpp"
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2020 WandererFan <wandererfan@gmail.com>                *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
#include <QPainter>
#include <QPainterPathStroker>
#include <QStyleOptionGraphicsItem>
#include <QPen>
#include <QColor>
#endif

#include <App/Application.h>
#include <App/Material.h>
#include <Base/Console.h>
#include <Base/Parameter.h>

#include <Mod/TechDraw/App/DrawUtil.h>
//#include <Mod/TechDraw/App/Preferences.h>

#include <qmath.h>
#include "Rez.h"
#include "DrawGuiUtil.h"
#include "PreferencesGui.h"
#include "QGIView.h"
#include "QGIGhostHighlight.h"

using namespace TechDrawGui;
using namespace TechDraw;

QGIGhostHighlight::QGIGhostHighlight()
{
    setInteractive(true);
    m_dragging = false;

    //make the ghost very visible
    QFont f(QGIView::getPrefFont());
    double fontSize = Preferences::labelFontSizeMM();
    setFont(f, fontSize);
    setReference("drag");
    setStyle(Qt::SolidLine);
    setColor(prefSelectColor());
    setWidth(Rez::guiX(1.0));
    setRadius(10.0);         //placeholder
}

QGIGhostHighlight::~QGIGhostHighlight()
{

}

QVariant QGIGhostHighlight::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if (change == ItemPositionHasChanged && scene()) {
        // nothing to do here?
    }
    return QGIHighlight::itemChange(change, value);
}

void QGIGhostHighlight::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
//    Base::Console().Message("QGIGhostHighlight::mousePress() - %X\n", this);
    if ( (event->button() == Qt::LeftButton) &&
        (flags() && QGraphicsItem::ItemIsMovable) ) {
            m_dragging = true;
            event->accept();
    }
    QGIHighlight::mousePressEvent(event);
}

void QGIGhostHighlight::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
//    Base::Console().Message("QGIGhostHighlight::mouseRelease() - pos: %s scenePos: %s\n",
//                                 DrawUtil::formatVector(pos()).c_str(),
//                                 DrawUtil::formatVector(mapToScene(pos())).c_str());
    if (m_dragging) {
        m_dragging = false;
        Q_EMIT positionChange(scenePos());
        event->accept();
    }
    QGIHighlight::mouseReleaseEvent(event);
}

void QGIGhostHighlight::setInteractive(bool state)
{
    setFlag(QGraphicsItem::ItemIsSelectable, state);
    setFlag(QGraphicsItem::ItemIsMovable, state);
    setFlag(QGraphicsItem::ItemSendsScenePositionChanges, state);
    setFlag(QGraphicsItem::ItemSendsGeometryChanges, state);
}

//radius should scaled, but not Rez::guix()
void QGIGhostHighlight::setRadius(double r)
{
    setBounds(-r, r, r, -r);
}

#include <Mod/TechDraw/Gui/moc_QGIGhostHighlight.cpp>
<commit_msg>TechDraw: [skip ci] fix -Wconstant-logical-operand<commit_after>/***************************************************************************
 *   Copyright (c) 2020 WandererFan <wandererfan@gmail.com>                *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
#include <QPainter>
#include <QPainterPathStroker>
#include <QStyleOptionGraphicsItem>
#include <QPen>
#include <QColor>
#endif

#include <App/Application.h>
#include <App/Material.h>
#include <Base/Console.h>
#include <Base/Parameter.h>

#include <Mod/TechDraw/App/DrawUtil.h>
//#include <Mod/TechDraw/App/Preferences.h>

#include <qmath.h>
#include "Rez.h"
#include "DrawGuiUtil.h"
#include "PreferencesGui.h"
#include "QGIView.h"
#include "QGIGhostHighlight.h"

using namespace TechDrawGui;
using namespace TechDraw;

QGIGhostHighlight::QGIGhostHighlight()
{
    setInteractive(true);
    m_dragging = false;

    //make the ghost very visible
    QFont f(QGIView::getPrefFont());
    double fontSize = Preferences::labelFontSizeMM();
    setFont(f, fontSize);
    setReference("drag");
    setStyle(Qt::SolidLine);
    setColor(prefSelectColor());
    setWidth(Rez::guiX(1.0));
    setRadius(10.0);         //placeholder
}

QGIGhostHighlight::~QGIGhostHighlight()
{

}

QVariant QGIGhostHighlight::itemChange(GraphicsItemChange change, const QVariant &value)
{
    if (change == ItemPositionHasChanged && scene()) {
        // nothing to do here?
    }
    return QGIHighlight::itemChange(change, value);
}

void QGIGhostHighlight::mousePressEvent(QGraphicsSceneMouseEvent * event)
{
//    Base::Console().Message("QGIGhostHighlight::mousePress() - %X\n", this);
    if ( (event->button() == Qt::LeftButton) &&
        (flags() & QGraphicsItem::ItemIsMovable) ) {
            m_dragging = true;
            event->accept();
    }
    QGIHighlight::mousePressEvent(event);
}

void QGIGhostHighlight::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
//    Base::Console().Message("QGIGhostHighlight::mouseRelease() - pos: %s scenePos: %s\n",
//                                 DrawUtil::formatVector(pos()).c_str(),
//                                 DrawUtil::formatVector(mapToScene(pos())).c_str());
    if (m_dragging) {
        m_dragging = false;
        Q_EMIT positionChange(scenePos());
        event->accept();
    }
    QGIHighlight::mouseReleaseEvent(event);
}

void QGIGhostHighlight::setInteractive(bool state)
{
    setFlag(QGraphicsItem::ItemIsSelectable, state);
    setFlag(QGraphicsItem::ItemIsMovable, state);
    setFlag(QGraphicsItem::ItemSendsScenePositionChanges, state);
    setFlag(QGraphicsItem::ItemSendsGeometryChanges, state);
}

//radius should scaled, but not Rez::guix()
void QGIGhostHighlight::setRadius(double r)
{
    setBounds(-r, r, r, -r);
}

#include <Mod/TechDraw/Gui/moc_QGIGhostHighlight.cpp>
<|endoftext|>


<commit_before>#include <cassert>
#include <cmath>
#include <complex>
#include <limits>
#include <fstream>
#include <iterator>

#include "Modulator_USR.hpp"

/*
 * Constructor / Destructor
 */
template <typename B, typename R, typename Q, proto_max<Q> MAX>
Modulator_USR<B,R,Q,MAX>
::Modulator_USR(const int N, const int bits_per_symbol, const std::string const_path, const R sigma,
                const bool disable_sig2, const int n_frames, const std::string name)
: Modulator<B,R,Q>(N, std::ceil((float)N / (float)bits_per_symbol) * 2, n_frames, name),
  bits_per_symbol(bits_per_symbol),
  nbr_symbols    (1 << bits_per_symbol),
  sigma          (sigma),
  sqrt_es        (0.0),
  disable_sig2   (disable_sig2),
  constellation  ()
{
	std::fstream const_file(const_path, std::ios_base::in);

	std::string temp;
	while (std::getline(const_file, temp))
	{
		if (temp[0] == '#') continue;

		std::istringstream buffer(temp);
		std::vector<R> line((std::istream_iterator<R>(buffer)), std::istream_iterator<R>());
		assert (line.size() < 3);

		if (line.size() == 2)
			constellation.push_back(std::complex<R>(line[0],line[1]));
		else
			constellation.push_back(std::complex<R>(line[0],0.0));
		sqrt_es += std::norm(constellation.back());
	}
	sqrt_es = sqrt(sqrt_es/nbr_symbols);

	assert (constellation.size() == nbr_symbols);

	for (auto i = 0; i < nbr_symbols; i++)
		constellation[i] /= (std::complex<R>)sqrt_es;

	const_file.close();
}

template <typename B, typename R, typename Q, proto_max<Q> MAX>
Modulator_USR<B,R,Q,MAX>
::~Modulator_USR()
{
}

/*
 * int get_buffer_size_after_modulation(const int N)
 * N = number of input bits
 * returns number of output symbols
 */
template <typename B, typename R, typename Q, proto_max<Q> MAX>
int Modulator_USR<B,R,Q,MAX>
::get_buffer_size_after_modulation(const int N)
{
	assert(this->bits_per_symbol % 2 == 0);
	return std::ceil((float)N / (float)this->bits_per_symbol) * 2;
}

/*
 * Modulator
 */
template <typename B,typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::modulate(const mipp::vector<B>& X_N1, mipp::vector<R>& X_N2)
{
	auto size_in  = (int)X_N1.size();
	auto size_out = (int)X_N2.size();
	auto bps      = this->bits_per_symbol;

	auto main_loop_size = size_in / bps;
	for (auto i = 0; i < main_loop_size; i++)
	{
		unsigned idx = 0;
		for (auto j = 0; j < bps; j++)
			idx += (1 << (bps-j-1)) * X_N1[i * bps +j];
		auto symbol = this->constellation[idx];

		X_N2[2*i   ] = symbol.real();
		X_N2[2*i +1] = symbol.imag();
	}

	// last elements if "size_in" is not a multiple of the number of bits per symbol
	if (main_loop_size * bps < size_in)
	{
		unsigned idx = 0;
		for (auto j = 0; j < size_in - (main_loop_size * bps); j++)
			idx += (1 << (bps-j-1)) * X_N1[main_loop_size * bps +j];
		auto symbol = this->constellation[idx];

		X_N2[size_out -2] = symbol.real();
		X_N2[size_out -1] = symbol.imag();
	}
}

/*
 * Demodulator
 */
template <typename B,typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::demodulate(const mipp::vector<Q>& Y_N1, mipp::vector<Q>& Y_N2)
{
	assert(typeid(R) == typeid(Q));
	assert(typeid(Q) == typeid(float) || typeid(Q) == typeid(double));

	auto size       = (int)Y_N2.size();
	auto inv_sigma2 = disable_sig2 ? (Q)1.0 : (Q)1.0 / (this->sigma * this->sigma);

	for (auto n = 0; n < size; n++) // boucle sur les LLRs
	{
		auto L0 = -std::numeric_limits<Q>::infinity();
		auto L1 = -std::numeric_limits<Q>::infinity();

		auto b  = n % this->bits_per_symbol; // position du bit
		auto k  = n / this->bits_per_symbol; // position du symbole

		auto complex_Yk = std::complex<Q>(Y_N1[2*k], Y_N1[2*k+1]);

		for (auto j = 0; j < this->nbr_symbols; j++)
			if ((j &(1 << (this->bits_per_symbol -b -1))) == 0)
				L0 = MAX(L0, -std::norm(complex_Yk - std::complex<Q>(this->constellation[j])) * inv_sigma2);
			else
				L1 = MAX(L1, -std::norm(complex_Yk - std::complex<Q>(this->constellation[j])) * inv_sigma2);

		Y_N2[n] = (L0 - L1);
	}
}

template <typename B, typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::demodulate(const mipp::vector<Q>& Y_N1, const mipp::vector<Q>& Y_N2, mipp::vector<Q>& Y_N3)
{
	assert(typeid(R) == typeid(Q));
	assert(typeid(Q) == typeid(float) || typeid(Q) == typeid(double));

	auto size       = (int)Y_N3.size();
	auto inv_sigma2 = disable_sig2 ? (Q)1.0 : (Q)1.0 / (this->sigma * this->sigma);

	for (auto n = 0; n < size; n++) // boucle sur les LLRs
	{
		auto L0 = -std::numeric_limits<Q>::infinity();
		auto L1 = -std::numeric_limits<Q>::infinity();
		auto b  = n % this->bits_per_symbol; // position du bit
		auto k  = n / this->bits_per_symbol; // position du symbole

		auto complex_Yk = std::complex<Q>(Y_N1[2*k], Y_N1[2*k+1]);

		for (auto j = 0; j < this->nbr_symbols; j++)
		{
			auto tempL = std::norm(complex_Yk - std::complex<Q>(this->constellation[j])) * inv_sigma2;
			for (auto l = 0; l < b; l++)
				tempL += (j & (1 << (this->bits_per_symbol -l -1))) * Y_N2[k * this->bits_per_symbol +l];

			for (auto l = b + 1; l < this->bits_per_symbol; l++)
				tempL += (j & (1 << (this->bits_per_symbol-l-1))) * Y_N2[k * this->bits_per_symbol +l];

			if ((j & (1 << (this->bits_per_symbol-b-1))) == 0)
				L0 = MAX(L0, -tempL);
			else
				L1 = MAX(L1, -tempL);
		}

		Y_N3[n] = (L0 - L1);
	}
}

<commit_msg>Cosmetic correction<commit_after>#include <cassert>
#include <cmath>
#include <complex>
#include <limits>
#include <fstream>
#include <iterator>

#include "Modulator_USR.hpp"

/*
 * Constructor / Destructor
 */
template <typename B, typename R, typename Q, proto_max<Q> MAX>
Modulator_USR<B,R,Q,MAX>
::Modulator_USR(const int N, const int bits_per_symbol, const std::string const_path, const R sigma,
                const bool disable_sig2, const int n_frames, const std::string name)
: Modulator<B,R,Q>(N, std::ceil((float)N / (float)bits_per_symbol) * 2, n_frames, name),
  bits_per_symbol(bits_per_symbol),
  nbr_symbols    (1 << bits_per_symbol),
  sigma          (sigma),
  sqrt_es        (0.0),
  disable_sig2   (disable_sig2),
  constellation  ()
{
	std::fstream const_file(const_path, std::ios_base::in);

	std::string temp;
	while (std::getline(const_file, temp))
	{
		if (temp[0] == '#') continue;

		std::istringstream buffer(temp);
		std::vector<R> line((std::istream_iterator<R>(buffer)), std::istream_iterator<R>());
		assert (line.size() < 3);

		if (line.size() == 2)
			constellation.push_back(std::complex<R>(line[0],line[1]));
		else
			constellation.push_back(std::complex<R>(line[0],0.0));
		sqrt_es += std::norm(constellation.back());
	}
	sqrt_es = sqrt(sqrt_es/nbr_symbols);

	assert (constellation.size() == nbr_symbols);

	for (auto i = 0; i < nbr_symbols; i++)
		constellation[i] /= (std::complex<R>)sqrt_es;

	const_file.close();
}

template <typename B, typename R, typename Q, proto_max<Q> MAX>
Modulator_USR<B,R,Q,MAX>
::~Modulator_USR()
{
}

/*
 * int get_buffer_size_after_modulation(const int N)
 * N = number of input bits
 * returns number of output symbols
 */
template <typename B, typename R, typename Q, proto_max<Q> MAX>
int Modulator_USR<B,R,Q,MAX>
::get_buffer_size_after_modulation(const int N)
{
	assert(this->bits_per_symbol % 2 == 0);
	return std::ceil((float)N / (float)this->bits_per_symbol) * 2;
}

/*
 * Modulator
 */
template <typename B,typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::modulate(const mipp::vector<B>& X_N1, mipp::vector<R>& X_N2)
{
	auto size_in  = (int)X_N1.size();
	auto size_out = (int)X_N2.size();
	auto bps      = this->bits_per_symbol;

	auto main_loop_size = size_in / bps;
	for (auto i = 0; i < main_loop_size; i++)
	{
		unsigned idx = 0;
		for (auto j = 0; j < bps; j++)
			idx += (1 << (bps-j-1)) * X_N1[i * bps +j];
		auto symbol = this->constellation[idx];

		X_N2[2*i   ] = symbol.real();
		X_N2[2*i +1] = symbol.imag();
	}

	// last elements if "size_in" is not a multiple of the number of bits per symbol
	if (main_loop_size * bps < size_in)
	{
		unsigned idx = 0;
		for (auto j = 0; j < size_in - (main_loop_size * bps); j++)
			idx += (1 << (bps-j-1)) * X_N1[main_loop_size * bps +j];
		auto symbol = this->constellation[idx];

		X_N2[size_out -2] = symbol.real();
		X_N2[size_out -1] = symbol.imag();
	}
}

/*
 * Demodulator
 */
template <typename B,typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::demodulate(const mipp::vector<Q>& Y_N1, mipp::vector<Q>& Y_N2)
{
	assert(typeid(R) == typeid(Q));
	assert(typeid(Q) == typeid(float) || typeid(Q) == typeid(double));

	auto size       = (int)Y_N2.size();
	auto inv_sigma2 = disable_sig2 ? (Q)1.0 : (Q)1.0 / (this->sigma * this->sigma);

	for (auto n = 0; n < size; n++) // boucle sur les LLRs
	{
		auto L0 = -std::numeric_limits<Q>::infinity();
		auto L1 = -std::numeric_limits<Q>::infinity();

		auto b  = n % this->bits_per_symbol; // position du bit
		auto k  = n / this->bits_per_symbol; // position du symbole

		auto complex_Yk = std::complex<Q>(Y_N1[2*k], Y_N1[2*k+1]);

		for (auto j = 0; j < this->nbr_symbols; j++)
			if ((j &(1 << (this->bits_per_symbol -b -1))) == 0)
				L0 = MAX(L0, -std::norm(complex_Yk - std::complex<Q>(this->constellation[j])) * inv_sigma2);
			else
				L1 = MAX(L1, -std::norm(complex_Yk - std::complex<Q>(this->constellation[j])) * inv_sigma2);

		Y_N2[n] = (L0 - L1);
	}
}

template <typename B, typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::demodulate(const mipp::vector<Q>& Y_N1, const mipp::vector<Q>& Y_N2, mipp::vector<Q>& Y_N3)
{
	assert(typeid(R) == typeid(Q));
	assert(typeid(Q) == typeid(float) || typeid(Q) == typeid(double));

	auto size       = (int)Y_N3.size();
	auto inv_sigma2 = disable_sig2 ? (Q)1.0 : (Q)1.0 / (this->sigma * this->sigma);

	for (auto n = 0; n < size; n++) // boucle sur les LLRs
	{
		auto L0 = -std::numeric_limits<Q>::infinity();
		auto L1 = -std::numeric_limits<Q>::infinity();
		auto b  = n % this->bits_per_symbol; // position du bit
		auto k  = n / this->bits_per_symbol; // position du symbole

		auto complex_Yk = std::complex<Q>(Y_N1[2*k], Y_N1[2*k+1]);

		for (auto j = 0; j < this->nbr_symbols; j++)
		{
			auto tempL = std::norm(complex_Yk - std::complex<Q>(this->constellation[j])) * inv_sigma2;
			for (auto l = 0; l < b; l++)
				tempL += (j & (1 << (this->bits_per_symbol -l -1))) * Y_N2[k * this->bits_per_symbol +l];

			for (auto l = b + 1; l < this->bits_per_symbol; l++)
				tempL += (j & (1 << (this->bits_per_symbol-l-1))) * Y_N2[k * this->bits_per_symbol +l];

			if ((j & (1 << (this->bits_per_symbol-b-1))) == 0)
				L0 = MAX(L0, -tempL);
			else
				L1 = MAX(L1, -tempL);
		}

		Y_N3[n] = (L0 - L1) + Y_N2[n];
	}
}

<|endoftext|>


<commit_before>#include <cassert>
#include <cmath>
#include <complex>
#include <limits>
#include <fstream>

#include "Modulator_USR.hpp"

/*
 * Constructor / Destructor
 */
template <typename B, typename R, typename Q, proto_max<Q> MAX>
Modulator_USR<B,R,Q,MAX>
::Modulator_USR(const int N, const int bits_per_symbol, const std::string const_path, const R sigma, const bool disable_sig2, const int n_frames,
                const std::string name)
 :Modulator<B,R,Q>(N, std::ceil((float)N / (float)bits_per_symbol) * 2, n_frames, name),
  bits_per_symbol(bits_per_symbol),
  nbr_symbols    (1 << bits_per_symbol),
  sigma          (sigma),
  sqrt_es        (0.0),
  disable_sig2   (disable_sig2),
  constellation  ()
{
	std::fstream const_file(const_path, std::ios_base::in);

	std::string temp;

	while (std::getline(const_file, temp)) {
		if (temp[0] == '#')
			continue;

	    std::istringstream buffer(temp);
	    std::vector<R> line((std::istream_iterator<R>(buffer)),
	                             std::istream_iterator<R>());
	    assert (line.size() < 3);

	    if (line.size() == 2)
	    	constellation.push_back(std::complex<R>(line[0],line[1]));
	    else
	    	constellation.push_back(std::complex<R>(line[0],0.0));
	    sqrt_es += std::norm(constellation.back());
	}
	sqrt_es = sqrt(sqrt_es/nbr_symbols);

	assert(constellation.size() == nbr_symbols);

	for(auto i = 0; i<nbr_symbols; i++)
		constellation[i] /= (std::complex<R>)sqrt_es;
	const_file.close();
}

template <typename B, typename R, typename Q, proto_max<Q> MAX>
Modulator_USR<B,R,Q,MAX>
::~Modulator_USR()
{
}

/*
 * int get_buffer_size_after_modulation(const int N)
 * N = number of input bits
 * returns number of output symbols
 */
template <typename B, typename R, typename Q, proto_max<Q> MAX>
int Modulator_USR<B,R,Q,MAX>
::get_buffer_size_after_modulation(const int N)
{
	assert(this->bits_per_symbol % 2 == 0);
	return std::ceil((float)N / (float)this->bits_per_symbol) * 2;
}

/*
 * Modulator
 */
template <typename B,typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::modulate(const mipp::vector<B>& X_N1, mipp::vector<R>& X_N2)
{
	auto size_in  = (int)X_N1.size();
	auto size_out = (int)X_N2.size();
	auto bps      = this->bits_per_symbol;

	auto main_loop_size = size_in / bps;
	for (auto i = 0; i < main_loop_size; i++)
	{
		unsigned idx = 0;
		for (auto j = 0; j < bps; j++)
			idx += (1 << j) * X_N1[i * bps +j];
		auto symbol = this->constellation[idx];

		X_N2[2*i   ] = symbol.real();
		X_N2[2*i +1] = symbol.imag();
	}

	// last elements if "size_in" is not a multiple of the number of bits per symbol
	if (main_loop_size * bps < size_in)
	{
		unsigned idx = 0;
		for (auto j = 0; j < size_in - (main_loop_size * bps); j++)
			idx += (1 << j) * X_N1[main_loop_size * bps +j];
		auto symbol = this->constellation[idx];

		X_N2[size_out -2] = symbol.real();
		X_N2[size_out -1] = symbol.imag();
	}
}

/*
 * Demodulator
 */
template <typename B,typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::demodulate(const mipp::vector<Q>& Y_N1, mipp::vector<Q>& Y_N2)
{
	assert(typeid(R) == typeid(Q));
	assert(typeid(Q) == typeid(float) || typeid(Q) == typeid(double));

	auto size       = (int)Y_N2.size();
	auto inv_sigma2 = disable_sig2 ? (Q)1.0 : (Q)1.0 / (this->sigma * this->sigma);

	for (auto n = 0; n < size; n++)// Boucle sur les LLRs
	{
		auto L0 = -std::numeric_limits<Q>::infinity();
		auto L1 = -std::numeric_limits<Q>::infinity();
		auto b  = n % this->bits_per_symbol; // position du bit
		auto k  = n / this->bits_per_symbol; // Position du symbole

		auto complex_Yk = std::complex<Q>(Y_N1[2*k], Y_N1[2*k+1]);

		for (auto j = 0; j < this->nbr_symbols; j++)
			if ((j & (1 << b)) == 0)
				L0 = MAX(L0, -std::norm(complex_Yk - std::complex<Q>(this->constellation[j]))* inv_sigma2);
			else
				L1 = MAX(L1, -std::norm(complex_Yk - std::complex<Q>(this->constellation[j]))* inv_sigma2);

		Y_N2[n] = (L0 - L1);
	}
}

template <typename B,typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::demodulate(const mipp::vector<Q>& Y_N1, const mipp::vector<Q>& Y_N2,mipp::vector<Q>& Y_N3)
{
	assert(typeid(R) == typeid(Q));
	assert(typeid(Q) == typeid(float) || typeid(Q) == typeid(double));

	auto size       = (int)Y_N3.size();
	auto inv_sigma2 = disable_sig2 ? (Q)1.0 : (Q)1.0 / (this->sigma * this->sigma);
	auto bps = this->bits_per_symbol;

	for (auto n = 0; n < size; n++)// Boucle sur les LLRs
	{
		auto L0 = -std::numeric_limits<Q>::infinity();
		auto L1 = -std::numeric_limits<Q>::infinity();
		auto b  = n % bps; // position du bit
		auto k  = n / bps; // Position du symbole

		auto complex_Yk = std::complex<Q>(Y_N1[2*k], Y_N1[2*k+1]);

		for (auto j = 0; j < this->nbr_symbols; j++)
		{
			auto tempL  = std::norm(complex_Yk - std::complex<Q>(this->constellation[j])) * inv_sigma2;
			for(auto l=0; l < b ; l++)
			{
				tempL += (j & (1 << l))*Y_N2[k*bps+l];
			}
			for(auto l=b+1; l < bps ; l++)
			{
				tempL += (j & (1 << l))*Y_N2[k*bps+l];
			}
			if ((j & (1 << b)) == 0)
				L0 = MAX(L0, -tempL);
			else
				L1 = MAX(L1, -tempL);
		}

		Y_N3[n] = (L0 - L1);
	}
}

<commit_msg>Fix a compilation error.<commit_after>#include <cassert>
#include <cmath>
#include <complex>
#include <limits>
#include <fstream>
#include <iterator>

#include "Modulator_USR.hpp"

/*
 * Constructor / Destructor
 */
template <typename B, typename R, typename Q, proto_max<Q> MAX>
Modulator_USR<B,R,Q,MAX>
::Modulator_USR(const int N, const int bits_per_symbol, const std::string const_path, const R sigma, const bool disable_sig2, const int n_frames,
                const std::string name)
 :Modulator<B,R,Q>(N, std::ceil((float)N / (float)bits_per_symbol) * 2, n_frames, name),
  bits_per_symbol(bits_per_symbol),
  nbr_symbols    (1 << bits_per_symbol),
  sigma          (sigma),
  sqrt_es        (0.0),
  disable_sig2   (disable_sig2),
  constellation  ()
{
	std::fstream const_file(const_path, std::ios_base::in);

	std::string temp;

	while (std::getline(const_file, temp)) {
		if (temp[0] == '#')
			continue;

	    std::istringstream buffer(temp);
	    std::vector<R> line((std::istream_iterator<R>(buffer)),
	                             std::istream_iterator<R>());
	    assert (line.size() < 3);

	    if (line.size() == 2)
	    	constellation.push_back(std::complex<R>(line[0],line[1]));
	    else
	    	constellation.push_back(std::complex<R>(line[0],0.0));
	    sqrt_es += std::norm(constellation.back());
	}
	sqrt_es = sqrt(sqrt_es/nbr_symbols);

	assert(constellation.size() == nbr_symbols);

	for(auto i = 0; i<nbr_symbols; i++)
		constellation[i] /= (std::complex<R>)sqrt_es;
	const_file.close();
}

template <typename B, typename R, typename Q, proto_max<Q> MAX>
Modulator_USR<B,R,Q,MAX>
::~Modulator_USR()
{
}

/*
 * int get_buffer_size_after_modulation(const int N)
 * N = number of input bits
 * returns number of output symbols
 */
template <typename B, typename R, typename Q, proto_max<Q> MAX>
int Modulator_USR<B,R,Q,MAX>
::get_buffer_size_after_modulation(const int N)
{
	assert(this->bits_per_symbol % 2 == 0);
	return std::ceil((float)N / (float)this->bits_per_symbol) * 2;
}

/*
 * Modulator
 */
template <typename B,typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::modulate(const mipp::vector<B>& X_N1, mipp::vector<R>& X_N2)
{
	auto size_in  = (int)X_N1.size();
	auto size_out = (int)X_N2.size();
	auto bps      = this->bits_per_symbol;

	auto main_loop_size = size_in / bps;
	for (auto i = 0; i < main_loop_size; i++)
	{
		unsigned idx = 0;
		for (auto j = 0; j < bps; j++)
			idx += (1 << j) * X_N1[i * bps +j];
		auto symbol = this->constellation[idx];

		X_N2[2*i   ] = symbol.real();
		X_N2[2*i +1] = symbol.imag();
	}

	// last elements if "size_in" is not a multiple of the number of bits per symbol
	if (main_loop_size * bps < size_in)
	{
		unsigned idx = 0;
		for (auto j = 0; j < size_in - (main_loop_size * bps); j++)
			idx += (1 << j) * X_N1[main_loop_size * bps +j];
		auto symbol = this->constellation[idx];

		X_N2[size_out -2] = symbol.real();
		X_N2[size_out -1] = symbol.imag();
	}
}

/*
 * Demodulator
 */
template <typename B,typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::demodulate(const mipp::vector<Q>& Y_N1, mipp::vector<Q>& Y_N2)
{
	assert(typeid(R) == typeid(Q));
	assert(typeid(Q) == typeid(float) || typeid(Q) == typeid(double));

	auto size       = (int)Y_N2.size();
	auto inv_sigma2 = disable_sig2 ? (Q)1.0 : (Q)1.0 / (this->sigma * this->sigma);

	for (auto n = 0; n < size; n++)// Boucle sur les LLRs
	{
		auto L0 = -std::numeric_limits<Q>::infinity();
		auto L1 = -std::numeric_limits<Q>::infinity();
		auto b  = n % this->bits_per_symbol; // position du bit
		auto k  = n / this->bits_per_symbol; // Position du symbole

		auto complex_Yk = std::complex<Q>(Y_N1[2*k], Y_N1[2*k+1]);

		for (auto j = 0; j < this->nbr_symbols; j++)
			if ((j & (1 << b)) == 0)
				L0 = MAX(L0, -std::norm(complex_Yk - std::complex<Q>(this->constellation[j]))* inv_sigma2);
			else
				L1 = MAX(L1, -std::norm(complex_Yk - std::complex<Q>(this->constellation[j]))* inv_sigma2);

		Y_N2[n] = (L0 - L1);
	}
}

template <typename B,typename R, typename Q, proto_max<Q> MAX>
void Modulator_USR<B,R,Q,MAX>
::demodulate(const mipp::vector<Q>& Y_N1, const mipp::vector<Q>& Y_N2,mipp::vector<Q>& Y_N3)
{
	assert(typeid(R) == typeid(Q));
	assert(typeid(Q) == typeid(float) || typeid(Q) == typeid(double));

	auto size       = (int)Y_N3.size();
	auto inv_sigma2 = disable_sig2 ? (Q)1.0 : (Q)1.0 / (this->sigma * this->sigma);
	auto bps = this->bits_per_symbol;

	for (auto n = 0; n < size; n++)// Boucle sur les LLRs
	{
		auto L0 = -std::numeric_limits<Q>::infinity();
		auto L1 = -std::numeric_limits<Q>::infinity();
		auto b  = n % bps; // position du bit
		auto k  = n / bps; // Position du symbole

		auto complex_Yk = std::complex<Q>(Y_N1[2*k], Y_N1[2*k+1]);

		for (auto j = 0; j < this->nbr_symbols; j++)
		{
			auto tempL  = std::norm(complex_Yk - std::complex<Q>(this->constellation[j])) * inv_sigma2;
			for(auto l=0; l < b ; l++)
			{
				tempL += (j & (1 << l))*Y_N2[k*bps+l];
			}
			for(auto l=b+1; l < bps ; l++)
			{
				tempL += (j & (1 << l))*Y_N2[k*bps+l];
			}
			if ((j & (1 << b)) == 0)
				L0 = MAX(L0, -tempL);
			else
				L1 = MAX(L1, -tempL);
		}

		Y_N3[n] = (L0 - L1);
	}
}

<|endoftext|>


<commit_before>#include "VMusic.h"
#include "VInterpolate.h"

VMusic::VMusic() {}
VMusic::~VMusic() {}

/**
* Opens music data from file.
*/
VMusic* VMusic::OpenMusicFile(sf::String filename)
{
	if (music.openFromFile(filename))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
	return nullptr;
}

/**
* Opens music data from memory.
*/
VMusic* VMusic::OpenMusicMemory(const void* data, size_t size)
{
	if (music.openFromMemory(data, size))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
}

/**
* Opens music data from a stream.
*/
VMusic* VMusic::OpenMusicStream(sf::InputStream& stream)
{
	if (music.openFromStream(stream))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
}

void VMusic::Update(float dt)
{
	if (!valid)
		return;

	if (Status() == music.Playing)
	{
		if (fadein)
		{
			fadeTimer += dt / fadeTime;
			music.setVolume(VInterpolate::Float(startVolume, finishVolume, fadeTimer) * (masterVolume / 100.0f));

			if (fadeTimer > 1.0f)
			{
				fadein = false;
				fadeTimer = 0;
			}
		}

		if (fadeout)
		{
			fadeTimer += dt / fadeTime;
			music.setVolume(VInterpolate::Float(startVolume, finishVolume, fadeTimer) * (masterVolume / 100.0f));

			if (fadeTimer > 1.0f)
			{
				fadeout = false;
				fadeTimer = 0;
			}
		}
	}
	else
	{
		fadein = false;
		fadeout = false;
	}
}

void VMusic::Play()
{
	if (!valid)
		return;

	music.play();
}

void VMusic::Pause()
{
	if (!valid)
		return;

	music.pause();
}

void VMusic::Stop()
{
	if (!valid)
		return;

	music.stop();
}

void VMusic::Fade(bool fadeIn, float fadeLength, float maxVolume, float minVolume)
{
	if ((fadeIn && !fadein) || (!fadeIn && !fadeout))
	{
		fadeTime = fadeLength;
		fadeTimer = 0;

		if (fadeIn)
		{
			startVolume = minVolume;
			finishVolume = maxVolume;
			fadein = true;
			fadeout = false;
			music.setVolume(minVolume * (masterVolume / 100.0f));
		}
		else
		{
			startVolume = maxVolume;
			finishVolume = minVolume;
			fadein = false;
			fadeout = true;
			music.setVolume(maxVolume * (masterVolume / 100.0f));
		}
	}
}

sf::Time VMusic::Duration()
{
	if (!valid)
		return sf::Time::Zero;

	return music.getDuration();
}

unsigned int VMusic::ChannelCount()
{
	if (!valid)
		return 0;

	return music.getChannelCount();
}

unsigned int VMusic::SampleRate()
{
	if (!valid)
		return 0;

	return music.getSampleRate();
}

sf::SoundStream::Status VMusic::Status()
{
	if (!valid)
		return sf::SoundStream::Stopped;

	return music.getStatus();
}

float VMusic::Attenuation()
{
	if (!valid)
		return 0;

	return music.getAttenuation();
}

bool VMusic::Loop()
{
	if (!valid)
		return false;

	return looping;
}

float VMusic::Pitch()
{
	if (!valid)
		return 0;

	return music.getPitch();
}

float VMusic::Volume()
{
	if (!valid)
		return 0;

	return masterVolume;
}

sf::Vector3f VMusic::Position()
{
	if (!valid)
		return sf::Vector3f();

	return music.getPosition();
}

bool VMusic::RelativeToListener()
{
	if (!valid)
		return false;

	return music.isRelativeToListener();
}

float VMusic::MinDistance()
{
	if (!valid)
		return 0;

	return music.getMinDistance();
}

float VMusic::PlayOffset()
{
	if (!valid)
		return 0;

	return music.getPlayingOffset().asSeconds();
}

void VMusic::SetAttenuation(float attenuation)
{
	if (!valid)
		return;

	music.setAttenuation(attenuation);
}

void VMusic::SetLoop(bool loop, float loopStart, float loopEnd)
{
	if (!valid)
		return;

	looping = loop;
	loopStartPoint = loopStart;
	if (loopEnd == 0)
		loopEndPoint = music.getDuration().asSeconds();

	music.setLoop(loop);
	music.setLoopPoints(sf::Music::TimeSpan(sf::seconds(loopStartPoint), sf::seconds(loopEndPoint - loopStartPoint)));
}

void VMusic::SetPitch(float pitch)
{
	if (!valid)
		return;

	music.setPitch(pitch);
}

void VMusic::SetVolume(float volume)
{
	if (volume < 0)
		volume = 0;

	masterVolume = volume;

	if (!valid)
		return;

	music.setVolume(masterVolume);
}

void VMusic::SetPosition(float x, float y, float z)
{
	if (!valid)
		return;

	music.setPosition(x, y, z);
}

void VMusic::SetPosition(const sf::Vector3f& position)
{
	if (!valid)
		return;

	music.setPosition(position);
}

void VMusic::SetRelativeToListener(bool relative)
{
	if (!valid)
		return;

	music.setRelativeToListener(relative);
}

void VMusic::SetMinDistance(float distance)
{
	if (!valid)
		return;

	music.setMinDistance(distance);
}

void VMusic::SetPlayOffset(float offset)
{
	if (!valid)
		return;

	music.setPlayingOffset(sf::seconds(offset));
}<commit_msg>Return NULL if fails to open.<commit_after>#include "VMusic.h"
#include "VInterpolate.h"

VMusic::VMusic() {}
VMusic::~VMusic() {}

/**
* Opens music data from file.
*/
VMusic* VMusic::OpenMusicFile(sf::String filename)
{
	if (music.openFromFile(filename))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
	return nullptr;
}

/**
* Opens music data from memory.
*/
VMusic* VMusic::OpenMusicMemory(const void* data, size_t size)
{
	if (music.openFromMemory(data, size))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
	return NULL;
}

/**
* Opens music data from a stream.
*/
VMusic* VMusic::OpenMusicStream(sf::InputStream& stream)
{
	if (music.openFromStream(stream))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
	return NULL;
}

void VMusic::Update(float dt)
{
	if (!valid)
		return;

	if (Status() == music.Playing)
	{
		if (fadein)
		{
			fadeTimer += dt / fadeTime;
			music.setVolume(VInterpolate::Float(startVolume, finishVolume, fadeTimer) * (masterVolume / 100.0f));

			if (fadeTimer > 1.0f)
			{
				fadein = false;
				fadeTimer = 0;
			}
		}

		if (fadeout)
		{
			fadeTimer += dt / fadeTime;
			music.setVolume(VInterpolate::Float(startVolume, finishVolume, fadeTimer) * (masterVolume / 100.0f));

			if (fadeTimer > 1.0f)
			{
				fadeout = false;
				fadeTimer = 0;
			}
		}
	}
	else
	{
		fadein = false;
		fadeout = false;
	}
}

void VMusic::Play()
{
	if (!valid)
		return;

	music.play();
}

void VMusic::Pause()
{
	if (!valid)
		return;

	music.pause();
}

void VMusic::Stop()
{
	if (!valid)
		return;

	music.stop();
}

void VMusic::Fade(bool fadeIn, float fadeLength, float maxVolume, float minVolume)
{
	if ((fadeIn && !fadein) || (!fadeIn && !fadeout))
	{
		fadeTime = fadeLength;
		fadeTimer = 0;

		if (fadeIn)
		{
			startVolume = minVolume;
			finishVolume = maxVolume;
			fadein = true;
			fadeout = false;
			music.setVolume(minVolume * (masterVolume / 100.0f));
		}
		else
		{
			startVolume = maxVolume;
			finishVolume = minVolume;
			fadein = false;
			fadeout = true;
			music.setVolume(maxVolume * (masterVolume / 100.0f));
		}
	}
}

sf::Time VMusic::Duration()
{
	if (!valid)
		return sf::Time::Zero;

	return music.getDuration();
}

unsigned int VMusic::ChannelCount()
{
	if (!valid)
		return 0;

	return music.getChannelCount();
}

unsigned int VMusic::SampleRate()
{
	if (!valid)
		return 0;

	return music.getSampleRate();
}

sf::SoundStream::Status VMusic::Status()
{
	if (!valid)
		return sf::SoundStream::Stopped;

	return music.getStatus();
}

float VMusic::Attenuation()
{
	if (!valid)
		return 0;

	return music.getAttenuation();
}

bool VMusic::Loop()
{
	if (!valid)
		return false;

	return looping;
}

float VMusic::Pitch()
{
	if (!valid)
		return 0;

	return music.getPitch();
}

float VMusic::Volume()
{
	if (!valid)
		return 0;

	return masterVolume;
}

sf::Vector3f VMusic::Position()
{
	if (!valid)
		return sf::Vector3f();

	return music.getPosition();
}

bool VMusic::RelativeToListener()
{
	if (!valid)
		return false;

	return music.isRelativeToListener();
}

float VMusic::MinDistance()
{
	if (!valid)
		return 0;

	return music.getMinDistance();
}

float VMusic::PlayOffset()
{
	if (!valid)
		return 0;

	return music.getPlayingOffset().asSeconds();
}

void VMusic::SetAttenuation(float attenuation)
{
	if (!valid)
		return;

	music.setAttenuation(attenuation);
}

void VMusic::SetLoop(bool loop, float loopStart, float loopEnd)
{
	if (!valid)
		return;

	looping = loop;
	loopStartPoint = loopStart;
	if (loopEnd == 0)
		loopEndPoint = music.getDuration().asSeconds();

	music.setLoop(loop);
	music.setLoopPoints(sf::Music::TimeSpan(sf::seconds(loopStartPoint), sf::seconds(loopEndPoint - loopStartPoint)));
}

void VMusic::SetPitch(float pitch)
{
	if (!valid)
		return;

	music.setPitch(pitch);
}

void VMusic::SetVolume(float volume)
{
	if (volume < 0)
		volume = 0;

	masterVolume = volume;

	if (!valid)
		return;

	music.setVolume(masterVolume);
}

void VMusic::SetPosition(float x, float y, float z)
{
	if (!valid)
		return;

	music.setPosition(x, y, z);
}

void VMusic::SetPosition(const sf::Vector3f& position)
{
	if (!valid)
		return;

	music.setPosition(position);
}

void VMusic::SetRelativeToListener(bool relative)
{
	if (!valid)
		return;

	music.setRelativeToListener(relative);
}

void VMusic::SetMinDistance(float distance)
{
	if (!valid)
		return;

	music.setMinDistance(distance);
}

void VMusic::SetPlayOffset(float offset)
{
	if (!valid)
		return;

	music.setPlayingOffset(sf::seconds(offset));
}<|endoftext|>