<commit_before>/*
    SWARM

    Copyright (C) 2012-2020 Torbjorn Rognes and Frederic Mahe

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Contact: Torbjorn Rognes <torognes@ifi.uio.no>,
    Department of Informatics, University of Oslo,
    PO Box 1080 Blindern, NO-0316 Oslo, Norway
*/

#include "swarm.h"

void pushop(char newop, char ** cigarendp, char * op, int * count);
void finishop(char ** cigarendp, char * op, int * count);

void pushop(char newop, char ** cigarendp, char * op, int * count)
{
  constexpr unsigned int buffer_length {25};

  if (newop == *op) {
    (*count)++;
  }
  else
  {
    *--*cigarendp = *op;
    if (*count > 1)
    {
      char buf[buffer_length];
      int len = snprintf(buf, buffer_length, "%d", *count);
      assert(len >= 0);
      *cigarendp -= len;
      memcpy(*cigarendp, buf, static_cast<size_t>(len));
    }
    *op = newop;
    *count = 1;
  }
}

void finishop(char ** cigarendp, char * op, int * count)
{
  constexpr unsigned int buffer_length {25};

  if ((op != nullptr) && (count != nullptr))
  {
    *--*cigarendp = *op;
    if (*count > 1)
    {
      char buf[buffer_length];
      int len = snprintf(buf, buffer_length, "%d", *count);
      assert(len >= 0);
      *cigarendp -= len;
      memcpy(*cigarendp, buf, static_cast<size_t>(len));
    }
    *op = 0;
    *count = 0;
  }
}

const unsigned char maskup      = 1;
const unsigned char maskleft    = 2;
const unsigned char maskextup   = 4;
const unsigned char maskextleft = 8;

/*

  Needleman/Wunsch/Sellers aligner

  finds a global alignment with minimum cost
  there should be positive costs/penalties for gaps and for mismatches
  matches should have zero cost (0)

  alignment priority when backtracking (from lower right corner):
  1. left/insert/e (gap in query sequence (qseq))
  2. align/diag/h (match/mismatch)
  3. up/delete/f (gap in database sequence (dseq))

  qseq: the reference/query/upper/vertical/from sequence
  dseq: the sample/database/lower/horisontal/to sequence

  typical costs:
  match: 0
  mismatch: 3
  gapopen: 4
  gapextend: 3

  input

  dseq: pointer to start of database sequence
  dend: pointer after database sequence
  qseq: pointer to start of query sequence
  qend: pointer after database sequence
  score_matrix: 32x32 matrix of longs with scores for aligning two symbols
  gapopen: positive number indicating penalty for opening a gap of length zero
  gapextend: positive number indicating penalty for extending a gap

  output

  nwscore: the global alignment score
  nwdiff: number of non-identical nucleotides in one optimal global alignment
  nwalignmentlength: the length of one optimal alignment
  nwalignment: cigar string with one optimal alignment

*/

void nw(char * dseq,
        int64_t dlen,
        char * qseq,
        int64_t qlen,
        int64_t * score_matrix,
        int64_t gapopen,
        int64_t gapextend,
        int64_t * nwscore,
        int64_t * nwdiff,
        int64_t * nwalignmentlength,
        char ** nwalignment,
        unsigned char * dir,
        int64_t * hearray,
        uint64_t queryno,
        uint64_t dbseqno)
{
  /* dir must point to at least qlen*dlen bytes of allocated memory
     hearray must point to at least 2*qlen longs of allocated memory
     (8*qlen bytes) */
  constexpr unsigned int multiplier {5};

  int64_t n {0};
  int64_t e {0};

  memset(dir, 0, static_cast<size_t>(qlen * dlen));

  int64_t i {0};
  int64_t j {0};

  for(auto i = 0L; i < qlen; i++)
    {
      hearray[2*i]   = 1 * gapopen + (i+1) * gapextend; // H (N)
      hearray[2*i+1] = 2 * gapopen + (i+2) * gapextend; // E
    }

  for(auto j = 0L; j < dlen; j++)
    {
      int64_t * hep {nullptr};
      hep = hearray;
      int64_t f = 2 * gapopen + (j+2) * gapextend;
      int64_t h = (j == 0) ? 0 : (gapopen + j * gapextend);

      for(auto i = 0L; i < qlen; i++)
        {
          int64_t index = qlen * j + i;

          n = *hep;
          e = *(hep+1);
          h += score_matrix
            [((nt_extract(dseq, static_cast<uint64_t>(j)) + 1) << multiplier)
             +(nt_extract(qseq, static_cast<uint64_t>(i)) + 1)];

          dir[index] |= (f < h ? maskup : 0);
          h = MIN(h, f);
          h = MIN(h, e);
          dir[index] |= (e == h ? maskleft : 0);

          *hep = h;

          h += gapopen + gapextend;
          e += gapextend;
          f += gapextend;

          dir[index] |= (f < h ? maskextup : 0);
          dir[index] |= (e < h ? maskextleft : 0);
          f = MIN(h,f);
          e = MIN(h,e);

          *(hep+1) = e;
          h = n;
          hep += 2;
        }
    }

  int64_t dist = hearray[2 * qlen - 2];

  /* backtrack: count differences and save alignment in cigar string */

  int64_t score {0};
  int64_t alength {0};
  int64_t matches {0};

  char * cigar = static_cast<char *>(xmalloc
                                     (static_cast<size_t>(qlen + dlen + 1)));
  char * cigarend {cigar + qlen + dlen + 1};

  char op {0};
  int count {0};
  *(--cigarend) = 0;

  i = qlen;
  j = dlen;

  while ((i>0) && (j>0))
    {
      int d = dir[qlen*(j-1)+(i-1)];

      alength++;

      if ((op == 'I') && ((d & maskextleft) != 0))
        {
          score += gapextend;
          j--;
          pushop('I', &cigarend, &op, &count);
        }
      else if ((op == 'D') && ((d & maskextup) != 0))
        {
          score += gapextend;
          i--;
          pushop('D', &cigarend, &op, &count);
        }
      else if ((d & maskleft) != 0)
        {
          score += gapextend;
          if (op != 'I') {
            score += gapopen;
          }
          j--;
          pushop('I', &cigarend, &op, &count);
        }
      else if ((d & maskup) != 0)
        {
          score += gapextend;
          if (op != 'D') {
            score += gapopen;
          }
          i--;
          pushop('D', &cigarend, &op, &count);
        }
      else
        {
          score += score_matrix
            [((nt_extract(dseq, static_cast<uint64_t>(j - 1)) + 1) << multiplier)
             +(nt_extract(qseq, static_cast<uint64_t>(i - 1)) + 1)];

          if (nt_extract(qseq, static_cast<uint64_t>(i - 1)) ==
              nt_extract(dseq, static_cast<uint64_t>(j - 1))) {
            matches++;
          }
          i--;
          j--;
          pushop('M', &cigarend, &op, &count);
        }
    }

  while(i>0)
    {
      alength++;
      score += gapextend;
      if (op != 'D') {
        score += gapopen;
      }
      i--;
      pushop('D', &cigarend, &op, &count);
    }

  while(j>0)
    {
      alength++;
      score += gapextend;
      if (op != 'I') {
        score += gapopen;
      }
      j--;
      pushop('I', &cigarend, &op, &count);
    }

  finishop(&cigarend, &op, &count);

  /* move and reallocate cigar */

  auto cigaralloc = static_cast<size_t>(cigar + qlen + dlen - cigarend + 1);
  memmove(cigar, cigarend, cigaralloc);
  cigar = static_cast<char*>(xrealloc(cigar, cigaralloc));

  * nwscore = dist;
  * nwdiff = alength - matches;
  * nwalignmentlength = alength;
  * nwalignment = cigar;

  assert(score == dist);

#if 0
  if (score != dist)
  {
    fprintf(stderr,
            "WARNING: Error with query no %" PRIu64 " and db sequence no %" PRIu64 ":\n",
            queryno, dbseqno);
    fprintf(stderr,
            "Initial and recomputed alignment score disagreement: %" PRId64 " %" PRId64 "\n",
            dist, score);
    fprintf(stderr, "Alignment: %s\n", cigar);
  }
#else
  (void) queryno;
  (void) dbseqno;
#endif
}
<commit_msg>fix warning: declaration shadows a local variable<commit_after>/*
    SWARM

    Copyright (C) 2012-2020 Torbjorn Rognes and Frederic Mahe

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Contact: Torbjorn Rognes <torognes@ifi.uio.no>,
    Department of Informatics, University of Oslo,
    PO Box 1080 Blindern, NO-0316 Oslo, Norway
*/

#include "swarm.h"

void pushop(char newop, char ** cigarendp, char * op, int * count);
void finishop(char ** cigarendp, char * op, int * count);

void pushop(char newop, char ** cigarendp, char * op, int * count)
{
  constexpr unsigned int buffer_length {25};

  if (newop == *op) {
    (*count)++;
  }
  else
  {
    *--*cigarendp = *op;
    if (*count > 1)
    {
      char buf[buffer_length];
      int len = snprintf(buf, buffer_length, "%d", *count);
      assert(len >= 0);
      *cigarendp -= len;
      memcpy(*cigarendp, buf, static_cast<size_t>(len));
    }
    *op = newop;
    *count = 1;
  }
}

void finishop(char ** cigarendp, char * op, int * count)
{
  constexpr unsigned int buffer_length {25};

  if ((op != nullptr) && (count != nullptr))
  {
    *--*cigarendp = *op;
    if (*count > 1)
    {
      char buf[buffer_length];
      int len = snprintf(buf, buffer_length, "%d", *count);
      assert(len >= 0);
      *cigarendp -= len;
      memcpy(*cigarendp, buf, static_cast<size_t>(len));
    }
    *op = 0;
    *count = 0;
  }
}

const unsigned char maskup      = 1;
const unsigned char maskleft    = 2;
const unsigned char maskextup   = 4;
const unsigned char maskextleft = 8;

/*

  Needleman/Wunsch/Sellers aligner

  finds a global alignment with minimum cost
  there should be positive costs/penalties for gaps and for mismatches
  matches should have zero cost (0)

  alignment priority when backtracking (from lower right corner):
  1. left/insert/e (gap in query sequence (qseq))
  2. align/diag/h (match/mismatch)
  3. up/delete/f (gap in database sequence (dseq))

  qseq: the reference/query/upper/vertical/from sequence
  dseq: the sample/database/lower/horisontal/to sequence

  typical costs:
  match: 0
  mismatch: 3
  gapopen: 4
  gapextend: 3

  input

  dseq: pointer to start of database sequence
  dend: pointer after database sequence
  qseq: pointer to start of query sequence
  qend: pointer after database sequence
  score_matrix: 32x32 matrix of longs with scores for aligning two symbols
  gapopen: positive number indicating penalty for opening a gap of length zero
  gapextend: positive number indicating penalty for extending a gap

  output

  nwscore: the global alignment score
  nwdiff: number of non-identical nucleotides in one optimal global alignment
  nwalignmentlength: the length of one optimal alignment
  nwalignment: cigar string with one optimal alignment

*/

