<commit_before>/*
 * Copyright (C) 2016-2018 Muhammad Tayyab Akram
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cassert>
#include <cstddef>
#include <cstring>
#include <vector>

extern "C" {
#include <Source/SFPattern.h>
#include <Source/SFScheme.h>
#include <Source/SFShapingKnowledge.h>
}

#include "OpenType/Builder.h"
#include "OpenType/Common.h"
#include "OpenType/GSUB.h"
#include "Utilities/General.h"
#include "Utilities/SFPattern+Testing.h"
#include "SchemeTester.h"

using namespace std;
using namespace SheenFigure::Tester;
using namespace SheenFigure::Tester::OpenType;
using namespace SheenFigure::Tester::Utilities;

class TestKnowledge {
public:
    static SFShapingKnowledgeRef instance() { return &object->knowledge.shape; }

private:
    static TestKnowledge *object;

    struct {
        vector<SFFeatureInfo> subst;
        vector<SFFeatureInfo> pos;
    } features;
    struct {
        SFScriptKnowledge script;
        SFShapingKnowledge shape;
    } knowledge;

    static SFScriptKnowledgeRef seekScript(const void *, SFTag scriptTag)
    {
        if (scriptTag == tag("test")) {
            return &object->knowledge.script;
        }

        return NULL;
    }

    TestKnowledge() {
        features.subst = {
            /* First Group. */
            { 1, tag("srqi"), REQUIRED,       INDIVIDUAL,   0x00 },
            { 1, tag("srq1"), REQUIRED,       SIMULTANEOUS, 0x00 },
            { 1, tag("son1"), ON_BY_DEFAULT,  SIMULTANEOUS, 0x00 },
            { 1, tag("sof1"), OFF_BY_DEFAULT, SIMULTANEOUS, 0x00 },
            /* Second Group. */
            { 2, tag("sim1"), REQUIRED,       SIMULTANEOUS, 0x00 },
            { 2, tag("sim2"), REQUIRED,       SIMULTANEOUS, 0x00 },
        };
        features.pos = {
            /* Third Group. */
            { 3, tag("pof1"), OFF_BY_DEFAULT, SIMULTANEOUS, 0x00 },
            { 3, tag("pon1"), ON_BY_DEFAULT,  SIMULTANEOUS, 0x00 },
            { 3, tag("prq1"), REQUIRED,       SIMULTANEOUS, 0x00 },
            { 3, tag("prqi"), REQUIRED,       INDIVIDUAL,   0x00 },
        };
        knowledge.script = {
            SFTextDirectionLeftToRight,
            { features.subst.data(), features.subst.size() },
            { features.pos.data(), features.pos.size() }
        };
        knowledge.shape = {
            &seekScript
        };
    }
};
TestKnowledge *TestKnowledge::object = new TestKnowledge();

static const UInt16 CUST = 0;
static const UInt16 PCST = 1;
static const UInt16 POF1 = 2;
static const UInt16 PON1 = 3;
static const UInt16 PRQ1 = 4;
static const UInt16 PRQI = 5;
static const UInt16 SCST = 6;
static const UInt16 SIM1 = 7;
static const UInt16 SIM2 = 8;
static const UInt16 SOF1 = 9;
static const UInt16 SON1 = 10;
static const UInt16 SRQ1 = 11;
static const UInt16 SRQI = 12;

static void loadTable(void *, SFTag tableTag, SFUInt8 *buffer, SFUInteger *length)
{
    if (tableTag == tag("GSUB")) {
        Builder builder;

        FeatureListTable &featureList = builder.createFeatureList({
            {tag("cust"), builder.createFeature({ CUST })},
            {tag("scst"), builder.createFeature({ SCST })},
            {tag("sim1"), builder.createFeature({ SIM1 })},
            {tag("sim2"), builder.createFeature({ SIM2 })},
            {tag("sof1"), builder.createFeature({ SOF1 })},
            {tag("son1"), builder.createFeature({ SON1 })},
            {tag("srq1"), builder.createFeature({ SRQ1 })},
            {tag("srqi"), builder.createFeature({ SRQI })},
        });
        ScriptListTable &scriptList = builder.createScriptList({
            {tag("test"), builder.createScript(builder.createLangSys({ 0, 1, 2, 3, 4, 5, 6, 7 }), {
                                                   {tag("LNG "), builder.createLangSys({ 7 })}
                                               })}
        });

        GSUB gsub;
        gsub.version = 0x00010000;
        gsub.scriptList = &scriptList;
        gsub.featureList = &featureList;
        gsub.lookupList = NULL;

        Writer writer;
        writer.write(&gsub);

        if (length) {
            *length = (SFUInteger)writer.size();
        }
        if (buffer) {
            memcpy(buffer, writer.data(), (size_t)writer.size());
        }
    } else if (tableTag == tag("GPOS")) {
        Builder builder;

        FeatureListTable &featureList = builder.createFeatureList({
            {tag("cust"), builder.createFeature({ CUST })},
            {tag("pcst"), builder.createFeature({ PCST })},
            {tag("pof1"), builder.createFeature({ POF1 })},
            {tag("pon1"), builder.createFeature({ PON1 })},
            {tag("prq1"), builder.createFeature({ PRQ1 })},
            {tag("prqi"), builder.createFeature({ PRQI })},
        });
        ScriptListTable &scriptList = builder.createScriptList({
            {tag("test"), builder.createScript(builder.createLangSys({ 0, 1, 2, 3, 4, 5 }), {
                                              {tag("LNG "), builder.createLangSys({ 2 })}
                                          })}
        });

        GPOS gpos;
        gpos.version = 0x00010000;
        gpos.scriptList = &scriptList;
        gpos.featureList = &featureList;
        gpos.lookupList = NULL;

        Writer writer;
        writer.write(&gpos);

        if (length) {
            *length = (SFUInteger)writer.size();
        }
        if (buffer) {
            memcpy(buffer, writer.data(), (size_t)writer.size());
        }
    }
}

static SFGlyphID getGlyphIDForCodepoint(void *, SFCodepoint)
{
    return 0;
}

static SFAdvance getAdvanceForGlyph(void *, SFFontLayout, SFGlyphID)
{
    return 0;
}

SchemeTester::SchemeTester()
{
}

void SchemeTester::testFeatures()
{
    /* Test unique features. */
    {
        SFSchemeRef scheme = SFSchemeCreate();

        SFTag featureTags[] = {
            tag("ccmp"), tag("liga"), tag("dist"), tag("kern")
        };
        SFUInt16 featureValues[] = {
            1, 2, 3, 4
        };
        SFUInteger featureCount = sizeof(featureValues) / sizeof(SFUInt16);

        SFSchemeSetFeatureValues(scheme, featureTags, featureValues, featureCount);

        assert(memcmp(scheme->_featureTags, featureTags, sizeof(featureTags)) == 0);
        assert(memcmp(scheme->_featureValues, featureValues, sizeof(featureValues)) == 0);
        assert(scheme->_featureCount == featureCount);

        SFSchemeRelease(scheme);
    }

    /* Test duplicated features. */
    {
        SFSchemeRef scheme = SFSchemeCreate();

        SFTag featureTags[] = {
            tag("ccmp"), tag("liga"), tag("dist"), tag("kern"), tag("ccmp"), tag("kern")
        };
        SFUInt16 featureValues[] = {
            1, 2, 3, 4, 5, 6
        };
        SFUInteger featureCount = sizeof(featureValues) / sizeof(SFUInt16);

        SFSchemeSetFeatureValues(scheme, featureTags, featureValues, featureCount);

        SFTag expectedTags[] = {
            tag("ccmp"), tag("liga"), tag("dist"), tag("kern")
        };
        SFUInt16 expectedValues[] = {
            5, 2, 3, 6
        };
        SFUInteger expectedCount = sizeof(expectedValues) / sizeof(SFUInt16);

        assert(memcmp(scheme->_featureTags, expectedTags, sizeof(expectedTags)) == 0);
        assert(memcmp(scheme->_featureValues, expectedValues, sizeof(expectedValues)) == 0);
        assert(scheme->_featureCount == expectedCount);

        SFSchemeRelease(scheme);
    }
}

void SchemeTester::testBuild()
{
    const SFFontProtocol protocol = {
        .finalize = NULL,
        .loadTable = &loadTable,
        .getGlyphIDForCodepoint = &getGlyphIDForCodepoint,
        .getAdvanceForGlyph = &getAdvanceForGlyph,
    };
    SFFontRef font = SFFontCreateWithProtocol(&protocol, NULL);

    SFScheme scheme;
    SFSchemeInitialize(&scheme, TestKnowledge::instance());
    SFSchemeSetFont(&scheme, font);
    SFSchemeSetScriptTag(&scheme, tag("test"));

    /* Test with default language. */
    {
        SFSchemeSetLanguageTag(&scheme, tag("dflt"));
        SFPatternRef pattern = SFSchemeBuildPattern(&scheme);

        SFTag expectedTags[] = {
            tag("srqi"), tag("srq1"), tag("son1"), tag("sim1"), tag("sim2"),
            tag("pon1"), tag("prq1"), tag("prqi")
        };
        SFLookupInfo expectedLookups[] = {
            {SRQI, 1}, {SON1, 1}, {SRQ1, 1}, {SIM1, 1}, {SIM2, 1},
            {PON1, 1}, {PRQ1, 1}, {PRQI, 1}
        };
        SFFeatureUnit expectedUnits[] = {
            { { &expectedLookups[0], 1 }, { 0, 1 }, 0x00 },
            { { &expectedLookups[1], 2 }, { 1, 2 }, 0x00 },
            { { &expectedLookups[3], 2 }, { 3, 2 }, 0x00 },
            { { &expectedLookups[5], 2 }, { 5, 2 }, 0x00 },
            { { &expectedLookups[7], 1 }, { 7, 1 }, 0x00 },
        };
        SFPattern expectedPattern = {
            .font = font,
            .featureTags = { expectedTags, 8 },
            .featureUnits = { expectedUnits, 3, 2 },
            .scriptTag = tag("test"),
            .languageTag = tag("dflt"),
            .defaultDirection = SFTextDirectionLeftToRight,
        };
        assert(SFPatternEqualToPattern(pattern, &expectedPattern));

        SFPatternRelease(pattern);
    }

    /* Test with a non-default language. */
    {
        SFSchemeSetLanguageTag(&scheme, tag("LNG "));
        SFPatternRef pattern = SFSchemeBuildPattern(&scheme);

        SFTag expectedTags[] = { tag("srqi") };
        SFLookupInfo expectedLookups[] = { {SRQI, 1} };
        SFFeatureUnit expectedUnits[] = {
            { { &expectedLookups[0], 1 }, { 0, 1 }, 0x00 },
        };
        SFPattern expectedPattern = {
            .font = font,
            .featureTags = { expectedTags, 1 },
            .featureUnits = { expectedUnits, 1, 0 },
            .scriptTag = tag("test"),
            .languageTag = tag("LNG "),
            .defaultDirection = SFTextDirectionLeftToRight,
        };
        assert(SFPatternEqualToPattern(pattern, &expectedPattern));

        SFPatternRelease(pattern);
    }

    /* Test by trying to turn off required features. */
    /* Test by disabling a feature marked as on by default. */
    /* Test by enabling a feature marked as off by default. */
    /* Test by setting custom value of a required feature. */
    /* Test by setting custom value of a feature marked as on by default. */
    /* Test by setting custom value of a feature marked as off by default. */
    /* Test by enabling simultaneous features across multiple groups. */
    /* Test by enabling custom features of GSUB and GPOS. */
    /* Test by enabling a custom feature available in both GSUB and GPOS. */
    {
        SFTag featureTags[] = {
            tag("srqi"), tag("prq1"), tag("son1"), tag("sof1"), tag("prqi"),
            tag("pon1"), tag("pof1"), tag("scst"), tag("pcst"), tag("cust")
        };
        SFUInt16 featureValues[] = {
            0, 0, 0, 1, 2, 3, 4, 5, 6, 7
        };

        SFSchemeSetLanguageTag(&scheme, tag("dflt"));
        SFSchemeSetFeatureValues(&scheme, featureTags, featureValues, sizeof(featureValues) / sizeof(SFUInt16));

        SFPatternRef pattern = SFSchemeBuildPattern(&scheme);

        SFTag expectedTags[] = {
            tag("srqi"), tag("srq1"), tag("sof1"), tag("sim1"), tag("sim2"), tag("scst"), tag("cust"),
            tag("pof1"), tag("pon1"), tag("prq1"), tag("prqi"), tag("pcst")
        };
        SFLookupInfo expectedLookups[] = {
            {SRQI, 1}, {SOF1, 1}, {SRQ1, 1}, {SIM1, 1}, {SIM2, 1}, {CUST, 7}, {SCST, 5},
            {POF1, 4}, {PON1, 3}, {PRQ1, 1}, {PRQI, 2}, {PCST, 6}
        };
        SFFeatureUnit expectedUnits[] = {
            { { &expectedLookups[0],  1 }, { 0,  1 }, 0x00 },
            { { &expectedLookups[1],  2 }, { 1,  2 }, 0x00 },
            { { &expectedLookups[3],  2 }, { 3,  2 }, 0x00 },
            { { &expectedLookups[5],  2 }, { 5,  2 }, 0x00 },
            { { &expectedLookups[7],  3 }, { 7,  3 }, 0x00 },
            { { &expectedLookups[10], 1 }, { 10, 1 }, 0x00 },
            { { &expectedLookups[11], 1 }, { 11, 1 }, 0x00 },
        };
        SFPattern expectedPattern = {
            .font = font,
            .featureTags = { expectedTags, 12 },
            .featureUnits = { expectedUnits, 4, 3 },
            .scriptTag = tag("test"),
            .languageTag = tag("dflt"),
            .defaultDirection = SFTextDirectionLeftToRight,
        };
        assert(SFPatternEqualToPattern(pattern, &expectedPattern));

        SFPatternRelease(pattern);
    }

    SFSchemeFinalize(&scheme);
    SFFontRelease(font);
}

