<commit_before>/*
 * Target.cc
 *
 * Author: William Ma <https://github.com/williampma>
 *
 * Copyright (C) 2015 OpenCog Foundation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/util/random.h>

#include <opencog/atomutils/Neighbors.h>
#include "Target.h"
#include "BCLogger.h"

namespace opencog {

Target::Target(const Handle& bd, const Handle& vd) : body(bd), vardecl(vd) {}

std::string	Target::to_string() const
{
	stringstream ss;
	ss << "body:" << std::endl << oc_to_string(body)
	   << "vardecl:" << std::endl << oc_to_string(vardecl)
	   << "rules:" << std::endl << oc_to_string(rules);
	return ss.str();
}

std::string oc_to_string(const Target& target)
{
	return target.to_string();
}

// #if 0
// /**
//  * Constructor of Target.
//  *
//  * Only the TargetSet class can create a Target object.
//  *
//  * @param as  the AtomSpace in which to store temporary information
//  * @param h   the original external Handle of the Target
//  */
// Target::Target(AtomSpace& as, const Handle& h, const Handle& hvardecl) : _as(as)
// {
// 	_htarget = h;
// 	_selection_count = 0;

// 	_vardecl = hvardecl;

// 	HandleSeq vars = VariableListCast(_vardecl)->get_variables().varseq;

// 	// _varmap is a map that bases on the external space
// 	for (auto& hv : vars)
// 		_varmap[hv] = UnorderedHandleSet();
// }

// /**
//  * Store a specific inference step for the Target into the AtomSpace.
//  *
//  * @param r         the rule applied
//  * @param premises  the premises selected to be the rule's input
//  */
// void Target::store_step(const Rule& r, const HandleSeq& premises)
// {
// 	// XXX TODO think of a good structure for storing the inference step
// 	// XXX TODO if the rule was actually applied, store the change to the TV?
// 	_as.add_link(SET_LINK,
// 	             _htarget,
// 	             _as.add_node(NODE, r.get_name()),
// 	             _as.add_link(LIST_LINK, premises));
// }

// /**
//  * Store new variable mappings.
//  *
//  * @param vm  a HandleMultimap object containing additional mappings
//  */
// void Target::store_varmap(HandleMultimap& vm)
// {
// 	for (auto& p : vm)
// 	{
// 		Handle hk = _as.add_atom(p.first);

// 		if (_varmap.count(hk) == 1)
// 		{
// 			for (auto& h : p.second)
// 				_varmap[hk].insert(_as.add_atom(h));
// 		}
// 	}
// }

// /**
//  * Store new variable mapping.
//  *
//  * @param vm  a HandleMap object containing additional mapping
//  */
// void Target::store_varmap(HandleMap& vm)
// {
// 	for (auto& p : vm)
// 	{
// 		Handle hk = _as.add_atom(p.first);

// 		if (_varmap.count(hk) == 1)
// 			_varmap[hk].insert(_as.add_atom(p.second));
// 	}
// }

// /**
//  * Count how many times  a Rule was selected for the Target.
//  *
//  * This method follow the inference tree atom structure to find all usage.
//  *
//  * @param r  the Rule to search
//  * @return   the number of times applied
//  */
// unsigned int Target::rule_count(const Rule& r) const
// {
// 	Handle hname = _as.get_node(NODE, r.get_name());

// 	// if this rule's name never appear in history, it wasn't used
// 	if (hname == Handle::UNDEFINED)
// 		return 0;

// 	Handle htarget = _as.get_atom(_htarget);

// 	if (htarget == Handle::UNDEFINED)
// 		return 0;

// 	HandleSeq q = get_target_neighbors(htarget, SET_LINK);

// 	return std::count(q.begin(), q.end(), hname);
// }

// std::string Target::to_string()
// {
// 	stringstream ss;
// 	ss << "Target handle = " << get_handle()->toShortString();
// 	ss << "With var_decl = " << get_vardecl()->toShortString();
// 	return ss.str();
// }

// //==================================================================

// /**
//  * Constructor.
//  */
// TargetSet::TargetSet() : _total_selection(0)
// {

// }

// /**
//  * Destructor.
//  */
// TargetSet::~TargetSet()
// {

// }

// /**
//  * Clear the TargetSet.
//  */
// void TargetSet::clear()
// {
// 	_history_space.clear();
// 	_targets_map.clear();
// }

// /**
//  * Add a new Target into the set.
//  *
//  * @param h  the atom to which the Target will be created
//  */
// void TargetSet::emplace(Handle h, Handle hvardecl)
// {
// 	h = _history_space.add_atom(h);

// 	if (_targets_map.count(h) == 1)
// 		return;

// 	hvardecl = _history_space.add_atom(hvardecl);

// 	LAZY_BC_LOG_DEBUG << "[Target] Adding:" << std::endl
// 	                  << h->toShortString() << "to target set";

// 	_targets_map.insert(std::pair<Handle, Target>(h, Target(_history_space, h, hvardecl)));
// }

// /**
//  * Get the size of the TargetSet.
//  */
// unsigned int TargetSet::size()
// {
// 	return _targets_map.size();
// }

// /**
//  * Select a Target from the set using some fitness criteria.
//  *
//  * Currently uses the selection count to apply weighted random selection.
//  *
//  * XXX TODO use criteria such as
//  * - how many steps from the initial target
//  * - how much was gained on this target the last time it was chosen
//  * etc
//  *
//  * @return a reference to the selected Target
//  */
// Target& TargetSet::select()
// {
// 	HandleSeq handles;
// 	std::vector<double> weights;
// 	for (auto& p : _targets_map)
// 	{
// 		handles.push_back(p.first);

// 		// XXX TODO add more criteria to the weight calculation
// 		weights.push_back(_total_selection - p.second.get_selection_count() + 1);
// 	}

// 	Target& t = _targets_map.at(handles[randGen().rand_discrete(weights)]);
// 	t.increment_selection_count();

// 	_total_selection++;

// 	return t;
// }