void nw(char * dseq,
        int64_t dlen,
        char * qseq,
        int64_t qlen,
        int64_t * score_matrix,
        int64_t gapopen,
        int64_t gapextend,
        int64_t * nwscore,
        int64_t * nwdiff,
        int64_t * nwalignmentlength,
        char ** nwalignment,
        unsigned char * dir,
        int64_t * hearray,
        uint64_t queryno,
        uint64_t dbseqno)
{
  /* dir must point to at least qlen*dlen bytes of allocated memory
     hearray must point to at least 2*qlen longs of allocated memory
     (8*qlen bytes) */
  constexpr unsigned int multiplier {5};

  int64_t n {0};
  int64_t e {0};

  memset(dir, 0, static_cast<size_t>(qlen * dlen));

  for(auto i = 0L; i < qlen; i++)
    {
      hearray[2 * i]     = 1 * gapopen + (i + 1) * gapextend; // H (N)
      hearray[2 * i + 1] = 2 * gapopen + (i + 2) * gapextend; // E
    }

  for(auto j = 0L; j < dlen; j++)
    {
      int64_t * hep {nullptr};
      hep = hearray;
      int64_t f = 2 * gapopen + (j+2) * gapextend;
      int64_t h = (j == 0) ? 0 : (gapopen + j * gapextend);

      for(auto i = 0L; i < qlen; i++)
        {
          int64_t index = qlen * j + i;

          n = *hep;
          e = *(hep+1);
          h += score_matrix
            [((nt_extract(dseq, static_cast<uint64_t>(j)) + 1) << multiplier)
             +(nt_extract(qseq, static_cast<uint64_t>(i)) + 1)];

          dir[index] |= (f < h ? maskup : 0);
          h = MIN(h, f);
          h = MIN(h, e);
          dir[index] |= (e == h ? maskleft : 0);

          *hep = h;

          h += gapopen + gapextend;
          e += gapextend;
          f += gapextend;

          dir[index] |= (f < h ? maskextup : 0);
          dir[index] |= (e < h ? maskextleft : 0);
          f = MIN(h,f);
          e = MIN(h,e);

          *(hep+1) = e;
          h = n;
          hep += 2;
        }
    }

  int64_t dist = hearray[2 * qlen - 2];

  /* backtrack: count differences and save alignment in cigar string */
  int64_t score {0};
  int64_t alength {0};
  int64_t matches {0};

  char * cigar = static_cast<char *>(xmalloc
                                     (static_cast<size_t>(qlen + dlen + 1)));
  char * cigarend {cigar + qlen + dlen + 1};

  char op {0};
  int count {0};
  *(--cigarend) = 0;

  int64_t i = qlen;
  int64_t j = dlen;

  while ((i>0) && (j>0))
    {
      int d = dir[qlen*(j-1)+(i-1)];

      alength++;

      if ((op == 'I') && ((d & maskextleft) != 0))
        {
          score += gapextend;
          j--;
          pushop('I', &cigarend, &op, &count);
        }
      else if ((op == 'D') && ((d & maskextup) != 0))
        {
          score += gapextend;
          i--;
          pushop('D', &cigarend, &op, &count);
        }
      else if ((d & maskleft) != 0)
        {
          score += gapextend;
          if (op != 'I') {
            score += gapopen;
          }
          j--;
          pushop('I', &cigarend, &op, &count);
        }
      else if ((d & maskup) != 0)
        {
          score += gapextend;
          if (op != 'D') {
            score += gapopen;
          }
          i--;
          pushop('D', &cigarend, &op, &count);
        }
      else
        {
          score += score_matrix
            [((nt_extract(dseq, static_cast<uint64_t>(j - 1)) + 1) << multiplier)
             +(nt_extract(qseq, static_cast<uint64_t>(i - 1)) + 1)];

          if (nt_extract(qseq, static_cast<uint64_t>(i - 1)) ==
              nt_extract(dseq, static_cast<uint64_t>(j - 1))) {
            matches++;
          }
          i--;
          j--;
          pushop('M', &cigarend, &op, &count);
        }
    }

  while(i>0)
    {
      alength++;
      score += gapextend;
      if (op != 'D') {
        score += gapopen;
      }
      i--;
      pushop('D', &cigarend, &op, &count);
    }

  while(j>0)
    {
      alength++;
      score += gapextend;
      if (op != 'I') {
        score += gapopen;
      }
      j--;
      pushop('I', &cigarend, &op, &count);
    }

  finishop(&cigarend, &op, &count);

  /* move and reallocate cigar */

  auto cigaralloc = static_cast<size_t>(cigar + qlen + dlen - cigarend + 1);
  memmove(cigar, cigarend, cigaralloc);
  cigar = static_cast<char*>(xrealloc(cigar, cigaralloc));

  * nwscore = dist;
  * nwdiff = alength - matches;
  * nwalignmentlength = alength;
  * nwalignment = cigar;

  assert(score == dist);

#if 0
  if (score != dist)
  {
    fprintf(stderr,
            "WARNING: Error with query no %" PRIu64 " and db sequence no %" PRIu64 ":\n",
            queryno, dbseqno);
    fprintf(stderr,
            "Initial and recomputed alignment score disagreement: %" PRId64 " %" PRId64 "\n",
            dist, score);
    fprintf(stderr, "Alignment: %s\n", cigar);
  }
#else
  (void) queryno;
  (void) dbseqno;
#endif
}
<|endoftext|>


<commit_before><commit_msg>#i110213# - setup master password container on demand.<commit_after><|endoftext|>


<commit_before><commit_msg>Specify iteration limit for Kinsol<commit_after><|endoftext|>


<commit_before><commit_msg>Update camera<commit_after><|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_CORE_HPP
#define STAN_MATH_REV_CORE_HPP

#include <stan/math/rev/core/accumulate_adjoints.hpp>
#include <stan/math/rev/core/arena_allocator.hpp>
#include <stan/math/rev/core/arena_matrix.hpp>
#include <stan/math/rev/core/autodiffstackstorage.hpp>
#include <stan/math/rev/core/build_vari_array.hpp>
#include <stan/math/rev/core/chainable_alloc.hpp>
#include <stan/math/rev/core/chainable_object.hpp>
#include <stan/math/rev/core/chainablestack.hpp>
#include <stan/math/rev/core/count_vars.hpp>
#include <stan/math/rev/core/callback_vari.hpp>
#include <stan/math/rev/core/init_chainablestack.hpp>
#include <stan/math/rev/core/std_iterator_traits.hpp>
#include <stan/math/rev/core/ddv_vari.hpp>
#include <stan/math/rev/core/deep_copy_vars.hpp>
#include <stan/math/rev/core/dv_vari.hpp>
#include <stan/math/rev/core/dvd_vari.hpp>
#include <stan/math/rev/core/dvv_vari.hpp>
#include <stan/math/rev/core/Eigen_NumTraits.hpp>
#include <stan/math/rev/core/empty_nested.hpp>
#include <stan/math/rev/core/gevv_vvv_vari.hpp>
#include <stan/math/rev/core/grad.hpp>
#include <stan/math/rev/core/nested_rev_autodiff.hpp>
#include <stan/math/rev/core/matrix_vari.hpp>
#include <stan/math/rev/core/nested_size.hpp>
#include <stan/math/rev/core/operator_addition.hpp>
#include <stan/math/rev/core/operator_divide_equal.hpp>
#include <stan/math/rev/core/operator_division.hpp>
#include <stan/math/rev/core/operator_equal.hpp>
#include <stan/math/rev/core/operator_greater_than.hpp>
#include <stan/math/rev/core/operator_greater_than_or_equal.hpp>
#include <stan/math/rev/core/operator_less_than.hpp>
#include <stan/math/rev/core/operator_less_than_or_equal.hpp>
#include <stan/math/rev/core/operator_logical_and.hpp>
#include <stan/math/rev/core/operator_logical_or.hpp>
#include <stan/math/rev/core/operator_minus_equal.hpp>
#include <stan/math/rev/core/operator_multiplication.hpp>
#include <stan/math/rev/core/operator_multiply_equal.hpp>
#include <stan/math/rev/core/operator_not_equal.hpp>
#include <stan/math/rev/core/operator_plus_equal.hpp>
#include <stan/math/rev/core/operator_subtraction.hpp>
#include <stan/math/rev/core/operator_unary_decrement.hpp>
#include <stan/math/rev/core/operator_unary_increment.hpp>
#include <stan/math/rev/core/operator_unary_negative.hpp>
#include <stan/math/rev/core/operator_unary_not.hpp>
#include <stan/math/rev/core/operator_unary_plus.hpp>
#include <stan/math/rev/core/precomp_vv_vari.hpp>
#include <stan/math/rev/core/precomp_vvv_vari.hpp>
#include <stan/math/rev/core/precomputed_gradients.hpp>
#include <stan/math/rev/core/print_stack.hpp>
#include <stan/math/rev/core/profiling.hpp>
#include <stan/math/rev/core/read_var.hpp>
#include <stan/math/rev/core/recover_memory.hpp>
#include <stan/math/rev/core/recover_memory_nested.hpp>
#include <stan/math/rev/core/scoped_chainablestack.hpp>
#include <stan/math/rev/core/set_zero_all_adjoints.hpp>
#include <stan/math/rev/core/set_zero_all_adjoints_nested.hpp>
#include <stan/math/rev/core/start_nested.hpp>
#include <stan/math/rev/core/std_complex.hpp>
#include <stan/math/rev/core/std_isinf.hpp>
#include <stan/math/rev/core/std_isnan.hpp>
#include <stan/math/rev/core/std_numeric_limits.hpp>
#include <stan/math/rev/core/stored_gradient_vari.hpp>
#include <stan/math/rev/core/typedefs.hpp>
#include <stan/math/rev/core/v_vari.hpp>
#include <stan/math/rev/core/var.hpp>
#include <stan/math/rev/core/vari.hpp>
#include <stan/math/rev/core/vd_vari.hpp>
#include <stan/math/rev/core/vdd_vari.hpp>
#include <stan/math/rev/core/vdv_vari.hpp>
#include <stan/math/rev/core/vector_vari.hpp>
#include <stan/math/rev/core/vv_vari.hpp>
#include <stan/math/rev/core/vvd_vari.hpp>
#include <stan/math/rev/core/vvv_vari.hpp>
#include <stan/math/rev/core/save_varis.hpp>
#include <stan/math/rev/core/zero_adjoints.hpp>

#endif
<commit_msg>cleanup core<commit_after>#ifndef STAN_MATH_REV_CORE_HPP
#define STAN_MATH_REV_CORE_HPP