void SchemeTester::test()
{
    testFeatures();
    testBuild();
}
<commit_msg>[test] Used gsub and gpos builders in scheme tester<commit_after>/*
 * Copyright (C) 2016-2018 Muhammad Tayyab Akram
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <cassert>
#include <cstddef>
#include <cstring>
#include <vector>

extern "C" {
#include <Source/SFPattern.h>
#include <Source/SFScheme.h>
#include <Source/SFShapingKnowledge.h>
}

#include "OpenType/Builder.h"
#include "OpenType/Common.h"
#include "OpenType/GSUB.h"
#include "Utilities/General.h"
#include "Utilities/SFPattern+Testing.h"
#include "SchemeTester.h"

using namespace std;
using namespace SheenFigure::Tester;
using namespace SheenFigure::Tester::OpenType;
using namespace SheenFigure::Tester::Utilities;

class TestKnowledge {
public:
    static SFShapingKnowledgeRef instance() { return &object->knowledge.shape; }

private:
    static TestKnowledge *object;

    struct {
        vector<SFFeatureInfo> subst;
        vector<SFFeatureInfo> pos;
    } features;
    struct {
        SFScriptKnowledge script;
        SFShapingKnowledge shape;
    } knowledge;

    static SFScriptKnowledgeRef seekScript(const void *, SFTag scriptTag)
    {
        if (scriptTag == tag("test")) {
            return &object->knowledge.script;
        }

        return NULL;
    }

    TestKnowledge() {
        features.subst = {
            /* First Group. */
            { 1, tag("srqi"), REQUIRED,       INDIVIDUAL,   0x00 },
            { 1, tag("srq1"), REQUIRED,       SIMULTANEOUS, 0x00 },
            { 1, tag("son1"), ON_BY_DEFAULT,  SIMULTANEOUS, 0x00 },
            { 1, tag("sof1"), OFF_BY_DEFAULT, SIMULTANEOUS, 0x00 },
            /* Second Group. */
            { 2, tag("sim1"), REQUIRED,       SIMULTANEOUS, 0x00 },
            { 2, tag("sim2"), REQUIRED,       SIMULTANEOUS, 0x00 },
        };
        features.pos = {
            /* Third Group. */
            { 3, tag("pof1"), OFF_BY_DEFAULT, SIMULTANEOUS, 0x00 },
            { 3, tag("pon1"), ON_BY_DEFAULT,  SIMULTANEOUS, 0x00 },
            { 3, tag("prq1"), REQUIRED,       SIMULTANEOUS, 0x00 },
            { 3, tag("prqi"), REQUIRED,       INDIVIDUAL,   0x00 },
        };
        knowledge.script = {
            SFTextDirectionLeftToRight,
            { features.subst.data(), features.subst.size() },
            { features.pos.data(), features.pos.size() }
        };
        knowledge.shape = {
            &seekScript
        };
    }
};
TestKnowledge *TestKnowledge::object = new TestKnowledge();

static const UInt16 CUST = 0;
static const UInt16 PCST = 1;
static const UInt16 POF1 = 2;
static const UInt16 PON1 = 3;
static const UInt16 PRQ1 = 4;
static const UInt16 PRQI = 5;
static const UInt16 SCST = 6;
static const UInt16 SIM1 = 7;
static const UInt16 SIM2 = 8;
static const UInt16 SOF1 = 9;
static const UInt16 SON1 = 10;
static const UInt16 SRQ1 = 11;
static const UInt16 SRQI = 12;

static void loadTable(void *, SFTag tableTag, SFUInt8 *buffer, SFUInteger *length)
{
    if (tableTag == tag("GSUB")) {
        Builder builder;

        FeatureListTable &featureList = builder.createFeatureList({
            {tag("cust"), builder.createFeature({ CUST })},
            {tag("scst"), builder.createFeature({ SCST })},
            {tag("sim1"), builder.createFeature({ SIM1 })},
            {tag("sim2"), builder.createFeature({ SIM2 })},
            {tag("sof1"), builder.createFeature({ SOF1 })},
            {tag("son1"), builder.createFeature({ SON1 })},
            {tag("srq1"), builder.createFeature({ SRQ1 })},
            {tag("srqi"), builder.createFeature({ SRQI })},
        });
        ScriptListTable &scriptList = builder.createScriptList({
            {tag("test"), builder.createScript(builder.createLangSys({ 0, 1, 2, 3, 4, 5, 6, 7 }), {
                                                   {tag("LNG "), builder.createLangSys({ 7 })}
                                               })}
        });
        GSUB &gsub = builder.createGSUB(&scriptList, &featureList, NULL);

        Writer writer;
        writer.write(&gsub);

        if (length) {
            *length = (SFUInteger)writer.size();
        }
        if (buffer) {
            memcpy(buffer, writer.data(), (size_t)writer.size());
        }
    } else if (tableTag == tag("GPOS")) {
        Builder builder;

        FeatureListTable &featureList = builder.createFeatureList({
            {tag("cust"), builder.createFeature({ CUST })},
            {tag("pcst"), builder.createFeature({ PCST })},
            {tag("pof1"), builder.createFeature({ POF1 })},
            {tag("pon1"), builder.createFeature({ PON1 })},
            {tag("prq1"), builder.createFeature({ PRQ1 })},
            {tag("prqi"), builder.createFeature({ PRQI })},
        });
        ScriptListTable &scriptList = builder.createScriptList({
            {tag("test"), builder.createScript(builder.createLangSys({ 0, 1, 2, 3, 4, 5 }), {
                                                   {tag("LNG "), builder.createLangSys({ 2 })}
                                               })}
        });
        GPOS &gpos = builder.createGPOS(&scriptList, &featureList, NULL);

        Writer writer;
        writer.write(&gpos);

        if (length) {
            *length = (SFUInteger)writer.size();
        }
        if (buffer) {
            memcpy(buffer, writer.data(), (size_t)writer.size());
        }
    }
}

static SFGlyphID getGlyphIDForCodepoint(void *, SFCodepoint)
{
    return 0;
}

static SFAdvance getAdvanceForGlyph(void *, SFFontLayout, SFGlyphID)
{
    return 0;
}

SchemeTester::SchemeTester()
{
}

void SchemeTester::testFeatures()
{
    /* Test unique features. */
    {
        SFSchemeRef scheme = SFSchemeCreate();

        SFTag featureTags[] = {
            tag("ccmp"), tag("liga"), tag("dist"), tag("kern")
        };
        SFUInt16 featureValues[] = {
            1, 2, 3, 4
        };
        SFUInteger featureCount = sizeof(featureValues) / sizeof(SFUInt16);

        SFSchemeSetFeatureValues(scheme, featureTags, featureValues, featureCount);

        assert(memcmp(scheme->_featureTags, featureTags, sizeof(featureTags)) == 0);
        assert(memcmp(scheme->_featureValues, featureValues, sizeof(featureValues)) == 0);
        assert(scheme->_featureCount == featureCount);

        SFSchemeRelease(scheme);
    }

    /* Test duplicated features. */
    {
        SFSchemeRef scheme = SFSchemeCreate();

        SFTag featureTags[] = {
            tag("ccmp"), tag("liga"), tag("dist"), tag("kern"), tag("ccmp"), tag("kern")
        };
        SFUInt16 featureValues[] = {
            1, 2, 3, 4, 5, 6
        };
        SFUInteger featureCount = sizeof(featureValues) / sizeof(SFUInt16);

        SFSchemeSetFeatureValues(scheme, featureTags, featureValues, featureCount);

        SFTag expectedTags[] = {
            tag("ccmp"), tag("liga"), tag("dist"), tag("kern")
        };
        SFUInt16 expectedValues[] = {
            5, 2, 3, 6
        };
        SFUInteger expectedCount = sizeof(expectedValues) / sizeof(SFUInt16);

        assert(memcmp(scheme->_featureTags, expectedTags, sizeof(expectedTags)) == 0);
        assert(memcmp(scheme->_featureValues, expectedValues, sizeof(expectedValues)) == 0);
        assert(scheme->_featureCount == expectedCount);

        SFSchemeRelease(scheme);
    }
}