// /**
//  * Get a specific Target.
//  *
//  * @param h  the handle of the Target
//  * @return   a reference to the Target
//  */
// Target& TargetSet::get(Handle h)
// {
// 	return _targets_map.at(_history_space.get_atom(h));
// }
// #endif

} // ~namespace opencog
<commit_msg>Clean Target.cc<commit_after>/*
 * Target.cc
 *
 * Author: William Ma <https://github.com/williampma>
 *
 * Copyright (C) 2015 OpenCog Foundation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <opencog/util/random.h>

#include <opencog/atomutils/Neighbors.h>
#include "Target.h"
#include "BCLogger.h"

namespace opencog {

Target::Target(const Handle& bd, const Handle& vd) : body(bd), vardecl(vd) {}

std::string	Target::to_string() const
{
	stringstream ss;
	ss << "body:" << std::endl << oc_to_string(body)
	   << "vardecl:" << std::endl << oc_to_string(vardecl)
	   << "rules:" << std::endl << oc_to_string(rules);
	return ss.str();
}

std::string oc_to_string(const Target& target)
{
	return target.to_string();
}

} // ~namespace opencog
<|endoftext|>


<commit_before>
#include <time.h>
#include <array>
#include <go32.h>
#include <sys/farptr.h>
#include <conio.h>
#include <dpmi.h>
#include <go32.h>
#include <pc.h>
#include <bios.h>
#include <time.h>
#include <unistd.h>

#include <conio.h>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <functional>
#include <unordered_map>
#include <memory>
#include <utility>
#include <string>
#include <map>
#include <algorithm>
#include <chrono>
#include <iostream>
#include <sg14/fixed_point>
#include <EASTL/vector.h>
#include <EASTL/array.h>

using eastl::vector;
using eastl::array;
using namespace std::chrono;
using sg14::fixed_point;

#include "NativeBitmap.h"
#include "Vec2i.h"
#include "IMapElement.h"
#include "CTeam.h"
#include "CItem.h"
#include "CActor.h"
#include "CGameDelegate.h"
#include "CMap.h"
#include "IRenderer.h"
#include "IFileLoaderDelegate.h"
#include "CGame.h"
#include "CPlainFileLoader.h"
#include "Vec2i.h"
#include "IMapElement.h"
#include "CTeam.h"
#include "CItem.h"
#include "CActor.h"
#include "CGameDelegate.h"
#include "CMap.h"
#include "IRenderer.h"
#include "commands/IGameCommand.h"
#include "RasterizerCommon.h"
#include "CRenderer.h"
#include "CPackedFileReader.h"
#include "LoadPNG.h"

std::shared_ptr<odb::CRenderer> renderer;

enum ESoundDriver : uint8_t { kNone, kPcSpeaker, kOpl2Lpt, kTandy, kCovox };

ESoundDriver soundDriver = kNone;
int soundTiming = 0;

void initOPL2(int instrument);
void playTune(const std::string&);
void setupOPL2(int instrument);
void stopSounds();
void soundTick();
void playMusic(int instrument, const std::string &musicTrack);

void initOPL2(int instrument) {
    setupOPL2(instrument);
}

std::function< std::string(std::string)> kDosLongFileNameTransformer = [](const std::string& filename ) {
    char c = 219;
    c = 176;
    c = 177;
    c = 178;
    c = '.';
    std::cout << c;
    std::cout.flush();

    auto dotPosition = std::find( std::begin(filename), std::end( filename), '.');
    auto indexDot =  std::distance( std::begin( filename ), dotPosition );
    auto extension = filename.substr( indexDot + 1, 3 );

    if ( indexDot >  8 ) {
        return filename.substr( 0, 6 ) + "~1." + extension;
    }

    if ( filename.length() - indexDot > 4 ) {
        return filename.substr( 0, indexDot ) + "~1." + extension;
    }

    return filename;
};

void* operator new[](size_t size, const char* pName, int flags, unsigned debugFlags,
                     const char* file, int line) {
    return malloc( size );
}

void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* pName,
                     int flags, unsigned debugFlags, const char* file, int line) {
    return malloc( size );
}

void renderTick() {
    renderer->render( 33 );
    renderer->handleSystemEvents();
}

std::shared_ptr<Knights::CGame> game;

int getchWithSoundTicks() {

    if (soundDriver != kNone ) {
        while (!kbhit()) {
            usleep((75) * 1000);
            soundTick();
        }

        stopSounds();
    }

    return getch();
}

void showText(std::shared_ptr<odb::NativeBitmap> bg, const std::string& mainText, const std::string& bottom ) {
    renderer->drawBitmap(0, 0, bg );
    renderer->fill(0, 64, 320, 200 - 64, 0 );
    renderer->flip();
    gotoxy(1,9);
    puts(mainText.c_str());
    gotoxy(1,25);
    printf(bottom.c_str());
}

void playSoundForAction(Knights::CommandType command ) {
    if (command == Knights::kUseCurrentItemInInventoryCommand) {
        playTune("aca");
    }

    if (command == Knights::kCycleLeftInventoryCommand) {
        playTune("ac");
    }

    if (command == Knights::kCycleRightInventoryCommand) {
        playTune("ca");
    }

    if (command == Knights::kPickItemCommand) {
        playTune("abc");
    }

    if (command == Knights::kDropItemCommand) {
        playTune("cba");
    }
}

void handleConsoleLines( Knights::CommandType command, int playerHealthDiff, int targetHealthDiff, std::shared_ptr<odb::CRenderer> renderer, std::shared_ptr<Knights::CActor> actorAtTarget ) {
    if ( command != '.') {
        char buffer[81];
        snprintf(buffer, 80, "%s", game->getLastCommand().c_str());
        renderer->appendToLog( buffer );
    }

    if ( targetHealthDiff < 0 ) {
        char buffer[81];
        snprintf(buffer, 80, "Player dealt %d of damage", -targetHealthDiff );
        renderer->appendToLog( buffer );
        if (actorAtTarget == nullptr || !actorAtTarget->isAlive()) {
            renderer->addDeathAt(actorAtTarget->getPosition());
        } else {
            renderer->addSplatAt(actorAtTarget->getPosition());
        }
    }

    if ( playerHealthDiff < 0 ) {
        char buffer[81];
        snprintf(buffer, 80, "Player took %d of damage", -playerHealthDiff);
        renderer->appendToLog( buffer );
        renderer->startDamageHighlight();
    } else if ( playerHealthDiff > 0 ) {
        char buffer[81];
        snprintf(buffer, 80, "Player gained %d of faith", playerHealthDiff);
        renderer->appendToLog( buffer );
        renderer->startHealHighlight();
    }
}

int main(int argc, char **argv) {
    int instrument = -1;

    const auto LEVEL_LIMIT = 7;
    clock_t t0;
    clock_t t1;
    int healthAtTargetBefore = 0;
    int healthAtTargetAfter = 0;
    auto delegate = std::make_shared<Knights::CGameDelegate>();
    auto fileLoader = std::make_shared<odb::CPackedFileReader>("data.pfs");
    auto bg = loadPNG( "intro.png", fileLoader );

    puts("Dungeons of Noudar 486 tech demo startup. Gonna load some stuff...");

    if ( argc >= 2 ) {
        if ( !std::strcmp(argv[1], "pcspeaker")) {
            soundDriver = kPcSpeaker;
            soundTiming = 100;
        }

        if ( !std::strcmp(argv[1], "opl2lpt")) {
            instrument = 80;
            soundTiming = 75;
            soundDriver = kOpl2Lpt;

            if (argc >= 3 ) {
                instrument = atoi(argv[2]);
            }

            initOPL2(instrument);
        }
    }

    renderer = std::make_shared<odb::CRenderer>();

    auto titleText = fileLoader->loadFileFromPath("title.txt");
    showText(bg, titleText, "Press any key to continue");
    getchWithSoundTicks();

    auto onLevelWillLoad = [&]() {
        showText(bg, "", "Loading...");
    };
    delegate->setOnLevelWillLoadCallback(onLevelWillLoad );

    game = std::make_shared<Knights::CGame>( fileLoader, renderer, delegate );
    auto tileProperties = odb::loadTileProperties(game->getLevelNumber(), fileLoader);
    renderer->loadTextures( odb::loadTexturesForLevel(game->getLevelNumber(), fileLoader), tileProperties);

    char buffer[40];
    snprintf(buffer, 40, "chapter%d.txt", game->getLevelNumber() );
    auto introText = fileLoader->loadFileFromPath(buffer);

    playTune("e8e8f8g8g8f8e8d8c8c8d8e8e8d12d4e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4d8d8e8c8d8e12f12e8c8d8e12f12e8d8c8d8p8e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4");
    showText(bg, introText, "Press any key to start" );
    getchWithSoundTicks();

    auto onLevelLoaded = [&]() {

        if (game != nullptr ) {
            if ( game->getLevelNumber() >= LEVEL_LIMIT ) {
                game->setIsPlaying( false );
            } else {
                auto tileProperties = odb::loadTileProperties(game->getLevelNumber(), fileLoader);
                renderer->loadTextures( odb::loadTexturesForLevel(game->getLevelNumber(), fileLoader), tileProperties);

                char buffer[40];
                snprintf(buffer, 40, "chapter%d.txt", game->getLevelNumber() );
                auto chapterText = fileLoader->loadFileFromPath(buffer);

                playTune("e8e8f8g8g8f8e8d8c8c8d8e8e8d12d4e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4d8d8e8c8d8e12f12e8c8d8e12f12e8d8c8d8p8e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4");
                showText(bg, chapterText, "Press any key to start");
                getchWithSoundTicks();
            }
        }
    };
    delegate->setOnLevelLoadedCallback(onLevelLoaded );

    auto noteTime = soundTiming;

    while ( game->isPlaying() ) {

        if (soundDriver != kNone ) {
            t0 = uclock();
        }

        auto playerHealthBefore = game->getMap()->getAvatar()->getHP();
        auto cursorPosition = game->getMap()->getTargetProjection(game->getMap()->getAvatar());
        auto actorAtTarget = game->getMap()->getActorAt(cursorPosition);

        if ( actorAtTarget != nullptr ) {
            healthAtTargetBefore = actorAtTarget->getHP();
        } else {
            healthAtTargetBefore = 0;
        }

        game->tick();
        renderTick();
        Knights::CommandType command = renderer->peekInput();
        game->tick();

        if ( actorAtTarget != nullptr ) {
            healthAtTargetAfter = actorAtTarget->getHP();
        } else {
            healthAtTargetAfter = 0;
        }

        auto targetHealthDiff = healthAtTargetAfter - healthAtTargetBefore;
        auto playerHealthAfter = game->getMap()->getAvatar()->getHP();
        auto playerHealthDiff = playerHealthAfter - playerHealthBefore;

        handleConsoleLines( command, playerHealthDiff, targetHealthDiff, renderer, actorAtTarget );

        if (soundDriver != kNone ) {

            playSoundForAction(command);

            t1 = uclock();
            auto diff = (1000 * (t1 - t0)) / UCLOCKS_PER_SEC;
            if (diff == 0) {
                diff = 1;
            }
            noteTime -= diff;

            if (noteTime < 0) {
                noteTime = soundTiming;
                soundTick();
            }
        }

    }

    stopSounds();

    return 0;
}
<commit_msg>Make action sounds longer<commit_after>
#include <time.h>
#include <array>
#include <go32.h>
#include <sys/farptr.h>
#include <conio.h>
#include <dpmi.h>
#include <go32.h>
#include <pc.h>
#include <bios.h>
#include <time.h>
#include <unistd.h>

#include <conio.h>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <functional>
#include <unordered_map>
#include <memory>
#include <utility>
#include <string>
#include <map>
#include <algorithm>
#include <chrono>
#include <iostream>
#include <sg14/fixed_point>
#include <EASTL/vector.h>
#include <EASTL/array.h>

using eastl::vector;
using eastl::array;
using namespace std::chrono;
using sg14::fixed_point;

#include "NativeBitmap.h"
#include "Vec2i.h"
#include "IMapElement.h"
#include "CTeam.h"
#include "CItem.h"
#include "CActor.h"
#include "CGameDelegate.h"
#include "CMap.h"
#include "IRenderer.h"
#include "IFileLoaderDelegate.h"
#include "CGame.h"
#include "CPlainFileLoader.h"
#include "Vec2i.h"
#include "IMapElement.h"
#include "CTeam.h"
#include "CItem.h"
#include "CActor.h"
#include "CGameDelegate.h"
#include "CMap.h"
#include "IRenderer.h"
#include "commands/IGameCommand.h"
#include "RasterizerCommon.h"
#include "CRenderer.h"
#include "CPackedFileReader.h"
#include "LoadPNG.h"

std::shared_ptr<odb::CRenderer> renderer;

enum ESoundDriver : uint8_t { kNone, kPcSpeaker, kOpl2Lpt, kTandy, kCovox };

ESoundDriver soundDriver = kNone;
int soundTiming = 0;

void initOPL2(int instrument);
void playTune(const std::string&);
void setupOPL2(int instrument);
void stopSounds();
void soundTick();
void playMusic(int instrument, const std::string &musicTrack);

void initOPL2(int instrument) {
    setupOPL2(instrument);
}

std::function< std::string(std::string)> kDosLongFileNameTransformer = [](const std::string& filename ) {
    char c = 219;
    c = 176;
    c = 177;
    c = 178;
    c = '.';
    std::cout << c;
    std::cout.flush();

    auto dotPosition = std::find( std::begin(filename), std::end( filename), '.');
    auto indexDot =  std::distance( std::begin( filename ), dotPosition );
    auto extension = filename.substr( indexDot + 1, 3 );

    if ( indexDot >  8 ) {
        return filename.substr( 0, 6 ) + "~1." + extension;
    }

    if ( filename.length() - indexDot > 4 ) {
        return filename.substr( 0, indexDot ) + "~1." + extension;
    }

    return filename;
};

void* operator new[](size_t size, const char* pName, int flags, unsigned debugFlags,
                     const char* file, int line) {
    return malloc( size );
}

void* operator new[](size_t size, size_t alignment, size_t alignmentOffset, const char* pName,
                     int flags, unsigned debugFlags, const char* file, int line) {
    return malloc( size );
}

void renderTick() {
    renderer->render( 33 );
    renderer->handleSystemEvents();
}

std::shared_ptr<Knights::CGame> game;

int getchWithSoundTicks() {

    if (soundDriver != kNone ) {
        while (!kbhit()) {
            usleep((75) * 1000);
            soundTick();
        }

        stopSounds();
    }

    return getch();
}

void showText(std::shared_ptr<odb::NativeBitmap> bg, const std::string& mainText, const std::string& bottom ) {
    renderer->drawBitmap(0, 0, bg );
    renderer->fill(0, 64, 320, 200 - 64, 0 );
    renderer->flip();
    gotoxy(1,9);
    puts(mainText.c_str());
    gotoxy(1,25);
    printf(bottom.c_str());
}

void playSoundForAction(Knights::CommandType command ) {
    if (command == Knights::kUseCurrentItemInInventoryCommand) {
        playTune("aca");
    }

    if (command == Knights::kCycleLeftInventoryCommand) {
        playTune("abc");
    }

    if (command == Knights::kCycleRightInventoryCommand) {
        playTune("cba");
    }

    if (command == Knights::kPickItemCommand) {
        playTune("defg");
    }

    if (command == Knights::kDropItemCommand) {
        playTune("gfed");
    }
}

void handleConsoleLines( Knights::CommandType command, int playerHealthDiff, int targetHealthDiff, std::shared_ptr<odb::CRenderer> renderer, std::shared_ptr<Knights::CActor> actorAtTarget ) {
    if ( command != '.') {
        char buffer[81];
        snprintf(buffer, 80, "%s", game->getLastCommand().c_str());
        renderer->appendToLog( buffer );
    }

    if ( targetHealthDiff < 0 ) {
        char buffer[81];
        snprintf(buffer, 80, "Player dealt %d of damage", -targetHealthDiff );
        renderer->appendToLog( buffer );
        if (actorAtTarget == nullptr || !actorAtTarget->isAlive()) {
            renderer->addDeathAt(actorAtTarget->getPosition());
        } else {
            renderer->addSplatAt(actorAtTarget->getPosition());
        }
    }

    if ( playerHealthDiff < 0 ) {
        char buffer[81];
        snprintf(buffer, 80, "Player took %d of damage", -playerHealthDiff);
        renderer->appendToLog( buffer );
        renderer->startDamageHighlight();
    } else if ( playerHealthDiff > 0 ) {
        char buffer[81];
        snprintf(buffer, 80, "Player gained %d of faith", playerHealthDiff);
        renderer->appendToLog( buffer );
        renderer->startHealHighlight();
    }
}

int main(int argc, char **argv) {
    int instrument = -1;

    const auto LEVEL_LIMIT = 7;
    clock_t t0;
    clock_t t1;
    int healthAtTargetBefore = 0;
    int healthAtTargetAfter = 0;
    auto delegate = std::make_shared<Knights::CGameDelegate>();
    auto fileLoader = std::make_shared<odb::CPackedFileReader>("data.pfs");
    auto bg = loadPNG( "intro.png", fileLoader );

    puts("Dungeons of Noudar 486 tech demo startup. Gonna load some stuff...");

    if ( argc >= 2 ) {
        if ( !std::strcmp(argv[1], "pcspeaker")) {
            soundDriver = kPcSpeaker;
            soundTiming = 100;
        }

        if ( !std::strcmp(argv[1], "opl2lpt")) {
            instrument = 80;
            soundTiming = 75;
            soundDriver = kOpl2Lpt;

            if (argc >= 3 ) {
                instrument = atoi(argv[2]);
            }

            initOPL2(instrument);
        }
    }

    renderer = std::make_shared<odb::CRenderer>();

    auto titleText = fileLoader->loadFileFromPath("title.txt");
    showText(bg, titleText, "Press any key to continue");
    getchWithSoundTicks();

    auto onLevelWillLoad = [&]() {
        showText(bg, "", "Loading...");
    };
    delegate->setOnLevelWillLoadCallback(onLevelWillLoad );

    game = std::make_shared<Knights::CGame>( fileLoader, renderer, delegate );
    auto tileProperties = odb::loadTileProperties(game->getLevelNumber(), fileLoader);
    renderer->loadTextures( odb::loadTexturesForLevel(game->getLevelNumber(), fileLoader), tileProperties);

    char buffer[40];
    snprintf(buffer, 40, "chapter%d.txt", game->getLevelNumber() );
    auto introText = fileLoader->loadFileFromPath(buffer);

    playTune("e8e8f8g8g8f8e8d8c8c8d8e8e8d12d4e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4d8d8e8c8d8e12f12e8c8d8e12f12e8d8c8d8p8e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4");
    showText(bg, introText, "Press any key to start" );
    getchWithSoundTicks();

    auto onLevelLoaded = [&]() {

        if (game != nullptr ) {
            if ( game->getLevelNumber() >= LEVEL_LIMIT ) {
                game->setIsPlaying( false );
            } else {
                auto tileProperties = odb::loadTileProperties(game->getLevelNumber(), fileLoader);
                renderer->loadTextures( odb::loadTexturesForLevel(game->getLevelNumber(), fileLoader), tileProperties);

                char buffer[40];
                snprintf(buffer, 40, "chapter%d.txt", game->getLevelNumber() );
                auto chapterText = fileLoader->loadFileFromPath(buffer);

                playTune("e8e8f8g8g8f8e8d8c8c8d8e8e8d12d4e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4d8d8e8c8d8e12f12e8c8d8e12f12e8d8c8d8p8e8e8f8g8g8f8e8d8c8c8d8e8d8c12c4");
                showText(bg, chapterText, "Press any key to start");
                getchWithSoundTicks();
            }
        }
    };
    delegate->setOnLevelLoadedCallback(onLevelLoaded );

    auto noteTime = soundTiming;

    while ( game->isPlaying() ) {

        if (soundDriver != kNone ) {
            t0 = uclock();
        }

        auto playerHealthBefore = game->getMap()->getAvatar()->getHP();
        auto cursorPosition = game->getMap()->getTargetProjection(game->getMap()->getAvatar());
        auto actorAtTarget = game->getMap()->getActorAt(cursorPosition);

        if ( actorAtTarget != nullptr ) {
            healthAtTargetBefore = actorAtTarget->getHP();
        } else {
            healthAtTargetBefore = 0;
        }

        game->tick();
        renderTick();
        Knights::CommandType command = renderer->peekInput();
        game->tick();

        if ( actorAtTarget != nullptr ) {
            healthAtTargetAfter = actorAtTarget->getHP();
        } else {
            healthAtTargetAfter = 0;
        }

        auto targetHealthDiff = healthAtTargetAfter - healthAtTargetBefore;
        auto playerHealthAfter = game->getMap()->getAvatar()->getHP();
        auto playerHealthDiff = playerHealthAfter - playerHealthBefore;

        handleConsoleLines( command, playerHealthDiff, targetHealthDiff, renderer, actorAtTarget );

        if (soundDriver != kNone ) {

            playSoundForAction(command);

            t1 = uclock();
            auto diff = (1000 * (t1 - t0)) / UCLOCKS_PER_SEC;
            if (diff == 0) {
                diff = 1;
            }
            noteTime -= diff;

            if (noteTime < 0) {
                noteTime = soundTiming;
                soundTick();
            }
        }

    }

    stopSounds();

    return 0;
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//  MeshFactoryTest.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "UnitTest++/src/UnitTest++.h"
#include "Render/Core/stateWrapper.h"
#include "Render/Core/meshFactory.h"
#include "Render/Setup/RenderSetup.h"
#include "Render/Core/displayMgr.h"
#include "Render/Util/MeshBuilder.h"
#include "Render/Util/RawMeshLoader.h"

#if ORYOL_OPENGL
#include "Render/gl/gl_impl.h"
#endif

using namespace Oryol;
using namespace Oryol::Core;
using namespace Oryol::IO;
using namespace Oryol::Render;
using namespace Oryol::Resource;

// NOTE: this is should not be treated as sample code on how
// to initialize a mesh!
TEST(MeshFactoryTest) {

    // setup a GL context
    auto renderSetup = RenderSetup::Windowed(400, 300, "Oryol Test");
    displayMgr displayManager;
    displayManager.SetupDisplay(renderSetup);

    // setup a meshFactory object
    stateWrapper stWrapper;
    meshFactory factory;
    factory.Setup(&stWrapper);
    factory.AttachLoader(RawMeshLoader::Create());

    // setup a MeshBuilder and create mesh geometry
    MeshBuilder mb;
    mb.SetNumVertices(4);
    mb.SetNumIndices(6);
    mb.AddComponent(VertexAttr::Position, VertexFormat::Float3);
    mb.AddComponent(VertexAttr::TexCoord0, VertexFormat::Float2);
    mb.AddPrimitiveGroup(PrimitiveType::Triangles, 0, 6);
    mb.Begin();
    mb.Vertex(0, VertexAttr::Position, 0.0f, 0.0f, 0.0f);  // top-left
    mb.Vertex(1, VertexAttr::Position, 1.0f, 0.0f, 0.0f);  // top-right
    mb.Vertex(2, VertexAttr::Position, 1.0f, 1.0f, 0.0f);  // bottom-right
    mb.Vertex(3, VertexAttr::Position, 0.0f, 1.0f, 0.0f);  // bottom-left
    mb.Vertex(0, VertexAttr::TexCoord0, 0.0f, 0.0f);
    mb.Vertex(1, VertexAttr::TexCoord0, 1.0f, 0.0f);
    mb.Vertex(2, VertexAttr::TexCoord0, 1.0f, 1.0f);
    mb.Vertex(3, VertexAttr::TexCoord0, 0.0f, 1.0f);
    mb.Triangle(0, 0, 1, 2);
    mb.Triangle(1, 0, 2, 3);
    mb.End();

    // setup the mesh
    const Ptr<Stream>& meshData = mb.GetStream();
    mesh mesh;
    mesh.setSetup(MeshSetup::FromData(Locator("myQuad")));
    mesh.setState(Resource::State::Setup);

    factory.SetupResource(mesh, meshData);
    CHECK(mesh.GetState() == Resource::State::Valid);
    CHECK(!mesh.GetId().IsValid());
    CHECK(mesh.GetSetup().GetLocator().Location() == "myQuad");
    CHECK(mesh.GetVertexBufferAttrs().GetNumVertices() == 4);
    CHECK(mesh.GetVertexBufferAttrs().GetUsage() == Usage::Immutable);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetNumComponents() == 2);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetByteSize() == 20);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponentByteOffset(0) == 0);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponentByteOffset(1) == 12);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(0).IsValid());
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(0).GetAttr() == VertexAttr::Position);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(0).GetFormat() == VertexFormat::Float3);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(0).GetByteSize() == 12);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(1).IsValid());
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(1).GetAttr() == VertexAttr::TexCoord0);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(1).GetFormat() == VertexFormat::Float2);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(1).GetByteSize() == 8);
    CHECK(mesh.GetIndexBufferAttrs().GetNumIndices() == 6);
    CHECK(mesh.GetIndexBufferAttrs().GetIndexType() == IndexType::Index16);
    CHECK(mesh.GetIndexBufferAttrs().GetUsage() == Usage::Immutable);
    CHECK(mesh.GetIndexBufferAttrs().GetByteSize() == 12);
    CHECK(mesh.GetNumPrimitiveGroups() == 1);
    CHECK(mesh.GetPrimitiveGroup(0).GetPrimitiveType() == PrimitiveType::Triangles);
    CHECK(mesh.GetPrimitiveGroup(0).GetBaseElement() == 0);
    CHECK(mesh.GetPrimitiveGroup(0).GetNumElements() == 6);
    #if ORYOL_OPENGL
    CHECK(mesh.glGetVertexBuffer() != 0);
    CHECK(mesh.glGetIndexBuffer() != 0);
    CHECK(mesh.glGetVertexArrayObject() != 0);
    for (uint32 i = 0; i < VertexAttr::NumVertexAttrs; i++) {
        const glVertexAttr& glAttr = mesh.glAttr(i);
        CHECK(glAttr.index == i);
        if (VertexAttr::Position == i) {
            CHECK(glAttr.enabled == GL_TRUE);
            CHECK(glAttr.size == 3);
            CHECK(glAttr.stride == 20);
            CHECK(glAttr.offset == 0);
            CHECK(glAttr.type == GL_FLOAT);
            CHECK(glAttr.normalized == GL_FALSE);
        }
        else if (VertexAttr::TexCoord0 == i) {
            CHECK(glAttr.enabled == GL_TRUE);
            CHECK(glAttr.size == 2);
            CHECK(glAttr.stride == 20);
            CHECK(glAttr.offset == 12);
            CHECK(glAttr.type == GL_FLOAT);
            CHECK(glAttr.normalized == GL_FALSE);
        }
        else {
            CHECK(glAttr.enabled == GL_FALSE);
            CHECK(glAttr.size == 0);
            CHECK(glAttr.stride == 0);
            CHECK(glAttr.offset == 0);
            CHECK(glAttr.type == 0);
            CHECK(glAttr.normalized == GL_FALSE);
        }
    }
    #endif

    factory.DestroyResource(mesh);
    CHECK(mesh.GetState() == Resource::State::Setup);
    CHECK(!mesh.GetId().IsValid());
    CHECK(mesh.GetVertexBufferAttrs().GetNumVertices() == 0);
    CHECK(mesh.GetVertexBufferAttrs().GetUsage() == Usage::InvalidUsage);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetNumComponents() == 0);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetByteSize() == 0);
    CHECK(mesh.GetIndexBufferAttrs().GetNumIndices() == 0);
    CHECK(mesh.GetIndexBufferAttrs().GetIndexType() == IndexType::InvalidIndexType);
    CHECK(mesh.GetIndexBufferAttrs().GetUsage() == Usage::InvalidUsage);
    CHECK(mesh.GetNumPrimitiveGroups() == 0);
    factory.Discard();
    displayManager.DiscardDisplay();
}<commit_msg>Removed redundant code from MeshFactoryTest<commit_after>//------------------------------------------------------------------------------
//  MeshFactoryTest.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "UnitTest++/src/UnitTest++.h"
#include "Render/Core/stateWrapper.h"
#include "Render/Core/meshFactory.h"
#include "Render/Setup/RenderSetup.h"
#include "Render/Core/displayMgr.h"
#include "Render/Util/MeshBuilder.h"
#include "Render/Util/RawMeshLoader.h"

#if ORYOL_OPENGL
#include "Render/gl/gl_impl.h"
#endif

using namespace Oryol;
using namespace Oryol::Core;
using namespace Oryol::IO;
using namespace Oryol::Render;
using namespace Oryol::Resource;

// NOTE: this is should not be treated as sample code on how
// to initialize a mesh!
TEST(MeshFactoryTest) {

    // setup a GL context
    auto renderSetup = RenderSetup::Windowed(400, 300, "Oryol Test");
    displayMgr displayManager;
    displayManager.SetupDisplay(renderSetup);

    // setup a meshFactory object
    stateWrapper stWrapper;
    meshFactory factory;
    factory.Setup(&stWrapper);
    factory.AttachLoader(RawMeshLoader::Create());

    // setup a MeshBuilder and create mesh geometry
    MeshBuilder mb;
    mb.SetNumVertices(4);
    mb.SetNumIndices(6);
    mb.AddComponent(VertexAttr::Position, VertexFormat::Float3);
    mb.AddComponent(VertexAttr::TexCoord0, VertexFormat::Float2);
    mb.AddPrimitiveGroup(PrimitiveType::Triangles, 0, 6);
    mb.Begin();
    mb.Vertex(0, VertexAttr::Position, 0.0f, 0.0f, 0.0f);  // top-left
    mb.Vertex(1, VertexAttr::Position, 1.0f, 0.0f, 0.0f);  // top-right
    mb.Vertex(2, VertexAttr::Position, 1.0f, 1.0f, 0.0f);  // bottom-right
    mb.Vertex(3, VertexAttr::Position, 0.0f, 1.0f, 0.0f);  // bottom-left
    mb.Vertex(0, VertexAttr::TexCoord0, 0.0f, 0.0f);
    mb.Vertex(1, VertexAttr::TexCoord0, 1.0f, 0.0f);
    mb.Vertex(2, VertexAttr::TexCoord0, 1.0f, 1.0f);
    mb.Vertex(3, VertexAttr::TexCoord0, 0.0f, 1.0f);
    mb.Triangle(0, 0, 1, 2);
    mb.Triangle(1, 0, 2, 3);
    mb.End();

    // setup the mesh
    const Ptr<Stream>& meshData = mb.GetStream();
    mesh mesh;
    mesh.setSetup(MeshSetup::FromData(Locator("myQuad")));

    factory.SetupResource(mesh, meshData);
    CHECK(mesh.GetState() == Resource::State::Valid);
    CHECK(!mesh.GetId().IsValid());
    CHECK(mesh.GetSetup().GetLocator().Location() == "myQuad");
    CHECK(mesh.GetVertexBufferAttrs().GetNumVertices() == 4);
    CHECK(mesh.GetVertexBufferAttrs().GetUsage() == Usage::Immutable);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetNumComponents() == 2);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetByteSize() == 20);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponentByteOffset(0) == 0);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponentByteOffset(1) == 12);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(0).IsValid());
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(0).GetAttr() == VertexAttr::Position);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(0).GetFormat() == VertexFormat::Float3);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(0).GetByteSize() == 12);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(1).IsValid());
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(1).GetAttr() == VertexAttr::TexCoord0);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(1).GetFormat() == VertexFormat::Float2);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetComponent(1).GetByteSize() == 8);
    CHECK(mesh.GetIndexBufferAttrs().GetNumIndices() == 6);
    CHECK(mesh.GetIndexBufferAttrs().GetIndexType() == IndexType::Index16);
    CHECK(mesh.GetIndexBufferAttrs().GetUsage() == Usage::Immutable);
    CHECK(mesh.GetIndexBufferAttrs().GetByteSize() == 12);
    CHECK(mesh.GetNumPrimitiveGroups() == 1);
    CHECK(mesh.GetPrimitiveGroup(0).GetPrimitiveType() == PrimitiveType::Triangles);
    CHECK(mesh.GetPrimitiveGroup(0).GetBaseElement() == 0);
    CHECK(mesh.GetPrimitiveGroup(0).GetNumElements() == 6);
    #if ORYOL_OPENGL
    CHECK(mesh.glGetVertexBuffer() != 0);
    CHECK(mesh.glGetIndexBuffer() != 0);
    CHECK(mesh.glGetVertexArrayObject() != 0);
    for (uint32 i = 0; i < VertexAttr::NumVertexAttrs; i++) {
        const glVertexAttr& glAttr = mesh.glAttr(i);
        CHECK(glAttr.index == i);
        if (VertexAttr::Position == i) {
            CHECK(glAttr.enabled == GL_TRUE);
            CHECK(glAttr.size == 3);
            CHECK(glAttr.stride == 20);
            CHECK(glAttr.offset == 0);
            CHECK(glAttr.type == GL_FLOAT);
            CHECK(glAttr.normalized == GL_FALSE);
        }
        else if (VertexAttr::TexCoord0 == i) {
            CHECK(glAttr.enabled == GL_TRUE);
            CHECK(glAttr.size == 2);
            CHECK(glAttr.stride == 20);
            CHECK(glAttr.offset == 12);
            CHECK(glAttr.type == GL_FLOAT);
            CHECK(glAttr.normalized == GL_FALSE);
        }
        else {
            CHECK(glAttr.enabled == GL_FALSE);
            CHECK(glAttr.size == 0);
            CHECK(glAttr.stride == 0);
            CHECK(glAttr.offset == 0);
            CHECK(glAttr.type == 0);
            CHECK(glAttr.normalized == GL_FALSE);
        }
    }
    #endif

    factory.DestroyResource(mesh);
    CHECK(mesh.GetState() == Resource::State::Setup);
    CHECK(!mesh.GetId().IsValid());
    CHECK(mesh.GetVertexBufferAttrs().GetNumVertices() == 0);
    CHECK(mesh.GetVertexBufferAttrs().GetUsage() == Usage::InvalidUsage);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetNumComponents() == 0);
    CHECK(mesh.GetVertexBufferAttrs().GetVertexLayout().GetByteSize() == 0);
    CHECK(mesh.GetIndexBufferAttrs().GetNumIndices() == 0);
    CHECK(mesh.GetIndexBufferAttrs().GetIndexType() == IndexType::InvalidIndexType);
    CHECK(mesh.GetIndexBufferAttrs().GetUsage() == Usage::InvalidUsage);
    CHECK(mesh.GetNumPrimitiveGroups() == 0);
    factory.Discard();
    displayManager.DiscardDisplay();
}<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
//    Nathan, liujun@multicorewareinc.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors as is and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
#include <iomanip>

using namespace cv;
using namespace cv::ocl;
using namespace testing;
using namespace std;

template <typename T>
static void blendLinearGold(const Mat &img1, const Mat &img2,
                            const Mat &weights1, const Mat &weights2,
                            Mat &result_gold)
{
    CV_Assert(img1.size() == img2.size() && img1.type() == img2.type());
    CV_Assert(weights1.size() == weights2.size() && weights1.size() == img1.size() &&
              weights1.type() == CV_32FC1 && weights2.type() == CV_32FC1);

    result_gold.create(img1.size(), img1.type());

    int cn = img1.channels();
    int step1 = img1.cols * img1.channels();

    for (int y = 0; y < img1.rows; ++y)
    {
        const float * const weights1_row = weights1.ptr<float>(y);
        const float * const weights2_row = weights2.ptr<float>(y);
        const T * const img1_row = img1.ptr<T>(y);
        const T * const img2_row = img2.ptr<T>(y);
        T * const result_gold_row = result_gold.ptr<T>(y);

        for (int x = 0; x < step1; ++x)
        {
            int x1 = x / cn;
            float w1 = weights1_row[x1], w2 = weights2_row[x1];
            result_gold_row[x] = saturate_cast<T>(((float)img1_row[x] * w1
                                                 + (float)img2_row[x] * w2) / (w1 + w2 + 1e-5f));
        }
    }
}

PARAM_TEST_CASE(Blend, MatDepth, int, bool)
{
    int depth, channels;
    bool useRoi;

    Mat src1, src2, weights1, weights2, dst;
    Mat src1_roi, src2_roi, weights1_roi, weights2_roi, dst_roi;
    oclMat gsrc1, gsrc2, gweights1, gweights2, gdst, gst;
    oclMat gsrc1_roi, gsrc2_roi, gweights1_roi, gweights2_roi, gdst_roi;

    virtual void SetUp()
    {
        depth = GET_PARAM(0);
        channels = GET_PARAM(1);
        useRoi = GET_PARAM(2);
    }

    void random_roi()
    {
        const int type = CV_MAKE_TYPE(depth, channels);

        const double upValue = 1200;

        Size roiSize = randomSize(1, 20);
        Border src1Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
        randomSubMat(src1, src1_roi, roiSize, src1Border, type, -upValue, upValue);

        Border src2Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
        randomSubMat(src2, src2_roi, roiSize, src2Border, type, -upValue, upValue);

        Border weights1Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
        randomSubMat(weights1, weights1_roi, roiSize, weights1Border, CV_32FC1, -upValue, upValue);

        Border weights2Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
        randomSubMat(weights2, weights2_roi, roiSize, weights2Border, CV_32FC1, -upValue, upValue);

        Border dstBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
        randomSubMat(dst, dst_roi, roiSize, dstBorder, type, 5, 16);

        generateOclMat(gsrc1, gsrc1_roi, src1, roiSize, src1Border);
        generateOclMat(gsrc2, gsrc2_roi, src2, roiSize, src2Border);
        generateOclMat(gweights1, gweights1_roi, weights1, roiSize, weights1Border);
        generateOclMat(gweights2, gweights2_roi, weights2, roiSize, weights2Border);
        generateOclMat(gdst, gdst_roi, dst, roiSize, dstBorder);
    }

    void Near(double eps = 0.0)
    {
        Mat whole, roi;
        gdst.download(whole);
        gdst_roi.download(roi);

        EXPECT_MAT_NEAR(dst, whole, eps);
        EXPECT_MAT_NEAR(dst_roi, roi, eps);
    }
};

typedef void (*blendLinearFunc)(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &weights1, const cv::Mat &weights2, cv::Mat &result_gold);

OCL_TEST_P(Blend, Accuracy)
{
    for (int i = 0; i < LOOP_TIMES; ++i)
    {
        random_roi();

        cv::ocl::blendLinear(gsrc1_roi, gsrc2_roi, gweights1_roi, gweights2_roi, gdst_roi);

        static blendLinearFunc funcs[] = {
            blendLinearGold<uchar>,
            blendLinearGold<schar>,
            blendLinearGold<ushort>,
            blendLinearGold<short>,
            blendLinearGold<int>,
            blendLinearGold<float>,
        };

        blendLinearFunc func = funcs[depth];
        func(src1_roi, src2_roi, weights1_roi, weights2_roi, dst_roi);

        Near(depth <= CV_32S ? 1.0 : 0.2);
    }
}

INSTANTIATE_TEST_CASE_P(OCL_ImgProc, Blend,
                        Combine(testing::Values(CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F),
                                testing::Range(1, 5), Bool()));
<commit_msg>ocl: fix testdata for blendLinear<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// @Authors
//    Nathan, liujun@multicorewareinc.com
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors as is and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
#include <iomanip>

using namespace cv;
using namespace cv::ocl;
using namespace testing;
using namespace std;

template <typename T>
static void blendLinearGold(const Mat &img1, const Mat &img2,
                            const Mat &weights1, const Mat &weights2,
                            Mat &result_gold)
{
    CV_Assert(img1.size() == img2.size() && img1.type() == img2.type());
    CV_Assert(weights1.size() == weights2.size() && weights1.size() == img1.size() &&
              weights1.type() == CV_32FC1 && weights2.type() == CV_32FC1);

    result_gold.create(img1.size(), img1.type());

    int cn = img1.channels();
    int step1 = img1.cols * img1.channels();

    for (int y = 0; y < img1.rows; ++y)
    {
        const float * const weights1_row = weights1.ptr<float>(y);
        const float * const weights2_row = weights2.ptr<float>(y);
        const T * const img1_row = img1.ptr<T>(y);
        const T * const img2_row = img2.ptr<T>(y);
        T * const result_gold_row = result_gold.ptr<T>(y);

        for (int x = 0; x < step1; ++x)
        {
            int x1 = x / cn;
            float w1 = weights1_row[x1], w2 = weights2_row[x1];
            result_gold_row[x] = saturate_cast<T>(((float)img1_row[x] * w1
                                                 + (float)img2_row[x] * w2) / (w1 + w2 + 1e-5f));
        }
    }
}

PARAM_TEST_CASE(Blend, MatDepth, int, bool)
{
    int depth, channels;
    bool useRoi;

    Mat src1, src2, weights1, weights2, dst;
    Mat src1_roi, src2_roi, weights1_roi, weights2_roi, dst_roi;
    oclMat gsrc1, gsrc2, gweights1, gweights2, gdst, gst;
    oclMat gsrc1_roi, gsrc2_roi, gweights1_roi, gweights2_roi, gdst_roi;

    virtual void SetUp()
    {
        depth = GET_PARAM(0);
        channels = GET_PARAM(1);
        useRoi = GET_PARAM(2);
    }

    void random_roi()
    {
        const int type = CV_MAKE_TYPE(depth, channels);

        const double upValue = 256;
        const double sumMinValue = 0.01; // we don't want to divide by "zero"

        Size roiSize = randomSize(1, 20);
        Border src1Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
        randomSubMat(src1, src1_roi, roiSize, src1Border, type, -upValue, upValue);

        Border src2Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
        randomSubMat(src2, src2_roi, roiSize, src2Border, type, -upValue, upValue);

        Border weights1Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
        randomSubMat(weights1, weights1_roi, roiSize, weights1Border, CV_32FC1, -upValue, upValue);

        Border weights2Border = randomBorder(0, useRoi ? MAX_VALUE : 0);
        randomSubMat(weights2, weights2_roi, roiSize, weights2Border, CV_32FC1, sumMinValue, upValue); // fill it as a (w1 + w12)

        weights2_roi = weights2_roi - weights1_roi;
        // check that weights2_roi is still a part of weights2 (not a new matrix)
        CV_Assert(checkNorm(weights2_roi,
            weights2(Rect(weights2Border.lef, weights2Border.top, roiSize.width, roiSize.height))) < 1e-6);

        Border dstBorder = randomBorder(0, useRoi ? MAX_VALUE : 0);
        randomSubMat(dst, dst_roi, roiSize, dstBorder, type, 5, 16);

        generateOclMat(gsrc1, gsrc1_roi, src1, roiSize, src1Border);
        generateOclMat(gsrc2, gsrc2_roi, src2, roiSize, src2Border);
        generateOclMat(gweights1, gweights1_roi, weights1, roiSize, weights1Border);
        generateOclMat(gweights2, gweights2_roi, weights2, roiSize, weights2Border);
        generateOclMat(gdst, gdst_roi, dst, roiSize, dstBorder);
    }

    void Near(double eps = 0.0)
    {
        Mat whole, roi;
        gdst.download(whole);
        gdst_roi.download(roi);

        EXPECT_MAT_NEAR(dst, whole, eps);
        EXPECT_MAT_NEAR(dst_roi, roi, eps);
    }
};

typedef void (*blendLinearFunc)(const cv::Mat &img1, const cv::Mat &img2, const cv::Mat &weights1, const cv::Mat &weights2, cv::Mat &result_gold);

OCL_TEST_P(Blend, Accuracy)
{
    for (int i = 0; i < LOOP_TIMES; ++i)
    {
        random_roi();

        cv::ocl::blendLinear(gsrc1_roi, gsrc2_roi, gweights1_roi, gweights2_roi, gdst_roi);

        static blendLinearFunc funcs[] = {
            blendLinearGold<uchar>,
            blendLinearGold<schar>,
            blendLinearGold<ushort>,
            blendLinearGold<short>,
            blendLinearGold<int>,
            blendLinearGold<float>,
        };

        blendLinearFunc func = funcs[depth];
        func(src1_roi, src2_roi, weights1_roi, weights2_roi, dst_roi);

        Near(depth <= CV_32S ? 1.0 : 0.2);
    }
}

INSTANTIATE_TEST_CASE_P(OCL_ImgProc, Blend,
                        Combine(testing::Values(CV_8U, CV_8S, CV_16U, CV_16S, CV_32S, CV_32F),
                                testing::Range(1, 5), Bool()));
<|endoftext|>


<commit_before>#include <import.hpp>

#include <kdb.hpp>
#include <modules.hpp>
#include <cmdline.hpp>
#include <keysetio.hpp>
#include <toolexcept.hpp>

#include <iostream>

#include <merging/threewaymerge.hpp>
#include <merging/metamergestrategy.hpp>
#include <mergehelper.hpp>

using namespace std;
using namespace kdb;
using namespace kdb::tools;
using namespace kdb::tools::merging;

ImportCommand::ImportCommand()
{}

int ImportCommand::execute(Cmdline const& cl)
{
	size_t argc = cl.arguments.size();
	if (argc != 1 && argc != 2 && argc != 3)
	{
		throw invalid_argument("need 1 to 3 arguments");
	}

	Key root (cl.arguments[0], KEY_END);
	if (!root.isValid())
	{
        throw invalid_argument ("root key \"" + cl.arguments[0] + "\" is not a valid key name");
	}

	KeySet originalKeys;
	kdb.get (originalKeys, root);
	KeySet base = originalKeys.cut (root);
	printWarnings (cerr, root);

	KeySet importedKeys;

	string format = cl.format;
	if (argc > 1) format = cl.arguments[1];

	string file = "/dev/stdin";
	if (argc > 2 && cl.arguments[2] != "-") file = cl.arguments[2];

	Modules modules;
	PluginPtr plugin = modules.load (format);

	Key errorKey (root);
	errorKey.setString (file);

	plugin->get (importedKeys, errorKey);

	printWarnings (cerr, errorKey);
	printError (cerr, errorKey);

	ThreeWayMerge merger;
	MergeHelper helper;

	helper.configureMerger (cl, merger);
	MergeResult result = merger.mergeKeySet (
			MergeTask (BaseMergeKeys (base, root), OurMergeKeys (base, root),
					TheirMergeKeys (importedKeys, root), root));

	helper.reportResult (cl, result, cout, cerr);

	if (!result.hasConflicts ())
	{
        if (cl.verbose)
		{
			cout << "The merged keyset with strategy " << cl.strategy << " is:" << endl;
			cout << result.getMergedKeys();
		}

		KeySet resultKeys = result.getMergedKeys();
		originalKeys.append(resultKeys);
		kdb.set (originalKeys, root);
		return 0;
	}
	else
	{
		return -1;
	}
}

ImportCommand::~ImportCommand()
{}
<commit_msg>cut import keys<commit_after>#include <import.hpp>

#include <kdb.hpp>
#include <modules.hpp>
#include <cmdline.hpp>
#include <keysetio.hpp>
#include <toolexcept.hpp>

#include <iostream>

#include <merging/threewaymerge.hpp>
#include <merging/metamergestrategy.hpp>
#include <mergehelper.hpp>

using namespace std;
using namespace kdb;
using namespace kdb::tools;
using namespace kdb::tools::merging;

ImportCommand::ImportCommand()
{}

int ImportCommand::execute(Cmdline const& cl)
{
	size_t argc = cl.arguments.size();
	if (argc != 1 && argc != 2 && argc != 3)
	{
		throw invalid_argument("need 1 to 3 arguments");
	}

	Key root (cl.arguments[0], KEY_END);
	if (!root.isValid())
	{
		throw invalid_argument ("root key \"" + cl.arguments[0] + "\" is not a valid key name");
	}

	KeySet originalKeys;
	kdb.get (originalKeys, root);
	KeySet base = originalKeys.cut (root);
	printWarnings (cerr, root);

	KeySet importedKeys;

	string format = cl.format;
	if (argc > 1) format = cl.arguments[1];

	string file = "/dev/stdin";
	if (argc > 2 && cl.arguments[2] != "-") file = cl.arguments[2];

	Modules modules;
	PluginPtr plugin = modules.load (format);

	Key errorKey (root);
	errorKey.setString (file);

	plugin->get(importedKeys, errorKey);
	importedKeys = importedKeys.cut(root);

	printWarnings (cerr, errorKey);
	printError (cerr, errorKey);

	ThreeWayMerge merger;
	MergeHelper helper;

	helper.configureMerger (cl, merger);
	MergeResult result = merger.mergeKeySet (
			MergeTask (BaseMergeKeys (base, root), OurMergeKeys (base, root),
					TheirMergeKeys (importedKeys, root), root));

	helper.reportResult (cl, result, cout, cerr);

	if (!result.hasConflicts ())
	{
        if (cl.verbose)
		{
			cout << "The merged keyset with strategy " << cl.strategy << " is:" << endl;
			cout << result.getMergedKeys();
		}

		KeySet resultKeys = result.getMergedKeys();
		originalKeys.append(resultKeys);
		kdb.set (originalKeys, root);
		return 0;
	}
	else
	{
		return -1;
	}
}

ImportCommand::~ImportCommand()
{}
<|endoftext|>


<commit_before>/*
 * strcheck.hpp
 *  The class to check if strings are integer, decimal, or real number
 *
 *  written by janus_wel<janus.wel.3@gmail.com>
 *  This source code is in public domain, and has NO WARRANTY.
 * */