#include <stan/math/rev/core/accumulate_adjoints.hpp>
#include <stan/math/rev/core/arena_allocator.hpp>
#include <stan/math/rev/core/arena_matrix.hpp>
#include <stan/math/rev/core/autodiffstackstorage.hpp>
#include <stan/math/rev/core/build_vari_array.hpp>
#include <stan/math/rev/core/chainable_alloc.hpp>
#include <stan/math/rev/core/chainable_object.hpp>
#include <stan/math/rev/core/chainablestack.hpp>
#include <stan/math/rev/core/count_vars.hpp>
#include <stan/math/rev/core/callback_vari.hpp>
#include <stan/math/rev/core/init_chainablestack.hpp>
#include <stan/math/rev/core/std_iterator_traits.hpp>
#include <stan/math/rev/core/ddv_vari.hpp>
#include <stan/math/rev/core/deep_copy_vars.hpp>
#include <stan/math/rev/core/dv_vari.hpp>
#include <stan/math/rev/core/dvd_vari.hpp>
#include <stan/math/rev/core/dvv_vari.hpp>
#include <stan/math/rev/core/Eigen_NumTraits.hpp>
#include <stan/math/rev/core/empty_nested.hpp>
#include <stan/math/rev/core/gevv_vvv_vari.hpp>
#include <stan/math/rev/core/grad.hpp>
#include <stan/math/rev/core/nested_rev_autodiff.hpp>
#include <stan/math/rev/core/matrix_vari.hpp>
#include <stan/math/rev/core/nested_size.hpp>
#include <stan/math/rev/core/operator_addition.hpp>
#include <stan/math/rev/core/operator_divide_equal.hpp>
#include <stan/math/rev/core/operator_division.hpp>
#include <stan/math/rev/core/operator_equal.hpp>
#include <stan/math/rev/core/operator_greater_than.hpp>
#include <stan/math/rev/core/operator_greater_than_or_equal.hpp>
#include <stan/math/rev/core/operator_less_than.hpp>
#include <stan/math/rev/core/operator_less_than_or_equal.hpp>
#include <stan/math/rev/core/operator_logical_and.hpp>
#include <stan/math/rev/core/operator_logical_or.hpp>
#include <stan/math/rev/core/operator_minus_equal.hpp>
#include <stan/math/rev/core/operator_multiplication.hpp>
#include <stan/math/rev/core/operator_multiply_equal.hpp>
#include <stan/math/rev/core/operator_not_equal.hpp>
#include <stan/math/rev/core/operator_plus_equal.hpp>
#include <stan/math/rev/core/operator_subtraction.hpp>
#include <stan/math/rev/core/operator_unary_decrement.hpp>
#include <stan/math/rev/core/operator_unary_increment.hpp>
#include <stan/math/rev/core/operator_unary_negative.hpp>
#include <stan/math/rev/core/operator_unary_not.hpp>
#include <stan/math/rev/core/operator_unary_plus.hpp>
#include <stan/math/rev/core/precomp_vv_vari.hpp>
#include <stan/math/rev/core/precomp_vvv_vari.hpp>
#include <stan/math/rev/core/precomputed_gradients.hpp>
#include <stan/math/rev/core/print_stack.hpp>
#include <stan/math/rev/core/profiling.hpp>
#include <stan/math/rev/core/read_var.hpp>
#include <stan/math/rev/core/recover_memory.hpp>
#include <stan/math/rev/core/recover_memory_nested.hpp>
#include <stan/math/rev/core/scoped_chainablestack.hpp>
#include <stan/math/rev/core/set_zero_all_adjoints.hpp>
#include <stan/math/rev/core/set_zero_all_adjoints_nested.hpp>
#include <stan/math/rev/core/start_nested.hpp>
#include <stan/math/rev/core/std_complex.hpp>
#include <stan/math/rev/core/std_isinf.hpp>
#include <stan/math/rev/core/std_isnan.hpp>
#include <stan/math/rev/core/std_numeric_limits.hpp>
#include <stan/math/rev/core/stored_gradient_vari.hpp>
#include <stan/math/rev/core/typedefs.hpp>
#include <stan/math/rev/core/var.hpp>
#include <stan/math/rev/core/vari.hpp>
#include <stan/math/rev/core/vd_vari.hpp>
#include <stan/math/rev/core/vdd_vari.hpp>
#include <stan/math/rev/core/vdv_vari.hpp>
#include <stan/math/rev/core/vector_vari.hpp>
#include <stan/math/rev/core/vv_vari.hpp>
#include <stan/math/rev/core/vvd_vari.hpp>
#include <stan/math/rev/core/vvv_vari.hpp>
#include <stan/math/rev/core/save_varis.hpp>
#include <stan/math/rev/core/zero_adjoints.hpp>

#endif
<|endoftext|>


<commit_before>
#include "boxed.h"
#include "function.h"
#include "closure.h"
#include "gi.h"
#include "gobject.h"
#include "util.h"
#include "value.h"

using v8::Array;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Persistent;
using Nan::New;
using Nan::FunctionCallbackInfo;
using Nan::WeakCallbackType;

namespace GNodeJS {

static void GObjectDestroyed(const v8::WeakCallbackInfo<GObject> &data);
static Local<FunctionTemplate> GetClassTemplateFromGI(GIBaseInfo *info);

static bool InitGParameterFromProperty(GParameter    *parameter,
                                       void          *klass,
                                       Local<String>  name,
                                       Local<Value>   value) {
    // XXX js->c name conversion
    String::Utf8Value name_str (name);
    GParamSpec *pspec = g_object_class_find_property (G_OBJECT_CLASS (klass), *name_str);

    if (pspec == NULL)
        return false;

    parameter->name = pspec->name;
    g_value_init (&parameter->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
    V8ToGValue (&parameter->value, value);
    return true;
}

static bool InitGParametersFromProperty(GParameter    **parameters_p,
                                        int            *n_parameters_p,
                                        void           *klass,
                                        Local<Object>  property_hash) {
    Local<Array> properties = property_hash->GetOwnPropertyNames ();
    int n_parameters = properties->Length ();
    GParameter *parameters = g_new0 (GParameter, n_parameters);

    for (int i = 0; i < n_parameters; i++) {
        Local<Value> name = properties->Get (i);
        Local<Value> value = property_hash->Get (name);

        if (!InitGParameterFromProperty (&parameters[i], klass, name->ToString (), value))
            return false;
    }

    *parameters_p = parameters;
    *n_parameters_p = n_parameters;
    return true;
}

static void ToggleNotify(gpointer user_data, GObject *gobject, gboolean toggle_down) {
    void *data = g_object_get_qdata (gobject, GNodeJS::object_quark());

    g_assert (data != NULL);

    auto *persistent = (Persistent<Object> *) data;

    if (toggle_down) {
        /* We're dropping from 2 refs to 1 ref. We are the last holder. Make
         * sure that that our weak ref is installed. */
        persistent->SetWeak (gobject, GObjectDestroyed, v8::WeakCallbackType::kParameter);
    } else {
        /* We're going from 1 ref to 2 refs. We can't let our wrapper be
         * collected, so make sure that our reference is persistent */
        persistent->ClearWeak ();
    }
}

static void AssociateGObject(Isolate *isolate, Local<Object> object, GObject *gobject) {
    object->SetAlignedPointerInInternalField (0, gobject);

    g_object_ref_sink (gobject);
    g_object_add_toggle_ref (gobject, ToggleNotify, NULL);

    Persistent<Object> *persistent = new Persistent<Object>(isolate, object);
    g_object_set_qdata (gobject, GNodeJS::object_quark(), persistent);
}

static void GObjectConstructor(const FunctionCallbackInfo<Value> &args) {
    Isolate *isolate = args.GetIsolate ();

    /* The flow of this function is a bit twisty.

     * There's two cases for when this code is called:
     * user code doing `new Gtk.Widget({ ... })`, and
     * internal code as part of WrapperFromGObject, where
     * the constructor is called with one external. */

    if (!args.IsConstructCall ()) {
        Nan::ThrowTypeError("Not a construct call.");
        return;
    }

    Local<Object> self = args.This ();

    if (args[0]->IsExternal ()) {
        /* The External case. This is how WrapperFromGObject is called. */

        void *data = External::Cast (*args[0])->Value ();
        GObject *gobject = G_OBJECT (data);

        AssociateGObject (isolate, self, gobject);
    } else {
        /* User code calling `new Gtk.Widget({ ... })` */

        GObject *gobject;
        GIBaseInfo *info = (GIBaseInfo *) External::Cast (*args.Data ())->Value ();
        GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info);
        void *klass = g_type_class_ref (gtype);

        GParameter *parameters = NULL;
        int n_parameters = 0;

        if (args[0]->IsObject ()) {
            Local<Object> property_hash = args[0]->ToObject ();

            if (!InitGParametersFromProperty (&parameters, &n_parameters, klass, property_hash)) {
                Nan::ThrowError("GObjectConstructor: Unable to make GParameters.");
                goto out;
            }
        }

        gobject = (GObject *) g_object_newv (gtype, n_parameters, parameters);
        AssociateGObject (isolate, self, gobject);

    out:
        g_free (parameters);
        g_type_class_unref (klass);
    }
}

static void GObjectDestroyed(const v8::WeakCallbackInfo<GObject> &data) {
    GObject *gobject = data.GetParameter ();

    void *type_data = g_object_get_qdata (gobject, GNodeJS::object_quark());
    assert (type_data != NULL);
    Persistent<Object> *persistent = (Persistent<Object> *) type_data;
    delete persistent;

    /* We're destroying the wrapper object, so make sure to clear out
     * the qdata that points back to us. */
    g_object_set_qdata (gobject, GNodeJS::object_quark(), NULL);

    g_object_unref (gobject);
}

static void SignalConnectInternal(const Nan::FunctionCallbackInfo<v8::Value> &args, bool after) {
    Isolate *isolate = args.GetIsolate ();
    GObject *gobject = GObjectFromWrapper (args.This ());

    if (!(args[0]->IsString() || args[0]->IsNumber())) {
        Nan::ThrowTypeError("Signal ID invalid.");
        return;
    }

    if (!args[1]->IsFunction()) {
        Nan::ThrowTypeError("Signal callback is not a function.");
        return;
    }

    String::Utf8Value signal_name (args[0]->ToString ());
    Local<Function> callback = args[1].As<Function>();

    GClosure *gclosure = MakeClosure (isolate, callback);

    // TODO return some sort of cancellation handle?
    // e.g.: return { disposable: function () {...}, signal_id: ID };
    ulong handler_id = g_signal_connect_closure (gobject, *signal_name, gclosure, after);
    args.GetReturnValue().Set((double)handler_id);
}

NAN_METHOD(SignalConnect) {
    SignalConnectInternal(info, false);
}

static void GObjectToString(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    Local<Object> self = info.This();
    GObject* g_object = GNodeJS::GObjectFromWrapper(self);
    GType type = G_OBJECT_TYPE (g_object);

    const char* typeName = g_type_name(type);
    char *className = *String::Utf8Value(self->GetConstructorName());
    void *address = self->GetAlignedPointerFromInternalField(0);

    char *str = g_strdup_printf(
            "[%s:%s %#zx]", typeName, className, (unsigned long)address);

    info.GetReturnValue().Set(UTF8(str));
    g_free(str);
}

static Local<FunctionTemplate> GetBaseClassTemplate() {
    static int count = 0;
    g_warning("GetBaseClassTemplate called (%i)", count);
    count++;
    auto tpl = New<FunctionTemplate> ();
    Nan::SetPrototypeMethod(tpl, "on", SignalConnect);
    Nan::SetPrototypeMethod(tpl, "connect", SignalConnect);
    Nan::SetPrototypeMethod(tpl, "addEventListener", SignalConnect);
    Nan::SetPrototypeMethod(tpl, "toString",
            [](const Nan::FunctionCallbackInfo<v8::Value>& info) -> void {
                char *str = *String::Utf8Value(info.This()->GetConstructorName());
                info.GetReturnValue().Set(UTF8(str));
            });
    return tpl;
}

static Local<FunctionTemplate> NewClassTemplate (GIBaseInfo *info) {
    const GType gtype = g_registered_type_info_get_g_type (info);

    g_assert(gtype != G_TYPE_NONE);

    const char *class_name = g_type_name (gtype);

    auto tpl = New<FunctionTemplate> (GObjectConstructor, New<External> (info));
    //tpl->Set (UTF8("gtype"), New((double)gtype));
    Nan::SetTemplate(tpl, "gtype", New((double)gtype));
    tpl->SetClassName (UTF8(class_name));
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    GIObjectInfo *parent_info = g_object_info_get_parent (info);
    if (parent_info) {
        auto parent_tpl = GetClassTemplateFromGI ((GIBaseInfo *) parent_info);
        tpl->Inherit(parent_tpl);
    } else {
        tpl->Inherit(GetBaseClassTemplate());
    }

    return tpl;
}

static Local<FunctionTemplate> GetClassTemplate(GType gtype) {
    // GIBaseInfo *info,
    void *data = g_type_get_qdata (gtype, GNodeJS::template_quark());

    if (data) {
        auto *persistent = (Persistent<FunctionTemplate> *) data;
        auto tpl = New<FunctionTemplate> (*persistent);
        return tpl;

    } else {
        GIBaseInfo *gi_info = g_irepository_find_by_gtype(NULL, gtype);

        auto tpl = NewClassTemplate(gi_info);
        auto *persistent = new Persistent<FunctionTemplate>(Isolate::GetCurrent(), tpl);
        persistent->SetWeak (
                g_base_info_ref (gi_info),
                GNodeJS::ClassDestroyed,
                WeakCallbackType::kParameter);

        g_type_set_qdata(gtype, GNodeJS::template_quark(), persistent);
        return tpl;
    }
}

static Local<FunctionTemplate> GetClassTemplateFromGI(GIBaseInfo *info) {
    GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info);
    return GetClassTemplate(gtype);
}