void SchemeTester::testBuild()
{
    const SFFontProtocol protocol = {
        .finalize = NULL,
        .loadTable = &loadTable,
        .getGlyphIDForCodepoint = &getGlyphIDForCodepoint,
        .getAdvanceForGlyph = &getAdvanceForGlyph,
    };
    SFFontRef font = SFFontCreateWithProtocol(&protocol, NULL);

    SFScheme scheme;
    SFSchemeInitialize(&scheme, TestKnowledge::instance());
    SFSchemeSetFont(&scheme, font);
    SFSchemeSetScriptTag(&scheme, tag("test"));

    /* Test with default language. */
    {
        SFSchemeSetLanguageTag(&scheme, tag("dflt"));
        SFPatternRef pattern = SFSchemeBuildPattern(&scheme);

        SFTag expectedTags[] = {
            tag("srqi"), tag("srq1"), tag("son1"), tag("sim1"), tag("sim2"),
            tag("pon1"), tag("prq1"), tag("prqi")
        };
        SFLookupInfo expectedLookups[] = {
            {SRQI, 1}, {SON1, 1}, {SRQ1, 1}, {SIM1, 1}, {SIM2, 1},
            {PON1, 1}, {PRQ1, 1}, {PRQI, 1}
        };
        SFFeatureUnit expectedUnits[] = {
            { { &expectedLookups[0], 1 }, { 0, 1 }, 0x00 },
            { { &expectedLookups[1], 2 }, { 1, 2 }, 0x00 },
            { { &expectedLookups[3], 2 }, { 3, 2 }, 0x00 },
            { { &expectedLookups[5], 2 }, { 5, 2 }, 0x00 },
            { { &expectedLookups[7], 1 }, { 7, 1 }, 0x00 },
        };
        SFPattern expectedPattern = {
            .font = font,
            .featureTags = { expectedTags, 8 },
            .featureUnits = { expectedUnits, 3, 2 },
            .scriptTag = tag("test"),
            .languageTag = tag("dflt"),
            .defaultDirection = SFTextDirectionLeftToRight,
        };
        assert(SFPatternEqualToPattern(pattern, &expectedPattern));

        SFPatternRelease(pattern);
    }

    /* Test with a non-default language. */
    {
        SFSchemeSetLanguageTag(&scheme, tag("LNG "));
        SFPatternRef pattern = SFSchemeBuildPattern(&scheme);

        SFTag expectedTags[] = { tag("srqi") };
        SFLookupInfo expectedLookups[] = { {SRQI, 1} };
        SFFeatureUnit expectedUnits[] = {
            { { &expectedLookups[0], 1 }, { 0, 1 }, 0x00 },
        };
        SFPattern expectedPattern = {
            .font = font,
            .featureTags = { expectedTags, 1 },
            .featureUnits = { expectedUnits, 1, 0 },
            .scriptTag = tag("test"),
            .languageTag = tag("LNG "),
            .defaultDirection = SFTextDirectionLeftToRight,
        };
        assert(SFPatternEqualToPattern(pattern, &expectedPattern));

        SFPatternRelease(pattern);
    }

    /* Test by trying to turn off required features. */
    /* Test by disabling a feature marked as on by default. */
    /* Test by enabling a feature marked as off by default. */
    /* Test by setting custom value of a required feature. */
    /* Test by setting custom value of a feature marked as on by default. */
    /* Test by setting custom value of a feature marked as off by default. */
    /* Test by enabling simultaneous features across multiple groups. */
    /* Test by enabling custom features of GSUB and GPOS. */
    /* Test by enabling a custom feature available in both GSUB and GPOS. */
    {
        SFTag featureTags[] = {
            tag("srqi"), tag("prq1"), tag("son1"), tag("sof1"), tag("prqi"),
            tag("pon1"), tag("pof1"), tag("scst"), tag("pcst"), tag("cust")
        };
        SFUInt16 featureValues[] = {
            0, 0, 0, 1, 2, 3, 4, 5, 6, 7
        };

        SFSchemeSetLanguageTag(&scheme, tag("dflt"));
        SFSchemeSetFeatureValues(&scheme, featureTags, featureValues, sizeof(featureValues) / sizeof(SFUInt16));

        SFPatternRef pattern = SFSchemeBuildPattern(&scheme);

        SFTag expectedTags[] = {
            tag("srqi"), tag("srq1"), tag("sof1"), tag("sim1"), tag("sim2"), tag("scst"), tag("cust"),
            tag("pof1"), tag("pon1"), tag("prq1"), tag("prqi"), tag("pcst")
        };
        SFLookupInfo expectedLookups[] = {
            {SRQI, 1}, {SOF1, 1}, {SRQ1, 1}, {SIM1, 1}, {SIM2, 1}, {CUST, 7}, {SCST, 5},
            {POF1, 4}, {PON1, 3}, {PRQ1, 1}, {PRQI, 2}, {PCST, 6}
        };
        SFFeatureUnit expectedUnits[] = {
            { { &expectedLookups[0],  1 }, { 0,  1 }, 0x00 },
            { { &expectedLookups[1],  2 }, { 1,  2 }, 0x00 },
            { { &expectedLookups[3],  2 }, { 3,  2 }, 0x00 },
            { { &expectedLookups[5],  2 }, { 5,  2 }, 0x00 },
            { { &expectedLookups[7],  3 }, { 7,  3 }, 0x00 },
            { { &expectedLookups[10], 1 }, { 10, 1 }, 0x00 },
            { { &expectedLookups[11], 1 }, { 11, 1 }, 0x00 },
        };
        SFPattern expectedPattern = {
            .font = font,
            .featureTags = { expectedTags, 12 },
            .featureUnits = { expectedUnits, 4, 3 },
            .scriptTag = tag("test"),
            .languageTag = tag("dflt"),
            .defaultDirection = SFTextDirectionLeftToRight,
        };
        assert(SFPatternEqualToPattern(pattern, &expectedPattern));

        SFPatternRelease(pattern);
    }

    SFSchemeFinalize(&scheme);
    SFFontRelease(font);
}

void SchemeTester::test()
{
    testFeatures();
    testBuild();
}
<|endoftext|>


<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "PorousFlowHeatEnergy.h"

#include "MooseVariable.h"

#include "libmesh/quadrature.h"

registerMooseObject("PorousFlowApp", PorousFlowHeatEnergy);

template <>
InputParameters
validParams<PorousFlowHeatEnergy>()
{
  InputParameters params = validParams<ElementIntegralPostprocessor>();
  params.addRequiredParam<UserObjectName>(
      "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names.");
  params.addParam<bool>(
      "include_porous_skeleton", true, "Include the heat energy of the porous skeleton");
  params.addParam<std::vector<unsigned int>>("phase",
                                             "The index(es) of the fluid phase that this "
                                             "Postprocessor is restricted to.  Multiple "
                                             "indices can be entered.");
  params.set<bool>("use_displaced_mesh") = true;
  params.addParam<unsigned int>("kernel_variable_number",
                                0,
                                "The PorousFlow variable number (according to the dictatory) of "
                                "the heat-energy kernel.  This is required only in the unusual "
                                "situation where a variety of different finite-element "
                                "interpolation schemes are employed in the simulation");
  params.addClassDescription("Calculates the sum of heat energy of fluid phase(s) and/or the "
                             "porous skeleton in a region");
  return params;
}

PorousFlowHeatEnergy::PorousFlowHeatEnergy(const InputParameters & parameters)
  : ElementIntegralPostprocessor(parameters),
    _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
    _num_phases(_dictator.numPhases()),
    _fluid_present(_num_phases > 0),
    _include_porous_skeleton(getParam<bool>("include_porous_skeleton")),
    _phase_index(getParam<std::vector<unsigned int>>("phase")),
    _porosity(getMaterialProperty<Real>("PorousFlow_porosity_nodal")),
    _rock_energy_nodal(getMaterialProperty<Real>("PorousFlow_matrix_internal_energy_nodal")),
    _fluid_density(_fluid_present ? &getMaterialProperty<std::vector<Real>>(
                                        "PorousFlow_fluid_phase_density_nodal")
                                  : nullptr),
    _fluid_saturation_nodal(
        _fluid_present ? &getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal")
                       : nullptr),
    _energy_nodal(_fluid_present ? &getMaterialProperty<std::vector<Real>>(
                                       "PorousFlow_fluid_phase_internal_energy_nodal")
                                 : nullptr),
    _var(getParam<unsigned>("kernel_variable_number") < _dictator.numVariables()
             ? _dictator.getCoupledStandardMooseVars()[getParam<unsigned>("kernel_variable_number")]
             : nullptr)
{
  if (!_phase_index.empty())
  {
    // Check that the phase indices entered are not greater than the number of phases
    const unsigned int max_phase_num = *std::max_element(_phase_index.begin(), _phase_index.end());
    if (max_phase_num > _num_phases - 1)
      paramError("phase",
                 "The Dictator proclaims that the phase index ",
                 max_phase_num,
                 " is greater than the largest phase index possible, which is ",
                 _num_phases - 1);
  }

  // Check that kernel_variable_number is OK
  if (getParam<unsigned>("kernel_variable_number") >= _dictator.numVariables())
    paramError("kernel_variable_number",
               "The Dictator pronounces that the number of PorousFlow variables is ",
               _dictator.numVariables(),
               ", however you have used ",
               getParam<unsigned>("kernel_variable_number"),
               ". This is an error");
}

Real
PorousFlowHeatEnergy::computeIntegral()
{
  Real sum = 0;

  // The use of _test in the loops below mean that the
  // integral is exactly the same as the one computed
  // by the PorousFlowMassTimeDerivative Kernel.  Because that
  // Kernel is lumped, this Postprocessor also needs to
  // be lumped.  Hence the use of the "nodal" Material
  // Properties
  const VariableTestValue & test = _var->phi();

  for (unsigned node = 0; node < test.size(); ++node)
  {
    Real nodal_volume = 0.0;
    for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
      nodal_volume += _JxW[_qp] * _coord[_qp] * test[node][_qp];

    Real energy = 0.0;
    if (_include_porous_skeleton)
      energy += (1.0 - _porosity[node]) * _rock_energy_nodal[node];

    for (auto ph : _phase_index)
      energy += (*_fluid_density)[node][ph] * (*_fluid_saturation_nodal)[node][ph] *
                (*_energy_nodal)[node][ph] * _porosity[node];

    sum += nodal_volume * energy;
  }

  return sum;
}

Real
PorousFlowHeatEnergy::computeQpIntegral()
{
  return 0.0;
}
<commit_msg>PorousFlowHeatEnergy uses _tid<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "PorousFlowHeatEnergy.h"

#include "MooseVariable.h"

#include "libmesh/quadrature.h"

registerMooseObject("PorousFlowApp", PorousFlowHeatEnergy);

template <>
InputParameters
validParams<PorousFlowHeatEnergy>()
{
  InputParameters params = validParams<ElementIntegralPostprocessor>();
  params.addRequiredParam<UserObjectName>(
      "PorousFlowDictator", "The UserObject that holds the list of PorousFlow variable names.");
  params.addParam<bool>(
      "include_porous_skeleton", true, "Include the heat energy of the porous skeleton");
  params.addParam<std::vector<unsigned int>>("phase",
                                             "The index(es) of the fluid phase that this "
                                             "Postprocessor is restricted to.  Multiple "
                                             "indices can be entered.");
  params.set<bool>("use_displaced_mesh") = true;
  params.addParam<unsigned int>("kernel_variable_number",
                                0,
                                "The PorousFlow variable number (according to the dictatory) of "
                                "the heat-energy kernel.  This is required only in the unusual "
                                "situation where a variety of different finite-element "
                                "interpolation schemes are employed in the simulation");
  params.addClassDescription("Calculates the sum of heat energy of fluid phase(s) and/or the "
                             "porous skeleton in a region");
  return params;
}

PorousFlowHeatEnergy::PorousFlowHeatEnergy(const InputParameters & parameters)
  : ElementIntegralPostprocessor(parameters),
    _dictator(getUserObject<PorousFlowDictator>("PorousFlowDictator")),
    _num_phases(_dictator.numPhases()),
    _fluid_present(_num_phases > 0),
    _include_porous_skeleton(getParam<bool>("include_porous_skeleton")),
    _phase_index(getParam<std::vector<unsigned int>>("phase")),
    _porosity(getMaterialProperty<Real>("PorousFlow_porosity_nodal")),
    _rock_energy_nodal(getMaterialProperty<Real>("PorousFlow_matrix_internal_energy_nodal")),
    _fluid_density(_fluid_present ? &getMaterialProperty<std::vector<Real>>(
                                        "PorousFlow_fluid_phase_density_nodal")
                                  : nullptr),
    _fluid_saturation_nodal(
        _fluid_present ? &getMaterialProperty<std::vector<Real>>("PorousFlow_saturation_nodal")
                       : nullptr),
    _energy_nodal(_fluid_present ? &getMaterialProperty<std::vector<Real>>(
                                       "PorousFlow_fluid_phase_internal_energy_nodal")
                                 : nullptr),
    _var(getParam<unsigned>("kernel_variable_number") < _dictator.numVariables()
             ? &_fe_problem.getStandardVariable(
                   _tid,
                   _dictator
                       .getCoupledStandardMooseVars()[getParam<unsigned>("kernel_variable_number")]
                       ->name())
             : nullptr)
{
  if (!_phase_index.empty())
  {
    // Check that the phase indices entered are not greater than the number of phases
    const unsigned int max_phase_num = *std::max_element(_phase_index.begin(), _phase_index.end());
    if (max_phase_num > _num_phases - 1)
      paramError("phase",
                 "The Dictator proclaims that the phase index ",
                 max_phase_num,
                 " is greater than the largest phase index possible, which is ",
                 _num_phases - 1);
  }

  // Check that kernel_variable_number is OK
  if (getParam<unsigned>("kernel_variable_number") >= _dictator.numVariables())
    paramError("kernel_variable_number",
               "The Dictator pronounces that the number of PorousFlow variables is ",
               _dictator.numVariables(),
               ", however you have used ",
               getParam<unsigned>("kernel_variable_number"),
               ". This is an error");
}

