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

#include "environment.h"
#include "filescriptsource.h"
#include "lexer.h"
#include "log.h"
#include "nullostream.h"
#include "parser.h"
#include "peachyparser.h"
#include "runtime.h"
#include "script.h"
#include "scriptsource.h"
#include "tokenfactory.h"
#include "tokensource.h"

using namespace peachy;

int main(int argc, char ** argv) {

  (void) argc;
  (void) argv;

  NullOStream * nullOStream = new NullOStream;
  Log * nullLogger = new Log(nullOStream);
  Log * debugLogger = new Log(&std::cout);

  debugLogger->info("Peachy test harness");

  ScriptSource * scriptSource;

  try {
    scriptSource = new FileScriptSource(nullLogger, "test.peachy");
  } catch(std::runtime_error e) {
    debugLogger->info("Unable to acquire script source");
    goto shortexit;
  }
  Environment * environment = new Environment(nullLogger);
  Runtime * runtime = new Runtime(nullLogger);
  TokenFactory * tokenFactory = new TokenFactory(nullLogger, nullLogger);
  TokenSource * tokenSource = new Lexer(nullLogger, tokenFactory, scriptSource);
  Parser * parser = new PeachyParser(debugLogger, tokenSource);
  Script * script = new Script(nullLogger, environment, runtime, parser);

  script->run();

  delete script;
  delete parser;
  delete tokenSource;
  delete tokenFactory;
  delete runtime;
  delete environment;
  delete scriptSource;

shortexit:

  delete nullLogger;
  delete nullOStream;

  debugLogger->info("Test harness complete");
  delete debugLogger;

  return 0;
}
<commit_msg>removed unused args<commit_after>#include <iostream>
#include <stdexcept>
#include <string>

#include "environment.h"
#include "filescriptsource.h"
#include "lexer.h"
#include "log.h"
#include "nullostream.h"
#include "parser.h"
#include "peachyparser.h"
#include "runtime.h"
#include "script.h"
#include "scriptsource.h"
#include "tokenfactory.h"
#include "tokensource.h"

using namespace peachy;

