<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "passes/techmap/simplemap.h"
#include <stdlib.h>
#include <stdio.h>

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

static SigBit get_bit_or_zero(const SigSpec &sig)
{
	if (GetSize(sig) == 0)
		return State::S0;
	return sig[0];
}

static void run_ice40_opts(Module *module)
{
	pool<SigBit> optimized_co;
	vector<Cell*> sb_lut_cells;
	SigMap sigmap(module);

	for (auto cell : module->selected_cells())
	{
		if (cell->type == "\\SB_LUT4")
		{
			sb_lut_cells.push_back(cell);
			continue;
		}

		if (cell->type == "\\SB_CARRY")
		{
			SigSpec non_const_inputs, replacement_output;
			int count_zeros = 0, count_ones = 0;

			SigBit inbit[3] = {
				get_bit_or_zero(cell->getPort("\\I0")),
				get_bit_or_zero(cell->getPort("\\I1")),
				get_bit_or_zero(cell->getPort("\\CI"))
			};
			for (int i = 0; i < 3; i++)
				if (inbit[i].wire == nullptr) {
					if (inbit[i] == State::S1)
						count_ones++;
					else
						count_zeros++;
				} else
					non_const_inputs.append(inbit[i]);

			if (count_zeros >= 2)
				replacement_output = State::S0;
			else if (count_ones >= 2)
				replacement_output = State::S1;
			else if (GetSize(non_const_inputs) == 1)
				replacement_output = non_const_inputs;

			if (GetSize(replacement_output)) {
				optimized_co.insert(sigmap(cell->getPort("\\CO")[0]));
				module->connect(cell->getPort("\\CO")[0], replacement_output);
				module->design->scratchpad_set_bool("opt.did_something", true);
				log("Optimized away SB_CARRY cell %s.%s: CO=%s\n",
						log_id(module), log_id(cell), log_signal(replacement_output));
				module->remove(cell);
			}
			continue;
		}

		if (cell->type == "$__ICE40_CARRY_LUT4")
		{
			SigSpec non_const_inputs, replacement_output;
			int count_zeros = 0, count_ones = 0;

			SigBit inbit[3] = {
				cell->getPort("\\A"),
				cell->getPort("\\B"),
				cell->getPort("\\CI")
			};
			for (int i = 0; i < 3; i++)
				if (inbit[i].wire == nullptr) {
					if (inbit[i] == State::S1)
						count_ones++;
					else
						count_zeros++;
				} else
					non_const_inputs.append(inbit[i]);

			if (count_zeros >= 2)
				replacement_output = State::S0;
			else if (count_ones >= 2)
				replacement_output = State::S1;
			else if (GetSize(non_const_inputs) == 1)
				replacement_output = non_const_inputs;

			if (GetSize(replacement_output)) {
				optimized_co.insert(sigmap(cell->getPort("\\CO")[0]));
				module->connect(cell->getPort("\\CO")[0], replacement_output);
				module->design->scratchpad_set_bool("opt.did_something", true);
				log("Optimized SB_CARRY from $__ICE40_CARRY_LUT4 cell (leaving behind SB_LUT4) %s.%s: CO=%s\n",
						log_id(module), log_id(cell), log_signal(replacement_output));
				cell->type = "\\SB_LUT4";
				cell->setPort("\\I0", RTLIL::S0);
				cell->setPort("\\I1", inbit[0]);
				cell->setPort("\\I2", inbit[1]);
				cell->setPort("\\I3", inbit[2]);
				cell->unsetPort("\\A");
				cell->unsetPort("\\B");
				cell->unsetPort("\\CI");
				cell->unsetPort("\\CO");
				cell->setParam("\\LUT_INIT", std::string("0110100110010110"));
				sb_lut_cells.push_back(cell);
			}
			continue;
		}
	}

	for (auto cell : sb_lut_cells)
	{
		SigSpec inbits;

		inbits.append(get_bit_or_zero(cell->getPort("\\I0")));
		inbits.append(get_bit_or_zero(cell->getPort("\\I1")));
		inbits.append(get_bit_or_zero(cell->getPort("\\I2")));
		inbits.append(get_bit_or_zero(cell->getPort("\\I3")));
		sigmap.apply(inbits);

		if (optimized_co.count(inbits[0])) goto remap_lut;
		if (optimized_co.count(inbits[1])) goto remap_lut;
		if (optimized_co.count(inbits[2])) goto remap_lut;
		if (optimized_co.count(inbits[3])) goto remap_lut;

		if (!sigmap(inbits).is_fully_const())
			continue;

	remap_lut:
		module->design->scratchpad_set_bool("opt.did_something", true);
		log("Mapping SB_LUT4 cell %s.%s back to logic.\n", log_id(module), log_id(cell));

		cell->type ="$lut";
		cell->setParam("\\WIDTH", 4);
		cell->setParam("\\LUT", cell->getParam("\\LUT_INIT"));
		cell->unsetParam("\\LUT_INIT");

		cell->setPort("\\A", SigSpec({
			get_bit_or_zero(cell->getPort("\\I3")),
			get_bit_or_zero(cell->getPort("\\I2")),
			get_bit_or_zero(cell->getPort("\\I1")),
			get_bit_or_zero(cell->getPort("\\I0"))
		}));
		cell->setPort("\\Y", cell->getPort("\\O")[0]);
		cell->unsetPort("\\I0");
		cell->unsetPort("\\I1");
		cell->unsetPort("\\I2");
		cell->unsetPort("\\I3");
		cell->unsetPort("\\O");

		cell->check();
		simplemap_lut(module, cell);
		module->remove(cell);
	}
}