#ifndef STRCHECK_HPP
#define STRCHECK_HPP

#include <cstring>
#include <locale>
#include <string>

namespace util {
    namespace string {
        template<typename Char> struct numeric_traits;
        template<> struct numeric_traits<char> {
            typedef char    char_type;
            static const char_type positive = '+';
            static const char_type negative = '-';
        };
        template<> struct numeric_traits<wchar_t> {
            typedef wchar_t char_type;
            static const char_type positive = L'+';
            static const char_type negative = L'-';
        };

        template<   typename Char,
                    typename CharTraits = std::char_traits<Char>,
                    typename NumTraits = numeric_traits<Char> >
        class basic_check {
            public:
                typedef Char                            char_type;
                typedef std::basic_string<char_type>    string_type;
                typedef std::ctype<char_type>           ctype_type;
                typedef std::numpunct<char_type>        numpunct_type;

            private:
                std::locale loc;

            public:
                // constructor
                explicit basic_check(void) : loc(std::locale()) {}
                explicit basic_check(const std::locale& loc) : loc(loc) {}

            private:
                const ctype_type& ctype(void) const {
                    static const ctype_type& ctype =
                        std::use_facet<ctype_type>(loc);
                    return ctype;
                }

                char_type decimal_point(void) const {
                    static const char_type decimal_point =
                        std::use_facet<numpunct_type>(loc).decimal_point();
                    return decimal_point;
                }