int main() {

  NullOStream * nullOStream = new NullOStream;
  Log * nullLogger = new Log(nullOStream);
  Log * debugLogger = new Log(&std::cout);

  debugLogger->info("Peachy test harness");

  ScriptSource * scriptSource;

  try {
    scriptSource = new FileScriptSource(nullLogger, "test.peachy");
  } catch(std::runtime_error e) {
    debugLogger->info("Unable to acquire script source");
    goto shortexit;
  }
  Environment * environment = new Environment(nullLogger);
  Runtime * runtime = new Runtime(nullLogger);
  TokenFactory * tokenFactory = new TokenFactory(nullLogger, nullLogger);
  TokenSource * tokenSource = new Lexer(nullLogger, tokenFactory, scriptSource);
  Parser * parser = new PeachyParser(debugLogger, tokenSource);
  Script * script = new Script(nullLogger, environment, runtime, parser);

  script->run();

  delete script;
  delete parser;
  delete tokenSource;
  delete tokenFactory;
  delete runtime;
  delete environment;
  delete scriptSource;

shortexit:

  delete nullLogger;
  delete nullOStream;

  debugLogger->info("Test harness complete");
  delete debugLogger;

  return 0;
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <new>
#include <algorithm>
#include <climits>
#include <unistd.h>
#include <cstring>

#include "Swimd.h"

using namespace std;

void fillRandomly(unsigned char* seq, int seqLength, int alphabetLength);
int * createSimpleScoreMatrix(int alphabetLength, int match, int mismatch);
int calculateSW(unsigned char query[], int queryLength, unsigned char ** db, int dbLength, int dbSeqLengths[],
                int gapOpen, int gapExt, int * scoreMatrix, int alphabetLength, SwimdSearchResult results[]);
int calculateGlobal(unsigned char query[], int queryLength, unsigned char ** db, int dbLength,
                    int dbSeqLengths[], int gapOpen, int gapExt, int * scoreMatrix,
                    int alphabetLength, SwimdSearchResult results[], const int);
void printInts(int a[], int aLength);
int maximumScore(SwimdSearchResult results[], int resultsLength);

int main(int argc, char * const argv[]) {

    char mode[32] = "SW"; // "SW", "NW", "HW" or "OV"
    if (argc > 1) {
        strcpy(mode, argv[1]);
    }

    clock_t start, finish;
    srand(42);

    int alphabetLength = 4;
    int gapOpen = 11;
    int gapExt = 1;

    // Create random query
    int queryLength = 1000;
    unsigned char query[queryLength];
    fillRandomly(query, queryLength, alphabetLength);

    // Create random database
    int dbLength = 200;
    unsigned char * db[dbLength];
    int dbSeqsLengths[dbLength];
    for (int i = 0; i < dbLength; i++) {
        dbSeqsLengths[i] = 800 + rand() % 4000;
        db[i] = new unsigned char[dbSeqsLengths[i]];
        fillRandomly(db[i], dbSeqsLengths[i], alphabetLength);
    }

    /*
      printf("Query:\n");
      for (int i = 0; i < queryLength; i++)
      printf("%d ", query[i]);
      printf("\n");

      printf("Database:\n");
      for (int i = 0; i < dbLength; i++) {
      printf("%d. ", i);
      for (int j = 0; j < dbSeqsLengths[i]; j++)
      printf("%d ", db[i][j]);
      printf("\n");
      }
    */

    // Create score matrix
    int * scoreMatrix = createSimpleScoreMatrix(alphabetLength, 3, -1);

    // Run Swimd
    printf("Starting Swimd!\n");
#ifdef __AVX2__
    printf("Using AVX2!\n");
#elif __SSE4_1__
    printf("Using SSE4.1!\n");
#endif
    start = clock();
    SwimdSearchResult results[dbLength];
    int resultCode;
    int modeCode;
    if (!strcmp(mode, "NW")) modeCode = SWIMD_MODE_NW;
    else if (!strcmp(mode, "HW")) modeCode = SWIMD_MODE_HW;
    else if (!strcmp(mode, "OV")) modeCode = SWIMD_MODE_OV;
    else if (!strcmp(mode, "SW")) modeCode = SWIMD_MODE_SW;
    else {
        printf("Invalid mode!\n");
        return 1;
    }
    resultCode = swimdSearchDatabase(query, queryLength, db, dbLength, dbSeqsLengths,
                                     gapOpen, gapExt, scoreMatrix, alphabetLength, results,
                                     modeCode, SWIMD_OVERFLOW_SIMPLE);
    finish = clock();
    double time1 = ((double)(finish-start)) / CLOCKS_PER_SEC;
    printf("Time: %lf\n", time1);

    if (resultCode != 0) {
        printf("Overflow happened!");
        exit(0);
    }
    printf("Maximum: %d\n", maximumScore(results, dbLength));
    printf("\n");

    // Run normal SW
    printf("Starting normal!\n");
    start = clock();
    SwimdSearchResult results2[dbLength];
    if (!strcmp(mode, "SW")) {
        resultCode = calculateSW(query, queryLength, db, dbLength, dbSeqsLengths,
                                 gapOpen, gapExt, scoreMatrix, alphabetLength, results2);
    } else {
        resultCode = calculateGlobal(query, queryLength, db, dbLength, dbSeqsLengths,
                                     gapOpen, gapExt, scoreMatrix, alphabetLength, results2, modeCode);
    }
    finish = clock();
    double time2 = ((double)(finish-start))/CLOCKS_PER_SEC;
    printf("Time: %lf\n", time2);

    printf("Maximum: %d\n", maximumScore(results2, dbLength));
    printf("\n");

    // Print differences in scores (hopefully there are none!)
    for (int i = 0; i < dbLength; i++) {
        if (results[i].score != results2[i].score) {
            printf("#%d: score is %d but should be %d\n", i, results[i].score, results2[i].score);
        }
        if (results[i].endLocationTarget != results2[i].endLocationTarget) {
            printf("#%d: end location in target is %d but should be %d\n",
                   i, results[i].endLocationTarget, results2[i].endLocationTarget);
        }
        if (results[i].endLocationQuery != results2[i].endLocationQuery) {
            printf("#%d: end location in query is %d but should be %d\n",
                   i, results[i].endLocationQuery, results2[i].endLocationQuery);
        }
        //printf("#%d: score -> %d, end location -> (q: %d, t: %d)\n",
        //       i, results[i].score, results[i].endLocationQuery, results[i].endLocationTarget);
    }

    printf("Times faster: %lf\n", time2/time1);

    // Free allocated memory
    for (int i = 0; i < dbLength; i++) {
        delete[] db[i];
    }
    delete[] scoreMatrix;
}

void fillRandomly(unsigned char* seq, int seqLength, int alphabetLength) {
    for (int i = 0; i < seqLength; i++)
        seq[i] = rand() % alphabetLength;
}

int* createSimpleScoreMatrix(int alphabetLength, int match, int mismatch) {
    int * scoreMatrix = new int[alphabetLength*alphabetLength];
    for (int i = 0; i < alphabetLength; i++) {
        for (int j = 0; j < alphabetLength; j++)
            scoreMatrix[i * alphabetLength + j] = (i==j ? match : mismatch);
    }
    return scoreMatrix;
}

int calculateSW(unsigned char query[], int queryLength, unsigned char ** db, int dbLength,
                int dbSeqLengths[], int gapOpen, int gapExt, int * scoreMatrix, int alphabetLength,
                SwimdSearchResult results[]) {
    int prevHs[queryLength];
    int prevEs[queryLength];

    for (int seqIdx = 0; seqIdx < dbLength; seqIdx++) {
        int maxH = 0;
        int endLocationTarget = 0;
        int endLocationQuery = 0;

        // Initialize all values to 0
        for (int i = 0; i < queryLength; i++) {
            prevHs[i] = prevEs[i] = 0;
        }

        for (int c = 0; c < dbSeqLengths[seqIdx]; c++) {
            int uF, uH, ulH;
            uF = uH = ulH = 0;

            for (int r = 0; r < queryLength; r++) {
                int E = max(prevHs[r] - gapOpen, prevEs[r] - gapExt);
                int F = max(uH - gapOpen, uF - gapExt);
                int score = scoreMatrix[query[r] * alphabetLength + db[seqIdx][c]];
                int H = max(0, max(E, max(F, ulH+score)));
                if (H > maxH) {
                    endLocationTarget = c;
                    endLocationQuery = r;
                    maxH = H;
                }
                uF = F;
                uH = H;
                ulH = prevHs[r];

                prevHs[r] = H;
                prevEs[r] = E;
            }
        }

        results[seqIdx].score = maxH;
        results[seqIdx].endLocationTarget = endLocationTarget;
        results[seqIdx].endLocationQuery = endLocationQuery;
    }

    return 0;
}

int calculateGlobal(unsigned char query[], int queryLength, unsigned char ** db, int dbLength,
                    int dbSeqLengths[], int gapOpen, int gapExt, int * scoreMatrix,
                    int alphabetLength, SwimdSearchResult results[], const int mode) {
    int prevHs[queryLength];
    int prevEs[queryLength];

    const int LOWER_SCORE_BOUND = INT_MIN + gapExt;

    for (int seqIdx = 0; seqIdx < dbLength; seqIdx++) {
        // Initialize all values to 0
        for (int r = 0; r < queryLength; r++) {
            // Query has fixed start and end if not OV
            prevHs[r] = mode == SWIMD_MODE_OV ? 0 : -1 * gapOpen - r * gapExt;
            prevEs[r] = LOWER_SCORE_BOUND;
        }

        int maxH = INT_MIN;
        int endLocationTarget = 0;
        int endLocationQuery = 0;

        int H = INT_MIN;
        int targetLength = dbSeqLengths[seqIdx];
        for (int c = 0; c < targetLength; c++) {
            int uF, uH, ulH;
            uF = LOWER_SCORE_BOUND;
            if (mode == SWIMD_MODE_NW) { // Database sequence has fixed start and end only in NW
                uH = -1 * gapOpen - c * gapExt;
                ulH = uH + gapExt;
            } else {
                uH = ulH = 0;
            }
            if (c == 0)
                ulH = 0;

            for (int r = 0; r < queryLength; r++) {
                int E = max(prevHs[r] - gapOpen, prevEs[r] - gapExt);
                int F = max(uH - gapOpen, uF - gapExt);
                int score = scoreMatrix[query[r] * alphabetLength + db[seqIdx][c]];
                H = max(E, max(F, ulH+score));

                if (mode == SWIMD_MODE_OV && c == targetLength - 1) {
                    if (H > maxH) {
                        maxH = H;
                        endLocationQuery = r;
                        endLocationTarget = c;
                    }
                }

                uF = F;
                uH = H;
                ulH = prevHs[r];

                prevHs[r] = H;
                prevEs[r] = E;
            }

            if (H > maxH) {
                maxH = H;
                endLocationTarget = c;
                endLocationQuery = queryLength - 1;
            }
        }

        if (mode == SWIMD_MODE_NW) {
            results[seqIdx].score = H;
            results[seqIdx].endLocationTarget = targetLength - 1;
            results[seqIdx].endLocationQuery = queryLength - 1;
        } else if (mode == SWIMD_MODE_OV || mode == SWIMD_MODE_HW) {
            results[seqIdx].score = maxH;
            results[seqIdx].endLocationTarget = endLocationTarget;
            results[seqIdx].endLocationQuery = endLocationQuery;
        } else return 1;
    }

    return 0;
}

void printInts(int a[], int aLength) {
    for (int i = 0; i < aLength; i++)
        printf("%d ", a[i]);
    printf("\n");
}

int maximumScore(SwimdSearchResult results[], int resultsLength) {
    int maximum = 0;
    for (int i = 0; i < resultsLength; i++)
        if (results[i].score > maximum)
            maximum = results[i].score;
    return maximum;
}
<commit_msg>Nicer error reporing in test.<commit_after>#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <new>
#include <algorithm>
#include <climits>
#include <unistd.h>
#include <cstring>

#include "Swimd.h"

using namespace std;

void fillRandomly(unsigned char* seq, int seqLength, int alphabetLength);
int * createSimpleScoreMatrix(int alphabetLength, int match, int mismatch);
int calculateSW(unsigned char query[], int queryLength, unsigned char ** db, int dbLength, int dbSeqLengths[],
                int gapOpen, int gapExt, int * scoreMatrix, int alphabetLength, SwimdSearchResult results[]);
int calculateGlobal(unsigned char query[], int queryLength, unsigned char ** db, int dbLength,
                    int dbSeqLengths[], int gapOpen, int gapExt, int * scoreMatrix,
                    int alphabetLength, SwimdSearchResult results[], const int);
void printInts(int a[], int aLength);
int maximumScore(SwimdSearchResult results[], int resultsLength);

int main(int argc, char * const argv[]) {

    char mode[32] = "SW"; // "SW", "NW", "HW" or "OV"
    if (argc > 1) {
        strcpy(mode, argv[1]);
    }

    clock_t start, finish;
    srand(42);

    int alphabetLength = 4;
    int gapOpen = 11;
    int gapExt = 1;

    // Create random query
    int queryLength = 1000;
    unsigned char query[queryLength];
    fillRandomly(query, queryLength, alphabetLength);

    // Create random database
    int dbLength = 200;
    unsigned char * db[dbLength];
    int dbSeqsLengths[dbLength];
    for (int i = 0; i < dbLength; i++) {
        dbSeqsLengths[i] = 800 + rand() % 4000;
        db[i] = new unsigned char[dbSeqsLengths[i]];
        fillRandomly(db[i], dbSeqsLengths[i], alphabetLength);
    }

    /*
      printf("Query:\n");
      for (int i = 0; i < queryLength; i++)
      printf("%d ", query[i]);
      printf("\n");

      printf("Database:\n");
      for (int i = 0; i < dbLength; i++) {
      printf("%d. ", i);
      for (int j = 0; j < dbSeqsLengths[i]; j++)
      printf("%d ", db[i][j]);
      printf("\n");
      }
    */

    // Create score matrix
    int * scoreMatrix = createSimpleScoreMatrix(alphabetLength, 3, -1);

    // Run Swimd
    printf("Starting Swimd!\n");
#ifdef __AVX2__
    printf("Using AVX2!\n");
#elif __SSE4_1__
    printf("Using SSE4.1!\n");
#endif
    start = clock();
    SwimdSearchResult results[dbLength];
    int resultCode;
    int modeCode;
    if (!strcmp(mode, "NW")) modeCode = SWIMD_MODE_NW;
    else if (!strcmp(mode, "HW")) modeCode = SWIMD_MODE_HW;
    else if (!strcmp(mode, "OV")) modeCode = SWIMD_MODE_OV;
    else if (!strcmp(mode, "SW")) modeCode = SWIMD_MODE_SW;
    else {
        printf("Invalid mode!\n");
        return 1;
    }
    resultCode = swimdSearchDatabase(query, queryLength, db, dbLength, dbSeqsLengths,
                                     gapOpen, gapExt, scoreMatrix, alphabetLength, results,
                                     modeCode, SWIMD_OVERFLOW_SIMPLE);
    finish = clock();
    double time1 = ((double)(finish-start)) / CLOCKS_PER_SEC;

    if (resultCode == SWIMD_ERR_OVERFLOW) {
        printf("Error: overflow happened!\n");
        exit(0);
    }
    if (resultCode == SWIMD_ERR_NO_SIMD_SUPPORT) {
        printf("Error: no SIMD support!\n");
        exit(0);
    }

    printf("Time: %lf\n", time1);
    printf("Maximum: %d\n", maximumScore(results, dbLength));
    printf("\n");

    // Run normal SW
    printf("Starting normal!\n");
    start = clock();
    SwimdSearchResult results2[dbLength];
    if (!strcmp(mode, "SW")) {
        resultCode = calculateSW(query, queryLength, db, dbLength, dbSeqsLengths,
                                 gapOpen, gapExt, scoreMatrix, alphabetLength, results2);
    } else {
        resultCode = calculateGlobal(query, queryLength, db, dbLength, dbSeqsLengths,
                                     gapOpen, gapExt, scoreMatrix, alphabetLength, results2, modeCode);
    }
    finish = clock();
    double time2 = ((double)(finish-start))/CLOCKS_PER_SEC;
    printf("Time: %lf\n", time2);

    printf("Maximum: %d\n", maximumScore(results2, dbLength));
    printf("\n");

    // Print differences in scores (hopefully there are none!)
    for (int i = 0; i < dbLength; i++) {
        if (results[i].score != results2[i].score) {
            printf("#%d: score is %d but should be %d\n", i, results[i].score, results2[i].score);
        }
        if (results[i].endLocationTarget != results2[i].endLocationTarget) {
            printf("#%d: end location in target is %d but should be %d\n",
                   i, results[i].endLocationTarget, results2[i].endLocationTarget);
        }
        if (results[i].endLocationQuery != results2[i].endLocationQuery) {
            printf("#%d: end location in query is %d but should be %d\n",
                   i, results[i].endLocationQuery, results2[i].endLocationQuery);
        }
        //printf("#%d: score -> %d, end location -> (q: %d, t: %d)\n",
        //       i, results[i].score, results[i].endLocationQuery, results[i].endLocationTarget);
    }

    printf("Times faster: %lf\n", time2/time1);

    // Free allocated memory
    for (int i = 0; i < dbLength; i++) {
        delete[] db[i];
    }
    delete[] scoreMatrix;
}

void fillRandomly(unsigned char* seq, int seqLength, int alphabetLength) {
    for (int i = 0; i < seqLength; i++)
        seq[i] = rand() % alphabetLength;
}

int* createSimpleScoreMatrix(int alphabetLength, int match, int mismatch) {
    int * scoreMatrix = new int[alphabetLength*alphabetLength];
    for (int i = 0; i < alphabetLength; i++) {
        for (int j = 0; j < alphabetLength; j++)
            scoreMatrix[i * alphabetLength + j] = (i==j ? match : mismatch);
    }
    return scoreMatrix;
}

int calculateSW(unsigned char query[], int queryLength, unsigned char ** db, int dbLength,
                int dbSeqLengths[], int gapOpen, int gapExt, int * scoreMatrix, int alphabetLength,
                SwimdSearchResult results[]) {
    int prevHs[queryLength];
    int prevEs[queryLength];

    for (int seqIdx = 0; seqIdx < dbLength; seqIdx++) {
        int maxH = 0;
        int endLocationTarget = 0;
        int endLocationQuery = 0;

        // Initialize all values to 0
        for (int i = 0; i < queryLength; i++) {
            prevHs[i] = prevEs[i] = 0;
        }

        for (int c = 0; c < dbSeqLengths[seqIdx]; c++) {
            int uF, uH, ulH;
            uF = uH = ulH = 0;

            for (int r = 0; r < queryLength; r++) {
                int E = max(prevHs[r] - gapOpen, prevEs[r] - gapExt);
                int F = max(uH - gapOpen, uF - gapExt);
                int score = scoreMatrix[query[r] * alphabetLength + db[seqIdx][c]];
                int H = max(0, max(E, max(F, ulH+score)));
                if (H > maxH) {
                    endLocationTarget = c;
                    endLocationQuery = r;
                    maxH = H;
                }
                uF = F;
                uH = H;
                ulH = prevHs[r];

                prevHs[r] = H;
                prevEs[r] = E;
            }
        }

        results[seqIdx].score = maxH;
        results[seqIdx].endLocationTarget = endLocationTarget;
        results[seqIdx].endLocationQuery = endLocationQuery;
    }

    return 0;
}

int calculateGlobal(unsigned char query[], int queryLength, unsigned char ** db, int dbLength,
                    int dbSeqLengths[], int gapOpen, int gapExt, int * scoreMatrix,
                    int alphabetLength, SwimdSearchResult results[], const int mode) {
    int prevHs[queryLength];
    int prevEs[queryLength];

    const int LOWER_SCORE_BOUND = INT_MIN + gapExt;

    for (int seqIdx = 0; seqIdx < dbLength; seqIdx++) {
        // Initialize all values to 0
        for (int r = 0; r < queryLength; r++) {
            // Query has fixed start and end if not OV
            prevHs[r] = mode == SWIMD_MODE_OV ? 0 : -1 * gapOpen - r * gapExt;
            prevEs[r] = LOWER_SCORE_BOUND;
        }

        int maxH = INT_MIN;
        int endLocationTarget = 0;
        int endLocationQuery = 0;

        int H = INT_MIN;
        int targetLength = dbSeqLengths[seqIdx];
        for (int c = 0; c < targetLength; c++) {
            int uF, uH, ulH;
            uF = LOWER_SCORE_BOUND;
            if (mode == SWIMD_MODE_NW) { // Database sequence has fixed start and end only in NW
                uH = -1 * gapOpen - c * gapExt;
                ulH = uH + gapExt;
            } else {
                uH = ulH = 0;
            }
            if (c == 0)
                ulH = 0;

            for (int r = 0; r < queryLength; r++) {
                int E = max(prevHs[r] - gapOpen, prevEs[r] - gapExt);
                int F = max(uH - gapOpen, uF - gapExt);
                int score = scoreMatrix[query[r] * alphabetLength + db[seqIdx][c]];
                H = max(E, max(F, ulH+score));

                if (mode == SWIMD_MODE_OV && c == targetLength - 1) {
                    if (H > maxH) {
                        maxH = H;
                        endLocationQuery = r;
                        endLocationTarget = c;
                    }
                }

                uF = F;
                uH = H;
                ulH = prevHs[r];

                prevHs[r] = H;
                prevEs[r] = E;
            }

            if (H > maxH) {
                maxH = H;
                endLocationTarget = c;
                endLocationQuery = queryLength - 1;
            }
        }

        if (mode == SWIMD_MODE_NW) {
            results[seqIdx].score = H;
            results[seqIdx].endLocationTarget = targetLength - 1;
            results[seqIdx].endLocationQuery = queryLength - 1;
        } else if (mode == SWIMD_MODE_OV || mode == SWIMD_MODE_HW) {
            results[seqIdx].score = maxH;
            results[seqIdx].endLocationTarget = endLocationTarget;
            results[seqIdx].endLocationQuery = endLocationQuery;
        } else return 1;
    }

    return 0;
}

void printInts(int a[], int aLength) {
    for (int i = 0; i < aLength; i++)
        printf("%d ", a[i]);
    printf("\n");
}

int maximumScore(SwimdSearchResult results[], int resultsLength) {
    int maximum = 0;
    for (int i = 0; i < resultsLength; i++)
        if (results[i].score > maximum)
            maximum = results[i].score;
    return maximum;
}
<|endoftext|>


<commit_before>/*******************************************************************************
Copyright (c) 2019, Jan Koester jan.koester@gmx.net
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
	* Redistributions of source code must retain the above copyright
	  notice, this list of conditions and the following disclaimer.
	* Redistributions in binary form must reproduce the above copyright
	  notice, this list of conditions and the following disclaimer in the
	  documentation and/or other materials provided with the distribution.
	* Neither the name of the <organization> nor the
	  names of its contributors may be used to endorse or promote products
	  derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/

#include <systempp/sysinfo.h>
#include <systempp/sysconsole.h>

#include <config.h>

#include "connections.h"
#include "eventapi.h"
#include "threadpool.h"
#include "exception.h"

#include "event.h"

bool libhttppp::Event::_Run=true;
bool libhttppp::Event::_Restart=false;

libhttppp::Event::Event(libsystempp::ServerSocket* serversocket) : EVENT(serversocket){
//     libhttppp::CtrlHandler::initCtrlHandler();
}

libhttppp::Event::~Event(){
}

libhttppp::EventApi::~EventApi(){
}

void libhttppp::Event::runEventloop(){
        libsystempp::CpuInfo cpuinfo;
        size_t thrs = cpuinfo.getCores();
        initEventHandler();
MAINWORKERLOOP:
        ThreadPool thpool;
        for (size_t i = 0; i < thrs; i++) {
            libsystempp::Thread *cthread=thpool.addThread();
            try{
                cthread->Create(WorkerThread, (void*)this);
            }catch(HTTPException &e){
                throw e;
            }
            for (libsystempp::Thread *curth = thpool.getfirstThread(); curth; curth = curth->nextThread) {
                curth->Join();
            }
        }
        if(libhttppp::Event::_Restart){
            libhttppp::Event::_Restart=false;
            goto MAINWORKERLOOP;
        }
}

void * libhttppp::Event::WorkerThread(void* wrkevent){
    Event *eventptr=((Event*)wrkevent);
    HTTPException excep;
    while (libhttppp::Event::_Run) {
        try {
            for (int i = 0; i < eventptr->waitEventHandler(); ++i) {
                int state=eventptr->StatusEventHandler(i);

                if(state==EventHandlerStatus::EVNOTREADY)
                    eventptr->ConnectEventHandler(i);

                if(eventptr->LockConnection(i)==LockState::LOCKED){
                    try{
                        switch(state){
                            case EventHandlerStatus::EVIN:
                                eventptr->ReadEventHandler(i);
                                break;
                            case EventHandlerStatus::EVOUT:
                                eventptr->WriteEventHandler(i);
                                break;
                            default:
                                throw excep[HTTPException::Error] << "no action try to close";
                                break;
                        }
                        eventptr->UnlockConnection(i);
                    }catch(HTTPException &e){
                        eventptr->CloseEventHandler(i);
                        if(e.getErrorType()==HTTPException::Critical){
                            eventptr->UnlockConnection(i);
                            throw e;
                        }
                        libsystempp::Console[SYSOUT] << e.what()
                            << libsystempp::Console[SYSOUT].endl;
                        eventptr->UnlockConnection(i);
                    }
                }
            }
        }catch(HTTPException &e){
            switch(e.getErrorType()){
                case HTTPException::Critical:
                    throw e;
                    break;
                default:
                    libsystempp::Console[SYSOUT] << e.what()
                        << libsystempp::Console[SYSOUT].endl;
            }
        }
    }
    return NULL;
}
<commit_msg>removed not more needed os folder<commit_after>/*******************************************************************************
Copyright (c) 2019, Jan Koester jan.koester@gmx.net
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
	* Redistributions of source code must retain the above copyright
	  notice, this list of conditions and the following disclaimer.
	* Redistributions in binary form must reproduce the above copyright
	  notice, this list of conditions and the following disclaimer in the
	  documentation and/or other materials provided with the distribution.
	* Neither the name of the <organization> nor the
	  names of its contributors may be used to endorse or promote products
	  derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/

#include <systempp/sysinfo.h>
#include <systempp/sysconsole.h>

#include "config.h"

#include "connections.h"
#include "eventapi.h"
#include "threadpool.h"
#include "exception.h"

#include "event.h"

bool libhttppp::Event::_Run=true;
bool libhttppp::Event::_Restart=false;

libhttppp::Event::Event(libsystempp::ServerSocket* serversocket) : EVENT(serversocket){
//     libhttppp::CtrlHandler::initCtrlHandler();
}

libhttppp::Event::~Event(){
}

libhttppp::EventApi::~EventApi(){
}

void libhttppp::Event::runEventloop(){
        libsystempp::CpuInfo cpuinfo;
        size_t thrs = cpuinfo.getCores();
        initEventHandler();
MAINWORKERLOOP:
        ThreadPool thpool;
        for (size_t i = 0; i < thrs; i++) {
            libsystempp::Thread *cthread=thpool.addThread();
            try{
                cthread->Create(WorkerThread, (void*)this);
            }catch(HTTPException &e){
                throw e;
            }
            for (libsystempp::Thread *curth = thpool.getfirstThread(); curth; curth = curth->nextThread) {
                curth->Join();
            }
        }
        if(libhttppp::Event::_Restart){
            libhttppp::Event::_Restart=false;
            goto MAINWORKERLOOP;
        }
}

void * libhttppp::Event::WorkerThread(void* wrkevent){
    Event *eventptr=((Event*)wrkevent);
    HTTPException excep;
    while (libhttppp::Event::_Run) {
        try {
            for (int i = 0; i < eventptr->waitEventHandler(); ++i) {
                int state=eventptr->StatusEventHandler(i);

                if(state==EventHandlerStatus::EVNOTREADY)
                    eventptr->ConnectEventHandler(i);

                if(eventptr->LockConnection(i)==LockState::LOCKED){
                    try{
                        switch(state){
                            case EventHandlerStatus::EVIN:
                                eventptr->ReadEventHandler(i);
                                break;
                            case EventHandlerStatus::EVOUT:
                                eventptr->WriteEventHandler(i);
                                break;
                            default:
                                throw excep[HTTPException::Error] << "no action try to close";
                                break;
                        }
                        eventptr->UnlockConnection(i);
                    }catch(HTTPException &e){
                        eventptr->CloseEventHandler(i);
                        if(e.getErrorType()==HTTPException::Critical){
                            eventptr->UnlockConnection(i);
                            throw e;
                        }
                        libsystempp::Console[SYSOUT] << e.what()
                            << libsystempp::Console[SYSOUT].endl;
                        eventptr->UnlockConnection(i);
                    }
                }
            }
        }catch(HTTPException &e){
            switch(e.getErrorType()){
                case HTTPException::Critical:
                    throw e;
                    break;
                default:
                    libsystempp::Console[SYSOUT] << e.what()
                        << libsystempp::Console[SYSOUT].endl;
            }
        }
    }
    return NULL;
}
<|endoftext|>


<commit_before>/*!
@file

@copyright Edouard Alligand and Joel Falcou 2015-2017
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
#ifndef BOOST_BRIGAND_TYPES_INHERIT_LINEARLY_HPP
#define BOOST_BRIGAND_TYPES_INHERIT_LINEARLY_HPP

#include <brigand/algorithms/fold.hpp>
#include <brigand/types/empty_base.hpp>

namespace brigand
{
  namespace lazy
  {
    template< typename Types
      , typename Node
      , typename Root = brigand::empty_base
    >
      struct inherit_linearly;
  template< typename Types
      , template<typename...> class Node, typename...Ts
      , typename Root
    >
  struct inherit_linearly<Types,Node<Ts...>,Root>
    {
      // TODO: change after lazy-fication
      using type = brigand::fold<Types,Root,bind<Node,Ts...>>;
    };
  }

  template< typename Types
            , typename Node
            , typename Root = brigand::empty_base
            >
  using inherit_linearly = typename lazy::inherit_linearly<Types,Node,Root>::type;
}
#endif
<commit_msg>Delete inherit_linearly.hpp<commit_after><|endoftext|>


<commit_before>#include "graph.hpp"

void
align_sequence (DnaString & my_sequence,
                boost::dynamic_bitset<> & qual,
                TGraph const & graph,
                std::vector<VertexLabels> & vertex_vector,
                String<TVertexDescriptor> & order,
                std::vector<ExactBacktracker> & backtracker,
                std::vector<ExactBacktracker> & reverse_backtracker,
                boost::unordered_set<TVertexDescriptor> const & free_nodes,
                std::vector<TVertexDescriptor> & matching_vertices,
                std::vector<TVertexDescriptor> & reverse_matching_vertices
               )
{
  initializeExactScoreMatrixAndBacktracker(length(my_sequence), length(order), backtracker);
  reverse_backtracker = backtracker;

  alignToGraphExact (my_sequence,
                     order,
                     graph,
                     matching_vertices,
                     vertex_vector,
                     backtracker,
                     free_nodes,
                     qual
                    );

  reverseComplement(my_sequence);

  boost::dynamic_bitset<> qual_reversed(qual.size());
  std::size_t qual_size = qual.size();
  for (unsigned pos = 0 ; pos < qual_size ; ++pos)
  {
    if (qual.test(pos))
    {
      qual_reversed[qual_size-pos-1] = 1;
    }
  }

  alignToGraphExact (my_sequence,
                     order,
                     graph,
                     reverse_matching_vertices,
                     vertex_vector,
                     reverse_backtracker,
                     free_nodes,
                     qual
                    );

  reverseComplement(my_sequence);
}

boost::dynamic_bitset<>
align_sequence_kmer (String<Dna> & my_sequence,
                     String<char> & qual,
                     unsigned const & id_numbers,
                     TKmerMap & kmer_map,
                     std::vector<VertexLabels> & vertex_vector,
                     int const & kmer_size,
                     int const & min_kmers
                    )
{
  unsigned best_kmer_index = find_best_kmer(qual, kmer_size);
  boost::dynamic_bitset<> matched_ids =
   align_kmer_to_graph (my_sequence,
                        id_numbers,
                        kmer_map,
                        vertex_vector,
                        best_kmer_index,
                        kmer_size,
                        min_kmers
                       );

  if (matched_ids.find_first() != matched_ids.npos)
  {
    return matched_ids;
  }

  reverseComplement(my_sequence);
  matched_ids =
   align_kmer_to_graph (my_sequence,
                        id_numbers,
                        kmer_map,
                        vertex_vector,
                        best_kmer_index,
                        kmer_size,
                        min_kmers
                       );

  reverseComplement(my_sequence);
  return matched_ids;
}

CharString myExtractTagValue(String<char> &tags)
{
  BamTagsDict tagsDict(tags);
  unsigned tagIdx = 0;
  if (!findTagKey(tagIdx, tagsDict, "RG"))
  {
    return "";
  }

  CharString read_group;

  if (!extractTagValue(read_group, tagsDict, tagIdx))
  {
    std::cerr << "Not a valid string at pos " << tagIdx << std::endl;
    return "";
  }

  return read_group;
}

void
createGenericGraph(callOptions & CO,
                   TGraph & graph,
                   std::vector<VertexLabels> & vertex_vector,
                   std::vector<std::string> & ids,
                   boost::unordered_map< std::pair<TVertexDescriptor, TVertexDescriptor>, boost::dynamic_bitset<> > & edge_ids,
                   boost::unordered_set<TVertexDescriptor> & free_nodes,
                   String<TVertexDescriptor> & order
                  )
{
  int number_of_exons = CO.number_of_exons;

  std::stringstream base_path;
  base_path << gyper_SOURCE_DIRECTORY << "/data/haplotypes/hla/references/" << CO.gene << "/";

  TVertexDescriptor begin_vertex;

  {
    std::string p3_string = base_path.str();
    p3_string.append("p3.fa");

    if (CO.verbose)
    {
      std::cout << "Adding utr    " << p3_string << std::endl;
    }

    const char* alignment_file_p3 = p3_string.c_str();
    graph = createGraph(alignment_file_p3, vertex_vector, ids, begin_vertex);
  }

  TVertexDescriptor new_begin_vertex;

  std::string tmp_string;
  std::string extension = ".fa";

  // First exon
  {
    tmp_string = base_path.str();
    std::string exon = "e";
    std::string feature_number = std::to_string(number_of_exons);
    exon.append(feature_number);
    exon.append(extension);
    tmp_string.append(exon);

    if (CO.verbose)
    {
      std::cout << "Adding exon   " << tmp_string << std::endl;
    }

    const char* alignment_file = tmp_string.c_str();
    free_nodes.insert(begin_vertex);
    extendGraph(graph, alignment_file, vertex_vector, edge_ids, new_begin_vertex, begin_vertex);

    --number_of_exons;
  }

  while (number_of_exons >= 1)
  {
    // Intron
    {
      tmp_string = base_path.str();
      std::string intron = "i";
      std::string feature_number = std::to_string(number_of_exons);
      intron.append(feature_number);
      intron.append(extension);
      tmp_string.append(intron);

      if (CO.verbose)
      {
        std::cout << "Adding intron " << tmp_string << std::endl;
      }

      const char* alignment_file = tmp_string.c_str();
      free_nodes.insert(begin_vertex);
      extendGraph(graph, alignment_file, vertex_vector, new_begin_vertex, begin_vertex);
    }

    // Exon
    {
      tmp_string = base_path.str();
      std::string exon = "e";
      std::string feature_number = std::to_string(number_of_exons);
      exon.append(feature_number);
      exon.append(extension);
      tmp_string.append(exon);

      if (CO.verbose)
      {
        std::cout << "Adding exon   " << tmp_string << std::endl;
      }

      const char* alignment_file = tmp_string.c_str();
      free_nodes.insert(begin_vertex);
      extendGraph(graph, alignment_file, vertex_vector, edge_ids, new_begin_vertex, begin_vertex);
    }

    --number_of_exons;
  }

  {
    // Final UTR
    tmp_string = base_path.str();
    std::string utr = "5p";
    utr.append(extension);
    tmp_string.append(utr);

    if (CO.verbose)
    {
      std::cout << "Adding utr    " << tmp_string << std::endl;
    }

    const char* alignment_file = tmp_string.c_str();
    free_nodes.insert(begin_vertex);
    extendGraph(graph, alignment_file, vertex_vector, new_begin_vertex, begin_vertex);
  }

  topologicalSort(order, graph);
}

void
create_exon_2_and_3_graph(callOptions & CO,
                          TGraph & graph,
                          std::vector<VertexLabels> & vertex_vector,
                          std::vector<std::string> & ids,
                          boost::unordered_map< std::pair<TVertexDescriptor, TVertexDescriptor>, boost::dynamic_bitset<> > & edge_ids,
                          boost::unordered_set<TVertexDescriptor> & free_nodes,
                          String<TVertexDescriptor> & order
                         )
{
  int number_of_exons = CO.number_of_exons;

  std::stringstream base_path;
  base_path << gyper_SOURCE_DIRECTORY << "/data/haplotypes/hla/references/" << CO.gene << "/";

  TVertexDescriptor begin_vertex;

  {
    std::string p3_string = base_path.str();
    p3_string.append("p3.fa");

    if (CO.verbose)
    {
      std::cout << "Adding utr    " << p3_string << std::endl;
    }

    const char* alignment_file_p3 = p3_string.c_str();
    graph = createGraph(alignment_file_p3, vertex_vector, ids, begin_vertex);
  }

  TVertexDescriptor new_begin_vertex;

  std::string tmp_string;
  std::string extension = ".fa";

  // First exon
  {
    tmp_string = base_path.str();
    std::string exon = "e";
    std::string feature_number = std::to_string(number_of_exons);
    exon.append(feature_number);
    exon.append(extension);
    tmp_string.append(exon);

    if (CO.verbose)
    {
      std::cout << "Adding exon   " << tmp_string << std::endl;
    }

    const char* alignment_file = tmp_string.c_str();
    free_nodes.insert(begin_vertex);
    if (number_of_exons == 2 || number_of_exons == 3)
    {
      extendGraph(graph, alignment_file, vertex_vector, edge_ids, new_begin_vertex, begin_vertex);
    }
    else
    {
      extendGraph(graph, alignment_file, vertex_vector, new_begin_vertex, begin_vertex);
    }

    --number_of_exons;
  }

  while (number_of_exons >= 1)
  {
    // Intron
    {
      tmp_string = base_path.str();
      std::string intron = "i";
      std::string feature_number = std::to_string(number_of_exons);
      intron.append(feature_number);
      intron.append(extension);
      tmp_string.append(intron);

      if (CO.verbose)
      {
        std::cout << "Adding intron " << tmp_string << std::endl;
      }

      const char* alignment_file = tmp_string.c_str();
      free_nodes.insert(begin_vertex);
      extendGraph(graph, alignment_file, vertex_vector, new_begin_vertex, begin_vertex);
    }

    // Exon
    {
      tmp_string = base_path.str();
      std::string exon = "e";
      std::string feature_number = std::to_string(number_of_exons);
      exon.append(feature_number);
      exon.append(extension);
      tmp_string.append(exon);

      if (CO.verbose)
      {
        std::cout << "Adding exon   " << tmp_string << std::endl;
      }

      const char* alignment_file = tmp_string.c_str();
      free_nodes.insert(begin_vertex);
      extendGraph(graph, alignment_file, vertex_vector, edge_ids, new_begin_vertex, begin_vertex);
    }

    --number_of_exons;
  }

  {
    // Final UTR
    tmp_string = base_path.str();
    std::string utr = "5p";
    utr.append(extension);
    tmp_string.append(utr);

    if (CO.verbose)
    {
      std::cout << "Adding utr    " << tmp_string << std::endl;
    }

    const char* alignment_file = tmp_string.c_str();
    free_nodes.insert(begin_vertex);
    extendGraph(graph, alignment_file, vertex_vector, new_begin_vertex, begin_vertex);
  }

  topologicalSort(order, graph);
}
<commit_msg>some additional prints added in verbose mode<commit_after>#include "graph.hpp"

void
align_sequence (DnaString & my_sequence,
                boost::dynamic_bitset<> & qual,
                TGraph const & graph,
                std::vector<VertexLabels> & vertex_vector,
                String<TVertexDescriptor> & order,
                std::vector<ExactBacktracker> & backtracker,
                std::vector<ExactBacktracker> & reverse_backtracker,
                boost::unordered_set<TVertexDescriptor> const & free_nodes,
                std::vector<TVertexDescriptor> & matching_vertices,
                std::vector<TVertexDescriptor> & reverse_matching_vertices
               )
{
  initializeExactScoreMatrixAndBacktracker(length(my_sequence), length(order), backtracker);
  reverse_backtracker = backtracker;

  alignToGraphExact (my_sequence,
                     order,
                     graph,
                     matching_vertices,
                     vertex_vector,
                     backtracker,
                     free_nodes,
                     qual
                    );

  reverseComplement(my_sequence);

  boost::dynamic_bitset<> qual_reversed(qual.size());
  std::size_t qual_size = qual.size();
  for (unsigned pos = 0 ; pos < qual_size ; ++pos)
  {
    if (qual.test(pos))
    {
      qual_reversed[qual_size-pos-1] = 1;
    }
  }

  alignToGraphExact (my_sequence,
                     order,
                     graph,
                     reverse_matching_vertices,
                     vertex_vector,
                     reverse_backtracker,
                     free_nodes,
                     qual
                    );

  reverseComplement(my_sequence);
}

boost::dynamic_bitset<>
align_sequence_kmer (String<Dna> & my_sequence,
                     String<char> & qual,
                     unsigned const & id_numbers,
                     TKmerMap & kmer_map,
                     std::vector<VertexLabels> & vertex_vector,
                     int const & kmer_size,
                     int const & min_kmers
                    )
{
  unsigned best_kmer_index = find_best_kmer(qual, kmer_size);
  boost::dynamic_bitset<> matched_ids =
   align_kmer_to_graph (my_sequence,
                        id_numbers,
                        kmer_map,
                        vertex_vector,
                        best_kmer_index,
                        kmer_size,
                        min_kmers
                       );

  if (matched_ids.find_first() != matched_ids.npos)
  {
    return matched_ids;
  }

  reverseComplement(my_sequence);
  matched_ids =
   align_kmer_to_graph (my_sequence,
                        id_numbers,
                        kmer_map,
                        vertex_vector,
                        best_kmer_index,
                        kmer_size,
                        min_kmers
                       );

  reverseComplement(my_sequence);
  return matched_ids;
}

CharString myExtractTagValue(String<char> &tags)
{
  BamTagsDict tagsDict(tags);
  unsigned tagIdx = 0;
  if (!findTagKey(tagIdx, tagsDict, "RG"))
  {
    return "";
  }

  CharString read_group;

  if (!extractTagValue(read_group, tagsDict, tagIdx))
  {
    std::cerr << "Not a valid string at pos " << tagIdx << std::endl;
    return "";
  }

  return read_group;
}

void
createGenericGraph(callOptions & CO,
                   TGraph & graph,
                   std::vector<VertexLabels> & vertex_vector,
                   std::vector<std::string> & ids,
                   boost::unordered_map< std::pair<TVertexDescriptor, TVertexDescriptor>, boost::dynamic_bitset<> > & edge_ids,
                   boost::unordered_set<TVertexDescriptor> & free_nodes,
                   String<TVertexDescriptor> & order
                  )
{
  int number_of_exons = CO.number_of_exons;

  std::stringstream base_path;
  base_path << gyper_SOURCE_DIRECTORY << "/data/haplotypes/hla/references/" << CO.gene << "/";

  TVertexDescriptor begin_vertex;

  {
    std::string p3_string = base_path.str();
    p3_string.append("p3.fa");

    if (CO.verbose)
    {
      std::cout << "Adding utr    " << p3_string << std::endl;
    }

    const char* alignment_file_p3 = p3_string.c_str();
    graph = createGraph(alignment_file_p3, vertex_vector, ids, begin_vertex);
  }

  TVertexDescriptor new_begin_vertex;

  std::string tmp_string;
  std::string extension = ".fa";

  // First exon
  {
    tmp_string = base_path.str();
    std::string exon = "e";
    std::string feature_number = std::to_string(number_of_exons);
    exon.append(feature_number);
    exon.append(extension);
    tmp_string.append(exon);

    if (CO.verbose)
    {
      std::cout << "Adding exon   " << tmp_string << std::endl;
    }

    const char* alignment_file = tmp_string.c_str();
    free_nodes.insert(begin_vertex);
    extendGraph(graph, alignment_file, vertex_vector, edge_ids, new_begin_vertex, begin_vertex);

    --number_of_exons;
  }

  while (number_of_exons >= 1)
  {
    // Intron
    {
      tmp_string = base_path.str();
      std::string intron = "i";
      std::string feature_number = std::to_string(number_of_exons);
      intron.append(feature_number);
      intron.append(extension);
      tmp_string.append(intron);

      if (CO.verbose)
      {
        std::cout << "Adding intron " << tmp_string << std::endl;
      }

      const char* alignment_file = tmp_string.c_str();
      free_nodes.insert(begin_vertex);
      extendGraph(graph, alignment_file, vertex_vector, new_begin_vertex, begin_vertex);
    }

    // Exon
    {
      tmp_string = base_path.str();
      std::string exon = "e";
      std::string feature_number = std::to_string(number_of_exons);
      exon.append(feature_number);
      exon.append(extension);
      tmp_string.append(exon);

      if (CO.verbose)
      {
        std::cout << "Adding exon   " << tmp_string << std::endl;
      }

      const char* alignment_file = tmp_string.c_str();
      free_nodes.insert(begin_vertex);
      extendGraph(graph, alignment_file, vertex_vector, edge_ids, new_begin_vertex, begin_vertex);
    }

    --number_of_exons;
  }

  {
    // Final UTR
    tmp_string = base_path.str();
    std::string utr = "5p";
    utr.append(extension);
    tmp_string.append(utr);

    if (CO.verbose)
    {
      std::cout << "Adding utr    " << tmp_string << std::endl;
    }

    const char* alignment_file = tmp_string.c_str();
    free_nodes.insert(begin_vertex);
    extendGraph(graph, alignment_file, vertex_vector, new_begin_vertex, begin_vertex);
  }

  topologicalSort(order, graph);
}

void
create_exon_2_and_3_graph(callOptions & CO,
                          TGraph & graph,
                          std::vector<VertexLabels> & vertex_vector,
                          std::vector<std::string> & ids,
                          boost::unordered_map< std::pair<TVertexDescriptor, TVertexDescriptor>, boost::dynamic_bitset<> > & edge_ids,
                          boost::unordered_set<TVertexDescriptor> & free_nodes,
                          String<TVertexDescriptor> & order
                         )
{
  int number_of_exons = CO.number_of_exons;

  std::stringstream base_path;
  base_path << gyper_SOURCE_DIRECTORY << "/data/haplotypes/hla/references/" << CO.gene << "/";

  TVertexDescriptor begin_vertex;

  {
    std::string p3_string = base_path.str();
    p3_string.append("p3.fa");

    if (CO.verbose)
    {
      std::cout << "Adding utr    " << p3_string << std::endl;
    }

    const char* alignment_file_p3 = p3_string.c_str();
    graph = createGraph(alignment_file_p3, vertex_vector, ids, begin_vertex);
  }

  TVertexDescriptor new_begin_vertex;

  std::string tmp_string;
  std::string extension = ".fa";

  // First exon
  {
    tmp_string = base_path.str();
    std::string exon = "e";
    std::string feature_number = std::to_string(number_of_exons);
    exon.append(feature_number);
    exon.append(extension);
    tmp_string.append(exon);

    // if (CO.verbose)
    // {
    //   std::cout << "Adding exon   " << tmp_string << std::endl;
    // }

    const char* alignment_file = tmp_string.c_str();
    free_nodes.insert(begin_vertex);
    if (number_of_exons == 2 || number_of_exons == 3)
    {
      if (CO.verbose)
      {
        std::cout << "Adding exon   " << tmp_string << std::endl;
      }

      extendGraph(graph, alignment_file, vertex_vector, edge_ids, new_begin_vertex, begin_vertex);
    }
    else
    {
      if (CO.verbose)
      {
        std::cout << "Adding exon   " << tmp_string << " as intron" << std::endl;
      }

      extendGraph(graph, alignment_file, vertex_vector, new_begin_vertex, begin_vertex);
    }

    --number_of_exons;
  }

  while (number_of_exons >= 1)
  {
    // Intron
    {
      tmp_string = base_path.str();
      std::string intron = "i";
      std::string feature_number = std::to_string(number_of_exons);
      intron.append(feature_number);
      intron.append(extension);
      tmp_string.append(intron);

      if (CO.verbose)
      {
        std::cout << "Adding intron " << tmp_string << std::endl;
      }

      const char* alignment_file = tmp_string.c_str();
      free_nodes.insert(begin_vertex);
      extendGraph(graph, alignment_file, vertex_vector, new_begin_vertex, begin_vertex);
    }

    // Exon
    {
      tmp_string = base_path.str();
      std::string exon = "e";
      std::string feature_number = std::to_string(number_of_exons);
      exon.append(feature_number);
      exon.append(extension);
      tmp_string.append(exon);

      // if (CO.verbose)
      // {
      //   std::cout << "Adding exon   " << tmp_string << std::endl;
      // }

      const char* alignment_file = tmp_string.c_str();
      free_nodes.insert(begin_vertex);
      if (number_of_exons == 2 || number_of_exons == 3)
      {
        if (CO.verbose)
        {
          std::cout << "Adding exon   " << tmp_string << std::endl;
        }

        extendGraph(graph, alignment_file, vertex_vector, edge_ids, new_begin_vertex, begin_vertex);
      }
      else
      {
        if (CO.verbose)
        {
          std::cout << "Adding exon   " << tmp_string << " as intron" << std::endl;
        }

        extendGraph(graph, alignment_file, vertex_vector, new_begin_vertex, begin_vertex);
      }
    }

    --number_of_exons;
  }

  {
    // Final UTR
    tmp_string = base_path.str();
    std::string utr = "5p";
    utr.append(extension);
    tmp_string.append(utr);

    if (CO.verbose)
    {
      std::cout << "Adding utr    " << tmp_string << std::endl;
    }

    const char* alignment_file = tmp_string.c_str();
    free_nodes.insert(begin_vertex);
    extendGraph(graph, alignment_file, vertex_vector, new_begin_vertex, begin_vertex);
  }

  topologicalSort(order, graph);
}
<|endoftext|>


<commit_before>// if s1 starts with s2 returns true, else false
// len is the length of s1
// s2 should be null-terminated
static bool starts_with(const char *s1, int len, const char *s2)
{
	int n = 0;
	while (*s2 && n < len) {
		if (*s1++ != *s2++)
			return false;
		n++;
	}
	return *s2 == 0;
}

// convert escape sequence to event, and return consumed bytes on success (failure == 0)
static int parse_escape_seq(struct tb_event *event, const char *buf, int len)
{
	if (len >= 6 && starts_with(buf, len, "\033[M")) {

		switch (buf[3] & 3) {
		case 0:
			if (buf[3] == 0x60)
				event->key = TB_KEY_MOUSE_WHEEL_UP;
			else
				event->key = TB_KEY_MOUSE_LEFT;
			break;
		case 1:
			if (buf[3] == 0x61)
				event->key = TB_KEY_MOUSE_WHEEL_DOWN;
			else
				event->key = TB_KEY_MOUSE_MIDDLE;
			break;
		case 2:
			event->key = TB_KEY_MOUSE_RIGHT;
			break;
		case 3:
			event->key = TB_KEY_MOUSE_RELEASE;
			break;
		default:
			return -6;
		}
		event->type = TB_EVENT_MOUSE; // TB_EVENT_KEY by default

		// the coord is 1,1 for upper left
		event->x = buf[4] - 1 - 32;
		event->y = buf[5] - 1 - 32;

		return 6;
	}

	// it's pretty simple here, find 'starts_with' match and return
	// success, else return failure
	int i;
	for (i = 0; keys[i]; i++) {
		if (starts_with(buf, len, keys[i])) {
			event->ch = 0;
			event->key = 0xFFFF-i;
			return strlen(keys[i]);
		}
	}
	return 0;
}

static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf, int inputmode)
{
	const char *buf = inbuf->buf;
	const int len = inbuf->len;
	if (len == 0)
		return false;

	if (buf[0] == '\033') {
		int n = parse_escape_seq(event, buf, len);
		if (n != 0) {
			bool success = true;
			if (n < 0) {
				success = false;
				n = -n;
			}
			bytebuffer_truncate(inbuf, n);
			return success;
		} else {
			// it's not escape sequence, then it's ALT or ESC,
			// check inputmode
			if (inputmode&TB_INPUT_ESC) {
				// if we're in escape mode, fill ESC event, pop
				// buffer, return success
				event->ch = 0;
				event->key = TB_KEY_ESC;
				event->mod = 0;
				bytebuffer_truncate(inbuf, 1);
				return true;
			} else if (inputmode&TB_INPUT_ALT) {
				// if we're in alt mode, set ALT modifier to
				// event and redo parsing
				event->mod = TB_MOD_ALT;
				bytebuffer_truncate(inbuf, 1);
				return extract_event(event, inbuf, inputmode);
			}
			assert(!"never got here");
		}
	}

	// if we're here, this is not an escape sequence and not an alt sequence
	// so, it's a FUNCTIONAL KEY or a UNICODE character

	// first of all check if it's a functional key
	if ((unsigned char)buf[0] <= TB_KEY_SPACE ||
	    (unsigned char)buf[0] == TB_KEY_BACKSPACE2)
	{
		// fill event, pop buffer, return success */
		event->ch = 0;
		event->key = (uint16_t)buf[0];
		bytebuffer_truncate(inbuf, 1);
		return true;
	}

	// feh... we got utf8 here

	// check if there is all bytes
	if (len >= tb_utf8_char_length(buf[0])) {
		/* everything ok, fill event, pop buffer, return success */
		tb_utf8_char_to_unicode(&event->ch, buf);
		event->key = 0;
		bytebuffer_truncate(inbuf, tb_utf8_char_length(buf[0]));
		return true;
	}

	// event isn't recognized, perhaps there is not enough bytes in utf8
	// sequence
	return false;
}
<commit_msg>Use uint8_t as mouse coordinate type in input parsing.<commit_after>// if s1 starts with s2 returns true, else false
// len is the length of s1
// s2 should be null-terminated
static bool starts_with(const char *s1, int len, const char *s2)
{
	int n = 0;
	while (*s2 && n < len) {
		if (*s1++ != *s2++)
			return false;
		n++;
	}
	return *s2 == 0;
}