struct Ice40OptPass : public Pass {
	Ice40OptPass() : Pass("ice40_opt", "iCE40: perform simple optimizations") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    ice40_opt [options] [selection]\n");
		log("\n");
		log("This command executes the following script:\n");
		log("\n");
		log("    do\n");
		log("        <ice40 specific optimizations>\n");
		log("        opt_expr -mux_undef -undriven [-full]\n");
		log("        opt_merge\n");
		log("        opt_rmdff\n");
		log("        opt_clean\n");
		log("    while <changed design>\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		string opt_expr_args = "-mux_undef -undriven";

		log_header(design, "Executing ICE40_OPT pass (performing simple optimizations).\n");
		log_push();

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			if (args[argidx] == "-full") {
				opt_expr_args += " -full";
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		while (1)
		{
			design->scratchpad_unset("opt.did_something");

			log_header(design, "Running ICE40 specific optimizations.\n");
			for (auto module : design->selected_modules())
				run_ice40_opts(module);

			Pass::call(design, "opt_expr " + opt_expr_args);
			Pass::call(design, "opt_merge");
			Pass::call(design, "opt_rmdff");
			Pass::call(design, "opt_clean");

			if (design->scratchpad_get_bool("opt.did_something") == false)
				break;

			log_header(design, "Rerunning OPT passes. (Removed registers in this run.)\n");
		}

		design->optimize();
		design->sort();
		design->check();

		log_header(design, "Finished OPT passes. (There is nothing left to do.)\n");
		log_pop();
	}
} Ice40OptPass;

PRIVATE_NAMESPACE_END
<commit_msg>Use Const::from_string() not its constructor...<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "passes/techmap/simplemap.h"
#include <stdlib.h>
#include <stdio.h>

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

static SigBit get_bit_or_zero(const SigSpec &sig)
{
	if (GetSize(sig) == 0)
		return State::S0;
	return sig[0];
}

static void run_ice40_opts(Module *module)
{
	pool<SigBit> optimized_co;
	vector<Cell*> sb_lut_cells;
	SigMap sigmap(module);

	for (auto cell : module->selected_cells())
	{
		if (cell->type == "\\SB_LUT4")
		{
			sb_lut_cells.push_back(cell);
			continue;
		}

		if (cell->type == "\\SB_CARRY")
		{
			SigSpec non_const_inputs, replacement_output;
			int count_zeros = 0, count_ones = 0;

			SigBit inbit[3] = {
				get_bit_or_zero(cell->getPort("\\I0")),
				get_bit_or_zero(cell->getPort("\\I1")),
				get_bit_or_zero(cell->getPort("\\CI"))
			};
			for (int i = 0; i < 3; i++)
				if (inbit[i].wire == nullptr) {
					if (inbit[i] == State::S1)
						count_ones++;
					else
						count_zeros++;
				} else
					non_const_inputs.append(inbit[i]);

			if (count_zeros >= 2)
				replacement_output = State::S0;
			else if (count_ones >= 2)
				replacement_output = State::S1;
			else if (GetSize(non_const_inputs) == 1)
				replacement_output = non_const_inputs;

			if (GetSize(replacement_output)) {
				optimized_co.insert(sigmap(cell->getPort("\\CO")[0]));
				module->connect(cell->getPort("\\CO")[0], replacement_output);
				module->design->scratchpad_set_bool("opt.did_something", true);
				log("Optimized away SB_CARRY cell %s.%s: CO=%s\n",
						log_id(module), log_id(cell), log_signal(replacement_output));
				module->remove(cell);
			}
			continue;
		}

		if (cell->type == "$__ICE40_CARRY_LUT4")
		{
			SigSpec non_const_inputs, replacement_output;
			int count_zeros = 0, count_ones = 0;

			SigBit inbit[3] = {
				cell->getPort("\\A"),
				cell->getPort("\\B"),
				cell->getPort("\\CI")
			};
			for (int i = 0; i < 3; i++)
				if (inbit[i].wire == nullptr) {
					if (inbit[i] == State::S1)
						count_ones++;
					else
						count_zeros++;
				} else
					non_const_inputs.append(inbit[i]);

			if (count_zeros >= 2)
				replacement_output = State::S0;
			else if (count_ones >= 2)
				replacement_output = State::S1;
			else if (GetSize(non_const_inputs) == 1)
				replacement_output = non_const_inputs;

			if (GetSize(replacement_output)) {
				optimized_co.insert(sigmap(cell->getPort("\\CO")[0]));
				module->connect(cell->getPort("\\CO")[0], replacement_output);
				module->design->scratchpad_set_bool("opt.did_something", true);
				log("Optimized SB_CARRY from $__ICE40_CARRY_LUT4 cell (leaving behind SB_LUT4) %s.%s: CO=%s\n",
						log_id(module), log_id(cell), log_signal(replacement_output));
				cell->type = "\\SB_LUT4";
				cell->setPort("\\I0", RTLIL::S0);
				cell->setPort("\\I1", inbit[0]);
				cell->setPort("\\I2", inbit[1]);
				cell->setPort("\\I3", inbit[2]);
				cell->unsetPort("\\A");
				cell->unsetPort("\\B");
				cell->unsetPort("\\CI");
				cell->unsetPort("\\CO");
				cell->setParam("\\LUT_INIT", RTLIL::Const::from_string("0110100110010110"));
				sb_lut_cells.push_back(cell);
			}
			continue;
		}
	}

	for (auto cell : sb_lut_cells)
	{
		SigSpec inbits;

		inbits.append(get_bit_or_zero(cell->getPort("\\I0")));
		inbits.append(get_bit_or_zero(cell->getPort("\\I1")));
		inbits.append(get_bit_or_zero(cell->getPort("\\I2")));
		inbits.append(get_bit_or_zero(cell->getPort("\\I3")));
		sigmap.apply(inbits);

		if (optimized_co.count(inbits[0])) goto remap_lut;
		if (optimized_co.count(inbits[1])) goto remap_lut;
		if (optimized_co.count(inbits[2])) goto remap_lut;
		if (optimized_co.count(inbits[3])) goto remap_lut;

		if (!sigmap(inbits).is_fully_const())
			continue;

	remap_lut:
		module->design->scratchpad_set_bool("opt.did_something", true);
		log("Mapping SB_LUT4 cell %s.%s back to logic.\n", log_id(module), log_id(cell));

		cell->type ="$lut";
		cell->setParam("\\WIDTH", 4);
		cell->setParam("\\LUT", cell->getParam("\\LUT_INIT"));
		cell->unsetParam("\\LUT_INIT");

		cell->setPort("\\A", SigSpec({
			get_bit_or_zero(cell->getPort("\\I3")),
			get_bit_or_zero(cell->getPort("\\I2")),
			get_bit_or_zero(cell->getPort("\\I1")),
			get_bit_or_zero(cell->getPort("\\I0"))
		}));
		cell->setPort("\\Y", cell->getPort("\\O")[0]);
		cell->unsetPort("\\I0");
		cell->unsetPort("\\I1");
		cell->unsetPort("\\I2");
		cell->unsetPort("\\I3");
		cell->unsetPort("\\O");

		cell->check();
		simplemap_lut(module, cell);
		module->remove(cell);
	}
}

struct Ice40OptPass : public Pass {
	Ice40OptPass() : Pass("ice40_opt", "iCE40: perform simple optimizations") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    ice40_opt [options] [selection]\n");
		log("\n");
		log("This command executes the following script:\n");
		log("\n");
		log("    do\n");
		log("        <ice40 specific optimizations>\n");
		log("        opt_expr -mux_undef -undriven [-full]\n");
		log("        opt_merge\n");
		log("        opt_rmdff\n");
		log("        opt_clean\n");
		log("    while <changed design>\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		string opt_expr_args = "-mux_undef -undriven";

		log_header(design, "Executing ICE40_OPT pass (performing simple optimizations).\n");
		log_push();

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			if (args[argidx] == "-full") {
				opt_expr_args += " -full";
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		while (1)
		{
			design->scratchpad_unset("opt.did_something");

			log_header(design, "Running ICE40 specific optimizations.\n");
			for (auto module : design->selected_modules())
				run_ice40_opts(module);

			Pass::call(design, "opt_expr " + opt_expr_args);
			Pass::call(design, "opt_merge");
			Pass::call(design, "opt_rmdff");
			Pass::call(design, "opt_clean");

			if (design->scratchpad_get_bool("opt.did_something") == false)
				break;

			log_header(design, "Rerunning OPT passes. (Removed registers in this run.)\n");
		}

		design->optimize();
		design->sort();
		design->check();

		log_header(design, "Finished OPT passes. (There is nothing left to do.)\n");
		log_pop();
	}
} Ice40OptPass;

PRIVATE_NAMESPACE_END
<|endoftext|>


<commit_before>/*
 * =====================================================================================
 *
 *       Filename:  3.cpp
 *
 *    Description:  Solution to the third problem of the `evens' section.
 *
 *        Version:  1.0
 *        Created:  28.01.2015  6,00,07
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Radoslav Georgiev (sid), rgeorgiev583@gmail.com
 *        Company:  Faculty of Mathematics and Informatics at Sofia University
 *
 * =====================================================================================
 */

#include <iostream>

using namespace std;

const int MAX_SIZE = 1000;
const char diff = 'a' - 'A';

bool isWordChar(char c)
{
    return c == '(' || c == ')' || c == '-' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';
}

const char* skipWhitespaceReverse(const char* s)
{
    while (*s == ' ')
        s--;

    return s;
}

const char* goToEnd(const char* s)
{
    while (*s)
        s++;

    return s;
}

char toUpper(char c)
{
    return c >= 'a' && c <= 'z' ? c - diff : c;
}

char toLower(char c)
{
    return c >= 'A' && c <= 'Z' ? c + diff : c;
}

void swap(char* a, char* b)
{
    char x = *a;
    *a = *b;
    *b = x;
}

// Ако изречението е невалидно, връщаме NULL
char* reverseSentence(char* rev, const char* s)
{
    if (!s)
        return NULL;

    const char* end = goToEnd(s);
    end--;

    if (end < s || *end != '!' && *end != '.' && *end != '?')
        return NULL;

    end--;

    const char* beg = end;
    bool is_first = true;

    while (beg >= s)
    {
        while (beg >= s && isWordChar(*beg))
            beg--;

        if (beg == end)
            return NULL;

        beg++;

        if (beg < s)
        {
            char first[2];
            strncat(first, beg, 1);
            *first = toLower(*first);
            strcat(rev, first);
            strncat(rev, beg + 1, end - beg);
        }
        else
        {
            strncat(rev, beg, end - beg + 1);
            end = beg - 1;

            if (*end != ' ')
                return NULL;

            end--;

            if (end < s)
                return NULL;

            if (*end == ',' || *end == ':' || *end == ';')
                strncat(rev, end, 1);

            strncat(rev, end + 1, 1);
        }
    }

    *rev = toUpper(*rev);
    char *p = rev, *lp = NULL;
    int b = 0;

    while (p)
    {
        if (*p == '(')
        {
            b++;

            if (lp && b == 0)
            {
                swap(p, lp);
                lp = NULL;
            }
        }
        else if (*p == ')')
        {
            b--;

            if (b == -1)
                lp = p;
        }

        p++;
    }

    return rev;
}

int main()
{
    char s[MAX_SIZE], rev[MAX_SIZE];
    cin.getline(s, MAX_SIZE);

    cout << reverseSentence(rev, s) << endl;

    return 0;
}
<commit_msg>added necessary cstring header<commit_after>/*
 * =====================================================================================
 *
 *       Filename:  3.cpp
 *
 *    Description:  Solution to the third problem of the `evens' section.
 *
 *        Version:  1.0
 *        Created:  28.01.2015  6,00,07
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Radoslav Georgiev (sid), rgeorgiev583@gmail.com
 *        Company:  Faculty of Mathematics and Informatics at Sofia University
 *
 * =====================================================================================
 */

#include <iostream>
#include <cstring>

using namespace std;

const int MAX_SIZE = 1000;
const char diff = 'a' - 'A';

bool isWordChar(char c)
{
    return c == '(' || c == ')' || c == '-' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';
}

const char* skipWhitespaceReverse(const char* s)
{
    while (*s == ' ')
        s--;

    return s;
}

const char* goToEnd(const char* s)
{
    while (*s)
        s++;

    return s;
}

char toUpper(char c)
{
    return c >= 'a' && c <= 'z' ? c - diff : c;
}

char toLower(char c)
{
    return c >= 'A' && c <= 'Z' ? c + diff : c;
}

void swap(char* a, char* b)
{
    char x = *a;
    *a = *b;
    *b = x;
}

// Ако изречението е невалидно, връщаме NULL
char* reverseSentence(char* rev, const char* s)
{
    if (!s)
        return NULL;

    const char* end = goToEnd(s);
    end--;

    if (end < s || *end != '!' && *end != '.' && *end != '?')
        return NULL;

    end--;

    const char* beg = end;
    bool is_first = true;

    while (beg >= s)
    {
        while (beg >= s && isWordChar(*beg))
            beg--;

        if (beg == end)
            return NULL;

        beg++;

        if (beg < s)
        {
            char first[2];
            strncat(first, beg, 1);
            *first = toLower(*first);
            strcat(rev, first);
            strncat(rev, beg + 1, end - beg);
        }
        else
        {
            strncat(rev, beg, end - beg + 1);
            end = beg - 1;

            if (*end != ' ')
                return NULL;

            end--;

            if (end < s)
                return NULL;

            if (*end == ',' || *end == ':' || *end == ';')
                strncat(rev, end, 1);

            strncat(rev, end + 1, 1);
        }
    }

    *rev = toUpper(*rev);
    char *p = rev, *lp = NULL;
    int b = 0;

    while (p)
    {
        if (*p == '(')
        {
            b++;

            if (lp && b == 0)
            {
                swap(p, lp);
                lp = NULL;
            }
        }
        else if (*p == ')')
        {
            b--;

            if (b == -1)
                lp = p;
        }

        p++;
    }

    return rev;
}

int main()
{
    char s[MAX_SIZE], rev[MAX_SIZE];
    cin.getline(s, MAX_SIZE);

    cout << reverseSentence(rev, s) << endl;

    return 0;
}
<|endoftext|>


<commit_before>/*
*    flv_media_stream_source.cpp:
*
*    Copyright (C) 2015 limhiaoing <blog.poxiao.me> All Rights Reserved.
*
*/

#include "pch.h"

#include <algorithm>
#include <memory>
#include <string>

#include "flv_media_stream_source.hpp"
#include "flv_player.hpp"

using namespace Platform::Collections;
using namespace Windows::Media::MediaProperties;

namespace dawn_player {

flv_media_stream_source::flv_media_stream_source()
{
}

void flv_media_stream_source::init(flv_player^ player, MediaStreamSource^ mss)
{
    this->player = player;
    this->mss = mss;
    starting_event_token = this->mss->Starting += ref new TypedEventHandler<MediaStreamSource^, MediaStreamSourceStartingEventArgs^>(this, &flv_media_stream_source::on_starting);
    sample_requested_event_token = this->mss->SampleRequested += ref new TypedEventHandler<MediaStreamSource^, MediaStreamSourceSampleRequestedEventArgs^>(this, &flv_media_stream_source::on_sample_requested);
}

IAsyncOperation<flv_media_stream_source^>^ flv_media_stream_source::create_async(IRandomAccessStream^ random_access_stream)
{
    return create_async(random_access_stream, true);
}

IAsyncOperation<flv_media_stream_source^>^ flv_media_stream_source::create_async(IRandomAccessStream^ random_access_stream, bool stream_can_seek)
{
    auto player = ref new flv_player();
    player->set_source(random_access_stream);
    auto media_info = ref new Map<Platform::String^, Platform::String^>();
    auto shared_task = std::make_shared<concurrency::task<open_result>>(concurrency::create_task(player->open_async(media_info)));
    return concurrency::create_async([=]() -> flv_media_stream_source^ {
        auto result = shared_task->get();
        if (result != open_result::ok) {
            player->close();
            return nullptr;
        }
        auto acpd_w = media_info->Lookup(L"AudioCodecPrivateData")->ToString();
        std::string acpd;
        std::transform(acpd_w->Begin(), acpd_w->End(), std::back_inserter(acpd), [](wchar_t ch) -> char {
            return static_cast<char>(ch);
        });
        unsigned int channel_count = std::stol(acpd.substr(4, 2), 0, 16) + std::stol(acpd.substr(6, 2), 0, 16) * 0x100;
        unsigned int sample_rate = std::stol(acpd.substr(8, 2), 0, 16) + std::stol(acpd.substr(10, 2), 0, 16) * 0x100 +
            std::stol(acpd.substr(12, 2), 0, 16) * 0x10000 + std::stol(acpd.substr(14, 2), 0, 16) * 0x1000000;
        unsigned int bit_rate = sample_rate * (std::stol(acpd.substr(28, 2), 0, 16) + std::stol(acpd.substr(30, 2), 0, 16) * 0x100);
        auto aep = AudioEncodingProperties::CreateAac(sample_rate, channel_count, bit_rate);
        auto asd = ref new AudioStreamDescriptor(aep);
        auto vep = VideoEncodingProperties::CreateH264();
        auto video_width = std::stoul(media_info->Lookup("Width")->ToString()->Data());
        auto video_height = std::stoul(media_info->Lookup("Width")->ToString()->Data());
        // It seems that H.264 only supports even numbered dimensions.
        vep->Width = video_width - (video_width % 2);
        vep->Height = video_height - (video_height % 2);
        auto vsd = ref new VideoStreamDescriptor(vep);
        auto mss = ref new MediaStreamSource(asd);
        mss->AddStreamDescriptor(vsd);
        mss->CanSeek = stream_can_seek && (media_info->Lookup(L"CanSeek")->ToString() == L"True");
        // Set BufferTime to 0 to improve seek experience in Debug mode
        mss->BufferTime = TimeSpan{ 0 };
        mss->Duration = TimeSpan{ std::stoll(media_info->Lookup(L"Duration")->ToString()->Data()) };
        auto flv_mss = ref new flv_media_stream_source();
        flv_mss->init(player, mss);
        return flv_mss;
    });
}

MediaStreamSource^ flv_media_stream_source::unwrap()
{
    return this->mss;
}

flv_media_stream_source::~flv_media_stream_source()
{
    if (this->player) {
        this->player->close();
        this->player = nullptr;
    }
    if (this->mss) {
        this->mss->Starting -= this->starting_event_token;
        this->mss->SampleRequested -= this->sample_requested_event_token;
        this->mss = nullptr;
    }
}

void flv_media_stream_source::on_starting(MediaStreamSource^ sender, MediaStreamSourceStartingEventArgs^ args)
{
    auto request = args->Request;
    auto start_position = request->StartPosition;
    if (start_position == nullptr) {
        request->SetActualStartPosition(TimeSpan{ this->player->get_position() });
    }
    else if (std::abs(start_position->Value.Duration - this->player->get_position()) < 10000000) {
        // No seek if interval less than 1 second
        request->SetActualStartPosition(TimeSpan{ this->player->get_position() });
    }
    else {
        auto deferral = request->GetDeferral();
        concurrency::create_task(this->player->begin_seek(start_position->Value.Duration)).then([=](concurrency::task<std::int64_t> task) {
            auto seek_to_time = task.get();
            if (seek_to_time == -1) {
                return;
            }
            request->SetActualStartPosition(TimeSpan{ seek_to_time });
            deferral->Complete();
            this->player->end_seek();
        });
    }
}

void flv_media_stream_source::on_sample_requested(MediaStreamSource^ sender, MediaStreamSourceSampleRequestedEventArgs^ args)
{
    auto request = args->Request;
    auto deferral = request->GetDeferral();
    if (request->StreamDescriptor->GetType()->FullName == AudioStreamDescriptor::typeid->FullName) {
        auto sample_info = ref new Map<Platform::String^, Platform::Object^>();
        concurrency::create_task(this->player->get_sample_async(sample_type::audio, sample_info)).then([=](concurrency::task<get_sample_result> task) {
            auto result = task.get();
            if (result == get_sample_result::ok) {
                auto sample = MediaStreamSample::CreateFromBuffer(dynamic_cast<Buffer^>(sample_info->Lookup(L"Data")),
                    TimeSpan{ std::stoll(sample_info->Lookup(L"Timestamp")->ToString()->Data()) });
                request->Sample = sample;
            }
            else if (result == get_sample_result::eos) {
                request->Sample = nullptr;
            }
            else if (result == get_sample_result::error) {
                sender->NotifyError(MediaStreamSourceErrorStatus::Other);
                return;
            }
            else {
                return;
            }
            deferral->Complete();
        });
    }
    else if (request->StreamDescriptor->GetType()->FullName == VideoStreamDescriptor::typeid->FullName) {
        auto sample_info = ref new Map<Platform::String^, Platform::Object^>();
        concurrency::create_task(this->player->get_sample_async(sample_type::video, sample_info)).then([=](concurrency::task<get_sample_result> task) {
            auto result = task.get();
            if (result == get_sample_result::ok) {
                auto sample = MediaStreamSample::CreateFromBuffer(dynamic_cast<Buffer^>(sample_info->Lookup(L"Data")),
                    TimeSpan{ std::stoll(sample_info->Lookup(L"Timestamp")->ToString()->Data()) });
                sample->DecodeTimestamp = TimeSpan{ std::stoll(sample_info->Lookup(L"DecodeTimestamp")->ToString()->Data()) };
                sample->KeyFrame = sample_info->Lookup(L"KeyFrame")->ToString() == L"True";
                request->Sample = sample;
            }
            else if (result == get_sample_result::eos) {
                request->Sample = nullptr;
            }
            else if (result == get_sample_result::error) {
                sender->NotifyError(MediaStreamSourceErrorStatus::Other);
                return;
            }
            else {
                return;
            }
            deferral->Complete();
        });
    }
}

} // namespace dawn_player
<commit_msg>flv_media_stream_source: Throws exception on failure in create_async<commit_after>/*
*    flv_media_stream_source.cpp:
*
*    Copyright (C) 2015 limhiaoing <blog.poxiao.me> All Rights Reserved.
*
*/

#include "pch.h"

#include <algorithm>
#include <memory>
#include <string>

#include "flv_media_stream_source.hpp"
#include "flv_player.hpp"

using namespace Platform::Collections;
using namespace Windows::Media::MediaProperties;

namespace dawn_player {

flv_media_stream_source::flv_media_stream_source()
{
}

void flv_media_stream_source::init(flv_player^ player, MediaStreamSource^ mss)
{
    this->player = player;
    this->mss = mss;
    starting_event_token = this->mss->Starting += ref new TypedEventHandler<MediaStreamSource^, MediaStreamSourceStartingEventArgs^>(this, &flv_media_stream_source::on_starting);
    sample_requested_event_token = this->mss->SampleRequested += ref new TypedEventHandler<MediaStreamSource^, MediaStreamSourceSampleRequestedEventArgs^>(this, &flv_media_stream_source::on_sample_requested);
}

IAsyncOperation<flv_media_stream_source^>^ flv_media_stream_source::create_async(IRandomAccessStream^ random_access_stream)
{
    return create_async(random_access_stream, true);
}

IAsyncOperation<flv_media_stream_source^>^ flv_media_stream_source::create_async(IRandomAccessStream^ random_access_stream, bool stream_can_seek)
{
    auto player = ref new flv_player();
    player->set_source(random_access_stream);
    auto media_info = ref new Map<Platform::String^, Platform::String^>();
    auto shared_task = std::make_shared<concurrency::task<open_result>>(concurrency::create_task(player->open_async(media_info)));
    return concurrency::create_async([=]() -> flv_media_stream_source^ {
        auto result = shared_task->get();
        if (result != open_result::ok) {
            player->close();
        }
        if (result == open_result::abort) {
            throw ref new Platform::OperationCanceledException("Operation canceled.");
        }
        else if (result != open_result::ok) {
            throw ref new Platform::FailureException("Failed to open FLV file.");
        }
        auto acpd_w = media_info->Lookup(L"AudioCodecPrivateData")->ToString();
        std::string acpd;
        std::transform(acpd_w->Begin(), acpd_w->End(), std::back_inserter(acpd), [](wchar_t ch) -> char {
            return static_cast<char>(ch);
        });
        unsigned int channel_count = std::stol(acpd.substr(4, 2), 0, 16) + std::stol(acpd.substr(6, 2), 0, 16) * 0x100;
        unsigned int sample_rate = std::stol(acpd.substr(8, 2), 0, 16) + std::stol(acpd.substr(10, 2), 0, 16) * 0x100 +
            std::stol(acpd.substr(12, 2), 0, 16) * 0x10000 + std::stol(acpd.substr(14, 2), 0, 16) * 0x1000000;
        unsigned int bit_rate = sample_rate * (std::stol(acpd.substr(28, 2), 0, 16) + std::stol(acpd.substr(30, 2), 0, 16) * 0x100);
        auto aep = AudioEncodingProperties::CreateAac(sample_rate, channel_count, bit_rate);
        auto asd = ref new AudioStreamDescriptor(aep);
        auto vep = VideoEncodingProperties::CreateH264();
        auto video_width = std::stoul(media_info->Lookup("Width")->ToString()->Data());
        auto video_height = std::stoul(media_info->Lookup("Width")->ToString()->Data());
        // It seems that H.264 only supports even numbered dimensions.
        vep->Width = video_width - (video_width % 2);
        vep->Height = video_height - (video_height % 2);
        auto vsd = ref new VideoStreamDescriptor(vep);
        auto mss = ref new MediaStreamSource(asd);
        mss->AddStreamDescriptor(vsd);
        mss->CanSeek = stream_can_seek && (media_info->Lookup(L"CanSeek")->ToString() == L"True");
        // Set BufferTime to 0 to improve seek experience in Debug mode
        mss->BufferTime = TimeSpan{ 0 };
        mss->Duration = TimeSpan{ std::stoll(media_info->Lookup(L"Duration")->ToString()->Data()) };
        auto flv_mss = ref new flv_media_stream_source();
        flv_mss->init(player, mss);
        return flv_mss;
    });
}

MediaStreamSource^ flv_media_stream_source::unwrap()
{
    return this->mss;
}

flv_media_stream_source::~flv_media_stream_source()
{
    if (this->player) {
        this->player->close();
        this->player = nullptr;
    }
    if (this->mss) {
        this->mss->Starting -= this->starting_event_token;
        this->mss->SampleRequested -= this->sample_requested_event_token;
        this->mss = nullptr;
    }
}

void flv_media_stream_source::on_starting(MediaStreamSource^ sender, MediaStreamSourceStartingEventArgs^ args)
{
    auto request = args->Request;
    auto start_position = request->StartPosition;
    if (start_position == nullptr) {
        request->SetActualStartPosition(TimeSpan{ this->player->get_position() });
    }
    else if (std::abs(start_position->Value.Duration - this->player->get_position()) < 10000000) {
        // No seek if interval less than 1 second
        request->SetActualStartPosition(TimeSpan{ this->player->get_position() });
    }
    else {
        auto deferral = request->GetDeferral();
        concurrency::create_task(this->player->begin_seek(start_position->Value.Duration)).then([=](concurrency::task<std::int64_t> task) {
            auto seek_to_time = task.get();
            if (seek_to_time == -1) {
                return;
            }
            request->SetActualStartPosition(TimeSpan{ seek_to_time });
            deferral->Complete();
            this->player->end_seek();
        });
    }
}

void flv_media_stream_source::on_sample_requested(MediaStreamSource^ sender, MediaStreamSourceSampleRequestedEventArgs^ args)
{
    auto request = args->Request;
    auto deferral = request->GetDeferral();
    if (request->StreamDescriptor->GetType()->FullName == AudioStreamDescriptor::typeid->FullName) {
        auto sample_info = ref new Map<Platform::String^, Platform::Object^>();
        concurrency::create_task(this->player->get_sample_async(sample_type::audio, sample_info)).then([=](concurrency::task<get_sample_result> task) {
            auto result = task.get();
            if (result == get_sample_result::ok) {
                auto sample = MediaStreamSample::CreateFromBuffer(dynamic_cast<Buffer^>(sample_info->Lookup(L"Data")),
                    TimeSpan{ std::stoll(sample_info->Lookup(L"Timestamp")->ToString()->Data()) });
                request->Sample = sample;
            }
            else if (result == get_sample_result::eos) {
                request->Sample = nullptr;
            }
            else if (result == get_sample_result::error) {
                sender->NotifyError(MediaStreamSourceErrorStatus::Other);
                return;
            }
            else {
                return;
            }
            deferral->Complete();
        });
    }
    else if (request->StreamDescriptor->GetType()->FullName == VideoStreamDescriptor::typeid->FullName) {
        auto sample_info = ref new Map<Platform::String^, Platform::Object^>();
        concurrency::create_task(this->player->get_sample_async(sample_type::video, sample_info)).then([=](concurrency::task<get_sample_result> task) {
            auto result = task.get();
            if (result == get_sample_result::ok) {
                auto sample = MediaStreamSample::CreateFromBuffer(dynamic_cast<Buffer^>(sample_info->Lookup(L"Data")),
                    TimeSpan{ std::stoll(sample_info->Lookup(L"Timestamp")->ToString()->Data()) });
                sample->DecodeTimestamp = TimeSpan{ std::stoll(sample_info->Lookup(L"DecodeTimestamp")->ToString()->Data()) };
                sample->KeyFrame = sample_info->Lookup(L"KeyFrame")->ToString() == L"True";
                request->Sample = sample;
            }
            else if (result == get_sample_result::eos) {
                request->Sample = nullptr;
            }
            else if (result == get_sample_result::error) {
                sender->NotifyError(MediaStreamSourceErrorStatus::Other);
                return;
            }
            else {
                return;
            }
            deferral->Complete();
        });
    }
}

} // namespace dawn_player
<|endoftext|>


<commit_before><commit_msg>Mistake in choice of FM_PROP<commit_after><|endoftext|>


<commit_before>#include "application/setups/editor/gui/editor_entity_selector.h"

#include "game/transcendental/cosmos.h"

void editor_entity_selector::clear() {
	in_rectangular_selection.clear();
	hovered.unset();
};

std::optional<ltrb> editor_entity_selector::find_screen_space_rect_selection(
	const camera_cone& camera,
	vec2i screen_size,
	vec2i mouse_pos
) const {
	if (rectangular_drag_origin.has_value()) {
		return ltrb::from_points(
			mouse_pos,
			camera.to_screen_space(screen_size, *rectangular_drag_origin)
		);
	}

	return std::nullopt;
}

void editor_entity_selector::do_left_press(
	const cosmos& cosm,
	bool has_ctrl,
	const vec2i world_cursor_pos,
	target_selections_type& selections
) {
	last_ldown_position = world_cursor_pos;
	held = hovered;

	if (const auto held_entity = cosm[held]) {
		flavour_of_held = held_entity.get_flavour_id();
		LOG_NVPS(flavour_of_held);
	}

	if (!has_ctrl) {
		/* Make a new selection */
		selections.clear();
	}
}

void editor_entity_selector::finish_rectangular(target_selections_type& into) {
	target_selections_type new_selections;

	for_each_selected_entity(
		[&](const auto e) {
			new_selections.emplace(e);
		},
		into
	);

	into = new_selections;

	rectangular_drag_origin = std::nullopt;
	in_rectangular_selection.clear();
	flavour_of_held = {};
}

void editor_entity_selector::do_left_release(
	const bool has_ctrl,
	target_selections_type& selections
) {
	if (const auto clicked = held) {
		if (has_ctrl) {
			if (found_in(selections, clicked)) {
				selections.erase(clicked);
			}
			else {
				selections.emplace(clicked);
			}
		}
		else {
			selections = { clicked };
		}
	}

	held = {};

	finish_rectangular(selections);
}

void editor_entity_selector::select_all(
	const cosmos& cosm,
	const editor_rect_select_type rect_select_mode,
	std::unordered_set<entity_id>& current_selections
) {
	const auto compared_flavour = [&](){
		if (flavour_of_held) {
			return flavour_of_held;
		}

		if (current_selections.size() == 1) {
			return cosm[(*current_selections.begin())].get_flavour_id();
		}

		return entity_flavour_id();
	}();

	finish_rectangular(current_selections);

	current_selections.clear();
	current_selections.reserve(cosm.get_entities_count());

	cosmic::for_each_entity(cosm, [&](const auto handle) {
		const auto id = handle.get_id();

		if (compared_flavour && rect_select_mode == editor_rect_select_type::SAME_FLAVOUR) {
			if (handle.get_flavour_id() == compared_flavour) {
				current_selections.emplace(id);
			}
		}
		else {
			current_selections.emplace(id);
		}
	});
}

void editor_entity_selector::unhover() {
	hovered = {};
}

static bool should_hover_standard_aabb(const cosmos& cosm, const entity_id id) {
	return cosm[id].dispatch([](const auto typed_handle){
		using T = std::decay_t<decltype(typed_handle)>;
		using E = typename T::used_entity_type;

		if (std::is_same_v<E, wandering_pixels_decoration>) {
			return false;
		}
		else if (std::is_same_v<E, static_light>) {
			return false;
		}

		return true;
	});
};

void editor_entity_selector::do_mousemotion(
	const necessary_images_in_atlas& sizes_for_icons,

	const cosmos& cosm,
	const editor_rect_select_type rect_select_mode,
	const vec2 world_cursor_pos,
	const camera_cone current_cone,
	const bool left_button_pressed
) {
	hovered = {};

	auto get_world_xywh = [&](const auto icon_id, const components::transform where) {
		return xywh::center_and_size(where.pos, vec2(sizes_for_icons.at(icon_id).get_size()) / current_cone.zoom).expand_to_square();
	};

	{
		const bool drag_just_left_dead_area = [&]() {
			const auto drag_dead_area = 3.f;
			const auto drag_offset = world_cursor_pos - last_ldown_position;

			return !drag_offset.is_epsilon(drag_dead_area);
		}();

		if (left_button_pressed && drag_just_left_dead_area) {
			rectangular_drag_origin = last_ldown_position;
			held = {};
		}
	}

	if (rectangular_drag_origin.has_value()) {
		auto world_range = ltrb::from_points(*rectangular_drag_origin, world_cursor_pos);

		in_rectangular_selection.clear();

		const auto query = visible_entities_query{
			cosm,
			{ world_range.get_center(), 1.f },
			world_range.get_size()
		};

		in_rectangular_selection.acquire_non_physical(query);
		in_rectangular_selection.acquire_physical(query);

		erase_if(in_rectangular_selection.all, [&](const entity_id id) {
			return !should_hover_standard_aabb(cosm, id);
	   	});

		for_each_iconed_entity(cosm,
			[&](const auto handle,
				const auto tex_id,
			   	const auto where,
				const auto color
			) {
				if (get_world_xywh(tex_id, where).hover(world_range)) {
					in_rectangular_selection.all.push_back(handle.get_id());
				}
			}
		);

		if (rect_select_mode == editor_rect_select_type::SAME_FLAVOUR) {
			erase_if(in_rectangular_selection.all, [&](const entity_id id) {
				return !(cosm[id].get_flavour_id() == flavour_of_held);
			});
		}
	}
	else {
		hovered.unset();

		for_each_iconed_entity(cosm,
			[&](const auto handle,
				const auto tex_id,
			   	const auto where,
				const auto color
			) {
				if (get_world_xywh(tex_id, where).hover(world_cursor_pos)) {
					hovered = handle.get_id();
				}
			}
		);

		if (!hovered) {
			hovered = get_hovered_world_entity(
				cosm,
				world_cursor_pos,
				[&](const entity_id id) {
					return should_hover_standard_aabb(cosm, id);
				}
			);
		}
	}
}

std::optional<ltrb> editor_entity_selector::find_selection_aabb(
	const cosmos& cosm,
	const target_selections_type& signi_selections
) const {
	ltrb total;

	auto combine_aabb_of = [&total, &cosm](const entity_id id) {
		const auto handle = cosm[id];

		if (const auto aabb = handle.find_aabb()) {
			total.contain(*aabb);
		}
	};

	if (held && cosm[held]) {
		combine_aabb_of(held);
	}

	for_each_selected_entity(
		combine_aabb_of,
		signi_selections
	);

	if (total.good()) {
		return total;
	}

	return std::nullopt;
}

std::optional<rgba> editor_entity_selector::find_highlight_color_of(
	const editor_entity_selector_settings& settings,
	const entity_id id,
	const target_selections_type& signi_selections
) const {
	if (held == id) {
		return settings.held_color;
	}

	if (hovered == id) {
		return settings.hovered_color;
	}

	const bool in_signi = found_in(signi_selections, id);
	const bool in_rectangular = found_in(in_rectangular_selection.all, id);

	if (in_signi != in_rectangular) {
		return settings.selected_color;
	}

	return std::nullopt;
}
<commit_msg>don't ever clear the flavour of held<commit_after>#include "application/setups/editor/gui/editor_entity_selector.h"

#include "game/transcendental/cosmos.h"

void editor_entity_selector::clear() {
	in_rectangular_selection.clear();
	hovered.unset();
};

std::optional<ltrb> editor_entity_selector::find_screen_space_rect_selection(
	const camera_cone& camera,
	vec2i screen_size,
	vec2i mouse_pos
) const {
	if (rectangular_drag_origin.has_value()) {
		return ltrb::from_points(
			mouse_pos,
			camera.to_screen_space(screen_size, *rectangular_drag_origin)
		);
	}

	return std::nullopt;
}

void editor_entity_selector::do_left_press(
	const cosmos& cosm,
	bool has_ctrl,
	const vec2i world_cursor_pos,
	target_selections_type& selections
) {
	last_ldown_position = world_cursor_pos;
	held = hovered;

	if (const auto held_entity = cosm[held]) {
		flavour_of_held = held_entity.get_flavour_id();
		LOG_NVPS(flavour_of_held);
	}

	if (!has_ctrl) {
		/* Make a new selection */
		selections.clear();
	}
}

void editor_entity_selector::finish_rectangular(target_selections_type& into) {
	target_selections_type new_selections;

	for_each_selected_entity(
		[&](const auto e) {
			new_selections.emplace(e);
		},
		into
	);

	into = new_selections;

	rectangular_drag_origin = std::nullopt;
	in_rectangular_selection.clear();
}

void editor_entity_selector::do_left_release(
	const bool has_ctrl,
	target_selections_type& selections
) {
	if (const auto clicked = held) {
		if (has_ctrl) {
			if (found_in(selections, clicked)) {
				selections.erase(clicked);
			}
			else {
				selections.emplace(clicked);
			}
		}
		else {
			selections = { clicked };
		}
	}

	held = {};

	finish_rectangular(selections);
}

void editor_entity_selector::select_all(
	const cosmos& cosm,
	const editor_rect_select_type rect_select_mode,
	std::unordered_set<entity_id>& current_selections
) {
	const auto compared_flavour = flavour_of_held;
	finish_rectangular(current_selections);

	current_selections.clear();
	current_selections.reserve(cosm.get_entities_count());

	cosmic::for_each_entity(cosm, [&](const auto handle) {
		const auto id = handle.get_id();

		if (compared_flavour && rect_select_mode == editor_rect_select_type::SAME_FLAVOUR) {
			if (handle.get_flavour_id() == compared_flavour) {
				current_selections.emplace(id);
			}
		}
		else {
			current_selections.emplace(id);
		}
	});
}

void editor_entity_selector::unhover() {
	hovered = {};
}

static bool should_hover_standard_aabb(const cosmos& cosm, const entity_id id) {
	return cosm[id].dispatch([](const auto typed_handle){
		using T = std::decay_t<decltype(typed_handle)>;
		using E = typename T::used_entity_type;

		if (std::is_same_v<E, wandering_pixels_decoration>) {
			return false;
		}
		else if (std::is_same_v<E, static_light>) {
			return false;
		}

		return true;
	});
};

void editor_entity_selector::do_mousemotion(
	const necessary_images_in_atlas& sizes_for_icons,

	const cosmos& cosm,
	const editor_rect_select_type rect_select_mode,
	const vec2 world_cursor_pos,
	const camera_cone current_cone,
	const bool left_button_pressed
) {
	hovered = {};

	auto get_world_xywh = [&](const auto icon_id, const components::transform where) {
		return xywh::center_and_size(where.pos, vec2(sizes_for_icons.at(icon_id).get_size()) / current_cone.zoom).expand_to_square();
	};

	{
		const bool drag_just_left_dead_area = [&]() {
			const auto drag_dead_area = 3.f;
			const auto drag_offset = world_cursor_pos - last_ldown_position;

			return !drag_offset.is_epsilon(drag_dead_area);
		}();

		if (left_button_pressed && drag_just_left_dead_area) {
			rectangular_drag_origin = last_ldown_position;
			held = {};
		}
	}

	if (rectangular_drag_origin.has_value()) {
		auto world_range = ltrb::from_points(*rectangular_drag_origin, world_cursor_pos);

		in_rectangular_selection.clear();

		const auto query = visible_entities_query{
			cosm,
			{ world_range.get_center(), 1.f },
			world_range.get_size()
		};

		in_rectangular_selection.acquire_non_physical(query);
		in_rectangular_selection.acquire_physical(query);

		erase_if(in_rectangular_selection.all, [&](const entity_id id) {
			return !should_hover_standard_aabb(cosm, id);
	   	});

		for_each_iconed_entity(cosm,
			[&](const auto handle,
				const auto tex_id,
			   	const auto where,
				const auto color
			) {
				if (get_world_xywh(tex_id, where).hover(world_range)) {
					in_rectangular_selection.all.push_back(handle.get_id());
				}
			}
		);

		if (rect_select_mode == editor_rect_select_type::SAME_FLAVOUR) {
			erase_if(in_rectangular_selection.all, [&](const entity_id id) {
				return !(cosm[id].get_flavour_id() == flavour_of_held);
			});
		}
	}
	else {
		hovered.unset();

		for_each_iconed_entity(cosm,
			[&](const auto handle,
				const auto tex_id,
			   	const auto where,
				const auto color
			) {
				if (get_world_xywh(tex_id, where).hover(world_cursor_pos)) {
					hovered = handle.get_id();
				}
			}
		);

		if (!hovered) {
			hovered = get_hovered_world_entity(
				cosm,
				world_cursor_pos,
				[&](const entity_id id) {
					return should_hover_standard_aabb(cosm, id);
				}
			);
		}
	}
}

std::optional<ltrb> editor_entity_selector::find_selection_aabb(
	const cosmos& cosm,
	const target_selections_type& signi_selections
) const {
	ltrb total;

	auto combine_aabb_of = [&total, &cosm](const entity_id id) {
		const auto handle = cosm[id];

		if (const auto aabb = handle.find_aabb()) {
			total.contain(*aabb);
		}
	};

	if (held && cosm[held]) {
		combine_aabb_of(held);
	}

	for_each_selected_entity(
		combine_aabb_of,
		signi_selections
	);

	if (total.good()) {
		return total;
	}

	return std::nullopt;
}

std::optional<rgba> editor_entity_selector::find_highlight_color_of(
	const editor_entity_selector_settings& settings,
	const entity_id id,
	const target_selections_type& signi_selections
) const {
	if (held == id) {
		return settings.held_color;
	}

	if (hovered == id) {
		return settings.hovered_color;
	}

	const bool in_signi = found_in(signi_selections, id);
	const bool in_rectangular = found_in(in_rectangular_selection.all, id);

	if (in_signi != in_rectangular) {
		return settings.selected_color;
	}

	return std::nullopt;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: e3ditem.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: aw $ $Date: 2000-12-11 11:54:22 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_DRAWING_DIRECTION3D_HPP_
#include <com/sun/star/drawing/Direction3D.hpp>
#endif
#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif
#pragma hdrstop

#include "e3ditem.hxx"

using namespace ::rtl;
using namespace ::com::sun::star;

// STATIC DATA -----------------------------------------------------------

DBG_NAME(SvxVector3DItem);

// -----------------------------------------------------------------------

TYPEINIT1_AUTOFACTORY(SvxVector3DItem, SfxPoolItem);

// -----------------------------------------------------------------------

SvxVector3DItem::SvxVector3DItem()
{
    DBG_CTOR(SvxVector3DItem, 0);
}

// -----------------------------------------------------------------------

SvxVector3DItem::SvxVector3DItem( USHORT nWhich, const Vector3D& rVal ) :
    SfxPoolItem( nWhich ),
    aVal( rVal )
{
    DBG_CTOR(SvxVector3DItem, 0);
}

// -----------------------------------------------------------------------

SvxVector3DItem::SvxVector3DItem( USHORT nWhich, SvStream& rStream ) :
    SfxPoolItem( nWhich )
{
    DBG_CTOR(SvxVector3DItem, 0);
    rStream >> aVal;
}

// -----------------------------------------------------------------------

SvxVector3DItem::SvxVector3DItem( const SvxVector3DItem& rItem ) :
    SfxPoolItem( rItem ),
    aVal( rItem.aVal )
{
    DBG_CTOR(SvxVector3DItem, 0);
}

// -----------------------------------------------------------------------

int SvxVector3DItem::operator==( const SfxPoolItem &rItem ) const
{
    DBG_CHKTHIS(SvxVector3DItem, 0);
    DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
    return ((SvxVector3DItem&)rItem).aVal == aVal;
}

// -----------------------------------------------------------------------

SfxPoolItem* SvxVector3DItem::Clone( SfxItemPool *pPool ) const
{
    DBG_CHKTHIS(SvxVector3DItem, 0);
    return new SvxVector3DItem( *this );
}

// -----------------------------------------------------------------------

SfxPoolItem* SvxVector3DItem::Create(SvStream &rStream, USHORT nVersion) const
{
    DBG_CHKTHIS(SvxVector3DItem, 0);
    Vector3D aStr;
    rStream >> aStr;
    return new SvxVector3DItem(Which(), aStr);
}

// -----------------------------------------------------------------------

SvStream& SvxVector3DItem::Store(SvStream &rStream, USHORT nItemVersion) const
{
    DBG_CHKTHIS(SvxVector3DItem, 0);

    // ## if (nItemVersion)
    rStream << aVal;

    return rStream;
}

// -----------------------------------------------------------------------

sal_Bool SvxVector3DItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
{
    drawing::Direction3D aDirection;

    // Werte eintragen
    aDirection.DirectionX = aVal.X();
    aDirection.DirectionY = aVal.Y();
    aDirection.DirectionZ = aVal.Z();

    rVal <<= aDirection;
    return( sal_True );
}

// -----------------------------------------------------------------------

sal_Bool SvxVector3DItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
{
    drawing::Direction3D aDirection;
    if(!(rVal >>= aDirection))
        return sal_False;

    aVal.X() = aDirection.DirectionX;
    aVal.Y() = aDirection.DirectionY;
    aVal.Z() = aDirection.DirectionZ;
    return sal_True;
}

// -----------------------------------------------------------------------

USHORT SvxVector3DItem::GetVersion (USHORT nFileFormatVersion) const
{
    return (nFileFormatVersion == SOFFICE_FILEFORMAT_31) ? USHRT_MAX : 0;
}

<commit_msg>#i10000# moved ~SvxVector3DItem from e3ditem.hxx<commit_after>/*************************************************************************
 *
 *  $RCSfile: e3ditem.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2005-01-24 16:45:32 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_DRAWING_DIRECTION3D_HPP_
#include <com/sun/star/drawing/Direction3D.hpp>
#endif
#ifndef _STREAM_HXX
#include <tools/stream.hxx>
#endif
#pragma hdrstop

#include "e3ditem.hxx"

using namespace ::rtl;
using namespace ::com::sun::star;

// STATIC DATA -----------------------------------------------------------

DBG_NAMEEX(SvxVector3DItem);
DBG_NAME(SvxVector3DItem);

// -----------------------------------------------------------------------

TYPEINIT1_AUTOFACTORY(SvxVector3DItem, SfxPoolItem);

// -----------------------------------------------------------------------

SvxVector3DItem::SvxVector3DItem()
{
    DBG_CTOR(SvxVector3DItem, 0);
}

SvxVector3DItem::~SvxVector3DItem()
{
    DBG_DTOR(SvxVector3DItem, 0);
}

// -----------------------------------------------------------------------

SvxVector3DItem::SvxVector3DItem( USHORT nWhich, const Vector3D& rVal ) :
    SfxPoolItem( nWhich ),
    aVal( rVal )
{
    DBG_CTOR(SvxVector3DItem, 0);
}

// -----------------------------------------------------------------------

SvxVector3DItem::SvxVector3DItem( USHORT nWhich, SvStream& rStream ) :
    SfxPoolItem( nWhich )
{
    DBG_CTOR(SvxVector3DItem, 0);
    rStream >> aVal;
}

// -----------------------------------------------------------------------

SvxVector3DItem::SvxVector3DItem( const SvxVector3DItem& rItem ) :
    SfxPoolItem( rItem ),
    aVal( rItem.aVal )
{
    DBG_CTOR(SvxVector3DItem, 0);
}

// -----------------------------------------------------------------------

int SvxVector3DItem::operator==( const SfxPoolItem &rItem ) const
{
    DBG_CHKTHIS(SvxVector3DItem, 0);
    DBG_ASSERT( SfxPoolItem::operator==( rItem ), "unequal type" );
    return ((SvxVector3DItem&)rItem).aVal == aVal;
}

// -----------------------------------------------------------------------

SfxPoolItem* SvxVector3DItem::Clone( SfxItemPool *pPool ) const
{
    DBG_CHKTHIS(SvxVector3DItem, 0);
    return new SvxVector3DItem( *this );
}

// -----------------------------------------------------------------------

SfxPoolItem* SvxVector3DItem::Create(SvStream &rStream, USHORT nVersion) const
{
    DBG_CHKTHIS(SvxVector3DItem, 0);
    Vector3D aStr;
    rStream >> aStr;
    return new SvxVector3DItem(Which(), aStr);
}

// -----------------------------------------------------------------------

SvStream& SvxVector3DItem::Store(SvStream &rStream, USHORT nItemVersion) const
{
    DBG_CHKTHIS(SvxVector3DItem, 0);

    // ## if (nItemVersion)
    rStream << aVal;

    return rStream;
}

// -----------------------------------------------------------------------

sal_Bool SvxVector3DItem::QueryValue( uno::Any& rVal, BYTE nMemberId ) const
{
    drawing::Direction3D aDirection;

    // Werte eintragen
    aDirection.DirectionX = aVal.X();
    aDirection.DirectionY = aVal.Y();
    aDirection.DirectionZ = aVal.Z();

    rVal <<= aDirection;
    return( sal_True );
}

// -----------------------------------------------------------------------

sal_Bool SvxVector3DItem::PutValue( const uno::Any& rVal, BYTE nMemberId )
{
    drawing::Direction3D aDirection;
    if(!(rVal >>= aDirection))
        return sal_False;

    aVal.X() = aDirection.DirectionX;
    aVal.Y() = aDirection.DirectionY;
    aVal.Z() = aDirection.DirectionZ;
    return sal_True;
}

// -----------------------------------------------------------------------

USHORT SvxVector3DItem::GetVersion (USHORT nFileFormatVersion) const
{
    return (nFileFormatVersion == SOFFICE_FILEFORMAT_31) ? USHRT_MAX : 0;
}

<|endoftext|>


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

///
/// @file dimm.H
/// @brief Encapsulation for dimms of all types
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: HB:FSP

#ifndef _MSS_DIMM_H_
#define _MSS_DIMM_H_

#include <fapi2.H>

#include <lib/mss_attribute_accessors.H>
#include <generic/memory/lib/utils/c_str.H>

namespace mss
{

namespace dimm
{

///
/// @class mss::dimm::kind
/// @brief A class containing information about a dimm like ranks, density, configuration - what kind of dimm is it?
///
class kind
{
    public:

        ///
        /// @brief Generate a vector of DIMM kind from a vector of DIMM
        /// @param[in] i_dimm a vector of DIMM
        /// @return std::vector of dimm::kind relating to the DIMM passed in
        ///
        static std::vector<kind> vector(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimm)
        {
            std::vector<kind> l_kinds;

            for (const auto& d : i_dimm)
            {
                l_kinds.push_back( kind(d) );
            }

            return l_kinds;
        }

        ///
        /// @brief operator=() - assign kinds (needed to sort vectors of kinds)
        /// @param[in] i_rhs the right hand side of the assignment statement
        /// @return reference to this
        ///
        inline kind& operator=(const kind& i_rhs)
        {
            iv_target = i_rhs.iv_target;
            iv_master_ranks = i_rhs.iv_master_ranks;
            iv_total_ranks = i_rhs.iv_total_ranks;
            iv_dram_density = i_rhs.iv_dram_density;
            iv_dram_width = i_rhs.iv_dram_width;
            iv_dram_generation = i_rhs.iv_dram_generation;
            iv_dimm_type = i_rhs.iv_dimm_type;
            iv_rows = i_rhs.iv_rows;
            iv_size = i_rhs.iv_size;
            iv_mfgid = i_rhs.iv_mfgid;
            iv_stack_type = i_rhs.iv_stack_type;
            iv_hybrid = i_rhs.iv_hybrid;
            iv_hybrid_memory_type = i_rhs.iv_hybrid_memory_type;
            return *this;
        }

        ///
        /// @brief operator==() - are two kinds the same?
        /// @param[in] i_rhs the right hand side of the comparison statement
        /// @return bool true iff the two kind are of the same kind
        /// @warning this does not compare the targets (iv_target,) just the values
        /// Also does not compare the mfgid as that's not really part of the DIMM kind but is additional information
        ///
        inline bool operator==(const kind& i_rhs) const
        {
            return ((iv_master_ranks == i_rhs.iv_master_ranks) &&
                    (iv_total_ranks == i_rhs.iv_total_ranks) &&
                    (iv_dram_density == i_rhs.iv_dram_density) &&
                    (iv_dram_width == i_rhs.iv_dram_width) &&
                    (iv_dram_generation == i_rhs.iv_dram_generation) &&
                    (iv_dimm_type == i_rhs.iv_dimm_type) &&
                    (iv_rows == i_rhs.iv_rows) &&
                    (iv_size == i_rhs.iv_size) &&
                    (iv_stack_type == i_rhs.iv_stack_type) &&
                    (iv_hybrid == i_rhs.iv_hybrid) &&
                    (iv_hybrid_memory_type == i_rhs.iv_hybrid_memory_type));
        }

        ///
        /// @brief operator!=() - are two kinds different?
        /// @param[in] i_rhs the right hand side of the comparison statement
        /// @return bool true iff the two kind are of different
        /// @warning this does not compare the targets (iv_target,) just the values
        ///
        inline bool operator!=(const kind& i_rhs) const
        {
            return !(this->operator==(i_rhs));
        }

        ///
        /// @brief Construct a dimm::kind data structure - information about the kind of DIMM this is
        /// @param[in] i_target a DIMM target
        ///
        kind(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target):
            iv_target(i_target)
        {
            FAPI_TRY( mss::eff_dram_gen(i_target, iv_dram_generation) );
            FAPI_TRY( mss::eff_dimm_type(i_target, iv_dimm_type) );
            FAPI_TRY( mss::eff_dram_density(i_target, iv_dram_density) );
            FAPI_TRY( mss::eff_dram_width(i_target, iv_dram_width) );
            FAPI_TRY( mss::eff_num_master_ranks_per_dimm(i_target, iv_master_ranks) );
            FAPI_TRY( mss::eff_num_ranks_per_dimm(i_target, iv_total_ranks) );
            FAPI_TRY( mss::eff_dram_row_bits(i_target, iv_rows) );
            FAPI_TRY( mss::eff_dimm_size(i_target, iv_size) );
            FAPI_TRY( mss::eff_dram_mfg_id(i_target, iv_mfgid) );
            FAPI_TRY( mss::eff_prim_stack_type( i_target, iv_stack_type) );
            FAPI_TRY( mss::eff_hybrid( i_target, iv_hybrid ));
            FAPI_TRY( mss::eff_hybrid_memory_type( i_target, iv_hybrid_memory_type ));
            return;

        fapi_try_exit:
            // Not 100% sure what to do here ...
            FAPI_ERR("error initializing DIMM structure: %s 0x%016lx", mss::c_str(i_target), uint64_t(fapi2::current_err));
            fapi2::Assert(false);
        }

        ///
        /// @brief Construct a DIMM kind used to identify this DIMM for tables.
        /// @param[in] i_master_ranks number of master ranks on the DIMM
        /// @param[in] i_total_ranks total number of ranks on the DIMM
        /// @param[in] i_dram_density density of the DRAM
        /// @param[in] i_dram_width width of the DRAM
        /// @param[in] i_dram_generation DRAM generation
        /// @param[in] i_dimm_type DIMM type (e.g. RDIMM)
        /// @param[in] i_rows number of rows in the DRAM
        /// @param[in] i_size the overal size of the DIMM in GB
        /// @param[in] i_mfgid the dram manufacturer id of the dimm, defaulted to 0
        /// @param[in] i_stack_type dram die type, single die package or 3DS
        /// @note can't be constexpr as fapi2::Target doesn't have a constexpr ctor.
        ///
        kind( const uint8_t i_master_ranks,
              const uint8_t i_total_ranks,
              const uint8_t i_dram_density,
              const uint8_t i_dram_width,
              const uint8_t i_dram_generation,
              const uint8_t i_dimm_type,
              const uint8_t i_rows,
              const uint32_t i_size,
              const uint16_t i_mfgid = 0,
              const uint8_t i_stack_type = fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_SDP,
              const uint8_t i_hybrid = fapi2::ENUM_ATTR_EFF_HYBRID_NOT_HYBRID,
              const uint8_t i_hybrid_memory_type = fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NONE):
            iv_target(0),
            iv_master_ranks(i_master_ranks),
            iv_total_ranks(i_total_ranks),
            iv_dram_density(i_dram_density),
            iv_dram_width(i_dram_width),
            iv_dram_generation(i_dram_generation),
            iv_dimm_type(i_dimm_type),
            iv_rows(i_rows),
            // TK consider calculating size rather than requiring it be set.
            iv_size(i_size),
            iv_mfgid(i_mfgid),
            iv_stack_type(i_stack_type),
            iv_hybrid(i_hybrid),
            iv_hybrid_memory_type(i_hybrid_memory_type)
        {
            // Bit of an idiot-check to be sure a hand-crafted dimm::kind make sense wrt slaves, masters, packages, etc.
            // Both of these are checked in eff_config. If they are messed up, they should be caught there
            if (iv_master_ranks > iv_total_ranks)
            {
                FAPI_ERR("Not enough total ranks? master: %d total: %d",
                         iv_master_ranks,
                         iv_total_ranks);
                fapi2::Assert(false);
            }

            if ((iv_total_ranks % iv_master_ranks) != 0)
            {
                FAPI_ERR("total or master ranks seems incorrect. master: %d total: %d",
                         iv_master_ranks,
                         iv_total_ranks);
                fapi2::Assert(false);
            }
        }

        fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
        uint8_t iv_master_ranks;
        uint8_t iv_total_ranks;
        uint8_t iv_dram_density;
        uint8_t iv_dram_width;
        uint8_t iv_dram_generation;
        uint8_t iv_dimm_type;
        uint8_t iv_rows;
        uint32_t iv_size;
        uint16_t iv_mfgid;
        uint8_t iv_stack_type;
        uint8_t iv_hybrid;
        uint8_t iv_hybrid_memory_type;

        ///
        /// @brief equal_config
        /// @param[in] i_input_compare the i_kind to compare against
        /// @return bool true iff the two kind are of the same kind for xlate purposes
        /// @warning this does not compare the targets (iv_target,), mfgid, prim_stack_type nor hybrid type
        ///
        inline bool equal_config(const kind& i_input_compare) const
        {
            return ((iv_master_ranks == i_input_compare.iv_master_ranks) &&
                    (iv_total_ranks == i_input_compare.iv_total_ranks) &&
                    (iv_dram_density == i_input_compare.iv_dram_density) &&
                    (iv_dram_width == i_input_compare.iv_dram_width) &&
                    (iv_dram_generation == i_input_compare.iv_dram_generation) &&
                    (iv_dimm_type == i_input_compare.iv_dimm_type) &&
                    (iv_rows == i_input_compare.iv_rows) &&
                    (iv_size == i_input_compare.iv_size));
        }
};

}

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

///
/// @file dimm.H
/// @brief Encapsulation for dimms of all types
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: HB:FSP

#ifndef _MSS_DIMM_H_
#define _MSS_DIMM_H_

#include <fapi2.H>

#include <lib/mss_attribute_accessors.H>
#include <generic/memory/lib/utils/c_str.H>

namespace mss
{

namespace dimm
{

///
/// @class mss::dimm::kind
/// @brief A class containing information about a dimm like ranks, density, configuration - what kind of dimm is it?
///
class kind
{
    public:

        ///
        /// @brief Generate a vector of DIMM kind from a vector of DIMM
        /// @param[in] i_dimm a vector of DIMM
        /// @return std::vector of dimm::kind relating to the DIMM passed in
        ///
        static std::vector<kind> vector(const std::vector<fapi2::Target<fapi2::TARGET_TYPE_DIMM>>& i_dimm)
        {
            std::vector<kind> l_kinds;

            for (const auto& d : i_dimm)
            {
                l_kinds.push_back( kind(d) );
            }

            return l_kinds;
        }

        ///
        /// @brief operator=() - assign kinds (needed to sort vectors of kinds)
        /// @param[in] i_rhs the right hand side of the assignment statement
        /// @return reference to this
        ///
        inline kind& operator=(const kind& i_rhs)
        {
            iv_target = i_rhs.iv_target;
            iv_master_ranks = i_rhs.iv_master_ranks;
            iv_total_ranks = i_rhs.iv_total_ranks;
            iv_dram_density = i_rhs.iv_dram_density;
            iv_dram_width = i_rhs.iv_dram_width;
            iv_dram_generation = i_rhs.iv_dram_generation;
            iv_dimm_type = i_rhs.iv_dimm_type;
            iv_rows = i_rhs.iv_rows;
            iv_size = i_rhs.iv_size;
            iv_mfgid = i_rhs.iv_mfgid;
            iv_stack_type = i_rhs.iv_stack_type;
            iv_hybrid = i_rhs.iv_hybrid;
            iv_hybrid_memory_type = i_rhs.iv_hybrid_memory_type;
            iv_rcd_mfgid = i_rhs.iv_rcd_mfgid;
            return *this;
        }

        ///
        /// @brief operator==() - are two kinds the same?
        /// @param[in] i_rhs the right hand side of the comparison statement
        /// @return bool true iff the two kind are of the same kind
        /// @warning this does not compare the targets (iv_target,) just the values
        /// Also does not compare the mfgid as that's not really part of the DIMM kind but is additional information
        ///
        inline bool operator==(const kind& i_rhs) const
        {
            return ((iv_master_ranks == i_rhs.iv_master_ranks) &&
                    (iv_total_ranks == i_rhs.iv_total_ranks) &&
                    (iv_dram_density == i_rhs.iv_dram_density) &&
                    (iv_dram_width == i_rhs.iv_dram_width) &&
                    (iv_dram_generation == i_rhs.iv_dram_generation) &&
                    (iv_dimm_type == i_rhs.iv_dimm_type) &&
                    (iv_rows == i_rhs.iv_rows) &&
                    (iv_size == i_rhs.iv_size) &&
                    (iv_stack_type == i_rhs.iv_stack_type) &&
                    (iv_hybrid == i_rhs.iv_hybrid) &&
                    (iv_hybrid_memory_type == i_rhs.iv_hybrid_memory_type) &&
                    (iv_rcd_mfgid == i_rhs.iv_rcd_mfgid));
        }

        ///
        /// @brief operator!=() - are two kinds different?
        /// @param[in] i_rhs the right hand side of the comparison statement
        /// @return bool true iff the two kind are of different
        /// @warning this does not compare the targets (iv_target,) just the values
        ///
        inline bool operator!=(const kind& i_rhs) const
        {
            return !(this->operator==(i_rhs));
        }

        ///
        /// @brief Construct a dimm::kind data structure - information about the kind of DIMM this is
        /// @param[in] i_target a DIMM target
        ///
        kind(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target):
            iv_target(i_target)
        {
            FAPI_TRY( mss::eff_dram_gen(i_target, iv_dram_generation) );
            FAPI_TRY( mss::eff_dimm_type(i_target, iv_dimm_type) );
            FAPI_TRY( mss::eff_dram_density(i_target, iv_dram_density) );
            FAPI_TRY( mss::eff_dram_width(i_target, iv_dram_width) );
            FAPI_TRY( mss::eff_num_master_ranks_per_dimm(i_target, iv_master_ranks) );
            FAPI_TRY( mss::eff_num_ranks_per_dimm(i_target, iv_total_ranks) );
            FAPI_TRY( mss::eff_dram_row_bits(i_target, iv_rows) );
            FAPI_TRY( mss::eff_dimm_size(i_target, iv_size) );
            FAPI_TRY( mss::eff_dram_mfg_id(i_target, iv_mfgid) );
            FAPI_TRY( mss::eff_prim_stack_type( i_target, iv_stack_type) );
            FAPI_TRY( mss::eff_hybrid( i_target, iv_hybrid ));
            FAPI_TRY( mss::eff_hybrid_memory_type( i_target, iv_hybrid_memory_type ));
            FAPI_TRY( mss::eff_rcd_mfg_id(i_target, iv_rcd_mfgid) );
            return;

        fapi_try_exit:
            // Not 100% sure what to do here ...
            FAPI_ERR("error initializing DIMM structure: %s 0x%016lx", mss::c_str(i_target), uint64_t(fapi2::current_err));
            fapi2::Assert(false);
        }

        ///
        /// @brief Construct a DIMM kind used to identify this DIMM for tables.
        /// @param[in] i_master_ranks number of master ranks on the DIMM
        /// @param[in] i_total_ranks total number of ranks on the DIMM
        /// @param[in] i_dram_density density of the DRAM
        /// @param[in] i_dram_width width of the DRAM
        /// @param[in] i_dram_generation DRAM generation
        /// @param[in] i_dimm_type DIMM type (e.g. RDIMM)
        /// @param[in] i_rows number of rows in the DRAM
        /// @param[in] i_size the overal size of the DIMM in GB
        /// @param[in] i_mfgid the dram manufacturer id of the dimm, defaulted to 0
        /// @param[in] i_stack_type dram die type, single die package or 3DS
        /// @param[in] i_hybrid, default not hybrid
        /// @param[in] i_hybrid_memory_type, defult none
        /// @param[in] i_rcd_mfgid dimm register and data buffer manufacturer id, default 0
        /// @note can't be constexpr as fapi2::Target doesn't have a constexpr ctor.
        ///
        kind( const uint8_t i_master_ranks,
              const uint8_t i_total_ranks,
              const uint8_t i_dram_density,
              const uint8_t i_dram_width,
              const uint8_t i_dram_generation,
              const uint8_t i_dimm_type,
              const uint8_t i_rows,
              const uint32_t i_size,
              const uint16_t i_mfgid = 0,
              const uint8_t i_stack_type = fapi2::ENUM_ATTR_EFF_PRIM_STACK_TYPE_SDP,
              const uint8_t i_hybrid = fapi2::ENUM_ATTR_EFF_HYBRID_NOT_HYBRID,
              const uint8_t i_hybrid_memory_type = fapi2::ENUM_ATTR_EFF_HYBRID_MEMORY_TYPE_NONE,
              const uint16_t i_rcd_mfgid = 0):
            iv_target(0),
            iv_master_ranks(i_master_ranks),
            iv_total_ranks(i_total_ranks),
            iv_dram_density(i_dram_density),
            iv_dram_width(i_dram_width),
            iv_dram_generation(i_dram_generation),
            iv_dimm_type(i_dimm_type),
            iv_rows(i_rows),
            // TK consider calculating size rather than requiring it be set.
            iv_size(i_size),
            iv_mfgid(i_mfgid),
            iv_stack_type(i_stack_type),
            iv_hybrid(i_hybrid),
            iv_hybrid_memory_type(i_hybrid_memory_type),
            iv_rcd_mfgid(i_rcd_mfgid)
        {
            // Bit of an idiot-check to be sure a hand-crafted dimm::kind make sense wrt slaves, masters, packages, etc.
            // Both of these are checked in eff_config. If they are messed up, they should be caught there
            if (iv_master_ranks > iv_total_ranks)
            {
                FAPI_ERR("Not enough total ranks? master: %d total: %d",
                         iv_master_ranks,
                         iv_total_ranks);
                fapi2::Assert(false);
            }

            if ((iv_total_ranks % iv_master_ranks) != 0)
            {
                FAPI_ERR("total or master ranks seems incorrect. master: %d total: %d",
                         iv_master_ranks,
                         iv_total_ranks);
                fapi2::Assert(false);
            }
        }

        fapi2::Target<fapi2::TARGET_TYPE_DIMM> iv_target;
        uint8_t iv_master_ranks;
        uint8_t iv_total_ranks;
        uint8_t iv_dram_density;
        uint8_t iv_dram_width;
        uint8_t iv_dram_generation;
        uint8_t iv_dimm_type;
        uint8_t iv_rows;
        uint32_t iv_size;
        uint16_t iv_mfgid;
        uint8_t iv_stack_type;
        uint8_t iv_hybrid;
        uint8_t iv_hybrid_memory_type;
        uint16_t iv_rcd_mfgid;

        ///
        /// @brief equal_config
        /// @param[in] i_input_compare the i_kind to compare against
        /// @return bool true iff the two kind are of the same kind for xlate purposes
        /// @warning this does not compare the targets (iv_target,), mfgid, prim_stack_type nor hybrid type
        ///
        inline bool equal_config(const kind& i_input_compare) const
        {
            return ((iv_master_ranks == i_input_compare.iv_master_ranks) &&
                    (iv_total_ranks == i_input_compare.iv_total_ranks) &&
                    (iv_dram_density == i_input_compare.iv_dram_density) &&
                    (iv_dram_width == i_input_compare.iv_dram_width) &&
                    (iv_dram_generation == i_input_compare.iv_dram_generation) &&
                    (iv_dimm_type == i_input_compare.iv_dimm_type) &&
                    (iv_rows == i_input_compare.iv_rows) &&
                    (iv_size == i_input_compare.iv_size));
        }
};

}

}
#endif
<|endoftext|>