            public:
                bool is_integer(const char_type* const str) const {
                    const char_type* const first =
                        (  (str[0] == NumTraits::positive)
                         | (str[0] == NumTraits::negative)) ? str + 1 : str;
                    const char_type* const last =
                        first + CharTraits::length(first);
                    const char_type* const found =
                        ctype().scan_not(ctype_type::digit, first, last);

                    return found == last;
                }

                bool is_integer(const string_type& str) const {
                    return is_integer(str.c_str());
                }

                bool is_decimal(const char_type* const str) const {
                    const char_type* const first =
                        (  (str[0] == NumTraits::positive)
                         | (str[0] == NumTraits::negative)) ? str + 1 : str;

                    const char_type* const point =
                        CharTraits::find(   first,
                                            CharTraits::length(first),
                                            decimal_point());

                    if (point == 0 || point == first) return false;

                    const char_type* integer =
                        ctype().scan_not(ctype_type::digit, first, point);
                    return ((integer == point) & is_integer(point + 1));
                }

                bool is_decimal(const string_type& str) const {
                    return is_decimal(str.c_str());
                }

                bool is_real(const char_type* const str) const {
                    return (is_integer(str) | is_decimal(str));
                }

                bool is_real(const string_type& str) const {
                    return is_real(str.c_str());
                }
        };