// convert escape sequence to event, and return consumed bytes on success (failure == 0)
static int parse_escape_seq(struct tb_event *event, const char *buf, int len)
{
	if (len >= 6 && starts_with(buf, len, "\033[M")) {

		switch (buf[3] & 3) {
		case 0:
			if (buf[3] == 0x60)
				event->key = TB_KEY_MOUSE_WHEEL_UP;
			else
				event->key = TB_KEY_MOUSE_LEFT;
			break;
		case 1:
			if (buf[3] == 0x61)
				event->key = TB_KEY_MOUSE_WHEEL_DOWN;
			else
				event->key = TB_KEY_MOUSE_MIDDLE;
			break;
		case 2:
			event->key = TB_KEY_MOUSE_RIGHT;
			break;
		case 3:
			event->key = TB_KEY_MOUSE_RELEASE;
			break;
		default:
			return -6;
		}
		event->type = TB_EVENT_MOUSE; // TB_EVENT_KEY by default

		// the coord is 1,1 for upper left
		event->x = (uint8_t)buf[4] - 1 - 32;
		event->y = (uint8_t)buf[5] - 1 - 32;

		return 6;
	}

	// it's pretty simple here, find 'starts_with' match and return
	// success, else return failure
	int i;
	for (i = 0; keys[i]; i++) {
		if (starts_with(buf, len, keys[i])) {
			event->ch = 0;
			event->key = 0xFFFF-i;
			return strlen(keys[i]);
		}
	}
	return 0;
}