Real
PorousFlowHeatEnergy::computeIntegral()
{
  Real sum = 0;

  // The use of _test in the loops below mean that the
  // integral is exactly the same as the one computed
  // by the PorousFlowMassTimeDerivative Kernel.  Because that
  // Kernel is lumped, this Postprocessor also needs to
  // be lumped.  Hence the use of the "nodal" Material
  // Properties
  const VariableTestValue & test = _var->phi();

  for (unsigned node = 0; node < test.size(); ++node)
  {
    Real nodal_volume = 0.0;
    for (_qp = 0; _qp < _qrule->n_points(); ++_qp)
      nodal_volume += _JxW[_qp] * _coord[_qp] * test[node][_qp];

    Real energy = 0.0;
    if (_include_porous_skeleton)
      energy += (1.0 - _porosity[node]) * _rock_energy_nodal[node];

    for (auto ph : _phase_index)
      energy += (*_fluid_density)[node][ph] * (*_fluid_saturation_nodal)[node][ph] *
                (*_energy_nodal)[node][ph] * _porosity[node];

    sum += nodal_volume * energy;
  }

  return sum;
}

Real
PorousFlowHeatEnergy::computeQpIntegral()
{
  return 0.0;
}
<|endoftext|>


<commit_before>/*
 * main.cpp
 *
 *  Created on: June, 2014
 *      Author: Thomas Fäulhammer
 */

#include <pcl/common/common.h>
#include <pcl_conversions.h>
#include <pcl/io/pcd_io.h>
#include "ros/ros.h"
#include "sensor_msgs/PointCloud2.h"
#include "std_msgs/String.h"
#include "recognition_srv_definitions/recognize.h"
#include <v4r/io/filesystem.h>

class MultiViewRecognizerDemo
{
private:
    typedef pcl::PointXYZRGB PointT;
    ros::NodeHandle *n_;
    ros::ServiceClient sv_rec_client_;
    std::string directory_;
    std::string topic_;
    bool KINECT_OK_;
    int input_method_; // defines te test input (0... camera topic, 1... file)

public:
    MultiViewRecognizerDemo()
    {
        input_method_ = 0;
    }

    void callMvRecognizerUsingCam(const sensor_msgs::PointCloud2::ConstPtr& msg)
    {
        std::cout << "Received point cloud.\n" << std::endl;
        recognition_srv_definitions::recognize srv;
        srv.request.cloud = *msg;

        if (sv_rec_client_.call(srv))
        {
            std::vector<std::string> model_ids;
            std::vector<Eigen::Matrix4f> transforms;

            for(size_t i=0; i < srv.response.ids.size(); i++)
            {
                model_ids.push_back(srv.response.ids[i].data);

                Eigen::Quaternionf q(srv.response.transforms[i].rotation.w,
                                     srv.response.transforms[i].rotation.x,
                                     srv.response.transforms[i].rotation.y,
                                     srv.response.transforms[i].rotation.z);

                Eigen::Vector3f translation(srv.response.transforms[i].translation.x,
                                            srv.response.transforms[i].translation.y,
                                            srv.response.transforms[i].translation.z);

                Eigen::Matrix4f trans;
                trans.block<3,3>(0,0) = q.toRotationMatrix();
                trans.block<3,1>(0,3) = translation;
                transforms.push_back(trans);
            }

            std::cout << "Called done..." << std::endl;
        }
        else
        {
            ROS_ERROR("Failed to call /recognition_service/sv_recognition");
        }
    }

    void checkCloudArrive (const sensor_msgs::PointCloud2::ConstPtr& msg)
    {
        KINECT_OK_ = true;
    }

    bool checkKinect ()
    {
        ros::Subscriber sub_pc = n_->subscribe (topic_, 1, &MultiViewRecognizerDemo::checkCloudArrive, this);
        ros::Rate loop_rate (1);
        size_t kinect_trials_ = 0;

        while (!KINECT_OK_ && ros::ok () && kinect_trials_ < 30)
        {
            std::cout << "Checking kinect status..." << std::endl;
            ros::spinOnce ();
            loop_rate.sleep ();
            kinect_trials_++;
        }
        return KINECT_OK_;
    }

    bool callMvRecognizerUsingFiles()
    {
        std::vector<std::string> test_cloud;
        v4r::io::getFilesInDirectory(directory_, test_cloud, "", ".*.pcd", false);
        for(size_t i=0; i < test_cloud.size(); i++)
        {
            pcl::PointCloud<PointT> cloud;
            pcl::io::loadPCDFile(directory_ + "/" + test_cloud[i], cloud);
            sensor_msgs::PointCloud2 cloud_ros;
            pcl::toROSMsg(cloud, cloud_ros);
            cloud_ros.header.stamp = ros::Time::now();
            recognition_srv_definitions::recognize srv_rec;
            srv_rec.request.cloud = cloud_ros;
            std::stringstream view_name_ss;
            view_name_ss << "view_" << i << std::endl;
            std::cout << "####### " << view_name_ss.str() << std::endl;
            srv_rec.request.view_name.data = view_name_ss.str();

            std::string pose_file = test_cloud[i];
            boost::replace_all(pose_file, ".pcd", ".txt");

#ifdef USE_WILLOW_DATASET_FOR_EVAL
            boost::replace_all(pose_file, "cloud_", "pose_");
#else
            pose_file = "transformation_" + pose_file;
#endif
            std::cout << "Checking if path " << directory_ << "/" << pose_file << " for transform exists. " << std::endl;

            if ( boost::filesystem::exists( directory_ + "/" + pose_file ) )
            {
                std::cout << "File exists." << std::endl;
                std::ifstream is( (directory_ + "/" + pose_file).c_str() );

#ifdef USE_WILLOW_DATASET_FOR_EVAL
                std::string s;
                std::vector<std::string> file_parts;
                std::getline( is, s );
                std::istringstream ss( s );
                std::vector<double> numbers;
                while (ss)
                {
                  std::string s;
                  if (!std::getline( ss, s, ' ' )) break;
                  file_parts.push_back( s );
                  if(file_parts.size()>1)
                      numbers.push_back(atof(s.c_str()));
                }
#else
                std::istream_iterator<double> start(is), end;
                std::vector<float> numbers(start, end);
                std::cout << "Read " << numbers.size() << " numbers" << std::endl;
#endif
                // print the numbers to stdout
                std::cout << "Transform to world coordinate system: " << std::endl;
                for(size_t i=0; i<numbers.size(); i++)
                {
                    std::cout << numbers[i] << " ";
                    srv_rec.request.transform.push_back(numbers[i]);
                }
                std::cout << std::endl;
            }

            if (!sv_rec_client_.call(srv_rec))
            {
                std::stringstream mm;
                mm << "Error calling multiview recognition service. "<< std::endl;
                ROS_ERROR(mm.str().c_str());
                return false;
            }
        }
    }

    bool initialize(int argc, char ** argv)
    {
        ros::init (argc, argv, "MultiViewRecognizerDemoFromFiles");
        n_ = new ros::NodeHandle ( "~" );

        std::string service_name_sv_rec = "/multiview_recognition_service/multiview_recognition_service";
        sv_rec_client_ = n_->serviceClient<recognition_srv_definitions::recognize>(service_name_sv_rec);

        n_->getParam ( "input_method", input_method_ );

        if ( input_method_ == 0 )
        {
            if(!n_->getParam ( "topic", topic_ ))
            {
                topic_ = "/camera/depth_registered/points";
            }
            std::cout << "Trying to connect to camera on topic " <<
                         topic_ << ". You can change the topic with param topic or " <<
                         " test pcd files from a directory by using input_method=1 and specifying param directory. " << std::endl;

            if ( checkKinect() )
            {
                std::cout << "Camera (topic: " << topic_ << ") is up and running." << std::endl;
                ros::Subscriber sub_pc = n_->subscribe (topic_, 1, &MultiViewRecognizerDemo::callMvRecognizerUsingCam, this);
                ros::spin();
            }
            else
            {
                std::cerr << "Camera (topic: " << topic_ << ") is not working." << std::endl;
                return false;
            }
        }
        else //input_method==1
        {
            if(n_->getParam ( "directory", directory_ ) && directory_.length())
            {
                callMvRecognizerUsingFiles();
            }
            else
            {
                std::cout << "No test directory (param directory) specified. " << std::endl;
                return false;
            }
        }
        return true;
    }
};

int
main (int argc, char ** argv)
{
    MultiViewRecognizerDemo m;
    m.initialize(argc, argv);
    return 0;
}
<commit_msg>fixed string formatting bug<commit_after>/*
 * main.cpp
 *
 *  Created on: June, 2014
 *      Author: Thomas Fäulhammer
 */

#include <pcl/common/common.h>
#include <pcl_conversions.h>
#include <pcl/io/pcd_io.h>
#include "ros/ros.h"
#include "sensor_msgs/PointCloud2.h"
#include "std_msgs/String.h"
#include "recognition_srv_definitions/recognize.h"
#include <v4r/io/filesystem.h>

class MultiViewRecognizerDemo
{
private:
    typedef pcl::PointXYZRGB PointT;
    ros::NodeHandle *n_;
    ros::ServiceClient sv_rec_client_;
    std::string directory_;
    std::string topic_;
    bool KINECT_OK_;
    int input_method_; // defines te test input (0... camera topic, 1... file)

public:
    MultiViewRecognizerDemo()
    {
        input_method_ = 0;
    }

    void callMvRecognizerUsingCam(const sensor_msgs::PointCloud2::ConstPtr& msg)
    {
        std::cout << "Received point cloud.\n" << std::endl;
        recognition_srv_definitions::recognize srv;
        srv.request.cloud = *msg;

        if (sv_rec_client_.call(srv))
        {
            std::vector<std::string> model_ids;
            std::vector<Eigen::Matrix4f> transforms;

            for(size_t i=0; i < srv.response.ids.size(); i++)
            {
                model_ids.push_back(srv.response.ids[i].data);

                Eigen::Quaternionf q(srv.response.transforms[i].rotation.w,
                                     srv.response.transforms[i].rotation.x,
                                     srv.response.transforms[i].rotation.y,
                                     srv.response.transforms[i].rotation.z);

                Eigen::Vector3f translation(srv.response.transforms[i].translation.x,
                                            srv.response.transforms[i].translation.y,
                                            srv.response.transforms[i].translation.z);

                Eigen::Matrix4f trans;
                trans.block<3,3>(0,0) = q.toRotationMatrix();
                trans.block<3,1>(0,3) = translation;
                transforms.push_back(trans);
            }

            std::cout << "Called done..." << std::endl;
        }
        else
        {
            ROS_ERROR("Failed to call /recognition_service/sv_recognition");
        }
    }