        typedef basic_check<char>       check;
        typedef basic_check<wchar_t>    wcheck;
    }
}

#endif // STRCHECK_HPP

<commit_msg>Add some member functions<commit_after>/*
 * strcheck.hpp
 *  The class to check if strings are integer, decimal, or real number
 *
 *  written by janus_wel<janus.wel.3@gmail.com>
 *  This source code is in public domain, and has NO WARRANTY.
 * */

#ifndef STRCHECK_HPP
#define STRCHECK_HPP

#include <cstring>
#include <locale>
#include <string>

namespace util {
    namespace string {
        template<typename Char> struct numeric_traits;
        template<> struct numeric_traits<char> {
            typedef char    char_type;
            static const char_type positive = '+';
            static const char_type negative = '-';
        };
        template<> struct numeric_traits<wchar_t> {
            typedef wchar_t char_type;
            static const char_type positive = L'+';
            static const char_type negative = L'-';
        };

        template<   typename Char,
                    typename CharTraits = std::char_traits<Char>,
                    typename NumTraits = numeric_traits<Char> >
        class basic_check {
            public:
                typedef Char                            char_type;
                typedef std::basic_string<char_type>    string_type;
                typedef std::ctype<char_type>           ctype_type;
                typedef std::numpunct<char_type>        numpunct_type;