static bool extract_event(struct tb_event *event, struct bytebuffer *inbuf, int inputmode)
{
	const char *buf = inbuf->buf;
	const int len = inbuf->len;
	if (len == 0)
		return false;

	if (buf[0] == '\033') {
		int n = parse_escape_seq(event, buf, len);
		if (n != 0) {
			bool success = true;
			if (n < 0) {
				success = false;
				n = -n;
			}
			bytebuffer_truncate(inbuf, n);
			return success;
		} else {
			// it's not escape sequence, then it's ALT or ESC,
			// check inputmode
			if (inputmode&TB_INPUT_ESC) {
				// if we're in escape mode, fill ESC event, pop
				// buffer, return success
				event->ch = 0;
				event->key = TB_KEY_ESC;
				event->mod = 0;
				bytebuffer_truncate(inbuf, 1);
				return true;
			} else if (inputmode&TB_INPUT_ALT) {
				// if we're in alt mode, set ALT modifier to
				// event and redo parsing
				event->mod = TB_MOD_ALT;
				bytebuffer_truncate(inbuf, 1);
				return extract_event(event, inbuf, inputmode);
			}
			assert(!"never got here");
		}
	}

	// if we're here, this is not an escape sequence and not an alt sequence
	// so, it's a FUNCTIONAL KEY or a UNICODE character

	// first of all check if it's a functional key
	if ((unsigned char)buf[0] <= TB_KEY_SPACE ||
	    (unsigned char)buf[0] == TB_KEY_BACKSPACE2)
	{
		// fill event, pop buffer, return success */
		event->ch = 0;
		event->key = (uint16_t)buf[0];
		bytebuffer_truncate(inbuf, 1);
		return true;
	}

	// feh... we got utf8 here

	// check if there is all bytes
	if (len >= tb_utf8_char_length(buf[0])) {
		/* everything ok, fill event, pop buffer, return success */
		tb_utf8_char_to_unicode(&event->ch, buf);
		event->key = 0;
		bytebuffer_truncate(inbuf, tb_utf8_char_length(buf[0]));
		return true;
	}

	// event isn't recognized, perhaps there is not enough bytes in utf8
	// sequence
	return false;
}
<|endoftext|>