Local<Function> MakeClass(GIBaseInfo *info) {
    auto tpl = GetClassTemplateFromGI (info);
    return tpl->GetFunction ();
}

Local<Value> WrapperFromGObject(GObject *gobject) {
    if (gobject == NULL)
        return Nan::Null();

    void *data = g_object_get_qdata (gobject, GNodeJS::object_quark());

    if (data) {
        /* Easy case: we already have an object. */
        auto *persistent = (Persistent<Object> *) data;
        auto obj = New<Object> (*persistent);
        return obj;

    } else {
        GType gtype = G_OBJECT_TYPE(gobject);
        g_type_ensure(gtype); //void *klass = g_type_class_ref (type);

        auto tpl = GetClassTemplate(gtype);
        Local<Function> constructor = tpl->GetFunction ();
        Local<Value> gobject_external = New<External> (gobject);
        Local<Value> args[] = { gobject_external };
        Local<Object> obj = constructor->NewInstance (1, args);

        return obj;
    }
}

GObject * GObjectFromWrapper(Local<Value> value) {
    Local<Object> object = value->ToObject ();

    void    *ptr     = object->GetAlignedPointerFromInternalField (0);
    GObject *gobject = G_OBJECT (ptr);
    return gobject;
}

};
<commit_msg>use "info" argument-name in GObjectCOnstructor<commit_after>
#include "boxed.h"
#include "function.h"
#include "closure.h"
#include "gi.h"
#include "gobject.h"
#include "util.h"
#include "value.h"

using v8::Array;
using v8::External;
using v8::Function;
using v8::FunctionTemplate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::String;
using v8::Persistent;
using Nan::New;
using Nan::FunctionCallbackInfo;
using Nan::WeakCallbackType;

namespace GNodeJS {

static void GObjectDestroyed(const v8::WeakCallbackInfo<GObject> &data);
static Local<FunctionTemplate> GetClassTemplateFromGI(GIBaseInfo *info);

static bool InitGParameterFromProperty(GParameter    *parameter,
                                       void          *klass,
                                       Local<String>  name,
                                       Local<Value>   value) {
    // XXX js->c name conversion
    String::Utf8Value name_str (name);
    GParamSpec *pspec = g_object_class_find_property (G_OBJECT_CLASS (klass), *name_str);

    if (pspec == NULL)
        return false;

    parameter->name = pspec->name;
    g_value_init (&parameter->value, G_PARAM_SPEC_VALUE_TYPE (pspec));
    V8ToGValue (&parameter->value, value);
    return true;
}

static bool InitGParametersFromProperty(GParameter    **parameters_p,
                                        int            *n_parameters_p,
                                        void           *klass,
                                        Local<Object>  property_hash) {
    Local<Array> properties = property_hash->GetOwnPropertyNames ();
    int n_parameters = properties->Length ();
    GParameter *parameters = g_new0 (GParameter, n_parameters);

    for (int i = 0; i < n_parameters; i++) {
        Local<Value> name = properties->Get (i);
        Local<Value> value = property_hash->Get (name);

        if (!InitGParameterFromProperty (&parameters[i], klass, name->ToString (), value))
            return false;
    }

    *parameters_p = parameters;
    *n_parameters_p = n_parameters;
    return true;
}

static void ToggleNotify(gpointer user_data, GObject *gobject, gboolean toggle_down) {
    void *data = g_object_get_qdata (gobject, GNodeJS::object_quark());

    g_assert (data != NULL);

    auto *persistent = (Persistent<Object> *) data;

    if (toggle_down) {
        /* We're dropping from 2 refs to 1 ref. We are the last holder. Make
         * sure that that our weak ref is installed. */
        persistent->SetWeak (gobject, GObjectDestroyed, v8::WeakCallbackType::kParameter);
    } else {
        /* We're going from 1 ref to 2 refs. We can't let our wrapper be
         * collected, so make sure that our reference is persistent */
        persistent->ClearWeak ();
    }
}

static void AssociateGObject(Isolate *isolate, Local<Object> object, GObject *gobject) {
    object->SetAlignedPointerInInternalField (0, gobject);

    g_object_ref_sink (gobject);
    g_object_add_toggle_ref (gobject, ToggleNotify, NULL);

    Persistent<Object> *persistent = new Persistent<Object>(isolate, object);
    g_object_set_qdata (gobject, GNodeJS::object_quark(), persistent);
}

static void GObjectConstructor(const FunctionCallbackInfo<Value> &info) {
    Isolate *isolate = info.GetIsolate ();

    /* The flow of this function is a bit twisty.

     * There's two cases for when this code is called:
     * user code doing `new Gtk.Widget({ ... })`, and
     * internal code as part of WrapperFromGObject, where
     * the constructor is called with one external. */

    if (!info.IsConstructCall ()) {
        Nan::ThrowTypeError("Not a construct call.");
        return;
    }

    Local<Object> self = info.This ();

    if (info[0]->IsExternal ()) {
        /* The External case. This is how WrapperFromGObject is called. */
        void *data = External::Cast (*info[0])->Value ();
        GObject *gobject = G_OBJECT (data);
        AssociateGObject (isolate, self, gobject);
    } else {
        /* User code calling `new Gtk.Widget({ ... })` */

        GObject *gobject;
        GIBaseInfo *gi_info = (GIBaseInfo *) External::Cast (*info.Data ())->Value ();
        GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) gi_info);
        void *klass = g_type_class_ref (gtype);

        GParameter *parameters = NULL;
        int n_parameters = 0;

        if (info[0]->IsObject ()) {
            Local<Object> property_hash = info[0]->ToObject ();

            if (!InitGParametersFromProperty (&parameters, &n_parameters, klass, property_hash)) {
                Nan::ThrowError("GObjectConstructor: Unable to make GParameters.");
                goto out;
            }
        }

        gobject = (GObject *) g_object_newv (gtype, n_parameters, parameters);
        AssociateGObject (isolate, self, gobject);

    out:
        g_free (parameters);
        g_type_class_unref (klass);
    }
}

static void GObjectDestroyed(const v8::WeakCallbackInfo<GObject> &data) {
    GObject *gobject = data.GetParameter ();

    void *type_data = g_object_get_qdata (gobject, GNodeJS::object_quark());
    assert (type_data != NULL);
    Persistent<Object> *persistent = (Persistent<Object> *) type_data;
    delete persistent;

    /* We're destroying the wrapper object, so make sure to clear out
     * the qdata that points back to us. */
    g_object_set_qdata (gobject, GNodeJS::object_quark(), NULL);

    g_object_unref (gobject);
}

static void SignalConnectInternal(const Nan::FunctionCallbackInfo<v8::Value> &args, bool after) {
    Isolate *isolate = args.GetIsolate ();
    GObject *gobject = GObjectFromWrapper (args.This ());

    if (!(args[0]->IsString() || args[0]->IsNumber())) {
        Nan::ThrowTypeError("Signal ID invalid.");
        return;
    }

    if (!args[1]->IsFunction()) {
        Nan::ThrowTypeError("Signal callback is not a function.");
        return;
    }

    String::Utf8Value signal_name (args[0]->ToString ());
    Local<Function> callback = args[1].As<Function>();

    GClosure *gclosure = MakeClosure (isolate, callback);

    // TODO return some sort of cancellation handle?
    // e.g.: return { disposable: function () {...}, signal_id: ID };
    ulong handler_id = g_signal_connect_closure (gobject, *signal_name, gclosure, after);
    args.GetReturnValue().Set((double)handler_id);
}

NAN_METHOD(SignalConnect) {
    SignalConnectInternal(info, false);
}

static void GObjectToString(const Nan::FunctionCallbackInfo<v8::Value> &info) {
    Local<Object> self = info.This();
    GObject* g_object = GNodeJS::GObjectFromWrapper(self);
    GType type = G_OBJECT_TYPE (g_object);

    const char* typeName = g_type_name(type);
    char *className = *String::Utf8Value(self->GetConstructorName());
    void *address = self->GetAlignedPointerFromInternalField(0);

    char *str = g_strdup_printf(
            "[%s:%s %#zx]", typeName, className, (unsigned long)address);

    info.GetReturnValue().Set(UTF8(str));
    g_free(str);
}

static Local<FunctionTemplate> GetBaseClassTemplate() {
    static int count = 0;
    g_warning("GetBaseClassTemplate called (%i)", count);
    count++;
    auto tpl = New<FunctionTemplate> ();
    Nan::SetPrototypeMethod(tpl, "on", SignalConnect);
    Nan::SetPrototypeMethod(tpl, "connect", SignalConnect);
    Nan::SetPrototypeMethod(tpl, "addEventListener", SignalConnect);
    Nan::SetPrototypeMethod(tpl, "toString",
            [](const Nan::FunctionCallbackInfo<v8::Value>& info) -> void {
                char *str = *String::Utf8Value(info.This()->GetConstructorName());
                info.GetReturnValue().Set(UTF8(str));
            });
    return tpl;
}

static Local<FunctionTemplate> NewClassTemplate (GIBaseInfo *info) {
    const GType gtype = g_registered_type_info_get_g_type (info);

    g_assert(gtype != G_TYPE_NONE);

    const char *class_name = g_type_name (gtype);

    auto tpl = New<FunctionTemplate> (GObjectConstructor, New<External> (info));
    //tpl->Set (UTF8("gtype"), New((double)gtype));
    Nan::SetTemplate(tpl, "gtype", New((double)gtype));
    tpl->SetClassName (UTF8(class_name));
    tpl->InstanceTemplate()->SetInternalFieldCount(1);

    GIObjectInfo *parent_info = g_object_info_get_parent (info);
    if (parent_info) {
        auto parent_tpl = GetClassTemplateFromGI ((GIBaseInfo *) parent_info);
        tpl->Inherit(parent_tpl);
    } else {
        tpl->Inherit(GetBaseClassTemplate());
    }

    return tpl;
}