            private:
                std::locale loc;

            public:
                // constructor
                explicit basic_check(void) : loc(std::locale()) {}
                explicit basic_check(const std::locale& loc) : loc(loc) {}

            private:
                const ctype_type& ctype(void) const {
                    static const ctype_type& ctype =
                        std::use_facet<ctype_type>(loc);
                    return ctype;
                }

                char_type decimal_point(void) const {
                    static const char_type decimal_point =
                        std::use_facet<numpunct_type>(loc).decimal_point();
                    return decimal_point;
                }

            public:
                bool is_positive(const char_type* const str) const {
                    return !is_negative(str);
                }

                bool is_positive(const string_type& str) const {
                    return is_positive(str.c_str());
                }

                bool is_negative(const char_type* const str) const {
                    return str[0] == NumTraits::negative;
                }

                bool is_negative(const string_type& str) const {
                    return is_negative(str.c_str());
                }

                bool is_integer(const char_type* const str) const {
                    const char_type* const first =
                        (  (str[0] == NumTraits::positive)
                         | (str[0] == NumTraits::negative)) ? str + 1 : str;
                    const char_type* const last =
                        first + CharTraits::length(first);
                    const char_type* const found =
                        ctype().scan_not(ctype_type::digit, first, last);

                    return found == last;
                }

                bool is_integer(const string_type& str) const {
                    return is_integer(str.c_str());
                }

                bool is_decimal(const char_type* const str) const {
                    const char_type* const first =
                        (  (str[0] == NumTraits::positive)
                         | (str[0] == NumTraits::negative)) ? str + 1 : str;

                    const char_type* const point =
                        CharTraits::find(   first,
                                            CharTraits::length(first),
                                            decimal_point());

                    if (point == 0 || point == first) return false;

                    const char_type* integer =
                        ctype().scan_not(ctype_type::digit, first, point);
                    return ((integer == point) & is_integer(point + 1));
                }

                bool is_decimal(const string_type& str) const {
                    return is_decimal(str.c_str());
                }

                bool is_real(const char_type* const str) const {
                    return (is_integer(str) | is_decimal(str));
                }

                bool is_real(const string_type& str) const {
                    return is_real(str.c_str());
                }
        };

        typedef basic_check<char>       check;
        typedef basic_check<wchar_t>    wcheck;
    }
}

#endif // STRCHECK_HPP

<|endoftext|>


<commit_before>#pragma once
#include <vector>
#include <utility>
#include <optional>
#include <tuple>
#include <iterator>
#include <initializer_list>

namespace aim {

        /** Ordered hash map
         */
        template <typename KeyT, typename ValueT>
        struct hash_map {
                using key_t = KeyT;
                using value_t = ValueT;
                using hash_fn = std::hash<key_t>;
                using hash_t = decltype(hash_fn{}(std::declval<key_t>()));
                using pair_t = std::tuple<hash_t, value_t>;

                using data_t = std::vector<pair_t>;
                using iterator = typename data_t::iterator;
                using const_iterator = typename data_t::const_iterator;

                hash_map()
                {}

                hash_map(std::initializer_list<pair_t> other)
                : data_(other)
                {}

                hash_map(const hash_map&) = default;
                hash_map(hash_map&&) = default;

                iterator begin() {
                        return std::begin(data_);
                }

                const_iterator begin() const {
                        return std::begin(data_);
                }

                iterator end() {
                        return std::end(data_);
                }

                const_iterator end() const {
                        return std::end(data_);
                }

                /** \brief Nonmutable iteration over map using function.
                 * \param func Function object takes type `pair_t` type as argument.
                 */
                template <typename Func>
                void iter(Func&& func) const {
                        for(auto&& node : data_)
                                func(node);
                }

                /** |brief Find existing element or return past-end element iterator.
                 */
                iterator find(const key_t& key) {
                        const auto hash_ = hash_fn{}(key);
                        auto res_ = _find(hash_);
                        return res_.found ? res_.itr : end();
                }

                /** |brief Find existing element or return past-end element iterator.
                 */
                const_iterator find(const key_t& key) const {
                        return find(key);
                }

                /** \brief Inserts new element to map.
                 * \param key Key to access.
                 * \param value New value.
                 * \return New element was created or reassigned to existing key.
                 */
                bool insert(const key_t& key, const value_t& value) {
                        const auto hash_ = hash_fn{}(key);
                        const auto& own = _find(hash_);
                        if (own.found) {
                                std::get<1>(*own.itr) = value;
                                return false;
                        }
                        else {
                                auto iter = own.itr;
                                std::advance(iter, 1);
                                data_.insert(iter, std::make_tuple(hash_, value));
                                return true;
                        }
                }

                /** \brief Removes element by its key.
                 * \param key
                 * \return True if element was removed and false otherwise.
                 */
                bool remove(const key_t& key) {
                        const auto hash_ = hash_fn{}(key);
                        const auto& own = _find(hash_);
                        if (own.found) {
                                data_.erase(own.itr);
                                return true;
                        }
                        else {
                                return false;
                        }
                }

        private:

                struct search_result {
                        bool found; /// Element was found
                        iterator itr; /// Iterator to previous element
                };

                /** \brief Searches element by its key's hash.
                 * \param hash_ Key's hash.
                 */
                search_result _find(const hash_t hash_) {
                        auto left = begin();
                        auto right = end();
                        bool searching = true;

                        auto result = search_result{false, right};

                        while (searching) {
                                const std::size_t dist = std::distance(left, right) / 2;

                                auto itr = left;

                                if (dist == 0) {
                                        result.found = false;
                                        result.itr = itr;
                                        break;
                                }

                                std::advance(itr, dist);

                                const auto itr_hash = std::get<0>(*itr);

                                if (itr_hash < hash_) {
                                        left = itr;
                                }
                                else if (itr_hash > hash_) {
                                        right = itr;
                                }
                                else if (itr_hash == hash_) {
                                        result.found = true;
                                        result.itr = itr;
                                        searching = false;
                                }
                                else {
                                        result.found = false;
                                        result.itr = itr;
                                        searching = false;
                                }
                        }
                        return result;
                }

                data_t data_;
        };
}
<commit_msg>Remove unusable code<commit_after>#pragma once
#include <vector>
#include <utility>
#include <optional>
#include <tuple>
#include <iterator>
#include <initializer_list>

namespace aim {

        /** Ordered hash map
         */
        template <typename KeyT, typename ValueT>
        struct hash_map {
                using key_t = KeyT;
                using value_t = ValueT;
                using hash_fn = std::hash<key_t>;
                using hash_t = decltype(hash_fn{}(std::declval<key_t>()));
                using pair_t = std::tuple<hash_t, value_t>;

                using data_t = std::vector<pair_t>;
                using iterator = typename data_t::iterator;
                using const_iterator = typename data_t::const_iterator;

                hash_map()
                {}

                hash_map(std::initializer_list<pair_t> other)
                : data_(other)
                {}