<commit_before>/**
 * Copyright (C) 2012 by INdT
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * @author Rodrigo Goncalves de Oliveira <rodrigo.goncalves@openbossa.org>
 * @author Roger Felipe Zanoni da Silva <roger.zanoni@openbossa.org>
 */

#include <QDebug>
#include <QPainter>
#include <QQmlProperty>

#include "layer.h"

//! Class constructor
Layer::Layer(QuasiDeclarativeItem *parent)
    : QuasiPaintedItem(parent)
      , m_drawType(Quasi::TiledDrawType)
      , m_factor(1.0)
      , m_type(Quasi::InfiniteType)
      , m_direction((Quasi::LayerDirection)-1) // Backward
      , m_areaToDraw(2.0)
      , m_columnOffset(0)
      , m_drawingMirrored(false)
      , m_shouldMirror(false)
      , m_tileWidth(32)
      , m_tileHeight(32)
      , m_latestPoint(0)
{
#if QT_VERSION >= 0x050000
    setZ(Quasi::InteractionLayerOrdering_01);
#else
    setZValue(Quasi::InteractionLayerOrdering_01);
#endif

    // this activates the item layered mode
    QQmlProperty(this, "layer.enabled").write(true);
}

//! Class destructor
Layer::~Layer()
{
    m_pixmaps.clear();
    m_mirroredTiles.clear();
}