static Local<FunctionTemplate> GetClassTemplate(GType gtype) {
    // GIBaseInfo *info,
    void *data = g_type_get_qdata (gtype, GNodeJS::template_quark());

    if (data) {
        auto *persistent = (Persistent<FunctionTemplate> *) data;
        auto tpl = New<FunctionTemplate> (*persistent);
        return tpl;

    } else {
        GIBaseInfo *gi_info = g_irepository_find_by_gtype(NULL, gtype);

        auto tpl = NewClassTemplate(gi_info);
        auto *persistent = new Persistent<FunctionTemplate>(Isolate::GetCurrent(), tpl);
        persistent->SetWeak (
                g_base_info_ref (gi_info),
                GNodeJS::ClassDestroyed,
                WeakCallbackType::kParameter);

        g_type_set_qdata(gtype, GNodeJS::template_quark(), persistent);
        return tpl;
    }
}

static Local<FunctionTemplate> GetClassTemplateFromGI(GIBaseInfo *info) {
    GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info);
    return GetClassTemplate(gtype);
}

Local<Function> MakeClass(GIBaseInfo *info) {
    auto tpl = GetClassTemplateFromGI (info);
    return tpl->GetFunction ();
}

Local<Value> WrapperFromGObject(GObject *gobject) {
    if (gobject == NULL)
        return Nan::Null();

    void *data = g_object_get_qdata (gobject, GNodeJS::object_quark());

    if (data) {
        /* Easy case: we already have an object. */
        auto *persistent = (Persistent<Object> *) data;
        auto obj = New<Object> (*persistent);
        return obj;

    } else {
        GType gtype = G_OBJECT_TYPE(gobject);
        g_type_ensure(gtype); //void *klass = g_type_class_ref (type);

        auto tpl = GetClassTemplate(gtype);
        Local<Function> constructor = tpl->GetFunction ();
        Local<Value> gobject_external = New<External> (gobject);
        Local<Value> args[] = { gobject_external };
        Local<Object> obj = constructor->NewInstance (1, args);

        return obj;
    }
}

GObject * GObjectFromWrapper(Local<Value> value) {
    Local<Object> object = value->ToObject ();

    void    *ptr     = object->GetAlignedPointerFromInternalField (0);
    GObject *gobject = G_OBJECT (ptr);
    return gobject;
}

};
<|endoftext|>


<commit_before>/**
 * @file rectangle_tree_impl.hpp
 * @author Andrew Wells
 *
 * Implementation of generalized rectangle tree.
 */
#ifndef __MLPACK_CORE_TREE_RECTANGLE_TREE_RECTANGLE_TREE_IMPL_HPP
#define __MLPACK_CORE_TREE_RECTANGLE_TREE_RECTANGLE_TREE_IMPL_HPP

// In case it wasn't included already for some reason.
#include "rectangle_tree.hpp"

#include <mlpack/core/util/cli.hpp>
#include <mlpack/core/util/log.hpp>
#include <mlpack/core/util/string_util.hpp>