                hash_map(const hash_map&) = default;
                hash_map(hash_map&&) = default;

                iterator begin() {
                        return std::begin(data_);
                }

                const_iterator begin() const {
                        return std::begin(data_);
                }

                iterator end() {
                        return std::end(data_);
                }

                const_iterator end() const {
                        return std::end(data_);
                }

                /** \brief Nonmutable iteration over map using function.
                 * \param func Function object takes type `pair_t` type as argument.
                 */
                template <typename Func>
                void iter(Func&& func) const {
                        for(auto&& node : data_)
                                func(node);
                }

                /** |brief Find existing element or return past-end element iterator.
                 */
                iterator find(const key_t& key) {
                        const auto hash_ = hash_fn{}(key);
                        auto res_ = _find(hash_);
                        return res_.found ? res_.itr : end();
                }

                /** |brief Find existing element or return past-end element iterator.
                 */
                const_iterator find(const key_t& key) const {
                        return find(key);
                }

                /** \brief Inserts new element to map.
                 * \param key Key to access.
                 * \param value New value.
                 * \return New element was created or reassigned to existing key.
                 */
                bool insert(const key_t& key, const value_t& value) {
                        const auto hash_ = hash_fn{}(key);
                        const auto& own = _find(hash_);
                        if (own.found) {
                                std::get<1>(*own.itr) = value;
                                return false;
                        }
                        else {
                                auto iter = own.itr;
                                std::advance(iter, 1);
                                data_.insert(iter, std::make_tuple(hash_, value));
                                return true;
                        }
                }

                /** \brief Removes element by its key.
                 * \param key
                 * \return True if element was removed and false otherwise.
                 */
                bool remove(const key_t& key) {
                        const auto hash_ = hash_fn{}(key);
                        const auto& own = _find(hash_);
                        if (own.found) {
                                data_.erase(own.itr);
                                return true;
                        }
                        else {
                                return false;
                        }
                }

        private:

                struct search_result {
                        bool found; /// Element was found
                        iterator itr; /// Iterator to previous element
                };

                /** \brief Searches element by its key's hash.
                 * \param hash_ Key's hash.
                 */
                search_result _find(const hash_t hash_) {
                        auto left = begin();
                        auto right = end();
                        bool searching = true;

                        auto result = search_result{false, right};

                        while (searching) {
                                const std::size_t dist = std::distance(left, right) / 2;

                                auto itr = left;

                                if (dist == 0) {
                                        result.found = false;
                                        result.itr = itr;
                                        break;
                                }

                                std::advance(itr, dist);

                                const auto itr_hash = std::get<0>(*itr);

                                if (itr_hash < hash_) {
                                        left = itr;
                                }
                                else if (itr_hash > hash_) {
                                        right = itr;
                                }
                                else {
                                        result.found = true;
                                        result.itr = itr;
                                        searching = false;
                                }
                        }
                        return result;
                }

                data_t data_;
        };
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkCellDataToPointData.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkCellDataToPointData.h"

#include "vtkCellData.h"
#include "vtkCell.h"
#include "vtkDataSet.h"
#include "vtkIdList.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkUnstructuredGrid.h"
#include "vtkSmartPointer.h"
#include "vtkUnsignedIntArray.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"

#include <algorithm>
#include <functional>

vtkStandardNewMacro(vtkCellDataToPointData);

//----------------------------------------------------------------------------
// Instantiate object so that cell data is not passed to output.
vtkCellDataToPointData::vtkCellDataToPointData()
{
  this->PassCellData = 0;
}

#define VTK_MAX_CELLS_PER_POINT 4096

//----------------------------------------------------------------------------
int vtkCellDataToPointData::RequestData(
  vtkInformation*,
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  vtkInformation* info = outputVector->GetInformationObject(0);
  vtkDataSet *output = vtkDataSet::SafeDownCast(
    info->Get(vtkDataObject::DATA_OBJECT()));

  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  vtkDataSet *input = vtkDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkDebugMacro(<<"Mapping cell data to point data");

  // Special traversal algorithm for unstructured grid
  if (input->IsA("vtkUnstructuredGrid"))
    {
    return this->RequestDataForUnstructuredGrid(0, inputVector, outputVector);
    }

  vtkIdType cellId, ptId;
  vtkIdType numCells, numPts;
  vtkCellData *inPD=input->GetCellData();
  vtkPointData *outPD=output->GetPointData();
  vtkIdList *cellIds;
  double weight;
  double *weights;

  vtkDebugMacro(<<"Mapping cell data to point data");

  // First, copy the input to the output as a starting point
  output->CopyStructure( input );

  cellIds = vtkIdList::New();
  cellIds->Allocate(VTK_MAX_CELLS_PER_POINT);

  if ( (numPts=input->GetNumberOfPoints()) < 1 )
    {
    vtkDebugMacro(<<"No input point data!");
    cellIds->Delete();
    return 1;
    }
  weights = new double[VTK_MAX_CELLS_PER_POINT];

  // Pass the point data first. The fields and attributes
  // which also exist in the cell data of the input will
  // be over-written during CopyAllocate
  output->GetPointData()->CopyGlobalIdsOff();
  output->GetPointData()->PassData(input->GetPointData());
  output->GetPointData()->CopyFieldOff("vtkGhostLevels");

  // notice that inPD and outPD are vtkCellData and vtkPointData; respectively.
  // It's weird, but it works.
  outPD->InterpolateAllocate(inPD,numPts);

  int abort=0;
  vtkIdType progressInterval=numPts/20 + 1;
  for (ptId=0; ptId < numPts && !abort; ptId++)
    {
    if ( !(ptId % progressInterval) )
      {
      this->UpdateProgress(static_cast<double>(ptId)/numPts);
      abort = GetAbortExecute();
      }

    input->GetPointCells(ptId, cellIds);
    numCells = cellIds->GetNumberOfIds();
    if ( numCells > 0 && numCells < VTK_MAX_CELLS_PER_POINT )
      {
      weight = 1.0 / numCells;
      for (cellId=0; cellId < numCells; cellId++)
        {
        weights[cellId] = weight;
        }
      outPD->InterpolatePoint(inPD, ptId, cellIds, weights);
      }
    else
      {
      outPD->NullPoint(ptId);
      }
    }

  if ( !this->PassCellData )
    {
    output->GetCellData()->CopyAllOff();
    output->GetCellData()->CopyFieldOn("vtkGhostLevels");
    }
  output->GetCellData()->PassData(input->GetCellData());

  cellIds->Delete();
  delete [] weights;

  return 1;
}

//----------------------------------------------------------------------------
void vtkCellDataToPointData::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Pass Cell Data: " << (this->PassCellData ? "On\n" : "Off\n");
}

//----------------------------------------------------------------------------
// Helper template function that implement the major part of the algorighm
// which will be expanded by the vtkTemplateMacro. The template function is
// provided so that coverage test can cover this function.
namespace
{
  template <typename T>
  void __spread (vtkUnstructuredGrid* const src, vtkUnsignedIntArray* const num,
             vtkDataArray* const srcarray, vtkDataArray* const dstarray,
             vtkIdType ncells, vtkIdType npoints, vtkIdType ncomps)
  {
    T const* const srcptr = static_cast<T const*>(srcarray->GetVoidPointer(0));
    T      * const dstptr = static_cast<T      *>(dstarray->GetVoidPointer(0));

    // zero initialization
    std::fill_n(dstptr, npoints*ncomps, T(0));

    // accumulate
    T const* srcbeg = srcptr;
    for (vtkIdType cid = 0; cid < ncells; ++cid, srcbeg += ncomps)
      {
      vtkIdList* const pids = src->GetCell(cid)->GetPointIds();
      for (vtkIdType i = 0, I = pids->GetNumberOfIds(); i < I; ++i)
        {
        T* const dstbeg = dstptr + pids->GetId(i)*ncomps;
        // accumulate cell data to point data <==> point_data += cell_data
        std::transform(srcbeg,srcbeg+ncomps,dstbeg,dstbeg,std::plus<T>());
        }
      }

    // average
    T* dstbeg = dstptr;
    for (vtkIdType pid = 0; pid < npoints; ++pid, dstbeg += ncomps)
      {
      // guard against divide by zero
      if (unsigned int const denum = num->GetValue(pid))
        {
        // divide point data by the number of cells using it <==>
        // point_data /= denum
        std::transform(dstbeg, dstbeg+ncomps, dstbeg,
          std::bind2nd(std::divides<T>(), denum));
        }
      }
  }
}

//----------------------------------------------------------------------------
int vtkCellDataToPointData::RequestDataForUnstructuredGrid
  (vtkInformation*,
   vtkInformationVector** inputVector,
   vtkInformationVector* outputVector)
{
  vtkUnstructuredGrid* const src = vtkUnstructuredGrid::SafeDownCast(
    inputVector[0]->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));
  vtkUnstructuredGrid* const dst = vtkUnstructuredGrid::SafeDownCast(
    outputVector->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));

  vtkIdType const ncells  = src->GetNumberOfCells ();
  vtkIdType const npoints = src->GetNumberOfPoints();
  if (ncells < 1 || npoints < 1)
    {
    vtkDebugMacro(<<"No input data!");
    return 1;
    }

  // count the number of cells associated with each point
  vtkSmartPointer<vtkUnsignedIntArray> num
    = vtkSmartPointer<vtkUnsignedIntArray>::New();
  num->SetNumberOfComponents(1);
  num->SetNumberOfTuples(npoints);
  std::fill_n(num->GetPointer(0), npoints, 0u);
  for (vtkIdType cid = 0; cid < ncells; ++cid)
    {
    vtkIdList* const pids = src->GetCell(cid)->GetPointIds();
    for (vtkIdType i = 0, I = pids->GetNumberOfIds(); i < I; ++i)
      {
      vtkIdType const pid = pids->GetId(i);
      num->SetValue(pid, num->GetValue(pid)+1);
      }
    }

  // First, copy the input to the output as a starting point
  dst->CopyStructure(src);
  vtkPointData* const opd = dst->GetPointData();

  // Pass the point data first. The fields and attributes
  // which also exist in the cell data of the input will
  // be over-written during CopyAllocate
  opd->CopyGlobalIdsOff();
  opd->PassData(src->GetPointData());
  opd->CopyFieldOff("vtkGhostLevels");

  // Copy all existing cell fields into a temporary cell data array
  vtkSmartPointer<vtkCellData> clean = vtkSmartPointer<vtkCellData>::New();
  clean->PassData(src->GetCellData());

  // Remove all fields that are not a data array.
  for (vtkIdType fid = clean->GetNumberOfArrays(); fid--;)
    {
    if (!clean->GetAbstractArray(fid)->IsA("vtkDataArray"))
      {
      clean->RemoveArray(fid);
      }
    }

  // Cell field list constructed from the filtered cell data array
  vtkDataSetAttributes::FieldList cfl(1);
  cfl.InitializeFieldList(clean);
  opd->InterpolateAllocate(cfl, npoints, npoints);

  for (int fid = 0, nfields = cfl.GetNumberOfFields(); fid < nfields; ++fid)
    {
    // update progress and check for an abort request.
    this->UpdateProgress((fid+1.)/nfields);
    if (this->GetAbortExecute())
      {
      break;
      }

    // indices into the field arrays associated with the cell and the point
    // respectively
    int const dstid = cfl.GetFieldIndex(fid);
    int const srcid = cfl.GetDSAIndex(0,fid);
    if  (srcid < 0 || dstid < 0)
      {
      continue;
      }

    vtkCellData * const srccelldata  = clean;
    vtkPointData* const dstpointdata = dst->GetPointData();

    if (!srccelldata || !dstpointdata)
      {
      continue;
      }

    vtkDataArray* const srcarray = srccelldata ->GetArray(srcid);
    vtkDataArray* const dstarray = dstpointdata->GetArray(dstid);
    dstarray->SetNumberOfTuples(npoints);

    vtkIdType const ncomps = srcarray->GetNumberOfComponents();
    switch (srcarray->GetDataType())
      {
      vtkTemplateMacro
        (__spread<VTK_TT>(src,num,srcarray,dstarray,ncells,npoints,ncomps));
      }
    }

  if (!this->PassCellData)
    {
    dst->GetCellData()->CopyAllOff();
    dst->GetCellData()->CopyFieldOn("vtkGhostLevels");
    }
  dst->GetCellData()->PassData(src->GetCellData());

  return 1;
}