    void checkCloudArrive (const sensor_msgs::PointCloud2::ConstPtr& msg)
    {
        KINECT_OK_ = true;
    }

    bool checkKinect ()
    {
        ros::Subscriber sub_pc = n_->subscribe (topic_, 1, &MultiViewRecognizerDemo::checkCloudArrive, this);
        ros::Rate loop_rate (1);
        size_t kinect_trials_ = 0;

        while (!KINECT_OK_ && ros::ok () && kinect_trials_ < 30)
        {
            std::cout << "Checking kinect status..." << std::endl;
            ros::spinOnce ();
            loop_rate.sleep ();
            kinect_trials_++;
        }
        return KINECT_OK_;
    }

    bool callMvRecognizerUsingFiles()
    {
        std::vector<std::string> test_cloud;
        v4r::io::getFilesInDirectory(directory_, test_cloud, "", ".*.pcd", false);
        for(size_t i=0; i < test_cloud.size(); i++)
        {
            pcl::PointCloud<PointT> cloud;
            pcl::io::loadPCDFile(directory_ + "/" + test_cloud[i], cloud);
            sensor_msgs::PointCloud2 cloud_ros;
            pcl::toROSMsg(cloud, cloud_ros);
            cloud_ros.header.stamp = ros::Time::now();
            recognition_srv_definitions::recognize srv_rec;
            srv_rec.request.cloud = cloud_ros;
            std::stringstream view_name_ss;
            view_name_ss << "view_" << i << std::endl;
            std::cout << "####### " << view_name_ss.str() << std::endl;
            srv_rec.request.view_name.data = view_name_ss.str();

            std::string pose_file = test_cloud[i];
            boost::replace_all(pose_file, ".pcd", ".txt");

#ifdef USE_WILLOW_DATASET_FOR_EVAL
            boost::replace_all(pose_file, "cloud_", "pose_");
#else
            pose_file = "transformation_" + pose_file;
#endif
            std::cout << "Checking if path " << directory_ << "/" << pose_file << " for transform exists. " << std::endl;

            if ( boost::filesystem::exists( directory_ + "/" + pose_file ) )
            {
                std::cout << "File exists." << std::endl;
                std::ifstream is( (directory_ + "/" + pose_file).c_str() );

#ifdef USE_WILLOW_DATASET_FOR_EVAL
                std::string s;
                std::vector<std::string> file_parts;
                std::getline( is, s );
                std::istringstream ss( s );
                std::vector<double> numbers;
                while (ss)
                {
                  std::string s;
                  if (!std::getline( ss, s, ' ' )) break;
                  file_parts.push_back( s );
                  if(file_parts.size()>1)
                      numbers.push_back(atof(s.c_str()));
                }
#else
                std::istream_iterator<double> start(is), end;
                std::vector<float> numbers(start, end);
                std::cout << "Read " << numbers.size() << " numbers" << std::endl;
#endif
                // print the numbers to stdout
                std::cout << "Transform to world coordinate system: " << std::endl;
                for(size_t i=0; i<numbers.size(); i++)
                {
                    std::cout << numbers[i] << " ";
                    srv_rec.request.transform.push_back(numbers[i]);
                }
                std::cout << std::endl;
            }

            if (!sv_rec_client_.call(srv_rec))
            {
                ROS_ERROR("Error calling multiview recognition service. ");
                return false;
            }
        }
    }

    bool initialize(int argc, char ** argv)
    {
        ros::init (argc, argv, "MultiViewRecognizerDemoFromFiles");
        n_ = new ros::NodeHandle ( "~" );

        std::string service_name_sv_rec = "/multiview_recognition_service/multiview_recognition_service";
        sv_rec_client_ = n_->serviceClient<recognition_srv_definitions::recognize>(service_name_sv_rec);

        n_->getParam ( "input_method", input_method_ );

        if ( input_method_ == 0 )
        {
            if(!n_->getParam ( "topic", topic_ ))
            {
                topic_ = "/camera/depth_registered/points";
            }
            std::cout << "Trying to connect to camera on topic " <<
                         topic_ << ". You can change the topic with param topic or " <<
                         " test pcd files from a directory by using input_method=1 and specifying param directory. " << std::endl;

            if ( checkKinect() )
            {
                std::cout << "Camera (topic: " << topic_ << ") is up and running." << std::endl;
                ros::Subscriber sub_pc = n_->subscribe (topic_, 1, &MultiViewRecognizerDemo::callMvRecognizerUsingCam, this);
                ros::spin();
            }
            else
            {
                std::cerr << "Camera (topic: " << topic_ << ") is not working." << std::endl;
                return false;
            }
        }
        else //input_method==1
        {
            if(n_->getParam ( "directory", directory_ ) && directory_.length())
            {
                callMvRecognizerUsingFiles();
            }
            else
            {
                std::cout << "No test directory (param directory) specified. " << std::endl;
                return false;
            }
        }
        return true;
    }
};

int
main (int argc, char ** argv)
{
    MultiViewRecognizerDemo m;
    m.initialize(argc, argv);
    return 0;
}
<|endoftext|>


<commit_before>//std
#include <array>
#include <chrono>
#include <iostream>

//mandala
#include "platform_win32.hpp"
#include "gpu.hpp"

//glew
#include <GL\glew.h>

//glfw
#include <GLFW\glfw3.h>

namespace mandala
{
    platform_win32_t platform;

    static inline void on_keyboard_key(GLFWwindow* window, int key, int scancode, int action, int mods)
	{
		input_event_t input_event;
		input_event.device_type = input_event_t::device_type_e::keyboard;
		input_event.keyboard.key = static_cast<input_event_t::keyboard_t::key_e>(key);

		if ((mods & GLFW_MOD_SHIFT) == GLFW_MOD_SHIFT)
		{
			input_event.keyboard.mod_flags |= input_event_t::mod_flag_shift;
		}

        if ((mods & GLFW_MOD_CONTROL) == GLFW_MOD_CONTROL)
        {
			input_event.keyboard.mod_flags |= input_event_t::mod_flag_ctrl;
        }

        if ((mods & GLFW_MOD_ALT) == GLFW_MOD_ALT)
        {
			input_event.keyboard.mod_flags |= input_event_t::mod_flag_alt;
        }

        if ((mods & GLFW_MOD_SUPER) == GLFW_MOD_SUPER)
        {
			input_event.keyboard.mod_flags |= input_event_t::mod_flag_super;
        }

        switch (action)
        {
        case GLFW_RELEASE:
            input_event.keyboard.type = input_event_t::keyboard_t::type_e::key_release;
            break;
        case GLFW_PRESS:
            input_event.keyboard.type = input_event_t::keyboard_t::type_e::key_press;
            break;
        case GLFW_REPEAT:
            input_event.keyboard.type = input_event_t::keyboard_t::type_e::key_repeat;
            break;
        }

        platform.input.events.push_back(input_event);
    }

    static inline void on_keyboard_character(GLFWwindow* window, unsigned int character)
    {
        input_event_t input_event;
        input_event.device_type = input_event_t::device_type_e::keyboard;
        input_event.keyboard.type = input_event_t::keyboard_t::type_e::character;
        input_event.keyboard.character = character;

        platform.input.events.push_back(input_event);
    }

    static inline void on_mouse_button(GLFWwindow* window, int button, int action, int mods)
    {
        input_event_t input_event;
        input_event.device_type = input_event_t::device_type_e::touch;
        input_event.touch.button = static_cast<input_event_t::touch_t::button_e>(button);
		input_event.touch.mod_flags = mods;

        bool is_press = (action == GLFW_PRESS);

        input_event.touch.type = is_press ? input_event_t::touch_t::type_e::press : input_event_t::touch_t::type_e::release;

        if (is_press)
        {
            ++platform.input.touch_id;

            input_event.touch.id = platform.input.touch_id;
        }
        else
        {
            platform.input.touch_id = 0;    //TODO: replace with something better
        }

        input_event.touch.location = platform.get_cursor_location();

        platform.input.events.push_back(input_event);
    }

    static inline void on_mouse_move(GLFWwindow* window, double x, double y)
	{
        const auto screen_size = platform.get_screen_size();

		input_event_t input_event;
		input_event.device_type = input_event_t::device_type_e::touch;
		input_event.touch.type = input_event_t::touch_t::type_e::move;
		input_event.touch.location.x = x;
		input_event.touch.location.y = screen_size.y - y;
		input_event.touch.location_delta.x = x - platform.cursor_location.x;
		input_event.touch.location_delta.y = screen_size.y - y - platform.cursor_location.y;
        input_event.touch.id = platform.input.touch_id;

		if (platform.is_cursor_centered)
		{
			const auto screen_size = platform.get_screen_size();

			platform.set_cursor_location(static_cast<vec2_f64_t>(screen_size) / 2.0);
		}

        platform.cursor_location = platform.get_cursor_location();

        platform.input.events.push_back(input_event);
    }

    static inline void on_mouse_scroll(GLFWwindow* window, double x, double y)
    {
        const auto screen_size = platform.get_screen_size();

        input_event_t input_event;
        input_event.device_type = input_event_t::device_type_e::touch;
        input_event.touch.type = input_event_t::touch_t::type_e::scroll;
        input_event.touch.location = platform.get_cursor_location();
        input_event.touch.location_delta.x = x;
        input_event.touch.location_delta.y = screen_size.y - y;

        platform.input.events.push_back(input_event);
    }

    static inline void on_window_resize(GLFWwindow* window, int width, int height)
	{
		//TODO: a less vebose solution is possible
        auto window_events_itr = std::find_if(platform.window.events.begin(), platform.window.events.end(), [](const window_event_t& window_event)
        {
            return window_event.type == window_event_t::type_e::resize;
        });

        if (window_events_itr != platform.window.events.end())
        {
            window_events_itr->rectangle.width = width;
			window_events_itr->rectangle.height = height;
        }
        else
        {
            window_event_t window_event;
            window_event.type = window_event_t::type_e::resize;
			window_event.rectangle.width = width;
			window_event.rectangle.height = height;

            platform.window.events.push_back(window_event);
        }

        platform.window.rectangle.width = width;
        platform.window.rectangle.height = height;
    }

    static inline void on_window_move(GLFWwindow* window, int x, int y)
	{
		//TODO: a less vebose solution is possible
        auto window_events_itr = std::find_if(platform.window.events.begin(), platform.window.events.end(), [](const window_event_t& window_event)
        {
            return window_event.type == window_event_t::type_e::move;
        });

        if (window_events_itr != platform.window.events.end())
        {
			window_events_itr->rectangle.x = x;
			window_events_itr->rectangle.y = y;
        }
        else
        {
            window_event_t window_event;
            window_event.type = window_event_t::type_e::move;
			window_event.rectangle.x = x;
			window_event.rectangle.y = y;

            platform.window.events.push_back(window_event);
        }

        platform.window.rectangle.x = x;
        platform.window.rectangle.y = y;
    }

    static inline void on_error(int error_code, const char* message)
    {
        throw std::exception();
    }

    platform_win32_t::platform_win32_t()
    {
    }

	platform_win32_t::~platform_win32_t()
	{
	}

	void platform_win32_t::app_run_start()
	{
		//glfw
		glfwInit();

		window_ptr = glfwCreateWindow(1, 1, "mandala", nullptr, nullptr);

        glfwMakeContextCurrent(window_ptr);

        glfwSetKeyCallback(window_ptr, on_keyboard_key);
        glfwSetCharCallback(window_ptr, on_keyboard_character);
        glfwSetMouseButtonCallback(window_ptr, on_mouse_button);
        glfwSetCursorPosCallback(window_ptr, on_mouse_move);
        glfwSetScrollCallback(window_ptr, on_mouse_scroll);
        glfwSetWindowSizeCallback(window_ptr, on_window_resize);
        glfwSetWindowPosCallback(window_ptr, on_window_move);

		//glew
        auto glew_init_result = glewInit();

        if (glew_init_result != GLEW_OK)
        {
            throw std::exception(unsafe_cast<char*>(glewGetErrorString(glew_init_result)));
        }
	}