//! Stores the source path for the image
/*!
 * \param source the image path
 */
void Layer::setSource(const QString &source)
{
    if (m_source != source)
        m_source = source;
}

//! Gets the image source path
/*!
 * \return the source path for the image
 */
QString Layer::source() const
{
    return m_source;
}

//! Stores the layer type
/*!
 * \param drawType can be Tiled (default) or Plane
 */
void Layer::setDrawType(Quasi::DrawType drawType)
{
    if (m_drawType != drawType)
        m_drawType = drawType;
}

//! Gets the layer type
/*!
 * \return Tiled or Plane according the layer draw type
 */
Quasi::DrawType Layer::drawType() const
{
    return m_drawType;
}

void Layer::setDirection(const Quasi::LayerDirection &direction)
{
    if (direction != m_direction){
        if (direction == Quasi::BackwardDirection)
            m_direction = (Quasi::LayerDirection)-1; // insane black magic
        else
            m_direction = direction;

        emit directionChanged();
    }
}

//! Stores the layer update factor
/*!
 * \param factor the factor value
 */
void Layer::setFactor(qreal factor)
{
    if (m_factor != factor)
        m_factor = factor;
}

//! Gets the layer update factor
/*!
 * \return layer update factor
 */
qreal Layer::factor() const
{
    return m_factor;
}