<commit_msg>Performance improvement to CellToPoint.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkCellDataToPointData.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkCellDataToPointData.h"

#include "vtkCellData.h"
#include "vtkCell.h"
#include "vtkDataSet.h"
#include "vtkIdList.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkSmartPointer.h"
#include "vtkUnsignedIntArray.h"
#include "vtkUnstructuredGrid.h"

#include <algorithm>
#include <functional>

vtkStandardNewMacro(vtkCellDataToPointData);

//----------------------------------------------------------------------------
// Instantiate object so that cell data is not passed to output.
vtkCellDataToPointData::vtkCellDataToPointData()
{
  this->PassCellData = 0;
}

#define VTK_MAX_CELLS_PER_POINT 4096

//----------------------------------------------------------------------------
int vtkCellDataToPointData::RequestData(
  vtkInformation*,
  vtkInformationVector** inputVector,
  vtkInformationVector* outputVector)
{
  vtkInformation* info = outputVector->GetInformationObject(0);
  vtkDataSet *output = vtkDataSet::SafeDownCast(
    info->Get(vtkDataObject::DATA_OBJECT()));

  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
  vtkDataSet *input = vtkDataSet::SafeDownCast(
    inInfo->Get(vtkDataObject::DATA_OBJECT()));

  vtkDebugMacro(<<"Mapping cell data to point data");

  // Special traversal algorithm for unstructured grid
  if (input->IsA("vtkUnstructuredGrid"))
    {
    return this->RequestDataForUnstructuredGrid(0, inputVector, outputVector);
    }

  vtkIdType cellId, ptId;
  vtkIdType numCells, numPts;
  vtkCellData *inPD=input->GetCellData();
  vtkPointData *outPD=output->GetPointData();
  vtkIdList *cellIds;
  double weight;
  double *weights;

  vtkDebugMacro(<<"Mapping cell data to point data");

  // First, copy the input to the output as a starting point
  output->CopyStructure( input );

  cellIds = vtkIdList::New();
  cellIds->Allocate(VTK_MAX_CELLS_PER_POINT);

  if ( (numPts=input->GetNumberOfPoints()) < 1 )
    {
    vtkDebugMacro(<<"No input point data!");
    cellIds->Delete();
    return 1;
    }
  weights = new double[VTK_MAX_CELLS_PER_POINT];

  // Pass the point data first. The fields and attributes
  // which also exist in the cell data of the input will
  // be over-written during CopyAllocate
  output->GetPointData()->CopyGlobalIdsOff();
  output->GetPointData()->PassData(input->GetPointData());
  output->GetPointData()->CopyFieldOff("vtkGhostLevels");

  // notice that inPD and outPD are vtkCellData and vtkPointData; respectively.
  // It's weird, but it works.
  outPD->InterpolateAllocate(inPD,numPts);

  int abort=0;
  vtkIdType progressInterval=numPts/20 + 1;
  for (ptId=0; ptId < numPts && !abort; ptId++)
    {
    if ( !(ptId % progressInterval) )
      {
      this->UpdateProgress(static_cast<double>(ptId)/numPts);
      abort = GetAbortExecute();
      }

    input->GetPointCells(ptId, cellIds);
    numCells = cellIds->GetNumberOfIds();
    if ( numCells > 0 && numCells < VTK_MAX_CELLS_PER_POINT )
      {
      weight = 1.0 / numCells;
      for (cellId=0; cellId < numCells; cellId++)
        {
        weights[cellId] = weight;
        }
      outPD->InterpolatePoint(inPD, ptId, cellIds, weights);
      }
    else
      {
      outPD->NullPoint(ptId);
      }
    }

  if ( !this->PassCellData )
    {
    output->GetCellData()->CopyAllOff();
    output->GetCellData()->CopyFieldOn("vtkGhostLevels");
    }
  output->GetCellData()->PassData(input->GetCellData());

  cellIds->Delete();
  delete [] weights;

  return 1;
}

//----------------------------------------------------------------------------
void vtkCellDataToPointData::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Pass Cell Data: " << (this->PassCellData ? "On\n" : "Off\n");
}

//----------------------------------------------------------------------------
// Helper template function that implement the major part of the algorighm
// which will be expanded by the vtkTemplateMacro. The template function is
// provided so that coverage test can cover this function.
namespace
{
  template <typename T>
  void __spread (vtkUnstructuredGrid* const src, vtkUnsignedIntArray* const num,
             vtkDataArray* const srcarray, vtkDataArray* const dstarray,
             vtkIdType ncells, vtkIdType npoints, vtkIdType ncomps)
  {
    T const* const srcptr = static_cast<T const*>(srcarray->GetVoidPointer(0));
    T      * const dstptr = static_cast<T      *>(dstarray->GetVoidPointer(0));

    // zero initialization
    std::fill_n(dstptr, npoints*ncomps, T(0));

    // accumulate
    T const* srcbeg = srcptr;
    vtkNew<vtkIdList> pids;
    for (vtkIdType cid = 0; cid < ncells; ++cid, srcbeg += ncomps)
      {
      src->GetCellPoints(cid, pids.GetPointer());
      for (vtkIdType i = 0, I = pids->GetNumberOfIds(); i < I; ++i)
        {
        T* const dstbeg = dstptr + pids->GetId(i)*ncomps;
        // accumulate cell data to point data <==> point_data += cell_data
        std::transform(srcbeg,srcbeg+ncomps,dstbeg,dstbeg,std::plus<T>());
        }
      }

    // average
    T* dstbeg = dstptr;
    for (vtkIdType pid = 0; pid < npoints; ++pid, dstbeg += ncomps)
      {
      // guard against divide by zero
      if (unsigned int const denum = num->GetValue(pid))
        {
        // divide point data by the number of cells using it <==>
        // point_data /= denum
        std::transform(dstbeg, dstbeg+ncomps, dstbeg,
          std::bind2nd(std::divides<T>(), denum));
        }
      }
  }
}

//----------------------------------------------------------------------------
int vtkCellDataToPointData::RequestDataForUnstructuredGrid
  (vtkInformation*,
   vtkInformationVector** inputVector,
   vtkInformationVector* outputVector)
{
  vtkUnstructuredGrid* const src = vtkUnstructuredGrid::SafeDownCast(
    inputVector[0]->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));
  vtkUnstructuredGrid* const dst = vtkUnstructuredGrid::SafeDownCast(
    outputVector->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));

  vtkIdType const ncells  = src->GetNumberOfCells ();
  vtkIdType const npoints = src->GetNumberOfPoints();
  if (ncells < 1 || npoints < 1)
    {
    vtkDebugMacro(<<"No input data!");
    return 1;
    }

  // count the number of cells associated with each point
  vtkSmartPointer<vtkUnsignedIntArray> num
    = vtkSmartPointer<vtkUnsignedIntArray>::New();
  num->SetNumberOfComponents(1);
  num->SetNumberOfTuples(npoints);
  std::fill_n(num->GetPointer(0), npoints, 0u);
  vtkNew<vtkIdList> pids;
  for (vtkIdType cid = 0; cid < ncells; ++cid)
    {
    src->GetCellPoints(cid, pids.GetPointer());
    for (vtkIdType i = 0, I = pids->GetNumberOfIds(); i < I; ++i)
      {
      vtkIdType const pid = pids->GetId(i);
      num->SetValue(pid, num->GetValue(pid)+1);
      }
    }

  // First, copy the input to the output as a starting point
  dst->CopyStructure(src);
  vtkPointData* const opd = dst->GetPointData();

  // Pass the point data first. The fields and attributes
  // which also exist in the cell data of the input will
  // be over-written during CopyAllocate
  opd->CopyGlobalIdsOff();
  opd->PassData(src->GetPointData());
  opd->CopyFieldOff("vtkGhostLevels");

  // Copy all existing cell fields into a temporary cell data array
  vtkSmartPointer<vtkCellData> clean = vtkSmartPointer<vtkCellData>::New();
  clean->PassData(src->GetCellData());

  // Remove all fields that are not a data array.
  for (vtkIdType fid = clean->GetNumberOfArrays(); fid--;)
    {
    if (!clean->GetAbstractArray(fid)->IsA("vtkDataArray"))
      {
      clean->RemoveArray(fid);
      }
    }

  // Cell field list constructed from the filtered cell data array
  vtkDataSetAttributes::FieldList cfl(1);
  cfl.InitializeFieldList(clean);
  opd->InterpolateAllocate(cfl, npoints, npoints);

  for (int fid = 0, nfields = cfl.GetNumberOfFields(); fid < nfields; ++fid)
    {
    // update progress and check for an abort request.
    this->UpdateProgress((fid+1.)/nfields);
    if (this->GetAbortExecute())
      {
      break;
      }

    // indices into the field arrays associated with the cell and the point
    // respectively
    int const dstid = cfl.GetFieldIndex(fid);
    int const srcid = cfl.GetDSAIndex(0,fid);
    if  (srcid < 0 || dstid < 0)
      {
      continue;
      }

    vtkCellData * const srccelldata  = clean;
    vtkPointData* const dstpointdata = dst->GetPointData();

    if (!srccelldata || !dstpointdata)
      {
      continue;
      }

    vtkDataArray* const srcarray = srccelldata ->GetArray(srcid);
    vtkDataArray* const dstarray = dstpointdata->GetArray(dstid);
    dstarray->SetNumberOfTuples(npoints);

    vtkIdType const ncomps = srcarray->GetNumberOfComponents();
    switch (srcarray->GetDataType())
      {
      vtkTemplateMacro
        (__spread<VTK_TT>(src,num,srcarray,dstarray,ncells,npoints,ncomps));
      }
    }

  if (!this->PassCellData)
    {
    dst->GetCellData()->CopyAllOff();
    dst->GetCellData()->CopyFieldOn("vtkGhostLevels");
    }
  dst->GetCellData()->PassData(src->GetCellData());

  return 1;
}

<|endoftext|>