	void platform_win32_t::app_run_end()
	{
        glfwDestroyWindow(window_ptr);
        glfwTerminate();

        window_ptr = nullptr;
	}

	void platform_win32_t::app_tick_start(float32_t dt)
	{
        glfwPollEvents();

		for (size_t gamepad_index = 0; gamepad_index < input.gamepad_states.size(); ++gamepad_index)
		{
            if (!glfwJoystickPresent(static_cast<int>(gamepad_index)))
			{
				break;
			}

			auto& gamepad_state = input.gamepad_states[gamepad_index];

			int axis_count = 0;
			auto axes = glfwGetJoystickAxes(static_cast<int>(gamepad_index), &axis_count);

			for (auto axis_index = 0; axis_index < axis_count; ++axis_index)
			{
				if (axes[axis_index] != gamepad_state.axes[axis_index])
				{
					input_event_t input_event;
					input_event.device_type = input_event_t::device_type_e::gamepad;
					input_event.gamepad.index = gamepad_index;
					input_event.gamepad.type = input_event_t::gamepad_t::type_e::axis_move;
					input_event.gamepad.axis_index = axis_index;
					input_event.gamepad.axis_value = axes[axis_index];
                    input_event.gamepad.axis_value_delta = axes[axis_index] - gamepad_state.axes[axis_index];

					platform.input.events.push_back(input_event);
				}

				gamepad_state.axes[axis_index] = axes[axis_index];
			}

			int button_count = 0;
			auto buttons = glfwGetJoystickButtons(static_cast<int>(gamepad_index), &button_count);

			for (auto button_index = 0; button_index < button_count; ++button_index)
			{
				if (buttons[button_index] != gamepad_state.buttons[button_index])
				{
					input_event_t input_event;
					input_event.device_type = input_event_t::device_type_e::gamepad;
					input_event.gamepad.index = gamepad_index;
					input_event.gamepad.type = buttons[button_index] == 0 ? input_event_t::gamepad_t::type_e::release : input_event_t::gamepad_t::type_e::press;
                    input_event.gamepad.button_index = button_index;

					platform.input.events.push_back(input_event);
				}

				gamepad_state.buttons[button_index] = buttons[button_index];
			}
		}
	}

	void platform_win32_t::app_tick_end(float32_t dt)
	{
	}

	void platform_win32_t::app_render_start()
	{
        gpu.clear(gpu_t::clear_flag_color | gpu_t::clear_flag_depth);
	}

	void platform_win32_t::app_render_end()
	{
        glfwSwapBuffers(window_ptr);
	}

	bool platform_win32_t::should_exit() const
	{
        return glfwWindowShouldClose(window_ptr) != 0;
	}

    platform_t::screen_size_type platform_win32_t::get_screen_size() const
    {
        screen_size_type screen_size;

        glfwGetWindowSize(window_ptr, &screen_size.x, &screen_size.y);

		return screen_size;
    }

	void platform_win32_t::set_screen_size(const screen_size_type& screen_size) const
	{
        glfwSetWindowSize(window_ptr, screen_size.x, screen_size.y);
	}

    bool platform_win32_t::pop_input_event(input_event_t& input_event)
    {
		if (input.events.empty())
        {
            return false;
        }

		input_event = input.events.front();
		input_event.id = input.event_id;
		input_event.is_consumed = false;

		input.events.pop_front();

		++input.event_id;

        return true;
    }

    bool platform_win32_t::pop_window_event(window_event_t& window_event)
    {
        if (window.events.empty())
        {
            return false;
        }

        window_event = window.events.front();

        window.events.pop_front();

        return true;
    }

	platform_t::cursor_location_type platform_win32_t::get_cursor_location() const
	{
        cursor_location_type cursor_location;

        glfwGetCursorPos(window_ptr, &cursor_location.x, &cursor_location.y);

        //cursor_location.y = get_screen_size().y - cursor_location.y;

		return cursor_location;
	}

	void platform_win32_t::set_cursor_location(const cursor_location_type& cursor_location) const
	{
        glfwSetCursorPos(window_ptr, cursor_location.x, cursor_location.y);
	}

	bool platform_win32_t::is_cursor_hidden() const
	{
        return glfwGetInputMode(window_ptr, GLFW_CURSOR) == GLFW_CURSOR_HIDDEN;
	}

	void platform_win32_t::set_cursor_hidden(bool is_hidden) const
	{
        glfwSetInputMode(window_ptr, GLFW_CURSOR, is_hidden ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL);
	}

	platform_t::window_title_type platform_win32_t::get_window_title() const
	{
		//TODO: implement this
		return std::string();
	}

	void platform_win32_t::set_window_title(const window_title_type& window_title) const
	{
        glfwSetWindowTitle(window_ptr, window_title.c_str());
	}

    platform_t::window_size_type platform_win32_t::get_window_size() const
	{
        window_size_type window_size;

        glfwGetWindowSize(window_ptr, &window_size.x, &window_size.y);

		return window_size;
	}

	void platform_win32_t::set_window_size(const window_size_type& window_size) const
	{
        glfwSetWindowSize(window_ptr, window_size.x, window_size.y);
	}

	platform_t::window_size_type platform_win32_t::get_window_location() const
	{
		vec2_i32_t window_location;

        glfwGetWindowPos(window_ptr, &window_location.x, &window_location.y);

		return window_location;
	}

	void platform_win32_t::set_window_location(const window_size_type& window_location) const
	{
        glfwSetWindowPos(window_ptr, window_location.x, window_location.y);
	}

	std::string platform_win32_t::get_clipboard_string() const
	{
		return glfwGetClipboardString(window_ptr);
	}

	void platform_win32_t::set_clipboard_string(const std::string& clipboard_string) const
	{
		glfwSetClipboardString(window_ptr, clipboard_string.c_str());
	}
}
<commit_msg>fixed bug where mouse scroll wheel input was calculated incorrectly<commit_after>//std
#include <array>
#include <chrono>
#include <iostream>

//mandala
#include "platform_win32.hpp"
#include "gpu.hpp"

//glew
#include <GL\glew.h>

//glfw
#include <GLFW\glfw3.h>

namespace mandala
{
    platform_win32_t platform;

    static inline void on_keyboard_key(GLFWwindow* window, int key, int scancode, int action, int mods)
	{
		input_event_t input_event;
		input_event.device_type = input_event_t::device_type_e::keyboard;
		input_event.keyboard.key = static_cast<input_event_t::keyboard_t::key_e>(key);

		if ((mods & GLFW_MOD_SHIFT) == GLFW_MOD_SHIFT)
		{
			input_event.keyboard.mod_flags |= input_event_t::mod_flag_shift;
		}

        if ((mods & GLFW_MOD_CONTROL) == GLFW_MOD_CONTROL)
        {
			input_event.keyboard.mod_flags |= input_event_t::mod_flag_ctrl;
        }

        if ((mods & GLFW_MOD_ALT) == GLFW_MOD_ALT)
        {
			input_event.keyboard.mod_flags |= input_event_t::mod_flag_alt;
        }

        if ((mods & GLFW_MOD_SUPER) == GLFW_MOD_SUPER)
        {
			input_event.keyboard.mod_flags |= input_event_t::mod_flag_super;
        }

        switch (action)
        {
        case GLFW_RELEASE:
            input_event.keyboard.type = input_event_t::keyboard_t::type_e::key_release;
            break;
        case GLFW_PRESS:
            input_event.keyboard.type = input_event_t::keyboard_t::type_e::key_press;
            break;
        case GLFW_REPEAT:
            input_event.keyboard.type = input_event_t::keyboard_t::type_e::key_repeat;
            break;
        }

        platform.input.events.push_back(input_event);
    }

    static inline void on_keyboard_character(GLFWwindow* window, unsigned int character)
    {
        input_event_t input_event;
        input_event.device_type = input_event_t::device_type_e::keyboard;
        input_event.keyboard.type = input_event_t::keyboard_t::type_e::character;
        input_event.keyboard.character = character;

        platform.input.events.push_back(input_event);
    }

    static inline void on_mouse_button(GLFWwindow* window, int button, int action, int mods)
    {
        input_event_t input_event;
        input_event.device_type = input_event_t::device_type_e::touch;
        input_event.touch.button = static_cast<input_event_t::touch_t::button_e>(button);
		input_event.touch.mod_flags = mods;

        bool is_press = (action == GLFW_PRESS);

        input_event.touch.type = is_press ? input_event_t::touch_t::type_e::press : input_event_t::touch_t::type_e::release;

        if (is_press)
        {
            ++platform.input.touch_id;

            input_event.touch.id = platform.input.touch_id;
        }
        else
        {
            platform.input.touch_id = 0;    //TODO: replace with something better
        }

        input_event.touch.location = platform.get_cursor_location();

        platform.input.events.push_back(input_event);
    }

    static inline void on_mouse_move(GLFWwindow* window, double x, double y)
	{
        const auto screen_size = platform.get_screen_size();

		input_event_t input_event;
		input_event.device_type = input_event_t::device_type_e::touch;
		input_event.touch.type = input_event_t::touch_t::type_e::move;
		input_event.touch.location.x = x;
		input_event.touch.location.y = screen_size.y - y;
		input_event.touch.location_delta.x = x - platform.cursor_location.x;
		input_event.touch.location_delta.y = screen_size.y - y - platform.cursor_location.y;
        input_event.touch.id = platform.input.touch_id;

		if (platform.is_cursor_centered)
		{
			const auto screen_size = platform.get_screen_size();

			platform.set_cursor_location(static_cast<vec2_f64_t>(screen_size) / 2.0);
		}

        platform.cursor_location = platform.get_cursor_location();

        platform.input.events.push_back(input_event);
    }

    static inline void on_mouse_scroll(GLFWwindow* window, double x, double y)
    {
        const auto screen_size = platform.get_screen_size();

        input_event_t input_event;
        input_event.device_type = input_event_t::device_type_e::touch;
        input_event.touch.type = input_event_t::touch_t::type_e::scroll;
        input_event.touch.location = platform.get_cursor_location();
        input_event.touch.location_delta.x = x;
        input_event.touch.location_delta.y = y;

        platform.input.events.push_back(input_event);
    }

    static inline void on_window_resize(GLFWwindow* window, int width, int height)
	{
		//TODO: a less vebose solution is possible
        auto window_events_itr = std::find_if(platform.window.events.begin(), platform.window.events.end(), [](const window_event_t& window_event)
        {
            return window_event.type == window_event_t::type_e::resize;
        });

        if (window_events_itr != platform.window.events.end())
        {
            window_events_itr->rectangle.width = width;
			window_events_itr->rectangle.height = height;
        }
        else
        {
            window_event_t window_event;
            window_event.type = window_event_t::type_e::resize;
			window_event.rectangle.width = width;
			window_event.rectangle.height = height;

            platform.window.events.push_back(window_event);
        }

        platform.window.rectangle.width = width;
        platform.window.rectangle.height = height;
    }

    static inline void on_window_move(GLFWwindow* window, int x, int y)
	{
		//TODO: a less vebose solution is possible
        auto window_events_itr = std::find_if(platform.window.events.begin(), platform.window.events.end(), [](const window_event_t& window_event)
        {
            return window_event.type == window_event_t::type_e::move;
        });

        if (window_events_itr != platform.window.events.end())
        {
			window_events_itr->rectangle.x = x;
			window_events_itr->rectangle.y = y;
        }
        else
        {
            window_event_t window_event;
            window_event.type = window_event_t::type_e::move;
			window_event.rectangle.x = x;
			window_event.rectangle.y = y;

            platform.window.events.push_back(window_event);
        }

        platform.window.rectangle.x = x;
        platform.window.rectangle.y = y;
    }