//! Stores the layer z order
/*!
 * \param order the layer z order
 */
void Layer::setOrder(Quasi::Ordering order)
{
#if QT_VERSION >= 0x050000
    if (z() != order)
        setZ(order);
#else
    if (zValue() != order)
        setZValue(order);
#endif
}

//! Gets the layer z order
/*!
 * \return layer z order
 */
Quasi::Ordering Layer::order() const
{
#if QT_VERSION >= 0x050000
    return (Quasi::Ordering)z();
#else
    return (Quasi::Ordering)zValue();
#endif
}

void Layer::setLayerType(const Quasi::LayerType &type)
{
    if (type != m_type){
        m_type = type;

        emit layerTypeChanged();
    }
}

void Layer::setTileHeight(const int &value)
{
    if (m_drawType == Quasi::PlaneDrawType)
        return;

    if (value != m_tileHeight){
        m_tileHeight = value;

        if (m_tileWidth != 0 && m_tileHeight != 0)
            emit tilesChanged();
    }
}

void Layer::setTileWidth(const int &value)
{
    if (m_drawType == Quasi::PlaneDrawType)
        return;

    if (value != m_tileWidth){
        m_tileWidth = value;

        if (m_tileWidth != 0 && m_tileHeight != 0)
            emit tilesChanged();
    }
}

//! Adds a tile on the list
/*!
 * \param pix the pixmap to append on the list
 * \return the list actual size or -1 if the layer can not accept tiled pixmaps
 */
int Layer::addTile(const QPixmap &pix)
{
    m_pixmaps.append(pix);

    return m_pixmaps.size();
}

//! Gets a tile from the list
/*!
 * \param pos the tile position on the list
 * \return the tile pixmap of position pos on the list or null, if none
 */
QPixmap Layer::getTile(int pos) const
{
    return m_pixmaps.at(pos);
}

void Layer::setDrawGrid(bool draw)
{
    if (draw != m_drawGrid)
        m_drawGrid = draw;
}

void Layer::setGridColor(const QColor &color)
{
    if (color != m_gridColor)
        m_gridColor = color;
}

//! Gets the tiles pixmap list size
/*!
 * \return the tiles pixmap list size
 */
int Layer::count() const
{
    return m_pixmaps.size();
}

void Layer::generateOffsets()
{
    bool completed = false;
    int start = 0;
    int step = m_numColumns;
    int max = m_totalColumns;
    int count = 0;
    int maxCount = step * (int)m_areaToDraw;
    bool first = true;
    Offsets::OffsetsList firstPoint;

    while (!completed) {
        Offsets::OffsetsList offsetsList;

        int tamanho;
        int fim = 0;
        bool finish = false;

        while (count < maxCount) {
            fim = (start + step) % max;

            if (fim - start > 0) {
                tamanho = step;
                count += tamanho;

                // TODO check this comparison. Is it really needed?
                if (finish || count != maxCount) {
                    offsetsList.append(Offsets(start, tamanho));

                    if (!finish)
                        start = fim;
                    finish = false;
                } else {
                    offsetsList.append(Offsets(start, tamanho));
                }
            } else {
                int oldStart = start;
                tamanho = max - start;
                count += tamanho;

                offsetsList.append(Offsets(start, tamanho));

                tamanho = step - tamanho;
                start = 0;
                count += tamanho;

                if (tamanho != 0) {
                    offsetsList.append(Offsets(0, tamanho));
                }

                if (count <= maxCount / 2) {
                    start = tamanho;
                    finish = true;
                } else
                    start = oldStart;
            }
        }

        count = 0;

        if (offsetsList == firstPoint)
            completed = true;
        else
            m_offsets.append(offsetsList);

        if (first) {
            firstPoint = offsetsList;
            first = false;
        }
    }
}

void Layer::updateTiles()
{
    if ((boundingRect().width() == 0) || (boundingRect().height() == 0))
        return;

    // TODO create enums to define image aspect, auto tile, etc...
    QPixmap pix(source()); // TODO

    if (m_drawType == Quasi::PlaneDrawType) {
        m_tileWidth = width();
        m_tileHeight = height();

        if (pix.width() % (int)width() != 0) {
            // XXX create some log system?
            qCritical() << QString("Quasi>>Image \'%1\' doesn't contains a proper size... CROPPING!").arg(source());

            int newWidth = pix.width() - (pix.width() % (int)width());
            pix = pix.copy(0, 0, newWidth, height());
        }
    }

    if (pix.width() < boundingRect().width()) {
        QPixmap temp(boundingRect().width(), boundingRect().height());
        QPainter p(&temp);
            p.drawTiledPixmap(boundingRect(), pix, QPoint(0,0));
        p.end();

        pix = temp;
    }

    QPixmap mirrored;
    if (m_type == Quasi::MirroredType){
        QImage image = pix.toImage();

        mirrored = QPixmap::fromImage(image.mirrored(true, false));
    }

    // visible tiles
    m_numColumns = boundingRect().width() / m_tileWidth;
    m_numRows = boundingRect().height() / m_tileHeight;

    // total of columns and rows
    m_totalColumns = pix.width() / m_tileWidth;
    m_totalRows = pix.height() / m_tileHeight;

    int i, j;
    for (i = 0; i < m_totalRows; i++) {
        for (j = 0; j < m_totalColumns; j++){
            QPixmap temp(m_tileWidth, m_tileHeight);

            QPainter p(&temp);
                p.setCompositionMode(QPainter::CompositionMode_Source);
                p.drawPixmap(0, 0, m_tileWidth, m_tileHeight,
                        pix, j * m_tileWidth, i * m_tileHeight, m_tileWidth, m_tileHeight);
            p.end();

            addTile(temp);

            if (m_type == Quasi::MirroredType) {
                QPainter p(&temp);
                    p.drawPixmap(0, 0, m_tileWidth, m_tileHeight,
                            mirrored, j * m_tileWidth, i * m_tileHeight, m_tileWidth, m_tileHeight);
                p.end();

                m_mirroredTiles.append(temp);
            }
        }
    }

    generateOffsets();
    drawPixmap();
}

QPixmap Layer::generatePartialPixmap(int startPoint, int size)
{
    QPixmap temp(m_tileWidth * size, boundingRect().height());

    QPainter p(&temp);
        int i, j;
        int index = 0;
        for (i = 0; i < m_numRows; i++) {
            for (j = 0; j < size; j++) {
                index = ((i * m_totalColumns) + (j + startPoint));

                // TODO improve comparison
                if (m_direction == Quasi::ForwardDirection) {
                    if (m_drawingMirrored)
                        p.drawPixmap(j * m_tileWidth, i * m_tileHeight, getTile(index));
                    else
                        p.drawPixmap(j * m_tileWidth, i * m_tileHeight, m_mirroredTiles.at(index));
                } else {
                    if (m_drawingMirrored)
                        p.drawPixmap(j * m_tileWidth, i * m_tileHeight, m_mirroredTiles.at(index));
                    else
                        p.drawPixmap(j * m_tileWidth, i * m_tileHeight, getTile(index));
                }
                // just draw a grid
                // XXX chech the possibility of drawn it only on a debug mode
                if (m_drawGrid) {
                    p.setPen(m_gridColor);
                    p.drawRect(j * m_tileWidth, i * m_tileHeight, m_tileWidth, m_tileHeight);
                }
            }
        }
    p.end();

    return temp;
}

void Layer::drawPixmap()
{
    if ((boundingRect().width() == 0) || (boundingRect().height() == 0))
        return;

    // TODO Forward
    if (m_currentImage)
        delete m_currentImage;

    m_currentImage = new QImage(boundingRect().width() * m_areaToDraw, boundingRect().height(), QImage::Format_ARGB32_Premultiplied);

    QPainter p(m_currentImage);
        int xPoint = 0;
        for (int i = 0; i < m_offsets[m_columnOffset].size(); i++) {
            Offsets offset = m_offsets[m_columnOffset].at(i);

            if (((m_type == Quasi::MirroredType) && (i != 0)
                    && (offset.point() - m_latestPoint < 0))
                    || m_shouldMirror) {
                m_drawingMirrored = !m_drawingMirrored;
                m_shouldMirror = false;
            }

            QPixmap pix = generatePartialPixmap(offset.point(), offset.size());
            p.drawPixmap(xPoint, 0, pix);

            xPoint += pix.width();
            m_latestPoint = offset.point();

            if ((m_type == Quasi::MirroredType)
                    && (i == m_offsets[m_columnOffset].size() - 1)
                    && (offset.size() < m_numColumns))
                m_shouldMirror = true;
        }

        if (m_direction == Quasi::ForwardDirection)
            m_columnOffset = (m_columnOffset - 1 < 0) ? m_offsets.size() - 1 : m_columnOffset - 1;
        else
            m_columnOffset = (m_columnOffset + 1) % m_offsets.size();
    p.end();
}
<commit_msg>Fixed initialization order in Layer class<commit_after>/**
 * Copyright (C) 2012 by INdT
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * @author Rodrigo Goncalves de Oliveira <rodrigo.goncalves@openbossa.org>
 * @author Roger Felipe Zanoni da Silva <roger.zanoni@openbossa.org>
 */

#include <QDebug>
#include <QPainter>
#include <QQmlProperty>

#include "layer.h"

//! Class constructor
Layer::Layer(QQuickItem *parent)
    : QuasiPaintedItem(parent)
      , m_direction((Quasi::LayerDirection)-1) // Backward
      , m_tileWidth(32)
      , m_tileHeight(32)
      , m_factor(1.0)
      , m_drawType(Quasi::TiledDrawType)
      , m_type(Quasi::InfiniteType)
      , m_areaToDraw(2.0)
      , m_columnOffset(0)
      , m_drawingMirrored(false)
      , m_shouldMirror(false)
      , m_latestPoint(0)
{
#if QT_VERSION >= 0x050000
    setZ(Quasi::InteractionLayerOrdering_01);
#else
    setZValue(Quasi::InteractionLayerOrdering_01);
#endif

    // this activates the item layered mode
    QQmlProperty(this, "layer.enabled").write(true);
}