namespace mlpack {
namespace tree {

template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
RectangleTree<SplitType, DescentType, StatisticType, MatType>::RectangleTree(
    MatType& data,
    const size_t maxLeafSize = 20,
    const size_t minLeafSize = 6,
    const size_t maxNumChildren = 4,
    const size_t minNumChildren = 0,
    const size_t firstDataIndex = 0):
    maxNumChildren(maxNumChildren),
    minNumChildren(minNumChildren),
    numChildren(0),
    children(maxNumChildren+1), // Add one to make splitting the node simpler
    parent(NULL),
    begin(0),
    count(0),
    maxLeafSize(maxLeafSize),
    minLeafSize(minLeafSize),
    bound(data.n_rows),
    parentDistance(0),
    dataset(new MatType(data.n_rows, static_cast<int>(maxLeafSize)+1)) // Add one to make splitting the node simpler
{
  stat = StatisticType(*this);

  std::cout << ToString() << std::endl;

  // For now, just insert the points in order.
  RectangleTree* root = this;

  //for(int i = firstDataIndex; i < 57; i++) { // 56,57 are the bound for where it works/breaks
  for(int i = firstDataIndex; i < data.n_rows; i++) {
    std::cout << "inserting point number: " << i << std::endl;
    root->InsertPoint(data.col(i));
    std::cout << "finished inserting point number: " << i << std::endl;
    std::cout << ToString() << std::endl;
  }

}

template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
RectangleTree<SplitType, DescentType, StatisticType, MatType>::RectangleTree(
  RectangleTree<SplitType, DescentType, StatisticType, MatType>* parentNode):
  maxNumChildren(parentNode->MaxNumChildren()),
  minNumChildren(parentNode->MinNumChildren()),
  numChildren(0),
  children(maxNumChildren+1),
  parent(parentNode),
  begin(0),
  count(0),
  maxLeafSize(parentNode->MaxLeafSize()),
  minLeafSize(parentNode->MinLeafSize()),
  bound(parentNode->Bound().Dim()),
  parentDistance(0),
  dataset(new MatType(static_cast<int>(parentNode->Bound().Dim()), static_cast<int>(maxLeafSize)+1)) // Add one to make splitting the node simpler
{
  stat = StatisticType(*this);
}

/**
 * Deletes this node, deallocating the memory for the children and calling
 * their destructors in turn.  This will invalidate any pointers or references
 * to any nodes which are children of this one.
 */
template<typename SplitType,
         typename DescentType,
	typename StatisticType,
         typename MatType>
RectangleTree<SplitType, DescentType, StatisticType, MatType>::
  ~RectangleTree()
{
  //LEAK MEMORY

  for(int i = 0; i < numChildren; i++) {
    delete children[i];
  }
  delete dataset;
}

/**
  * Deletes this node but leaves the children untouched.  Needed for when we
  * split nodes and remove nodes (inserting and deleting points).
  */
template<typename SplitType,
                  typename DescentType,
                  typename StatisticType,
                  typename MatType>
void RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    softDelete()
{
  /* do nothing.  I'm not sure how to handle this yet, so for now, we will leak memory */
}

/**
 * Recurse through the tree and insert the point at the leaf node chosen
 * by the heuristic.
 */
template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
void RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    InsertPoint(const arma::vec& point)
{

  std::cout << "insert point called" << std::endl;
  // Expand the bound regardless of whether it is a leaf node.
  bound |= point;

  // If this is a leaf node, we stop here and add the point.
  if(numChildren == 0) {
    std::cout << "count = " << count << std::endl;
    dataset->col(count++) = point;
    SplitNode();
    return;
  }

  // If it is not a leaf node, we use the DescentHeuristic to choose a child
  // to which we recurse.
  double minScore = DescentType::EvalNode(children[0]->Bound(), point);
  int bestIndex = 0;

  for(int i = 1; i < numChildren; i++) {
    double score = DescentType::EvalNode(children[i]->Bound(), point);
    if(score < minScore) {
      minScore = score;
      bestIndex = i;
    }
  }
  children[bestIndex]->InsertPoint(point);
}

template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    TreeSize() const
{
  int n = 0;
  for(int i = 0; i < numChildren; i++) {
    n += children[i]->TreeSize();
  }
  return n + 1; // we add one for this node
}

template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    TreeDepth() const
{
  /* Because R trees are balanced, we could simplify this.  However, X trees are not
     guaranteed to be balanced so I keep it as is: */

  // Recursively count the depth of each subtree.  The plus one is
  // because we have to count this node, too.
  int maxSubDepth = 0;
  for(int i = 0; i < numChildren; i++) {
    int d = children[i]->TreeDepth();
    if(d > maxSubDepth)
      maxSubDepth = d;
  }
  return maxSubDepth + 1;
}

template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
inline bool RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    IsLeaf() const
{
  return numChildren == 0;
}

/**
 * Return a bound on the furthest point in the node form the centroid.
 * This returns 0 unless the node is a leaf.
 */
template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
inline double RectangleTree<SplitType, DescentType, StatisticType, MatType>::
FurthestPointDistance() const
{
  if(!IsLeaf())
    return 0.0;

  // Otherwise return the distance from the centroid to a corner of the bound.
  return 0.5 * bound.Diameter();
}

/**
 * Return the furthest possible descendant distance.  This returns the maximum
 * distance from the centroid to the edge of the bound and not the empirical
 * quantity which is the actual furthest descendant distance.  So the actual
 * furthest descendant distance may be less than what this method returns (but
 * it will never be greater than this).
 */
template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
inline double RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    FurthestDescendantDistance() const
{
  return furthestDescendantDistance;
}

/**
 * Return the number of points contained in this node.  Zero if it is a non-leaf node.
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    NumPoints() const
{
  if(numChildren != 0) // This is not a leaf node.
    return 0;

  return count;
}

/**
 * Return the number of descendants contained in this node.  MEANINIGLESS AS IT CURRENTLY STANDS.
 * USE NumPoints() INSTEAD.
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    NumDescendants() const
{
  return count;
}

/**
 * Return the index of a particular descendant contained in this node.  SEE OTHER WARNINGS
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    Descendant(const size_t index) const
{
  return (begin + index);
}

/**
 * Return the index of a particular point contained in this node.  SEE OTHER WARNINGS
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    Point(const size_t index) const
{
  return (begin + index);
}

/**
 * Return the last point in the tree.  SINCE THE TREE STORES DATA SEPARATELY IN EACH LEAF
 * THIS IS CURRENTLY MEANINGLESS.
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::End() const
{
  if(numChildren)
    return begin + count;
  return children[numChildren-1]->End();
}

  //have functions for returning the list of modified indices if we end up doing it that way.

/**
 * Split the tree.  This calls the SplitType code to split a node.  This method should only
 * be called on a leaf node.
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
void RectangleTree<SplitType, DescentType, StatisticType, MatType>::SplitNode()
{
  // This should always be a leaf node.  When we need to split other nodes,
  // the split will be called from here but will take place in the SplitType code.
  assert(numChildren == 0);

  // Check to see if we are full.
  if(count < maxLeafSize)
    return; // We don't need to split.

  std::cout << "we are actually splitting the node." << std::endl;
  // If we are full, then we need to split (or at least try).  The SplitType takes
  // care of this and of moving up the tree if necessary.
  SplitType::SplitLeafNode(this);
  std::cout << "we finished actually splitting the node." << std::endl;

  std::cout << ToString() << std::endl;
}

/**
 * Returns a string representation of this object.
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
std::string RectangleTree<SplitType, DescentType, StatisticType, MatType>::ToString() const
{
  std::ostringstream convert;
  convert << "RectangleTree [" << this << "]" << std::endl;
  convert << "  First point: " << begin << std::endl;
  convert << "  Number of descendants: " << numChildren << std::endl;
  convert << "  Number of points: " << count << std::endl;
  convert << "  Bound: " << std::endl;
  convert << mlpack::util::Indent(bound.ToString(), 2);
  convert << "  Statistic: " << std::endl;
  //convert << mlpack::util::Indent(stat.ToString(), 2);
  convert << "  Max leaf size: " << maxLeafSize << std::endl;
  convert << "  Min leaf size: " << minLeafSize << std::endl;
  convert << "  Max num of children: " << maxNumChildren << std::endl;
  convert << "  Min num of children: " << minNumChildren << std::endl;
  convert << "  Parent address: " << parent << std::endl;

  // How many levels should we print?  This will print the root and it's children.
  if(parent == NULL || parent->Parent() == NULL) {
    for(int i = 0; i < numChildren; i++) {
      convert << children[i]->ToString();
    }
  }
  return convert.str();
}

}; //namespace tree
}; //namespace mlpack

#endif
<commit_msg>bug fix.   had n_rows when I needed n_cols<commit_after>/**
 * @file rectangle_tree_impl.hpp
 * @author Andrew Wells
 *
 * Implementation of generalized rectangle tree.
 */
#ifndef __MLPACK_CORE_TREE_RECTANGLE_TREE_RECTANGLE_TREE_IMPL_HPP
#define __MLPACK_CORE_TREE_RECTANGLE_TREE_RECTANGLE_TREE_IMPL_HPP

// In case it wasn't included already for some reason.
#include "rectangle_tree.hpp"

#include <mlpack/core/util/cli.hpp>
#include <mlpack/core/util/log.hpp>
#include <mlpack/core/util/string_util.hpp>

namespace mlpack {
namespace tree {

template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
RectangleTree<SplitType, DescentType, StatisticType, MatType>::RectangleTree(
    MatType& data,
    const size_t maxLeafSize = 20,
    const size_t minLeafSize = 6,
    const size_t maxNumChildren = 4,
    const size_t minNumChildren = 0,
    const size_t firstDataIndex = 0):
    maxNumChildren(maxNumChildren),
    minNumChildren(minNumChildren),
    numChildren(0),
    children(maxNumChildren+1), // Add one to make splitting the node simpler
    parent(NULL),
    begin(0),
    count(0),
    maxLeafSize(maxLeafSize),
    minLeafSize(minLeafSize),
    bound(data.n_rows),
    parentDistance(0),
    dataset(new MatType(data.n_rows, static_cast<int>(maxLeafSize)+1)) // Add one to make splitting the node simpler
{
  stat = StatisticType(*this);

  std::cout << ToString() << std::endl;

  // For now, just insert the points in order.
  RectangleTree* root = this;

  //for(int i = firstDataIndex; i < 57; i++) { // 56,57 are the bound for where it works/breaks
  for(int i = firstDataIndex; i < data.n_cols; i++) {
    std::cout << "inserting point number: " << i << std::endl;
    root->InsertPoint(data.col(i));
    std::cout << "finished inserting point number: " << i << std::endl;
    std::cout << ToString() << std::endl;
  }

}

template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
RectangleTree<SplitType, DescentType, StatisticType, MatType>::RectangleTree(
  RectangleTree<SplitType, DescentType, StatisticType, MatType>* parentNode):
  maxNumChildren(parentNode->MaxNumChildren()),
  minNumChildren(parentNode->MinNumChildren()),
  numChildren(0),
  children(maxNumChildren+1),
  parent(parentNode),
  begin(0),
  count(0),
  maxLeafSize(parentNode->MaxLeafSize()),
  minLeafSize(parentNode->MinLeafSize()),
  bound(parentNode->Bound().Dim()),
  parentDistance(0),
  dataset(new MatType(static_cast<int>(parentNode->Bound().Dim()), static_cast<int>(maxLeafSize)+1)) // Add one to make splitting the node simpler
{
  stat = StatisticType(*this);
}

/**
 * Deletes this node, deallocating the memory for the children and calling
 * their destructors in turn.  This will invalidate any pointers or references
 * to any nodes which are children of this one.
 */
template<typename SplitType,
         typename DescentType,
	typename StatisticType,
         typename MatType>
RectangleTree<SplitType, DescentType, StatisticType, MatType>::
  ~RectangleTree()
{
  //LEAK MEMORY

  for(int i = 0; i < numChildren; i++) {
    delete children[i];
  }
  delete dataset;
}

/**
  * Deletes this node but leaves the children untouched.  Needed for when we
  * split nodes and remove nodes (inserting and deleting points).
  */
template<typename SplitType,
                  typename DescentType,
                  typename StatisticType,
                  typename MatType>
void RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    softDelete()
{
  /* do nothing.  I'm not sure how to handle this yet, so for now, we will leak memory */
}

/**
 * Recurse through the tree and insert the point at the leaf node chosen
 * by the heuristic.
 */
template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
void RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    InsertPoint(const arma::vec& point)
{

  std::cout << "insert point called" << std::endl;
  // Expand the bound regardless of whether it is a leaf node.
  bound |= point;

  // If this is a leaf node, we stop here and add the point.
  if(numChildren == 0) {
    std::cout << "count = " << count << std::endl;
    dataset->col(count++) = point;
    SplitNode();
    return;
  }

  // If it is not a leaf node, we use the DescentHeuristic to choose a child
  // to which we recurse.
  double minScore = DescentType::EvalNode(children[0]->Bound(), point);
  int bestIndex = 0;

  for(int i = 1; i < numChildren; i++) {
    double score = DescentType::EvalNode(children[i]->Bound(), point);
    if(score < minScore) {
      minScore = score;
      bestIndex = i;
    }
  }
  children[bestIndex]->InsertPoint(point);
}

template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    TreeSize() const
{
  int n = 0;
  for(int i = 0; i < numChildren; i++) {
    n += children[i]->TreeSize();
  }
  return n + 1; // we add one for this node
}

template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    TreeDepth() const
{
  /* Because R trees are balanced, we could simplify this.  However, X trees are not
     guaranteed to be balanced so I keep it as is: */

  // Recursively count the depth of each subtree.  The plus one is
  // because we have to count this node, too.
  int maxSubDepth = 0;
  for(int i = 0; i < numChildren; i++) {
    int d = children[i]->TreeDepth();
    if(d > maxSubDepth)
      maxSubDepth = d;
  }
  return maxSubDepth + 1;
}

template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
inline bool RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    IsLeaf() const
{
  return numChildren == 0;
}

/**
 * Return a bound on the furthest point in the node form the centroid.
 * This returns 0 unless the node is a leaf.
 */
template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
inline double RectangleTree<SplitType, DescentType, StatisticType, MatType>::
FurthestPointDistance() const
{
  if(!IsLeaf())
    return 0.0;

  // Otherwise return the distance from the centroid to a corner of the bound.
  return 0.5 * bound.Diameter();
}

/**
 * Return the furthest possible descendant distance.  This returns the maximum
 * distance from the centroid to the edge of the bound and not the empirical
 * quantity which is the actual furthest descendant distance.  So the actual
 * furthest descendant distance may be less than what this method returns (but
 * it will never be greater than this).
 */
template<typename SplitType,
         typename DescentType,
	 typename StatisticType,
         typename MatType>
inline double RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    FurthestDescendantDistance() const
{
  return furthestDescendantDistance;
}

/**
 * Return the number of points contained in this node.  Zero if it is a non-leaf node.
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    NumPoints() const
{
  if(numChildren != 0) // This is not a leaf node.
    return 0;

  return count;
}

/**
 * Return the number of descendants contained in this node.  MEANINIGLESS AS IT CURRENTLY STANDS.
 * USE NumPoints() INSTEAD.
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    NumDescendants() const
{
  return count;
}

/**
 * Return the index of a particular descendant contained in this node.  SEE OTHER WARNINGS
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    Descendant(const size_t index) const
{
  return (begin + index);
}

/**
 * Return the index of a particular point contained in this node.  SEE OTHER WARNINGS
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::
    Point(const size_t index) const
{
  return (begin + index);
}

/**
 * Return the last point in the tree.  SINCE THE TREE STORES DATA SEPARATELY IN EACH LEAF
 * THIS IS CURRENTLY MEANINGLESS.
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
inline size_t RectangleTree<SplitType, DescentType, StatisticType, MatType>::End() const
{
  if(numChildren)
    return begin + count;
  return children[numChildren-1]->End();
}

  //have functions for returning the list of modified indices if we end up doing it that way.

/**
 * Split the tree.  This calls the SplitType code to split a node.  This method should only
 * be called on a leaf node.
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
void RectangleTree<SplitType, DescentType, StatisticType, MatType>::SplitNode()
{
  // This should always be a leaf node.  When we need to split other nodes,
  // the split will be called from here but will take place in the SplitType code.
  assert(numChildren == 0);

  // Check to see if we are full.
  if(count < maxLeafSize)
    return; // We don't need to split.

  std::cout << "we are actually splitting the node." << std::endl;
  // If we are full, then we need to split (or at least try).  The SplitType takes
  // care of this and of moving up the tree if necessary.
  SplitType::SplitLeafNode(this);
  std::cout << "we finished actually splitting the node." << std::endl;

  std::cout << ToString() << std::endl;
}

/**
 * Returns a string representation of this object.
 */
template<typename SplitType,
	 typename DescentType,
	 typename StatisticType,
	 typename MatType>
std::string RectangleTree<SplitType, DescentType, StatisticType, MatType>::ToString() const
{
  std::ostringstream convert;
  convert << "RectangleTree [" << this << "]" << std::endl;
  convert << "  First point: " << begin << std::endl;
  convert << "  Number of descendants: " << numChildren << std::endl;
  convert << "  Number of points: " << count << std::endl;
  convert << "  Bound: " << std::endl;
  convert << mlpack::util::Indent(bound.ToString(), 2);
  convert << "  Statistic: " << std::endl;
  //convert << mlpack::util::Indent(stat.ToString(), 2);
  convert << "  Max leaf size: " << maxLeafSize << std::endl;
  convert << "  Min leaf size: " << minLeafSize << std::endl;
  convert << "  Max num of children: " << maxNumChildren << std::endl;
  convert << "  Min num of children: " << minNumChildren << std::endl;
  convert << "  Parent address: " << parent << std::endl;

  // How many levels should we print?  This will print the root and it's children.
  if(parent == NULL || parent->Parent() == NULL) {
    for(int i = 0; i < numChildren; i++) {
      convert << children[i]->ToString();
    }
  }
  return convert.str();
}

}; //namespace tree
}; //namespace mlpack

#endif
<|endoftext|>


<commit_before>#include <nds.h>
#include <maxmod9.h>
#include <stdio.h>

#include "ball.h"
#include "geometry.h"
#include "player.h"
#include "stats.h"

// Audio
#include "soundbank.h"
#include "soundbank_bin.h"

// Methods

void initBall(ball *b) {
    b->speed = 2;
    b->box.pos.x = 100;
    b->box.pos.y = 30;
    b->box.width = 10;
    b->box.height = 10;
    b->direction.x = 1;
    b->direction.y = 1;

    // SFX_WALL
    b->sfx_wall.id = SFX_WALL;
    b->sfx_wall.rate = 1024;
    b->sfx_wall.handle = 0;
    b->sfx_wall.volume = 255;
    b->sfx_wall.panning = 128;

    // SFX_PANEL
    b->sfx_panel.id = SFX_PANEL;
    b->sfx_panel.rate = 1024;
    b->sfx_panel.handle = 0;
    b->sfx_panel.volume = 255;
    b->sfx_panel.panning = 128;

    // SFX_READY
    b->sfx_scoring.id = SFX_READY;
    b->sfx_scoring.rate = 1024;
    b->sfx_scoring.handle = 0;
    b->sfx_scoring.volume = 255;
    b->sfx_scoring.panning = 128;
}

/**
 * @param ball b
 * @return void
 */
void moveBall(ball *b, player *p1, player *p2, scoreBox *sBox) {
    b->box.pos.x += b->direction.x * b->speed;
    b->box.pos.y += b->direction.y * b->speed;

    bool hitLeftPaddle = intersect(b->box, p1->box);
    bool hitRightPaddle = intersect(b->box, p2->box);

    // horizontal collision
    if (b->box.pos.x <= 0) {
       scoring(1, b, sBox);
    } else if (b->box.pos.x + b->box.width >= SCREEN_WIDTH) {
       scoring(0, b, sBox);
    } else if (hitLeftPaddle || hitRightPaddle) {
        // calculate relative position to player box, then set direction according to that relative position
        // if relative position is low (i.e. closer to 0, the ball hit the paddle early),
        // then the ball goes back in the direction it came from
        // if relative position is high (i.e. closer to 1, the ball hit the paddle late),
        // then the ball bounces off the paddle, going off in the other direction
        // if relative position is around 0.5 (i.e. the ball hit the paddle in the middle),
        // then the ball goes back from the middle of the paddle
        float relativePos;
        if (hitLeftPaddle) {
            // player 1
            relativePos = (b->box.pos.y - p1->box.pos.y) / (p1->box.height);
        } else {
            // player 2
            relativePos = (b->box.pos.y - p2->box.pos.y) / (p2->box.height);
        }
        // y is negative, so the ball is flying up: reverse relative position
        if (b->direction.y < 0) {
            relativePos = 1 - relativePos;
        }

        // new x direction, reverse the sign
        b->direction.x *= -1;

        // new y direction, keep the sign
        b->direction.y = (b->direction.y > 0) ? 1 : -1;
        b->direction.y *= 0.5 - 1.5 * relativePos;

        // position ball so that it does not intersect the paddles anymore
        if (hitLeftPaddle) {
            b->box.pos.x = p1->box.pos.x + p1->box.width;
        } else {
            b->box.pos.x = p2->box.pos.x - b->box.width;
        }

        // sound effect
        mmEffect( SFX_PANEL );
        mmEffectEx( &b->sfx_panel );
    }

    // vertical collision
    if (b->box.pos.y <= 0 || b->box.pos.y + b->box.height >= SCREEN_HEIGHT) {
        b->direction.y *= -1;
        mmEffect( SFX_WALL );
        mmEffectEx( &b->sfx_wall );
    }

    // Updating sprite position
    b->sprite->x = (int)b->box.pos.x;
    b->sprite->y = (int)b->box.pos.y;
}

void scoring(int player, ball *b, scoreBox *sBox) {
    b->box.pos.x = SCREEN_WIDTH / 2;
    b->box.pos.y = SCREEN_HEIGHT / 2;
    b->direction.x = (b->direction.x > 0) ? -1 : 1;
    b->direction.y = 1;

    countPoint(sBox, player);

    mmEffectEx( &b->sfx_scoring );
    mmEffect( SFX_READY );
}
<commit_msg>Revert "konvex -> konkav"<commit_after>#include <nds.h>
#include <maxmod9.h>
#include <stdio.h>

#include "ball.h"
#include "geometry.h"
#include "player.h"
#include "stats.h"

// Audio
#include "soundbank.h"
#include "soundbank_bin.h"

// Methods

void initBall(ball *b) {
    b->speed = 2;
    b->box.pos.x = 100;
    b->box.pos.y = 30;
    b->box.width = 10;
    b->box.height = 10;
    b->direction.x = 1;
    b->direction.y = 1;

    // SFX_WALL
    b->sfx_wall.id = SFX_WALL;
    b->sfx_wall.rate = 1024;
    b->sfx_wall.handle = 0;
    b->sfx_wall.volume = 255;
    b->sfx_wall.panning = 128;

    // SFX_PANEL
    b->sfx_panel.id = SFX_PANEL;
    b->sfx_panel.rate = 1024;
    b->sfx_panel.handle = 0;
    b->sfx_panel.volume = 255;
    b->sfx_panel.panning = 128;

    // SFX_READY
    b->sfx_scoring.id = SFX_READY;
    b->sfx_scoring.rate = 1024;
    b->sfx_scoring.handle = 0;
    b->sfx_scoring.volume = 255;
    b->sfx_scoring.panning = 128;
}

/**
 * @param ball b
 * @return void
 */
void moveBall(ball *b, player *p1, player *p2, scoreBox *sBox) {
    b->box.pos.x += b->direction.x * b->speed;
    b->box.pos.y += b->direction.y * b->speed;

    bool hitLeftPaddle = intersect(b->box, p1->box);
    bool hitRightPaddle = intersect(b->box, p2->box);

    // horizontal collision
    if (b->box.pos.x <= 0) {
       scoring(1, b, sBox);
    } else if (b->box.pos.x + b->box.width >= SCREEN_WIDTH) {
       scoring(0, b, sBox);
    } else if (hitLeftPaddle || hitRightPaddle) {
        // calculate relative position to player box, then set direction according to that relative position
        // if relative position is low (i.e. closer to 0, the ball hit the paddle early),
        // then the ball goes back in the direction it came from
        // if relative position is high (i.e. closer to 1, the ball hit the paddle late),
        // then the ball bounces off the paddle, going off in the other direction
        // if relative position is around 0.5 (i.e. the ball hit the paddle in the middle),
        // then the ball goes back from the middle of the paddle
        float relativePos;
        if (hitLeftPaddle) {
            // player 1
            relativePos = (b->box.pos.y - p1->box.pos.y) / (p1->box.height);
        } else {
            // player 2
            relativePos = (b->box.pos.y - p2->box.pos.y) / (p2->box.height);
        }
        // y is negative, so the ball is flying up: reverse relative position
        if (b->direction.y < 0) {
            relativePos = 1 - relativePos;
        }

        // new x direction, reverse the sign
        b->direction.x *= -1;

        // new y direction, keep the sign
        b->direction.y = (b->direction.y > 0) ? 1 : -1;
        b->direction.y *= -0.5 + 1.5 * relativePos;

        // position ball so that it does not intersect the paddles anymore
        if (hitLeftPaddle) {
            b->box.pos.x = p1->box.pos.x + p1->box.width;
        } else {
            b->box.pos.x = p2->box.pos.x - b->box.width;
        }

        // sound effect
        mmEffect( SFX_PANEL );
        mmEffectEx( &b->sfx_panel );
    }

    // vertical collision
    if (b->box.pos.y <= 0 || b->box.pos.y + b->box.height >= SCREEN_HEIGHT) {
        b->direction.y *= -1;
        mmEffect( SFX_WALL );
        mmEffectEx( &b->sfx_wall );
    }

    // Updating sprite position
    b->sprite->x = (int)b->box.pos.x;
    b->sprite->y = (int)b->box.pos.y;
}

void scoring(int player, ball *b, scoreBox *sBox) {
    b->box.pos.x = SCREEN_WIDTH / 2;
    b->box.pos.y = SCREEN_HEIGHT / 2;
    b->direction.x = (b->direction.x > 0) ? -1 : 1;
    b->direction.y = 1;

    countPoint(sBox, player);

    mmEffectEx( &b->sfx_scoring );
    mmEffect( SFX_READY );
}
<|endoftext|>


<commit_before>//
// Created by pkanev on 4/24/2017.
//

#include <NativeScriptAssert.h>
#include "v8-dom-agent-impl.h"
#include <ArgConverter.h>
#include <Runtime.h>
#include <v8_inspector/src/inspector/utils/v8-inspector-common.h>

namespace v8_inspector {

using tns::Runtime;
using tns::ArgConverter;

namespace DOMAgentState {
static const char domEnabled[] = "domEnabled";
}

V8DOMAgentImpl::V8DOMAgentImpl(V8InspectorSessionImpl* session,
                               protocol::FrontendChannel* frontendChannel,
                               protocol::DictionaryValue* state)
    : m_session(session),
      m_frontend(frontendChannel),
      m_state(state),
      m_enabled(false) {
    Instance = this;
}

V8DOMAgentImpl::~V8DOMAgentImpl() { }

void V8DOMAgentImpl::enable(ErrorString*) {
    if (m_enabled) {
        return;
    }

    m_state->setBoolean(DOMAgentState::domEnabled, true);

    m_enabled = true;
}

void V8DOMAgentImpl::disable(ErrorString*) {
    if (!m_enabled) {
        return;
    }

    m_state->setBoolean(DOMAgentState::domEnabled, false);

    m_enabled = false;
}

void V8DOMAgentImpl::getDocument(ErrorString* errorString, std::unique_ptr<protocol::DOM::Node>* out_root) {
    std::unique_ptr<protocol::DOM::Node> defaultNode = protocol::DOM::Node::create()
            .setNodeId(0)
            .setNodeType(9)
            .setNodeName("Frame")
            .setLocalName("Frame")
            .setNodeValue("")
            .build();

    std::string getDocumentFunctionString = "getDocument";
    // TODO: Pete: Find a better way to get a hold of the isolate
    auto isolate = v8::Isolate::GetCurrent();
    auto context = isolate->GetCurrentContext();
    auto global = context->Global();

    auto globalInspectorObject = utils::Common::getGlobalInspectorObject(isolate);

    if (!globalInspectorObject.IsEmpty()) {
        auto getDocument = globalInspectorObject->Get(ArgConverter::ConvertToV8String(isolate, getDocumentFunctionString));

        if (!getDocument.IsEmpty() && getDocument->IsFunction()) {
            auto getDocumentFunc = getDocument.As<v8::Function>();
            v8::Local<v8::Value> args[] = {  };
            v8::TryCatch tc;

            auto maybeResult = getDocumentFunc->Call(context, global, 0, args);

            if (tc.HasCaught()) {
                *errorString = utils::Common::getJSCallErrorMessage(getDocumentFunctionString, tc.Message()->Get()).c_str();

                *out_root = std::move(defaultNode);
                return;
            }

            v8::Local<v8::Value> outResult;

            if (maybeResult.ToLocal(&outResult)) {
                auto resultString = ArgConverter::ConvertToUtf16String(outResult->ToString());

                auto resultUtf16Data = resultString.data();

                auto resultJson = protocol::parseJSON(String16((const uint16_t*) resultUtf16Data));

                protocol::ErrorSupport errorSupport;
                auto domNode = protocol::DOM::Node::parse(resultJson.get(), &errorSupport);

                auto errorSupportString = errorSupport.errors().utf8();
                *errorString = errorSupportString.c_str();
                if (!errorSupportString.empty()) {
                    auto errorMessage = "Error while parsing debug `DOM Node` object. ";
                    DEBUG_WRITE_FORCE("JS Error: %s", errorMessage, errorSupportString.c_str());
                } else {
                    *out_root = std::move(domNode);

                    return;
                }
            } else {
                *errorString = "Didn't get a proper result from __getDocument call. Returning empty visual tree.";
            }
        }
    }

    *out_root = std::move(defaultNode);
}

void V8DOMAgentImpl::removeNode(ErrorString* errorString, int in_nodeId) {
    std::string removeNodeFunctionString = "removeNode";

    // TODO: Pete: Find a better way to get a hold of the isolate
    auto isolate = v8::Isolate::GetCurrent();
    auto context = isolate->GetCurrentContext();
    auto global = context->Global();

    auto globalInspectorObject = utils::Common::getGlobalInspectorObject(isolate);

    if (!globalInspectorObject.IsEmpty()) {
        auto removeNode = globalInspectorObject->Get(ArgConverter::ConvertToV8String(isolate, removeNodeFunctionString));

        if (!removeNode.IsEmpty() && removeNode->IsFunction()) {
            auto removeNodeFunc = removeNode.As<v8::Function>();
            v8::Local<v8::Value> args[] = { v8::Number::New(isolate, in_nodeId) };
            v8::TryCatch tc;

            removeNodeFunc->Call(context, global, 1, args);

            if (tc.HasCaught()) {
                *errorString = utils::Common::getJSCallErrorMessage(removeNodeFunctionString, tc.Message()->Get()).c_str();
            }

            return;
        }
    }

    *errorString = "Couldn't remove the selected DOMNode from the visual tree.";
}

// Pete: return empty resolved object - prevents crashes when opening the 'properties', 'event listeners' tabs
// Not supported
void V8DOMAgentImpl::resolveNode(ErrorString*, int in_nodeId, const Maybe<String>& in_objectGroup, std::unique_ptr<protocol::Runtime::RemoteObject>* out_object) {
    auto resolvedNode = protocol::Runtime::RemoteObject::create()
                        .setType("View")
                        .build();

    *out_object = std::move(resolvedNode);
}

void V8DOMAgentImpl::setAttributeValue(ErrorString* errorString, int in_nodeId, const String& in_name,
                                       const String& in_value) {
    // Irrelevant
}

void V8DOMAgentImpl::setAttributesAsText(ErrorString* errorString, int in_nodeId, const String& in_text,
        const Maybe<String>& in_name) {
    // call modules' View class methods to modify view's attribute
    // TODO: Pete: Find a better way to get a hold of the isolate
    std::string setAttributeAsTextFunctionString = "setAttributeAsText";
    auto isolate = v8::Isolate::GetCurrent();
    auto context = isolate->GetCurrentContext();
    auto global = context->Global();

    auto globalInspectorObject = utils::Common::getGlobalInspectorObject(isolate);

    if (!globalInspectorObject.IsEmpty()) {
        auto setAttributeAsText = globalInspectorObject->Get(ArgConverter::ConvertToV8String(isolate, setAttributeAsTextFunctionString));

        if (!setAttributeAsText.IsEmpty() && setAttributeAsText->IsFunction()) {
            auto setAttributeAsTextFunc = setAttributeAsText.As<v8::Function>();
            // TODO: Pete: Setting the content to contain utf-16 characters will still output garbage
            v8::Local<v8::Value> args[] = {
                v8::Number::New(isolate, in_nodeId),
                v8_inspector::toV8String(isolate, in_text),
                v8_inspector::toV8String(isolate, in_name.fromJust())
            };
            v8::TryCatch tc;

            setAttributeAsTextFunc->Call(context, global, 3, args);

            if (tc.HasCaught()) {
                *errorString = utils::Common::getJSCallErrorMessage(setAttributeAsTextFunctionString, tc.Message()->Get()).c_str();
            }

            return;
        }
    }
}

void V8DOMAgentImpl::removeAttribute(ErrorString* errorString, int in_nodeId, const String& in_name) {
    // Irrelevant
}

// Not supported
void V8DOMAgentImpl::performSearch(ErrorString*, const String& in_query,
                                   const Maybe<protocol::Array<int>>& in_nodeIds,
                                   String* out_searchId, int* out_resultCount) {

}

// Not supported
void V8DOMAgentImpl::getSearchResults(ErrorString*, const String& in_searchId, int in_fromIndex,
                                      int in_toIndex,
                                      std::unique_ptr<protocol::Array<int>>* out_nodeIds) {

}

// Not supported
void V8DOMAgentImpl::discardSearchResults(ErrorString*, const String& in_searchId) {

}

V8DOMAgentImpl* V8DOMAgentImpl::Instance = 0;
}
<commit_msg>fix(devtools): if Elements tab is empty, try to repopulate on consecutive opening<commit_after>//
// Created by pkanev on 4/24/2017.
//

#include <NativeScriptAssert.h>
#include "v8-dom-agent-impl.h"
#include <ArgConverter.h>
#include <Runtime.h>
#include <v8_inspector/src/inspector/utils/v8-inspector-common.h>

namespace v8_inspector {

using tns::Runtime;
using tns::ArgConverter;

namespace DOMAgentState {
static const char domEnabled[] = "domEnabled";
}

V8DOMAgentImpl::V8DOMAgentImpl(V8InspectorSessionImpl* session,
                               protocol::FrontendChannel* frontendChannel,
                               protocol::DictionaryValue* state)
    : m_session(session),
      m_frontend(frontendChannel),
      m_state(state),
      m_enabled(false) {
    Instance = this;
}

V8DOMAgentImpl::~V8DOMAgentImpl() { }

void V8DOMAgentImpl::enable(ErrorString*) {
    if (m_enabled) {
        return;
    }

    m_state->setBoolean(DOMAgentState::domEnabled, true);

    m_enabled = true;
}

void V8DOMAgentImpl::disable(ErrorString*) {
    if (!m_enabled) {
        return;
    }

    m_state->setBoolean(DOMAgentState::domEnabled, false);

    m_enabled = false;
}

void V8DOMAgentImpl::getDocument(ErrorString* errorString, std::unique_ptr<protocol::DOM::Node>* out_root) {
    std::string getDocumentFunctionString = "getDocument";
    // TODO: Pete: Find a better way to get a hold of the isolate
    auto isolate = v8::Isolate::GetCurrent();
    auto context = isolate->GetCurrentContext();
    auto global = context->Global();

    auto globalInspectorObject = utils::Common::getGlobalInspectorObject(isolate);

    if (!globalInspectorObject.IsEmpty()) {
        auto getDocument = globalInspectorObject->Get(ArgConverter::ConvertToV8String(isolate, getDocumentFunctionString));

        if (!getDocument.IsEmpty() && getDocument->IsFunction()) {
            auto getDocumentFunc = getDocument.As<v8::Function>();
            v8::Local<v8::Value> args[] = {  };
            v8::TryCatch tc;

            auto maybeResult = getDocumentFunc->Call(context, global, 0, args);

            if (tc.HasCaught()) {
                *errorString = utils::Common::getJSCallErrorMessage(getDocumentFunctionString, tc.Message()->Get()).c_str();

                return;
            }

            v8::Local<v8::Value> outResult;

            if (maybeResult.ToLocal(&outResult)) {
                auto resultString = ArgConverter::ConvertToUtf16String(outResult->ToString());

                auto resultUtf16Data = resultString.data();

                auto resultJson = protocol::parseJSON(String16((const uint16_t*) resultUtf16Data));

                protocol::ErrorSupport errorSupport;
                auto domNode = protocol::DOM::Node::parse(resultJson.get(), &errorSupport);

                auto errorSupportString = errorSupport.errors().utf8();
                *errorString = errorSupportString.c_str();
                if (!errorSupportString.empty()) {
                    auto errorMessage = "Error while parsing debug `DOM Node` object. ";
                    DEBUG_WRITE_FORCE("JS Error: %s", errorMessage, errorSupportString.c_str());
                    *errorString = errorSupportString.c_str();
                } else {
                    *out_root = std::move(domNode);

                    return;
                }
            } else {
                *errorString = "Didn't get a proper result from __getDocument call. Returning empty visual tree.";
            }
        }
    }

    *errorString = "getDocument function not available on the global object.";
}

void V8DOMAgentImpl::removeNode(ErrorString* errorString, int in_nodeId) {
    std::string removeNodeFunctionString = "removeNode";

    // TODO: Pete: Find a better way to get a hold of the isolate
    auto isolate = v8::Isolate::GetCurrent();
    auto context = isolate->GetCurrentContext();
    auto global = context->Global();

    auto globalInspectorObject = utils::Common::getGlobalInspectorObject(isolate);

    if (!globalInspectorObject.IsEmpty()) {
        auto removeNode = globalInspectorObject->Get(ArgConverter::ConvertToV8String(isolate, removeNodeFunctionString));

        if (!removeNode.IsEmpty() && removeNode->IsFunction()) {
            auto removeNodeFunc = removeNode.As<v8::Function>();
            v8::Local<v8::Value> args[] = { v8::Number::New(isolate, in_nodeId) };
            v8::TryCatch tc;

            removeNodeFunc->Call(context, global, 1, args);

            if (tc.HasCaught()) {
                *errorString = utils::Common::getJSCallErrorMessage(removeNodeFunctionString, tc.Message()->Get()).c_str();
            }

            return;
        }
    }

    *errorString = "Couldn't remove the selected DOMNode from the visual tree.";
}

// Pete: return empty resolved object - prevents crashes when opening the 'properties', 'event listeners' tabs
// Not supported
void V8DOMAgentImpl::resolveNode(ErrorString*, int in_nodeId, const Maybe<String>& in_objectGroup, std::unique_ptr<protocol::Runtime::RemoteObject>* out_object) {
    auto resolvedNode = protocol::Runtime::RemoteObject::create()
                        .setType("View")
                        .build();

    *out_object = std::move(resolvedNode);
}

void V8DOMAgentImpl::setAttributeValue(ErrorString* errorString, int in_nodeId, const String& in_name,
                                       const String& in_value) {
    // Irrelevant
}

void V8DOMAgentImpl::setAttributesAsText(ErrorString* errorString, int in_nodeId, const String& in_text,
        const Maybe<String>& in_name) {
    // call modules' View class methods to modify view's attribute
    // TODO: Pete: Find a better way to get a hold of the isolate
    std::string setAttributeAsTextFunctionString = "setAttributeAsText";
    auto isolate = v8::Isolate::GetCurrent();
    auto context = isolate->GetCurrentContext();
    auto global = context->Global();

    auto globalInspectorObject = utils::Common::getGlobalInspectorObject(isolate);

    if (!globalInspectorObject.IsEmpty()) {
        auto setAttributeAsText = globalInspectorObject->Get(ArgConverter::ConvertToV8String(isolate, setAttributeAsTextFunctionString));

        if (!setAttributeAsText.IsEmpty() && setAttributeAsText->IsFunction()) {
            auto setAttributeAsTextFunc = setAttributeAsText.As<v8::Function>();
            // TODO: Pete: Setting the content to contain utf-16 characters will still output garbage
            v8::Local<v8::Value> args[] = {
                v8::Number::New(isolate, in_nodeId),
                v8_inspector::toV8String(isolate, in_text),
                v8_inspector::toV8String(isolate, in_name.fromJust())
            };
            v8::TryCatch tc;

            setAttributeAsTextFunc->Call(context, global, 3, args);

            if (tc.HasCaught()) {
                *errorString = utils::Common::getJSCallErrorMessage(setAttributeAsTextFunctionString, tc.Message()->Get()).c_str();
            }

            return;
        }
    }
}

void V8DOMAgentImpl::removeAttribute(ErrorString* errorString, int in_nodeId, const String& in_name) {
    // Irrelevant
}

// Not supported
void V8DOMAgentImpl::performSearch(ErrorString*, const String& in_query,
                                   const Maybe<protocol::Array<int>>& in_nodeIds,
                                   String* out_searchId, int* out_resultCount) {

}

// Not supported
void V8DOMAgentImpl::getSearchResults(ErrorString*, const String& in_searchId, int in_fromIndex,
                                      int in_toIndex,
                                      std::unique_ptr<protocol::Array<int>>* out_nodeIds) {

}

// Not supported
void V8DOMAgentImpl::discardSearchResults(ErrorString*, const String& in_searchId) {

}

V8DOMAgentImpl* V8DOMAgentImpl::Instance = 0;
}
<|endoftext|>