    static inline void on_error(int error_code, const char* message)
    {
        throw std::exception();
    }

    platform_win32_t::platform_win32_t()
    {
    }

	platform_win32_t::~platform_win32_t()
	{
	}

	void platform_win32_t::app_run_start()
	{
		//glfw
		glfwInit();

		window_ptr = glfwCreateWindow(1, 1, "mandala", nullptr, nullptr);

        glfwMakeContextCurrent(window_ptr);

        glfwSetKeyCallback(window_ptr, on_keyboard_key);
        glfwSetCharCallback(window_ptr, on_keyboard_character);
        glfwSetMouseButtonCallback(window_ptr, on_mouse_button);
        glfwSetCursorPosCallback(window_ptr, on_mouse_move);
        glfwSetScrollCallback(window_ptr, on_mouse_scroll);
        glfwSetWindowSizeCallback(window_ptr, on_window_resize);
        glfwSetWindowPosCallback(window_ptr, on_window_move);

		//glew
        auto glew_init_result = glewInit();

        if (glew_init_result != GLEW_OK)
        {
            throw std::exception(unsafe_cast<char*>(glewGetErrorString(glew_init_result)));
        }
	}

	void platform_win32_t::app_run_end()
	{
        glfwDestroyWindow(window_ptr);
        glfwTerminate();

        window_ptr = nullptr;
	}

	void platform_win32_t::app_tick_start(float32_t dt)
	{
        glfwPollEvents();

		for (size_t gamepad_index = 0; gamepad_index < input.gamepad_states.size(); ++gamepad_index)
		{
            if (!glfwJoystickPresent(static_cast<int>(gamepad_index)))
			{
				break;
			}

			auto& gamepad_state = input.gamepad_states[gamepad_index];

			int axis_count = 0;
			auto axes = glfwGetJoystickAxes(static_cast<int>(gamepad_index), &axis_count);

			for (auto axis_index = 0; axis_index < axis_count; ++axis_index)
			{
				if (axes[axis_index] != gamepad_state.axes[axis_index])
				{
					input_event_t input_event;
					input_event.device_type = input_event_t::device_type_e::gamepad;
					input_event.gamepad.index = gamepad_index;
					input_event.gamepad.type = input_event_t::gamepad_t::type_e::axis_move;
					input_event.gamepad.axis_index = axis_index;
					input_event.gamepad.axis_value = axes[axis_index];
                    input_event.gamepad.axis_value_delta = axes[axis_index] - gamepad_state.axes[axis_index];

					platform.input.events.push_back(input_event);
				}

				gamepad_state.axes[axis_index] = axes[axis_index];
			}

			int button_count = 0;
			auto buttons = glfwGetJoystickButtons(static_cast<int>(gamepad_index), &button_count);

			for (auto button_index = 0; button_index < button_count; ++button_index)
			{
				if (buttons[button_index] != gamepad_state.buttons[button_index])
				{
					input_event_t input_event;
					input_event.device_type = input_event_t::device_type_e::gamepad;
					input_event.gamepad.index = gamepad_index;
					input_event.gamepad.type = buttons[button_index] == 0 ? input_event_t::gamepad_t::type_e::release : input_event_t::gamepad_t::type_e::press;
                    input_event.gamepad.button_index = button_index;

					platform.input.events.push_back(input_event);
				}

				gamepad_state.buttons[button_index] = buttons[button_index];
			}
		}
	}

	void platform_win32_t::app_tick_end(float32_t dt)
	{
	}

	void platform_win32_t::app_render_start()
	{
        gpu.clear(gpu_t::clear_flag_color | gpu_t::clear_flag_depth);
	}

	void platform_win32_t::app_render_end()
	{
        glfwSwapBuffers(window_ptr);
	}

	bool platform_win32_t::should_exit() const
	{
        return glfwWindowShouldClose(window_ptr) != 0;
	}

    platform_t::screen_size_type platform_win32_t::get_screen_size() const
    {
        screen_size_type screen_size;

        glfwGetWindowSize(window_ptr, &screen_size.x, &screen_size.y);

		return screen_size;
    }

	void platform_win32_t::set_screen_size(const screen_size_type& screen_size) const
	{
        glfwSetWindowSize(window_ptr, screen_size.x, screen_size.y);
	}

    bool platform_win32_t::pop_input_event(input_event_t& input_event)
    {
		if (input.events.empty())
        {
            return false;
        }

		input_event = input.events.front();
		input_event.id = input.event_id;
		input_event.is_consumed = false;

		input.events.pop_front();

		++input.event_id;

        return true;
    }

    bool platform_win32_t::pop_window_event(window_event_t& window_event)
    {
        if (window.events.empty())
        {
            return false;
        }

        window_event = window.events.front();

        window.events.pop_front();

        return true;
    }

	platform_t::cursor_location_type platform_win32_t::get_cursor_location() const
	{
        cursor_location_type cursor_location;

        glfwGetCursorPos(window_ptr, &cursor_location.x, &cursor_location.y);

        //cursor_location.y = get_screen_size().y - cursor_location.y;

		return cursor_location;
	}

	void platform_win32_t::set_cursor_location(const cursor_location_type& cursor_location) const
	{
        glfwSetCursorPos(window_ptr, cursor_location.x, cursor_location.y);
	}

	bool platform_win32_t::is_cursor_hidden() const
	{
        return glfwGetInputMode(window_ptr, GLFW_CURSOR) == GLFW_CURSOR_HIDDEN;
	}

	void platform_win32_t::set_cursor_hidden(bool is_hidden) const
	{
        glfwSetInputMode(window_ptr, GLFW_CURSOR, is_hidden ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL);
	}

	platform_t::window_title_type platform_win32_t::get_window_title() const
	{
		//TODO: implement this
		return std::string();
	}

	void platform_win32_t::set_window_title(const window_title_type& window_title) const
	{
        glfwSetWindowTitle(window_ptr, window_title.c_str());
	}

    platform_t::window_size_type platform_win32_t::get_window_size() const
	{
        window_size_type window_size;

        glfwGetWindowSize(window_ptr, &window_size.x, &window_size.y);

		return window_size;
	}

	void platform_win32_t::set_window_size(const window_size_type& window_size) const
	{
        glfwSetWindowSize(window_ptr, window_size.x, window_size.y);
	}

	platform_t::window_size_type platform_win32_t::get_window_location() const
	{
		vec2_i32_t window_location;

        glfwGetWindowPos(window_ptr, &window_location.x, &window_location.y);

		return window_location;
	}

	void platform_win32_t::set_window_location(const window_size_type& window_location) const
	{
        glfwSetWindowPos(window_ptr, window_location.x, window_location.y);
	}

	std::string platform_win32_t::get_clipboard_string() const
	{
		return glfwGetClipboardString(window_ptr);
	}