//! Class destructor
Layer::~Layer()
{
    m_pixmaps.clear();
    m_mirroredTiles.clear();
}

//! Stores the source path for the image
/*!
 * \param source the image path
 */
void Layer::setSource(const QString &source)
{
    if (m_source != source)
        m_source = source;
}

//! Gets the image source path
/*!
 * \return the source path for the image
 */
QString Layer::source() const
{
    return m_source;
}

//! Stores the layer type
/*!
 * \param drawType can be Tiled (default) or Plane
 */
void Layer::setDrawType(Quasi::DrawType drawType)
{
    if (m_drawType != drawType)
        m_drawType = drawType;
}

//! Gets the layer type
/*!
 * \return Tiled or Plane according the layer draw type
 */
Quasi::DrawType Layer::drawType() const
{
    return m_drawType;
}

void Layer::setDirection(const Quasi::LayerDirection &direction)
{
    if (direction != m_direction){
        if (direction == Quasi::BackwardDirection)
            m_direction = (Quasi::LayerDirection)-1; // insane black magic
        else
            m_direction = direction;

        emit directionChanged();
    }
}

//! Stores the layer update factor
/*!
 * \param factor the factor value
 */
void Layer::setFactor(qreal factor)
{
    if (m_factor != factor)
        m_factor = factor;
}

//! Gets the layer update factor
/*!
 * \return layer update factor
 */
qreal Layer::factor() const
{
    return m_factor;
}

//! Stores the layer z order
/*!
 * \param order the layer z order
 */
void Layer::setOrder(Quasi::Ordering order)
{
#if QT_VERSION >= 0x050000
    if (z() != order)
        setZ(order);
#else
    if (zValue() != order)
        setZValue(order);
#endif
}

//! Gets the layer z order
/*!
 * \return layer z order
 */
Quasi::Ordering Layer::order() const
{
#if QT_VERSION >= 0x050000
    return (Quasi::Ordering)z();
#else
    return (Quasi::Ordering)zValue();
#endif
}

void Layer::setLayerType(const Quasi::LayerType &type)
{
    if (type != m_type){
        m_type = type;

        emit layerTypeChanged();
    }
}

void Layer::setTileHeight(const int &value)
{
    if (m_drawType == Quasi::PlaneDrawType)
        return;

    if (value != m_tileHeight){
        m_tileHeight = value;

        if (m_tileWidth != 0 && m_tileHeight != 0)
            emit tilesChanged();
    }
}

void Layer::setTileWidth(const int &value)
{
    if (m_drawType == Quasi::PlaneDrawType)
        return;

    if (value != m_tileWidth){
        m_tileWidth = value;

        if (m_tileWidth != 0 && m_tileHeight != 0)
            emit tilesChanged();
    }
}

//! Adds a tile on the list
/*!
 * \param pix the pixmap to append on the list
 * \return the list actual size or -1 if the layer can not accept tiled pixmaps
 */
int Layer::addTile(const QPixmap &pix)
{
    m_pixmaps.append(pix);

    return m_pixmaps.size();
}

//! Gets a tile from the list
/*!
 * \param pos the tile position on the list
 * \return the tile pixmap of position pos on the list or null, if none
 */
QPixmap Layer::getTile(int pos) const
{
    return m_pixmaps.at(pos);
}

void Layer::setDrawGrid(bool draw)
{
    if (draw != m_drawGrid)
        m_drawGrid = draw;
}

void Layer::setGridColor(const QColor &color)
{
    if (color != m_gridColor)
        m_gridColor = color;
}

//! Gets the tiles pixmap list size
/*!
 * \return the tiles pixmap list size
 */
int Layer::count() const
{
    return m_pixmaps.size();
}

void Layer::generateOffsets()
{
    bool completed = false;
    int start = 0;
    int step = m_numColumns;
    int max = m_totalColumns;
    int count = 0;
    int maxCount = step * (int)m_areaToDraw;
    bool first = true;
    Offsets::OffsetsList firstPoint;

    while (!completed) {
        Offsets::OffsetsList offsetsList;

        int tamanho;
        int fim = 0;
        bool finish = false;

        while (count < maxCount) {
            fim = (start + step) % max;

            if (fim - start > 0) {
                tamanho = step;
                count += tamanho;

                // TODO check this comparison. Is it really needed?
                if (finish || count != maxCount) {
                    offsetsList.append(Offsets(start, tamanho));

                    if (!finish)
                        start = fim;
                    finish = false;
                } else {
                    offsetsList.append(Offsets(start, tamanho));
                }
            } else {
                int oldStart = start;
                tamanho = max - start;
                count += tamanho;

                offsetsList.append(Offsets(start, tamanho));

                tamanho = step - tamanho;
                start = 0;
                count += tamanho;

                if (tamanho != 0) {
                    offsetsList.append(Offsets(0, tamanho));
                }

                if (count <= maxCount / 2) {
                    start = tamanho;
                    finish = true;
                } else
                    start = oldStart;
            }
        }

        count = 0;

        if (offsetsList == firstPoint)
            completed = true;
        else
            m_offsets.append(offsetsList);

        if (first) {
            firstPoint = offsetsList;
            first = false;
        }
    }
}

void Layer::updateTiles()
{
    if ((boundingRect().width() == 0) || (boundingRect().height() == 0))
        return;

    // TODO create enums to define image aspect, auto tile, etc...
    QPixmap pix(source()); // TODO

    if (m_drawType == Quasi::PlaneDrawType) {
        m_tileWidth = width();
        m_tileHeight = height();

        if (pix.width() % (int)width() != 0) {
            // XXX create some log system?
            qCritical() << QString("Quasi>>Image \'%1\' doesn't contains a proper size... CROPPING!").arg(source());

            int newWidth = pix.width() - (pix.width() % (int)width());
            pix = pix.copy(0, 0, newWidth, height());
        }
    }

    if (pix.width() < boundingRect().width()) {
        QPixmap temp(boundingRect().width(), boundingRect().height());
        QPainter p(&temp);
            p.drawTiledPixmap(boundingRect(), pix, QPoint(0,0));
        p.end();

        pix = temp;
    }

    QPixmap mirrored;
    if (m_type == Quasi::MirroredType){
        QImage image = pix.toImage();

        mirrored = QPixmap::fromImage(image.mirrored(true, false));
    }

    // visible tiles
    m_numColumns = boundingRect().width() / m_tileWidth;
    m_numRows = boundingRect().height() / m_tileHeight;

    // total of columns and rows
    m_totalColumns = pix.width() / m_tileWidth;
    m_totalRows = pix.height() / m_tileHeight;

    int i, j;
    for (i = 0; i < m_totalRows; i++) {
        for (j = 0; j < m_totalColumns; j++){
            QPixmap temp(m_tileWidth, m_tileHeight);

            QPainter p(&temp);
                p.setCompositionMode(QPainter::CompositionMode_Source);
                p.drawPixmap(0, 0, m_tileWidth, m_tileHeight,
                        pix, j * m_tileWidth, i * m_tileHeight, m_tileWidth, m_tileHeight);
            p.end();

            addTile(temp);

            if (m_type == Quasi::MirroredType) {
                QPainter p(&temp);
                    p.drawPixmap(0, 0, m_tileWidth, m_tileHeight,
                            mirrored, j * m_tileWidth, i * m_tileHeight, m_tileWidth, m_tileHeight);
                p.end();

                m_mirroredTiles.append(temp);
            }
        }
    }

    generateOffsets();
    drawPixmap();
}

QPixmap Layer::generatePartialPixmap(int startPoint, int size)
{
    QPixmap temp(m_tileWidth * size, boundingRect().height());

    QPainter p(&temp);
        int i, j;
        int index = 0;
        for (i = 0; i < m_numRows; i++) {
            for (j = 0; j < size; j++) {
                index = ((i * m_totalColumns) + (j + startPoint));

                // TODO improve comparison
                if (m_direction == Quasi::ForwardDirection) {
                    if (m_drawingMirrored)
                        p.drawPixmap(j * m_tileWidth, i * m_tileHeight, getTile(index));
                    else
                        p.drawPixmap(j * m_tileWidth, i * m_tileHeight, m_mirroredTiles.at(index));
                } else {
                    if (m_drawingMirrored)
                        p.drawPixmap(j * m_tileWidth, i * m_tileHeight, m_mirroredTiles.at(index));
                    else
                        p.drawPixmap(j * m_tileWidth, i * m_tileHeight, getTile(index));
                }
                // just draw a grid
                // XXX chech the possibility of drawn it only on a debug mode
                if (m_drawGrid) {
                    p.setPen(m_gridColor);
                    p.drawRect(j * m_tileWidth, i * m_tileHeight, m_tileWidth, m_tileHeight);
                }
            }
        }
    p.end();

    return temp;
}

void Layer::drawPixmap()
{
    if ((boundingRect().width() == 0) || (boundingRect().height() == 0))
        return;

    // TODO Forward
    if (m_currentImage)
        delete m_currentImage;

    m_currentImage = new QImage(boundingRect().width() * m_areaToDraw, boundingRect().height(), QImage::Format_ARGB32_Premultiplied);

    QPainter p(m_currentImage);
        int xPoint = 0;
        for (int i = 0; i < m_offsets[m_columnOffset].size(); i++) {
            Offsets offset = m_offsets[m_columnOffset].at(i);

            if (((m_type == Quasi::MirroredType) && (i != 0)
                    && (offset.point() - m_latestPoint < 0))
                    || m_shouldMirror) {
                m_drawingMirrored = !m_drawingMirrored;
                m_shouldMirror = false;
            }

            QPixmap pix = generatePartialPixmap(offset.point(), offset.size());
            p.drawPixmap(xPoint, 0, pix);

            xPoint += pix.width();
            m_latestPoint = offset.point();

            if ((m_type == Quasi::MirroredType)
                    && (i == m_offsets[m_columnOffset].size() - 1)
                    && (offset.size() < m_numColumns))
                m_shouldMirror = true;
        }

        if (m_direction == Quasi::ForwardDirection)
            m_columnOffset = (m_columnOffset - 1 < 0) ? m_offsets.size() - 1 : m_columnOffset - 1;
        else
            m_columnOffset = (m_columnOffset + 1) % m_offsets.size();
    p.end();
}
<|endoftext|>