	void platform_win32_t::set_clipboard_string(const std::string& clipboard_string) const
	{
		glfwSetClipboardString(window_ptr, clipboard_string.c_str());
	}
}
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Open Connectome Project (http://openconnecto.me)
 * Written by Da Zheng (zhengda1936@gmail.com)
 *
 * This file is part of FlashMatrix.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "log.h"
#include "local_vec_store.h"
#include "data_frame.h"
#include "mem_vv_store.h"
#include "mem_vec_store.h"
#include "matrix_store.h"

namespace fm
{

local_vec_store::ptr local_vec_store::get_portion(off_t loc, size_t size)
{
	assert(loc + size <= get_length());
	size_t entry_size = get_type().get_size();
	if (get_raw_arr())
		return local_vec_store::ptr(new local_ref_vec_store(
					get_raw_arr() + loc * entry_size, get_global_start() + loc,
					size, get_type(), get_node_id()));
	else {
		const local_vec_store *const_this = this;
		return local_vec_store::ptr(new local_cref_vec_store(
					const_this->get_raw_arr() + loc * entry_size,
					get_global_start() + loc, size, get_type(), get_node_id()));
	}
}

local_vec_store::const_ptr local_vec_store::get_portion(off_t loc,
			size_t size) const
{
	assert(get_raw_arr());
	assert(loc + size <= get_length());
	size_t entry_size = get_type().get_size();
	return local_vec_store::ptr(new local_cref_vec_store(
				get_raw_arr() + loc * entry_size, get_global_start() + loc,
				size, get_type(), get_node_id()));
}

bool local_vec_store::set_portion(std::shared_ptr<const local_vec_store> store,
		off_t loc)
{
	if (store->get_type() != get_type()) {
		BOOST_LOG_TRIVIAL(error) << "The input store has a different type";
		return false;
	}
	if (loc + store->get_length() > get_length()) {
		BOOST_LOG_TRIVIAL(error) << "out of boundary";
		return false;
	}
	if (get_raw_arr() == NULL) {
		BOOST_LOG_TRIVIAL(error) << "This local vector is read-only";
		return false;
	}
	size_t entry_size = get_type().get_size();
	memcpy(get_raw_arr() + loc * entry_size, store->get_raw_arr(),
			store->get_length() * entry_size);
	return true;
}

detail::vec_store::ptr local_vec_store::sort_with_index()
{
	char *data_ptr = get_raw_arr();
	if (data_ptr == NULL) {
		BOOST_LOG_TRIVIAL(error) << "This local vec store is read-only";
		return detail::vec_store::ptr();
	}

	local_vec_store::ptr buf(new local_buf_vec_store(get_global_start(),
				get_length(), get_scalar_type<off_t>(), get_node_id()));
	// TODO we need to make is serial.
	get_type().get_sorter().sort_with_index(data_ptr,
			(off_t *) buf->get_raw_arr(), get_length(), false);
	return buf;
}

void local_vec_store::sort()
{
	char *data_ptr = get_raw_arr();
	assert(data_ptr);
	get_type().get_sorter().serial_sort(data_ptr, get_length(), false);
}

bool local_vec_store::is_sorted() const
{
	// Test if the array is sorted in the ascending order.
	return get_type().get_sorter().is_sorted(get_raw_arr(), get_length(), false);
}

data_frame::ptr local_vec_store::groupby(
		const gr_apply_operate<local_vec_store> &op, bool with_val) const
{
	const scalar_type &output_type = op.get_output_type();
	const agg_operate &find_next = get_type().get_agg_ops().get_find_next();

	assert(is_sorted());
	detail::vec_store::ptr agg;
	// TODO it might not be a good idea to create a mem_vector
	if (op.get_num_out_eles() == 1)
		agg = detail::smp_vec_store::create(0, output_type);
	else
		agg = detail::mem_vv_store::create(output_type);
	detail::smp_vec_store::ptr val;
	if (with_val)
		val = detail::smp_vec_store::create(0, get_type());

	size_t out_size;
	// If the user can predict the number of output elements, we can create
	// a buffer of the expected size.
	if (op.get_num_out_eles() > 0)
		out_size = op.get_num_out_eles();
	else
		// If the user can't, we create a small buffer.
		out_size = 16;
	local_buf_vec_store one_agg(0, out_size, output_type, -1);
	std::vector<const char *> val_locs;
	off_t init_global_start = get_global_start();
	size_t loc = 0;
	while (loc < get_length()) {
		size_t curr_length = get_length() - loc;
		const char *curr_ptr = get_raw_arr() + get_entry_size() * loc;
		size_t rel_end;
		find_next.run(curr_length, curr_ptr, &rel_end);
		local_cref_vec_store lcopy(curr_ptr, init_global_start + loc, rel_end,
				get_type(), get_node_id());
		op.run(curr_ptr, lcopy, one_agg);
		agg->append(one_agg);
		if (with_val)
			val_locs.push_back(curr_ptr);
		loc += rel_end;
	}
	if (with_val) {
		val->resize(val_locs.size());
		val->set(val_locs);
	}
	data_frame::ptr ret = data_frame::create();
	if (with_val)
		ret->add_vec("val", val);
	ret->add_vec("agg", agg);
	return ret;
}

local_vec_store::ptr local_vec_store::get(std::vector<off_t> &idxs) const
{
	local_vec_store::ptr ret(new local_buf_vec_store(-1, idxs.size(), get_type(), -1));
	std::vector<const char *> ptrs(idxs.size());
	for (size_t i = 0; i < idxs.size(); i++)
		ptrs[i] = this->get(idxs[i]);
	get_type().get_sg().gather(ptrs, ret->get_raw_arr());
	return ret;
}

detail::matrix_store::const_ptr local_vec_store::conv2mat(size_t nrow,
		size_t ncol, bool byrow) const
{
	BOOST_LOG_TRIVIAL(error)
		<< "can't convert a local vector to a matrix";
	return detail::matrix_store::ptr();
}

bool local_ref_vec_store::resize(size_t new_length)
{
	BOOST_LOG_TRIVIAL(error)
		<< "can't resize a local reference vector store";
	assert(0);
	return false;
}

bool local_cref_vec_store::resize(size_t new_length)
{
	BOOST_LOG_TRIVIAL(error)
		<< "can't resize a local reference vector store";
	assert(0);
	return false;
}

bool local_buf_vec_store::resize(size_t new_length)
{
	if (get_length() < new_length) {
		arr.expand(new_length * get_type().get_size());
		set_data(arr.get_raw(), arr.get_raw());
	}
	detail::vec_store::resize(new_length);
	return true;
}

}
<commit_msg>[Matrix]: avoid expanding the local vector buffer if necessary.<commit_after>/*
 * Copyright 2015 Open Connectome Project (http://openconnecto.me)
 * Written by Da Zheng (zhengda1936@gmail.com)
 *
 * This file is part of FlashMatrix.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "log.h"
#include "local_vec_store.h"
#include "data_frame.h"
#include "mem_vv_store.h"
#include "mem_vec_store.h"
#include "matrix_store.h"

namespace fm
{

local_vec_store::ptr local_vec_store::get_portion(off_t loc, size_t size)
{
	assert(loc + size <= get_length());
	size_t entry_size = get_type().get_size();
	if (get_raw_arr())
		return local_vec_store::ptr(new local_ref_vec_store(
					get_raw_arr() + loc * entry_size, get_global_start() + loc,
					size, get_type(), get_node_id()));
	else {
		const local_vec_store *const_this = this;
		return local_vec_store::ptr(new local_cref_vec_store(
					const_this->get_raw_arr() + loc * entry_size,
					get_global_start() + loc, size, get_type(), get_node_id()));
	}
}

local_vec_store::const_ptr local_vec_store::get_portion(off_t loc,
			size_t size) const
{
	assert(get_raw_arr());
	assert(loc + size <= get_length());
	size_t entry_size = get_type().get_size();
	return local_vec_store::ptr(new local_cref_vec_store(
				get_raw_arr() + loc * entry_size, get_global_start() + loc,
				size, get_type(), get_node_id()));
}

bool local_vec_store::set_portion(std::shared_ptr<const local_vec_store> store,
		off_t loc)
{
	if (store->get_type() != get_type()) {
		BOOST_LOG_TRIVIAL(error) << "The input store has a different type";
		return false;
	}
	if (loc + store->get_length() > get_length()) {
		BOOST_LOG_TRIVIAL(error) << "out of boundary";
		return false;
	}
	if (get_raw_arr() == NULL) {
		BOOST_LOG_TRIVIAL(error) << "This local vector is read-only";
		return false;
	}
	size_t entry_size = get_type().get_size();
	memcpy(get_raw_arr() + loc * entry_size, store->get_raw_arr(),
			store->get_length() * entry_size);
	return true;
}

detail::vec_store::ptr local_vec_store::sort_with_index()
{
	char *data_ptr = get_raw_arr();
	if (data_ptr == NULL) {
		BOOST_LOG_TRIVIAL(error) << "This local vec store is read-only";
		return detail::vec_store::ptr();
	}

	local_vec_store::ptr buf(new local_buf_vec_store(get_global_start(),
				get_length(), get_scalar_type<off_t>(), get_node_id()));
	// TODO we need to make is serial.
	get_type().get_sorter().sort_with_index(data_ptr,
			(off_t *) buf->get_raw_arr(), get_length(), false);
	return buf;
}

void local_vec_store::sort()
{
	char *data_ptr = get_raw_arr();
	assert(data_ptr);
	get_type().get_sorter().serial_sort(data_ptr, get_length(), false);
}

bool local_vec_store::is_sorted() const
{
	// Test if the array is sorted in the ascending order.
	return get_type().get_sorter().is_sorted(get_raw_arr(), get_length(), false);
}

data_frame::ptr local_vec_store::groupby(
		const gr_apply_operate<local_vec_store> &op, bool with_val) const
{
	const scalar_type &output_type = op.get_output_type();
	const agg_operate &find_next = get_type().get_agg_ops().get_find_next();

	assert(is_sorted());
	detail::vec_store::ptr agg;
	// TODO it might not be a good idea to create a mem_vector
	if (op.get_num_out_eles() == 1)
		agg = detail::smp_vec_store::create(0, output_type);
	else
		agg = detail::mem_vv_store::create(output_type);
	detail::smp_vec_store::ptr val;
	if (with_val)
		val = detail::smp_vec_store::create(0, get_type());

	size_t out_size;
	// If the user can predict the number of output elements, we can create
	// a buffer of the expected size.
	if (op.get_num_out_eles() > 0)
		out_size = op.get_num_out_eles();
	else
		// If the user can't, we create a small buffer.
		out_size = 16;
	local_buf_vec_store one_agg(0, out_size, output_type, -1);
	std::vector<const char *> val_locs;
	off_t init_global_start = get_global_start();
	size_t loc = 0;
	while (loc < get_length()) {
		size_t curr_length = get_length() - loc;
		const char *curr_ptr = get_raw_arr() + get_entry_size() * loc;
		size_t rel_end;
		find_next.run(curr_length, curr_ptr, &rel_end);
		local_cref_vec_store lcopy(curr_ptr, init_global_start + loc, rel_end,
				get_type(), get_node_id());
		op.run(curr_ptr, lcopy, one_agg);
		agg->append(one_agg);
		if (with_val)
			val_locs.push_back(curr_ptr);
		loc += rel_end;
	}
	if (with_val) {
		val->resize(val_locs.size());
		val->set(val_locs);
	}
	data_frame::ptr ret = data_frame::create();
	if (with_val)
		ret->add_vec("val", val);
	ret->add_vec("agg", agg);
	return ret;
}

local_vec_store::ptr local_vec_store::get(std::vector<off_t> &idxs) const
{
	local_vec_store::ptr ret(new local_buf_vec_store(-1, idxs.size(), get_type(), -1));
	std::vector<const char *> ptrs(idxs.size());
	for (size_t i = 0; i < idxs.size(); i++)
		ptrs[i] = this->get(idxs[i]);
	get_type().get_sg().gather(ptrs, ret->get_raw_arr());
	return ret;
}

detail::matrix_store::const_ptr local_vec_store::conv2mat(size_t nrow,
		size_t ncol, bool byrow) const
{
	BOOST_LOG_TRIVIAL(error)
		<< "can't convert a local vector to a matrix";
	return detail::matrix_store::ptr();
}

bool local_ref_vec_store::resize(size_t new_length)
{
	BOOST_LOG_TRIVIAL(error)
		<< "can't resize a local reference vector store";
	assert(0);
	return false;
}

bool local_cref_vec_store::resize(size_t new_length)
{
	BOOST_LOG_TRIVIAL(error)
		<< "can't resize a local reference vector store";
	assert(0);
	return false;
}

bool local_buf_vec_store::resize(size_t new_length)
{
	size_t new_num_bytes = new_length * get_type().get_size();
	if (arr.get_num_bytes() < new_num_bytes) {
		arr.expand(new_num_bytes);
		set_data(arr.get_raw(), arr.get_raw());
	}
	detail::vec_store::resize(new_length);
	return true;
}

}
<|endoftext|>


<commit_before>//!@Alan
//!
//! Exercise 6.10:
//! Using pointers, write a function to swap the values of two ints.
//! Test the function by calling it and printing the swapped values.
//!

#include <iostream>
#include <string>
#include <stdexcept>

using namespace std;

void swap(int* _n1, int* _n2);

int main()
{
    int n1, n2;

    cout<<"Please Enter:\n";
    while(cin>>n1>>n2)
    {
        swap(&n1, &n2);
        cout<<n1<<" "<<n2<<endl;
    }

    return 0;
}

void swap(int* _n1, int* _n2)
{
    int temp;
    temp = *_n1;
    *_n1 = *_n2;
    *_n2 = temp;
}
<commit_msg>Update ex6_10.cpp<commit_after>//!@Yue wang
//!
//! Exercise 6.10:
//! Using pointers, write a function to swap the values of two ints.
//! Test the function by calling it and printing the swapped values.
//!
#include <iostream>
#include <string>
#include <stdexcept>

void swap(int* lhs, int* rhs)
{
    int tmp;
    tmp = *lhs;
    *lhs = *rhs;
    *rhs = tmp;
}

int main()
{
    for (int lft, rht; std::cout << "Please Enter:\n", std::cin >> lft >> rht; )
    {
        swap(&lft, &rht);
        std::cout << lft << " " << rht << std::endl;
    }

    return 0;
}
<|endoftext|>


<commit_before>//! @Alan
//!
//! Exercise 11.8:
//! Write a program that stores the excluded words in a vector
//! instead of in a set. What are the advantages to using a set?
//  copied from the post on stack overflow:
//  1.No matter what elements you add or remove (unless you add
//  a duplicate, which is not allowed in a set), it will always
//  be ordered.
//  2.A vector has exactly and only the ordering you explicitly
//  give it. Items in a vector are where you put them. If you put
//  them in out of order, then they're out of order; you now need
//  to sort the container to put them back in order.
//  3.However, if you are constantly inserting and removing items
//  from the container, vector will run into many issues.
//  4.The time it takes to insert an item into a vector is proportional
//  to the number of items already in the vector. The time it takes
//  to insert an item into a set is proportional to the log of the
//  number of items. If the number of items is large, that's a huge
//  difference. Log(100,000) is 17; that's a major speed improvement.
//  The same goes for removal.

//  http://stackoverflow.com/questions/8686725/what-is-the-difference-between-stdset-and-stdvector
//!
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<std::string> exclude = {"aa", "bb", "cc"};
    for (std::string word; std::cin >> word;) {
        if (std::find(exclude.begin(), exclude.end(), word) != exclude.end())
            std::cout << "excluded!" << std::endl;
        else
            exclude.push_back(word);
    }
    for (auto const& s : exclude) std::cout << s << " ";
    std::cout << std::endl;
}
<commit_msg>Update ex11_8.cpp<commit_after>//! @Alan
//!
//! Exercise 11.8:
//! Write a program that stores the excluded words in a vector
//! instead of in a set. What are the advantages to using a set?
//!

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
    vector<string> exclude={"aa", "bb", "cc"};
    for(string word; cin>>word; )
    {
        if(find(exclude.begin(), exclude.end(), word)!=exclude.end())
            cout<<"excluded!"<<endl;
        else
            exclude.push_back(word);
    }

    for(const auto &s:exclude)
        cout<<s<<" ";
    cout<<endl;
}
<|endoftext|>