<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This utility program exists to process the False Start blacklist file into
// a static hash table so that it can be efficiently queried by Chrome.

#include <stdio.h>
#include <stdlib.h>

#include <set>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "net/base/ssl_false_start_blacklist.h"

using net::SSLFalseStartBlacklist;

static const unsigned kBuckets = SSLFalseStartBlacklist::kBuckets;

static bool verbose = false;

static int
usage(const char* argv0) {
  fprintf(stderr, "Usage: %s <blacklist file> <output .c file>\n", argv0);
  return 1;
}

// StripWWWPrefix removes "www." from the beginning of any elements of the
// vector.
static void StripWWWPrefix(std::vector<std::string>* hosts) {
  static const char kPrefix[] = "www.";
  static const unsigned kPrefixLen = sizeof(kPrefix) - 1;

  for (size_t i = 0; i < hosts->size(); i++) {
    const std::string& h = (*hosts)[i];
    if (h.size() >= kPrefixLen &&
        memcmp(h.data(), kPrefix, kPrefixLen) == 0) {
      (*hosts)[i] = h.substr(kPrefixLen, h.size() - kPrefixLen);
    }
  }
}

// RemoveDuplicateEntries removes all duplicates from |hosts|.
static void RemoveDuplicateEntries(std::vector<std::string>* hosts) {
  std::set<std::string> hosts_set;
  std::vector<std::string> ret;

  for (std::vector<std::string>::const_iterator
       i = hosts->begin(); i != hosts->end(); i++) {
    if (hosts_set.count(*i)) {
      if (verbose)
        fprintf(stderr, "Removing duplicate entry for %s\n", i->c_str());
      continue;
    }
    hosts_set.insert(*i);
    ret.push_back(*i);
  }

  hosts->swap(ret);
}

// ParentDomain returns the parent domain for a given domain name or the empty
// string if the name is a top-level domain.
static std::string ParentDomain(const std::string& in) {
  for (size_t i = 0; i < in.size(); i++) {
    if (in[i] == '.') {
      return in.substr(i + 1, in.size() - i - 1);
    }
  }

  return std::string();
}

// RemoveRedundantEntries removes any entries which are subdomains of other
// entries. (i.e. foo.example.com would be removed if example.com were also
// included.)
static void RemoveRedundantEntries(std::vector<std::string>* hosts) {
  std::set<std::string> hosts_set;
  std::vector<std::string> ret;

  for (std::vector<std::string>::const_iterator
       i = hosts->begin(); i != hosts->end(); i++) {
    hosts_set.insert(*i);
  }

  for (std::vector<std::string>::const_iterator
       i = hosts->begin(); i != hosts->end(); i++) {
    std::string parent = ParentDomain(*i);
    while (!parent.empty()) {
      if (hosts_set.count(parent))
        break;
      parent = ParentDomain(parent);
    }
    if (parent.empty()) {
      ret.push_back(*i);
    } else {
      if (verbose)
        fprintf(stderr, "Removing %s as redundant\n", i->c_str());
    }
  }

  hosts->swap(ret);
}

// CheckLengths returns true iff every host is less than 256 bytes long (not
// including the terminating NUL) and contains two or more labels.
static bool CheckLengths(const std::vector<std::string>& hosts) {
  for (std::vector<std::string>::const_iterator
       i = hosts.begin(); i != hosts.end(); i++) {
     if (i->size() >= 256) {
       fprintf(stderr, "Entry %s is too large\n", i->c_str());
       return false;
     }
     if (SSLFalseStartBlacklist::LastTwoLabels(i->c_str()) == NULL) {
       fprintf(stderr, "Entry %s contains too few labels\n", i->c_str());
       return false;
     }
  }

  return true;
}

int main(int argc, char** argv) {
  if (argc != 3)
    return usage(argv[0]);

  const char* input_file = argv[1];
  const char* output_file = argv[2];
  FILE* input = fopen(input_file, "r");
  if (!input) {
    perror("open");
    return usage(argv[0]);
  }

  if (fseek(input, 0, SEEK_END)) {
    perror("fseek");
    return 1;
  }

  const long input_size = ftell(input);

  if (fseek(input, 0, SEEK_SET)) {
    perror("fseek");
    return 1;
  }

  char* buffer = static_cast<char*>(malloc(input_size));
  if (fread(buffer, input_size, 1, input) != 1) {
    perror("fread");
    free(buffer);
    fclose(input);
    return 1;
  }
  fclose(input);

  std::vector<std::string> hosts;

  off_t line_start = 0;
  bool is_comment = false;
  bool non_whitespace_seen = false;
  for (long i = 0; i <= input_size; i++) {
    if (i == input_size || buffer[i] == '\n') {
      if (!is_comment && non_whitespace_seen)
        hosts.push_back(std::string(&buffer[line_start], i - line_start));
      is_comment = false;
      non_whitespace_seen = false;
      line_start = i + 1;
      continue;
    }

    if (i == line_start && buffer[i] == '#')
      is_comment = true;
    if (buffer[i] != ' ' && buffer[i] != '\t')
      non_whitespace_seen = true;
  }
  free(buffer);

  fprintf(stderr, "Have %d hosts after parse\n", (int) hosts.size());
  StripWWWPrefix(&hosts);
  RemoveDuplicateEntries(&hosts);
  fprintf(stderr, "Have %d hosts after removing duplicates\n", (int) hosts.size());
  RemoveRedundantEntries(&hosts);
  fprintf(stderr, "Have %d hosts after removing redundants\n", (int) hosts.size());
  if (!CheckLengths(hosts)) {
    fprintf(stderr, "One or more entries is too large or too small\n");
    return 2;
  }

  fprintf(stderr, "Using %d entry hash table\n", kBuckets);
  uint32 table[kBuckets];
  std::vector<std::string> buckets[kBuckets];

  for (std::vector<std::string>::const_iterator
       i = hosts.begin(); i != hosts.end(); i++) {
    const char* last_two_labels =
        SSLFalseStartBlacklist::LastTwoLabels(i->c_str());
    const unsigned h = SSLFalseStartBlacklist::Hash(last_two_labels);
    buckets[h & (kBuckets - 1)].push_back(*i);
  }

  std::string table_data;
  unsigned max_bucket_size = 0;
  for (unsigned i = 0; i < kBuckets; i++) {
    if (buckets[i].size() > max_bucket_size)
      max_bucket_size = buckets[i].size();

    table[i] = table_data.size();
    for (std::vector<std::string>::const_iterator
         j = buckets[i].begin(); j != buckets[i].end(); j++) {
      table_data.push_back((char) j->size());
      table_data.append(*j);
    }
  }

  fprintf(stderr, "Largest bucket has %d entries\n", max_bucket_size);

  FILE* out = fopen(output_file, "w+");
  if (!out) {
    perror("opening output file");
    return 4;
  }

  fprintf(out, "// Copyright (c) 2010 The Chromium Authors. All rights "
          "reserved.\n// Use of this source code is governed by a BSD-style "
          "license that can be\n// found in the LICENSE file.\n\n");
  fprintf(out, "// WARNING: this code is generated by\n"
               "// ssl_false_start_blacklist_process.cc. Do not edit.\n\n");
  fprintf(out, "#include \"base/basictypes.h\"\n\n");
  fprintf(out, "#include \"net/base/ssl_false_start_blacklist.h\"\n\n");
  fprintf(out, "namespace net {\n\n");
  fprintf(out, "const uint32 SSLFalseStartBlacklist::kHashTable[%d + 1] = {\n",
          kBuckets);
  for (unsigned i = 0; i < kBuckets; i++) {
    fprintf(out, "  %u,\n", (unsigned) table[i]);
  }
  fprintf(out, "  %u,\n", (unsigned) table_data.size());
  fprintf(out, "};\n\n");

  fprintf(out, "const char SSLFalseStartBlacklist::kHashData[] = \n");
  for (unsigned i = 0, line_length = 0; i < table_data.size(); i++) {
    if (line_length == 0)
      fprintf(out, "  \"");
    uint8 c = static_cast<uint8>(table_data[i]);
    if (c < 32 || c > 127 || c == '"') {
      fprintf(out, "\\%c%c%c", '0' + ((c >> 6) & 7), '0' + ((c >> 3) & 7),
              '0' + (c & 7));
      line_length += 4;
    } else {
      fprintf(out, "%c", c);
      line_length++;
    }
    if (i == table_data.size() - 1) {
      fprintf(out, "\";\n");
    } else if (line_length >= 70) {
      fprintf(out, "\"\n");
      line_length = 0;
    }
  }
  fprintf(out, "\n}  // namespace net\n");
  fclose(out);

  return 0;
}
<commit_msg>net: use a char array for the False Start blacklist.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This utility program exists to process the False Start blacklist file into
// a static hash table so that it can be efficiently queried by Chrome.

#include <stdio.h>
#include <stdlib.h>

#include <set>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "net/base/ssl_false_start_blacklist.h"

using net::SSLFalseStartBlacklist;

static const unsigned kBuckets = SSLFalseStartBlacklist::kBuckets;

static bool verbose = false;

static int
usage(const char* argv0) {
  fprintf(stderr, "Usage: %s <blacklist file> <output .c file>\n", argv0);
  return 1;
}

// StripWWWPrefix removes "www." from the beginning of any elements of the
// vector.
static void StripWWWPrefix(std::vector<std::string>* hosts) {
  static const char kPrefix[] = "www.";
  static const unsigned kPrefixLen = sizeof(kPrefix) - 1;

  for (size_t i = 0; i < hosts->size(); i++) {
    const std::string& h = (*hosts)[i];
    if (h.size() >= kPrefixLen &&
        memcmp(h.data(), kPrefix, kPrefixLen) == 0) {
      (*hosts)[i] = h.substr(kPrefixLen, h.size() - kPrefixLen);
    }
  }
}

// RemoveDuplicateEntries removes all duplicates from |hosts|.
static void RemoveDuplicateEntries(std::vector<std::string>* hosts) {
  std::set<std::string> hosts_set;
  std::vector<std::string> ret;

  for (std::vector<std::string>::const_iterator
       i = hosts->begin(); i != hosts->end(); i++) {
    if (hosts_set.count(*i)) {
      if (verbose)
        fprintf(stderr, "Removing duplicate entry for %s\n", i->c_str());
      continue;
    }
    hosts_set.insert(*i);
    ret.push_back(*i);
  }

  hosts->swap(ret);
}

// ParentDomain returns the parent domain for a given domain name or the empty
// string if the name is a top-level domain.
static std::string ParentDomain(const std::string& in) {
  for (size_t i = 0; i < in.size(); i++) {
    if (in[i] == '.') {
      return in.substr(i + 1, in.size() - i - 1);
    }
  }

  return std::string();
}

// RemoveRedundantEntries removes any entries which are subdomains of other
// entries. (i.e. foo.example.com would be removed if example.com were also
// included.)
static void RemoveRedundantEntries(std::vector<std::string>* hosts) {
  std::set<std::string> hosts_set;
  std::vector<std::string> ret;

  for (std::vector<std::string>::const_iterator
       i = hosts->begin(); i != hosts->end(); i++) {
    hosts_set.insert(*i);
  }

  for (std::vector<std::string>::const_iterator
       i = hosts->begin(); i != hosts->end(); i++) {
    std::string parent = ParentDomain(*i);
    while (!parent.empty()) {
      if (hosts_set.count(parent))
        break;
      parent = ParentDomain(parent);
    }
    if (parent.empty()) {
      ret.push_back(*i);
    } else {
      if (verbose)
        fprintf(stderr, "Removing %s as redundant\n", i->c_str());
    }
  }

  hosts->swap(ret);
}

// CheckLengths returns true iff every host is less than 256 bytes long (not
// including the terminating NUL) and contains two or more labels.
static bool CheckLengths(const std::vector<std::string>& hosts) {
  for (std::vector<std::string>::const_iterator
       i = hosts.begin(); i != hosts.end(); i++) {
     if (i->size() >= 256) {
       fprintf(stderr, "Entry %s is too large\n", i->c_str());
       return false;
     }
     if (SSLFalseStartBlacklist::LastTwoLabels(i->c_str()) == NULL) {
       fprintf(stderr, "Entry %s contains too few labels\n", i->c_str());
       return false;
     }
  }

  return true;
}

int main(int argc, char** argv) {
  if (argc != 3)
    return usage(argv[0]);

  const char* input_file = argv[1];
  const char* output_file = argv[2];
  FILE* input = fopen(input_file, "r");
  if (!input) {
    perror("open");
    return usage(argv[0]);
  }

  if (fseek(input, 0, SEEK_END)) {
    perror("fseek");
    return 1;
  }

  const long input_size = ftell(input);

  if (fseek(input, 0, SEEK_SET)) {
    perror("fseek");
    return 1;
  }

  char* buffer = static_cast<char*>(malloc(input_size));
  if (fread(buffer, input_size, 1, input) != 1) {
    perror("fread");
    free(buffer);
    fclose(input);
    return 1;
  }
  fclose(input);

  std::vector<std::string> hosts;

  off_t line_start = 0;
  bool is_comment = false;
  bool non_whitespace_seen = false;
  for (long i = 0; i <= input_size; i++) {
    if (i == input_size || buffer[i] == '\n') {
      if (!is_comment && non_whitespace_seen)
        hosts.push_back(std::string(&buffer[line_start], i - line_start));
      is_comment = false;
      non_whitespace_seen = false;
      line_start = i + 1;
      continue;
    }

    if (i == line_start && buffer[i] == '#')
      is_comment = true;
    if (buffer[i] != ' ' && buffer[i] != '\t')
      non_whitespace_seen = true;
  }
  free(buffer);

  fprintf(stderr, "Have %d hosts after parse\n", (int) hosts.size());
  StripWWWPrefix(&hosts);
  RemoveDuplicateEntries(&hosts);
  fprintf(stderr, "Have %d hosts after removing duplicates\n", (int) hosts.size());
  RemoveRedundantEntries(&hosts);
  fprintf(stderr, "Have %d hosts after removing redundants\n", (int) hosts.size());
  if (!CheckLengths(hosts)) {
    fprintf(stderr, "One or more entries is too large or too small\n");
    return 2;
  }

  fprintf(stderr, "Using %d entry hash table\n", kBuckets);
  uint32 table[kBuckets];
  std::vector<std::string> buckets[kBuckets];

  for (std::vector<std::string>::const_iterator
       i = hosts.begin(); i != hosts.end(); i++) {
    const char* last_two_labels =
        SSLFalseStartBlacklist::LastTwoLabels(i->c_str());
    const unsigned h = SSLFalseStartBlacklist::Hash(last_two_labels);
    buckets[h & (kBuckets - 1)].push_back(*i);
  }

  std::string table_data;
  unsigned max_bucket_size = 0;
  for (unsigned i = 0; i < kBuckets; i++) {
    if (buckets[i].size() > max_bucket_size)
      max_bucket_size = buckets[i].size();

    table[i] = table_data.size();
    for (std::vector<std::string>::const_iterator
         j = buckets[i].begin(); j != buckets[i].end(); j++) {
      table_data.push_back((char) j->size());
      table_data.append(*j);
    }
  }

  fprintf(stderr, "Largest bucket has %d entries\n", max_bucket_size);

  FILE* out = fopen(output_file, "w+");
  if (!out) {
    perror("opening output file");
    return 4;
  }

  fprintf(out, "// Copyright (c) 2010 The Chromium Authors. All rights "
          "reserved.\n// Use of this source code is governed by a BSD-style "
          "license that can be\n// found in the LICENSE file.\n\n");
  fprintf(out, "// WARNING: this code is generated by\n"
               "// ssl_false_start_blacklist_process.cc. Do not edit.\n\n");
  fprintf(out, "#include \"base/basictypes.h\"\n\n");
  fprintf(out, "#include \"net/base/ssl_false_start_blacklist.h\"\n\n");
  fprintf(out, "namespace net {\n\n");
  fprintf(out, "const uint32 SSLFalseStartBlacklist::kHashTable[%d + 1] = {\n",
          kBuckets);
  for (unsigned i = 0; i < kBuckets; i++) {
    fprintf(out, "  %u,\n", (unsigned) table[i]);
  }
  fprintf(out, "  %u,\n", (unsigned) table_data.size());
  fprintf(out, "};\n\n");

  fprintf(out, "const char SSLFalseStartBlacklist::kHashData[] = {\n");
  for (unsigned i = 0, line_length = 0; i < table_data.size(); i++) {
    if (line_length == 0)
      fprintf(out, "  ");
    uint8 c = static_cast<uint8>(table_data[i]);
    line_length += fprintf(out, "%d, ", c);
    if (i == table_data.size() - 1) {
      fprintf(out, "\n};\n");
    } else if (line_length >= 70) {
      fprintf(out, "\n");
      line_length = 0;
    }
  }
  fprintf(out, "\n}  // namespace net\n");
  fclose(out);

  return 0;
}
<|endoftext|>


<commit_before><commit_msg>Simplify a proxy test. TEST=none<commit_after><|endoftext|>


<commit_before>/*
 * PathGrowingMatcher.cpp
 *
 *  Created on: Jun 13, 2013
 *      Author: Henning
 */

#include "PathGrowingMatcher.h"
#include "../auxiliary/PrioQueueForInts.h"

namespace NetworKit {

Matching PathGrowingMatcher::run(Graph& G) {
	// make copy since graph will be transformed
	count n = G.numberOfNodes();

	// init matching to empty
	Matching m1(n);
	Matching m2(n);
	bool takeM1 = true;

	// degrees tracks degree of vertices,
	// avoids to make a copy of the graph and
	// delete vertices and edges explicitly
	std::vector<count> degrees(n);
	G.forNodes([&](node u) {
		degrees[u] = G.degree(u);
	});

	// alive tracks if vertices are alive or not in the algorithm
	std::vector<bool> alive(n, true);
	count numEdges = G.numberOfEdges();

	// PQ to retrieve vertices with degree > 0 quickly
	Aux::PrioQueueForInts bpq(degrees, n-1);

	// main loop
	while (numEdges > 0) {
		// use vertex with positive degree
		node v = bpq.extractMax();
		assert(v != none);

		// path growing
		while (degrees[v] > 0) {
			// find heaviest incident edge
			node bestNeighbor = 0;
			edgeweight bestWeight = 0;
			G.forEdgesOf(v, [&](node v, node u, edgeweight weight) {
				if (alive[u]) {
					if (weight > bestWeight) {
						bestNeighbor = u;
						bestWeight = weight;
					}
				}
			});

			if (takeM1) {
				// add edge to m1
				m1.match(v, bestNeighbor);
				takeM1 = false;
			}
			else {
				// add edge to m2
				m2.match(v, bestNeighbor);
				takeM1 = true;
			}

			// remove current vertex and its incident edges from graph
			G.forEdgesOf(v, [&](node v, node u) {
				if (alive[u]) {
					degrees[u]--;
					numEdges--;
					bpq.changePrio(u, degrees[u]);
				}
			});
			alive[v] = false;
			bpq.remove(v);

			// start next iteration from best neighbor
			v = bestNeighbor;
		}
	}

	// return the heavier one of the two
	edgeweight weight1 = m1.weight(G);
	edgeweight weight2 = m2.weight(G);
	if (weight1 > weight2)
		return m1;
	else
		return m2;
}

} /* namespace NetworKit */
<commit_msg>PGA assertion: static graphs with all nodes alive<commit_after>/*
 * PathGrowingMatcher.cpp
 *
 *  Created on: Jun 13, 2013
 *      Author: Henning
 */

#include "PathGrowingMatcher.h"
#include "../auxiliary/PrioQueueForInts.h"

namespace NetworKit {

Matching PathGrowingMatcher::run(Graph& G) {
	// make copy since graph will be transformed
	count n = G.numberOfNodes();
	assert(n == G.upperNodeIdBound());

	// init matching to empty
	Matching m1(n);
	Matching m2(n);
	bool takeM1 = true;

	// degrees tracks degree of vertices,
	// avoids to make a copy of the graph and
	// delete vertices and edges explicitly
	std::vector<count> degrees(n);
	G.forNodes([&](node u) {
		degrees[u] = G.degree(u);
	});

	// alive tracks if vertices are alive or not in the algorithm
	std::vector<bool> alive(n, true);
	count numEdges = G.numberOfEdges();

	// PQ to retrieve vertices with degree > 0 quickly
	Aux::PrioQueueForInts bpq(degrees, n-1);

	// main loop
	while (numEdges > 0) {
		// use vertex with positive degree
		node v = bpq.extractMax();
		assert(v != none);

		// path growing
		while (degrees[v] > 0) {
			// find heaviest incident edge
			node bestNeighbor = 0;
			edgeweight bestWeight = 0;
			G.forEdgesOf(v, [&](node v, node u, edgeweight weight) {
				if (alive[u]) {
					if (weight > bestWeight) {
						bestNeighbor = u;
						bestWeight = weight;
					}
				}
			});

			if (takeM1) {
				// add edge to m1
				m1.match(v, bestNeighbor);
				takeM1 = false;
			}
			else {
				// add edge to m2
				m2.match(v, bestNeighbor);
				takeM1 = true;
			}

			// remove current vertex and its incident edges from graph
			G.forEdgesOf(v, [&](node v, node u) {
				if (alive[u]) {
					degrees[u]--;
					numEdges--;
					bpq.changePrio(u, degrees[u]);
				}
			});
			alive[v] = false;
			bpq.remove(v);

			// start next iteration from best neighbor
			v = bestNeighbor;
		}
	}

	// return the heavier one of the two
	edgeweight weight1 = m1.weight(G);
	edgeweight weight2 = m2.weight(G);
	if (weight1 > weight2)
		return m1;
	else
		return m2;
}

} /* namespace NetworKit */
<|endoftext|>


<commit_before>/*
***************************************
*   Asylum3D @ 2014-12-17
***************************************
*/

#ifndef __ASYLUM3D_HPP__
#define __ASYLUM3D_HPP__

/* Asylum Namespace */
namespace asy {

/***************/
/* Effect Port */
/***************/
class IEffect : public asylum
{
private:
    int32s  m_ref_cnt;

public:
    /* ==== */
    IEffect ()
    {
        m_ref_cnt = 0;
    }

    /* ============= */
    virtual ~IEffect ()
    {
    }

public:
    /* ====== */
    void free ()
    {
        m_ref_cnt -= 1;
        if (m_ref_cnt <= 0)
            delete this;
    }

    /* ========= */
    void add_ref ()
    {
        m_ref_cnt += 1;
    }

public:
    /* ==================== */
    virtual void enter () = 0;

    /* ==================== */
    virtual void leave () = 0;
};

/******************/
/* Attribute Port */
/******************/
class IAttrib : public asylum
{
protected:
    int64u  m_type;

public:
    /* ================ */
    virtual ~IAttrib () {}

public:
    /* ===================== */
    virtual void commit () = 0;

    /* ============== */
    int64u type () const
    {
        return (m_type);
    }
};

// Attribute Type
#define ATTR_TYPE_ALPHAOP   0x00000001ULL   // Alpha Blend
#define ATTR_TYPE_TEXTURE   0x00000002ULL   // Have Texture
#define ATTR_TYPE_SPECULAR  0x00000004ULL   // Specular Light
#define ATTR_TYPE_NRML_MAP  0x00000008ULL   // Normal Map
#define ATTR_TYPE_LGHT_MAP  0x00000010ULL   // Light Map

/*************/
/* Mesh Port */
/*************/
class IMesh : public asylum
{
public:
    /* ============== */
    virtual ~IMesh () {}

    /* ===================== */
    virtual void commit () = 0;
};

/****************/
/* Commit Batch */
/****************/
struct commit_batch
{
    IMesh**     mesh;
    IAttrib*    attr;

    /* ====== */
    void free ()
    {
        IMesh*  tmp;
        size_t  idx;

        if (this->attr != NULL)
            delete this->attr;
        if (this->mesh != NULL) {
            for (idx = 0; ; idx++) {
                tmp = this->mesh[idx];
                if (tmp == NULL)
                    break;
                delete tmp;
            }
            mem_free(this->mesh);
        }
    }
};

/***************/
/* Object Base */
/***************/
struct object_inst;
struct object_base
{
    void*               real;
    uint_t              type;
    sAABB               aabb;
    sSPHERE             ball;
    array<commit_batch> list;
    void (*kill) (void* real);
    void (*tran) (object_inst* dest, void* param,
                  const vec3d_t* rote, const vec3d_t* move,
                  const vec3d_t* scale);
    /* ====== */
    void free ()
    {
        if (this->real != NULL &&
            this->kill != NULL)
            this->kill(this->real);
        this->list.free();
    }
};

/*******************/
/* Object Instance */
/*******************/
struct object_inst
{
    int32u          type;
    mat4x4_t        tran;
    object_base*    base;

    union {
        sAABB   aabb;
        sSPHERE ball;
    } bound;

    /* ========= */
    void free () {}
};

// Instance Type
#define INST_TYPE_STATIC    0
#define INST_TYPE_DYNAMIC   1

/***************/
/* Commit Unit */
/***************/
struct commit_unit
{
    object_inst*    inst;
    commit_batch*   unit;

    /* ========= */
    void free () {}
};

/***************/
/* Commit Pipe */
/***************/
struct commit_pipe
{
    IEffect*            effect;
    array<commit_unit>  stuffz;

    /* ====== */
    void free ()
    {
        if (this->effect != NULL)
            this->effect->free();
        this->stuffz.free();
    }
};

}   /* namespace */

/******************/
/* Effect Factory */
/******************/
CR_API asy::IEffect* create_asy3d_ffct_array (asy::IEffect** list, size_t count);

#endif  /* __ASYLUM3D_HPP__ */
<commit_msg>Asylum: 加入计数用的基类<commit_after>/*
***************************************
*   Asylum3D @ 2014-12-17
***************************************
*/

#ifndef __ASYLUM3D_HPP__
#define __ASYLUM3D_HPP__

/* Asylum Namespace */
namespace asy {

/***************/
/* Effect Port */
/***************/
class IEffect : public asylum
{
private:
    int32s  m_ref_cnt;

public:
    /* ==== */
    IEffect ()
    {
        m_ref_cnt = 0;
    }

    /* ============= */
    virtual ~IEffect ()
    {
    }

public:
    /* ====== */
    void free ()
    {
        m_ref_cnt -= 1;
        if (m_ref_cnt <= 0)
            delete this;
    }

    /* ========= */
    void add_ref ()
    {
        m_ref_cnt += 1;
    }

public:
    /* ==================== */
    virtual void enter () = 0;

    /* ==================== */
    virtual void leave () = 0;
};

/**************/
/* Stuff Base */
/**************/
class stuff_base : public asylum
{
protected:
    int32u  m_nv, m_nt;

public:
    /* ================== */
    int32u get_vnum () const
    {
        return (m_nv);
    }

    /* ================== */
    int32u get_tnum () const
    {
        return (m_nt);
    }
};

/******************/
/* Attribute Port */
/******************/
class IAttrib : public stuff_base
{
protected:
    int64u  m_type;

public:
    /* ================ */
    virtual ~IAttrib () {}

public:
    /* ===================== */
    virtual void commit () = 0;

    /* ============== */
    int64u type () const
    {
        return (m_type);
    }
};

// Attribute Type
#define ATTR_TYPE_ALPHAOP   0x00000001ULL   // Alpha Blend
#define ATTR_TYPE_TEXTURE   0x00000002ULL   // Have Texture
#define ATTR_TYPE_SPECULAR  0x00000004ULL   // Specular Light
#define ATTR_TYPE_NRML_MAP  0x00000008ULL   // Normal Map
#define ATTR_TYPE_LGHT_MAP  0x00000010ULL   // Light Map

/*************/
/* Mesh Port */
/*************/
class IMesh : public stuff_base
{
public:
    /* ============== */
    virtual ~IMesh () {}

    /* ===================== */
    virtual void commit () = 0;
};

/****************/
/* Commit Batch */
/****************/
struct commit_batch
{
    IMesh**     mesh;
    IAttrib*    attr;

    /* ====== */
    void free ()
    {
        IMesh*  tmp;
        size_t  idx;

        if (this->attr != NULL)
            delete this->attr;
        if (this->mesh != NULL) {
            for (idx = 0; ; idx++) {
                tmp = this->mesh[idx];
                if (tmp == NULL)
                    break;
                delete tmp;
            }
            mem_free(this->mesh);
        }
    }
};

/***************/
/* Object Base */
/***************/
struct object_inst;
struct object_base
{
    void*               real;
    uint_t              type;
    sAABB               aabb;
    sSPHERE             ball;
    array<commit_batch> list;
    void (*kill) (void* real);
    void (*tran) (object_inst* dest, void* param,
                  const vec3d_t* rote, const vec3d_t* move,
                  const vec3d_t* scale);
    /* ====== */
    void free ()
    {
        if (this->real != NULL &&
            this->kill != NULL)
            this->kill(this->real);
        this->list.free();
    }
};

/*******************/
/* Object Instance */
/*******************/
struct object_inst
{
    int32u          type;
    mat4x4_t        tran;
    object_base*    base;

    union {
        sAABB   aabb;
        sSPHERE ball;
    } bound;

    /* ========= */
    void free () {}
};

// Instance Type
#define INST_TYPE_STATIC    0
#define INST_TYPE_DYNAMIC   1

/***************/
/* Commit Unit */
/***************/
struct commit_unit
{
    object_inst*    inst;
    commit_batch*   unit;

    /* ========= */
    void free () {}
};

/***************/
/* Commit Pipe */
/***************/
struct commit_pipe
{
    IEffect*            effect;
    array<commit_unit>  stuffz;

    /* ====== */
    void free ()
    {
        if (this->effect != NULL)
            this->effect->free();
        this->stuffz.free();
    }
};

}   /* namespace */

/******************/
/* Effect Factory */
/******************/
CR_API asy::IEffect* create_asy3d_ffct_array (asy::IEffect** list, size_t count);

#endif  /* __ASYLUM3D_HPP__ */
<|endoftext|>


<commit_before>//Copyright (c) 2022 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include "PolygonConnector.h"

#include "linearAlg2D.h"
#include "AABB.h"

namespace cura
{

PolygonConnector::PolygonConnector(const coord_t line_width)
: line_width(line_width)
{}

void PolygonConnector::add(const Polygons& input)
{
    for (ConstPolygonRef poly : input)
    {
        input_polygons.push_back(poly);
    }
}

void PolygonConnector::add(const VariableWidthPaths& input)
{
    for(const VariableWidthLines& lines : input)
    {
        for(const ExtrusionLine& line : lines)
        {
            input_paths.push_back(line);
        }
    }
}

void PolygonConnector::connect(Polygons& output_polygons, VariableWidthPaths& output_paths)
{
    std::vector<Polygon> result_polygons = connectGroup(input_polygons);
    for(Polygon& polygon : result_polygons)
    {
        output_polygons.add(polygon);
    }

    std::vector<ExtrusionLine> result_paths = connectGroup(input_paths);
    output_paths.push_back(result_paths);
}

Point PolygonConnector::getPosition(const Point& vertex) const
{
    return vertex;
}

Point PolygonConnector::getPosition(const ExtrusionJunction& junction) const
{
    return junction.p;
}

coord_t PolygonConnector::getWidth(const Point&) const
{
    return line_width;
}

coord_t PolygonConnector::getWidth(const ExtrusionJunction& junction) const
{
    return junction.w;
}

void PolygonConnector::addVertex(Polygon& polygonal, const Point& position, const coord_t) const
{
    polygonal.add(position);
}

void PolygonConnector::addVertex(Polygon& polygonal, const Point& vertex) const
{
    polygonal.add(vertex);
}

void PolygonConnector::addVertex(ExtrusionLine& polygonal, const Point& position, const coord_t width) const
{
    polygonal.emplace_back(position, width, 1); //Perimeter indices don't make sense any more once perimeters are merged. Use 1 as placeholder, being the first "normal" wall.
}

void PolygonConnector::addVertex(ExtrusionLine& polygonal, const ExtrusionJunction& vertex) const
{
    polygonal.emplace_back(vertex);
}

bool PolygonConnector::isClosed(Polygon&) const
{
    return true;
}

bool PolygonConnector::isClosed(ExtrusionLine& polygonal) const
{
    return vSize2(polygonal.front() - polygonal.back()) < 10;
}

template<>
ExtrusionLine PolygonConnector::createEmpty<ExtrusionLine>() const
{
    constexpr size_t inset_index = 1; //Specialising to set inset_index to 1 instead of maximum int. Connected polys are not specific to any inset.
    constexpr bool is_odd = false;
    ExtrusionLine result(inset_index, is_odd);
    result.is_closed = true;
    return result; //No copy, via RVO.
}

}//namespace cura

<commit_msg>Use a more standard 5um snap distance for detecting closed polys<commit_after>//Copyright (c) 2022 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include "PolygonConnector.h"

#include "linearAlg2D.h"
#include "AABB.h"

namespace cura
{

PolygonConnector::PolygonConnector(const coord_t line_width)
: line_width(line_width)
{}

void PolygonConnector::add(const Polygons& input)
{
    for (ConstPolygonRef poly : input)
    {
        input_polygons.push_back(poly);
    }
}

void PolygonConnector::add(const VariableWidthPaths& input)
{
    for(const VariableWidthLines& lines : input)
    {
        for(const ExtrusionLine& line : lines)
        {
            input_paths.push_back(line);
        }
    }
}

void PolygonConnector::connect(Polygons& output_polygons, VariableWidthPaths& output_paths)
{
    std::vector<Polygon> result_polygons = connectGroup(input_polygons);
    for(Polygon& polygon : result_polygons)
    {
        output_polygons.add(polygon);
    }

    std::vector<ExtrusionLine> result_paths = connectGroup(input_paths);
    output_paths.push_back(result_paths);
}

Point PolygonConnector::getPosition(const Point& vertex) const
{
    return vertex;
}

Point PolygonConnector::getPosition(const ExtrusionJunction& junction) const
{
    return junction.p;
}

coord_t PolygonConnector::getWidth(const Point&) const
{
    return line_width;
}

coord_t PolygonConnector::getWidth(const ExtrusionJunction& junction) const
{
    return junction.w;
}

void PolygonConnector::addVertex(Polygon& polygonal, const Point& position, const coord_t) const
{
    polygonal.add(position);
}

void PolygonConnector::addVertex(Polygon& polygonal, const Point& vertex) const
{
    polygonal.add(vertex);
}

void PolygonConnector::addVertex(ExtrusionLine& polygonal, const Point& position, const coord_t width) const
{
    polygonal.emplace_back(position, width, 1); //Perimeter indices don't make sense any more once perimeters are merged. Use 1 as placeholder, being the first "normal" wall.
}

void PolygonConnector::addVertex(ExtrusionLine& polygonal, const ExtrusionJunction& vertex) const
{
    polygonal.emplace_back(vertex);
}

bool PolygonConnector::isClosed(Polygon&) const
{
    return true;
}

bool PolygonConnector::isClosed(ExtrusionLine& polygonal) const
{
    return vSize2(polygonal.front() - polygonal.back()) < 25;
}

template<>
ExtrusionLine PolygonConnector::createEmpty<ExtrusionLine>() const
{
    constexpr size_t inset_index = 1; //Specialising to set inset_index to 1 instead of maximum int. Connected polys are not specific to any inset.
    constexpr bool is_odd = false;
    ExtrusionLine result(inset_index, is_odd);
    result.is_closed = true;
    return result; //No copy, via RVO.
}

}//namespace cura

<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/model/CModelValue.cpp,v $
   $Revision: 1.24 $
   $Name:  $
   $Author: shoops $
   $Date: 2006/07/21 19:57:55 $
   End CVS Header */

// Copyright  2005 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include <iostream>
#include <string>
#include <vector>
#include <limits>

#include "copasi.h"

#include "CModel.h"
#include "CModelValue.h"

#include "CopasiDataModel/CCopasiDataModel.h"
#include "function/CExpression.h"
#include "report/CCopasiObjectReference.h"
#include "report/CKeyFactory.h"
#include "utilities/utility.h"

//static
const std::string CModelEntity::StatusName[] =
  {
    "fixed",
    "assignment",
    "ode",
    "determined by reactions",
    ""
  };

//static
const char * CModelEntity::XMLStatus[] =
  {
    "fixed",
    "assignment",
    "ode",
    "reactions",
    NULL
  };

// the "variable" keyword is used for compatibility reasons. It actually means "this metab is part
// of the reaction network, copasi needs to figure out if it is independent, dependent (moieties) or unused."

CModelEntity::CModelEntity(const std::string & name,
                           const CCopasiContainer * pParent,
                           const std::string & type,
                           const unsigned C_INT32 & flag):
    CCopasiContainer(name, pParent, type, (flag | CCopasiObject::Container | CCopasiObject::ValueDbl)),
    mKey(""),
    mpValueAccess(NULL),
    mpValueData(NULL),
    mpIValue(NULL),
    mRate(0.0),
    mStatus(FIXED),
    mUsed(true),
    mpModel(NULL)
{
  initObjects();

  *mpIValue = 1.0;
  *mpValueData = std::numeric_limits<C_FLOAT64>::quiet_NaN();

  CONSTRUCTOR_TRACE;
}

CModelEntity::CModelEntity(const CModelEntity & src,
                           const CCopasiContainer * pParent):
    CCopasiContainer(src, pParent),
    mKey(""),
    mpValueAccess(NULL),
    mpValueData(NULL),
    mpIValue(NULL),
    mRate(src.mRate),
    mStatus(FIXED),
    mUsed(src.mUsed),
    mpModel(NULL)
{
  initObjects();

  setStatus(src.mStatus);

  *mpValueData = *src.mpValueData;
  *mpIValue = *src.mpIValue;

  CONSTRUCTOR_TRACE;
}

CModelEntity::~CModelEntity()
{
  if (mpModel)
    mpModel->getStateTemplate().remove(this);

  // After the above call we definitely own the data and
  // therfore must destroy them.

  pdelete(mpValueData);
  pdelete(mpIValue);

  DESTRUCTOR_TRACE;
}

const std::string & CModelEntity::getKey() const {return mKey;}

const C_FLOAT64 & CModelEntity::getValue() const {return *mpValueAccess;}

const C_FLOAT64 & CModelEntity::getInitialValue() const {return *mpIValue;}

const CModelEntity::Status & CModelEntity::getStatus() const {return mStatus;}

bool CModelEntity::compile()
{return true;}

void CModelEntity::calculate()
{}

/**
 * Return rate of production of this entity
 */
const C_FLOAT64 & CModelEntity::getRate() const
  {
    return mRate;
  }

//***********

void CModelEntity::setValue(const C_FLOAT64 & value)
{
  if (mStatus == FIXED) return;

  *mpValueData = value;

#ifdef COPASI_DEBUG
  //if (mStatus == FIXED)
  //std::cout << "warning: set the transient concentration on a fixed entity" << std::endl;
#endif
}

void CModelEntity::setInitialValue(const C_FLOAT64 & initialValue)
{
  *mpIValue = initialValue;

  if (mStatus != FIXED) return;
}

void CModelEntity::setRate(const C_FLOAT64 & rate)
{
  mRate = rate;
}

//  ******************

void CModelEntity::setStatus(const CModelEntity::Status & status)
{
  if (mStatus != status)
    {
      mStatus = status;
      this->setValuePtr(mpValueData);

      if (isFixed())
        {
          mDependencies.clear();
          mpValueReference->setDirectDependencies(mDependencies);
          mpValueReference->clearRefresh();
          mpRateReference->setDirectDependencies(mDependencies);
          mpRateReference->clearRefresh();
        }
    }
}

void * CModelEntity::getValuePointer() const
  {return const_cast<C_FLOAT64 *>(mpValueAccess);}

void CModelEntity::initObjects()
{
  C_FLOAT64 Dummy;

  mpValueReference =
    static_cast<CCopasiObjectReference<C_FLOAT64> *>(addObjectReference("Value",
        Dummy,
        CCopasiObject::ValueDbl));
  mpIValueReference =
    static_cast<CCopasiObjectReference<C_FLOAT64> *>(addObjectReference("InitialValue",
        Dummy,
        CCopasiObject::ValueDbl));

  mpRateReference =
    static_cast<CCopasiObjectReference<C_FLOAT64> *>(addObjectReference("Rate", mRate, CCopasiObject::ValueDbl));

  addObjectReference("SBMLId", mSBMLId, CCopasiObject::ValueString);

  mpModel = static_cast<CModel *>(getObjectAncestor("Model"));

  if (mpModel)
    {
      mpModel->getStateTemplate().add(this);
    }
  else
    {
      // This creates the needed values.
      setInitialValuePtr(NULL);
      setValuePtr(NULL);
    }
}

void CModelEntity::setInitialValuePtr(C_FLOAT64 * pInitialValue)
{
  mpIValue = pInitialValue;
  if (!mpIValue) mpIValue = new C_FLOAT64;
  mpIValueReference->setReference(*mpIValue);
}

void CModelEntity::setValuePtr(C_FLOAT64 * pValue)
{
  mpValueData = pValue;
  if (!mpValueData) mpValueData = new C_FLOAT64;

  if (mStatus == FIXED)
    mpValueAccess = mpIValue;
  else
    mpValueAccess = mpValueData;

  mpValueReference->setReference(*mpValueAccess);
}

bool CModelEntity::setObjectParent(const CCopasiContainer * pParent)
{
  CCopasiContainer::setObjectParent(pParent);
  CModel * pNewModel = static_cast<CModel *>(getObjectAncestor("Model"));

  if (mpModel == pNewModel) return true;

  C_FLOAT64 InitialValue = *mpIValue;
  C_FLOAT64 Value = *mpValueData;

  if (mpModel)
    {
      mpModel->getStateTemplate().remove(this);
    }
  else
    {
      pdelete(mpIValue);
      pdelete(mpValueData);
    }

  if (pNewModel)
    {
      pNewModel->getStateTemplate().add(this);
    }
  else
    {
      mpValueData = new C_FLOAT64;
      mpIValue = new C_FLOAT64;
    }

  mpModel = pNewModel;
  *mpIValue = InitialValue;
  *mpValueData = Value;

  return true;
}

void CModelEntity::setSBMLId(const std::string& id)
{
  this->mSBMLId = id;
}

const std::string& CModelEntity::getSBMLId() const
  {
    return this->mSBMLId;
  }

void CModelEntity::setUsed(const bool & used)
{mUsed = used;}

const bool & CModelEntity::isUsed() const
  {return mUsed;}

//********************************************************************+

CModelValue::CModelValue(const std::string & name,
                         const CCopasiContainer * pParent):
    CModelEntity(name, pParent, "ModelValue"),
    mpExpression(NULL)
{
  mKey = GlobalKeys.add("ModelValue", this);
  initObjects();

  CONSTRUCTOR_TRACE;
}

CModelValue::CModelValue(const CModelValue & src,
                         const CCopasiContainer * pParent):
    CModelEntity(src, pParent),
    mpExpression(src.isFixed() ? NULL : new CExpression(*src.mpExpression))
{
  mKey = GlobalKeys.add("ModelValue", this);
  initObjects();
  CONSTRUCTOR_TRACE;
}

CModelValue::~CModelValue()
{
  GlobalKeys.remove(mKey);
  pdelete(mpExpression);

  DESTRUCTOR_TRACE;
}

void CModelValue::initObjects()
{}

void CModelValue::setStatus(const CModelEntity::Status & status)
{
  CModelEntity::setStatus(status);

  std::set< const CCopasiObject * > NoDependencies;
  std::set< const CCopasiObject * > Self;
  Self.insert(this);

  if (isFixed())
    {
      pdelete(mpExpression);
    }
  else if (mpExpression == NULL)
    {
      mpExpression = new CExpression;
    }

  switch (getStatus())
    {
    case ASSIGNMENT:
        setDirectDependencies(mpExpression->getDirectDependencies());
      setRefresh(this, &CModelValue::calculate);
      mpValueReference->setDirectDependencies(Self);
      mpRateReference->setDirectDependencies(NoDependencies);
      break;

    case ODE:
      setDirectDependencies(mpExpression->getDirectDependencies());
      setRefresh(this, &CModelValue::calculate);
      mpValueReference->setDirectDependencies(NoDependencies);
      mpRateReference->setDirectDependencies(Self);
      break;

    case FIXED:
    default:
      setDirectDependencies(NoDependencies);
      clearRefresh();
      mpValueReference->setDirectDependencies(NoDependencies);
      mpRateReference->setDirectDependencies(NoDependencies);
      break;
    }
}

bool CModelValue::compile()
{
  if (isFixed()) return true;

  std::vector< CCopasiContainer * > listOfContainer;
  listOfContainer.push_back(getObjectAncestor("Model"));

  bool success = mpExpression->compile(listOfContainer);

  setDirectDependencies(mpExpression->getDirectDependencies());

  return success;
}

void CModelValue::calculate()
{
  switch (getStatus())
    {
    case ASSIGNMENT:
      *mpValueData = mpExpression->calcValue();
      break;

    case ODE:
      mRate = mpExpression->calcValue();
      break;

    default:
      break;
    }
}

bool CModelValue::setExpression(const std::string & expression)
{
  if (isFixed()) return false;

  if (mpExpression == NULL)
    mpExpression = new CExpression;

  return mpExpression->setInfix(expression);
}

std::string CModelValue::getExpression() const
  {
    if (isFixed() || mpExpression == NULL)
      return "";

    return mpExpression->getInfix();
  }

std::ostream & operator<<(std::ostream &os, const CModelValue & d)
{
  os << "    ++++CModelValue: " << d.getObjectName() << std::endl;
  os << "        mValue " << *d.mpValueAccess << " mIValue " << *d.mpIValue << std::endl;
  os << "        mRate " << d.mRate << " mStatus " << d.getStatus() << std::endl;
  os << "    ----CModelValue " << std::endl;

  return os;
}
<commit_msg>setStatus also sets whether the model entity is used in simulation, i.e., FIXED is always unused.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/model/CModelValue.cpp,v $
   $Revision: 1.25 $
   $Name:  $
   $Author: shoops $
   $Date: 2006/08/02 20:10:08 $
   End CVS Header */

// Copyright  2005 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include <iostream>
#include <string>
#include <vector>
#include <limits>

#include "copasi.h"

#include "CModel.h"
#include "CModelValue.h"

#include "CopasiDataModel/CCopasiDataModel.h"
#include "function/CExpression.h"
#include "report/CCopasiObjectReference.h"
#include "report/CKeyFactory.h"
#include "utilities/utility.h"

//static
const std::string CModelEntity::StatusName[] =
  {
    "fixed",
    "assignment",
    "ode",
    "determined by reactions",
    ""
  };

//static
const char * CModelEntity::XMLStatus[] =
  {
    "fixed",
    "assignment",
    "ode",
    "reactions",
    NULL
  };

// the "variable" keyword is used for compatibility reasons. It actually means "this metab is part
// of the reaction network, copasi needs to figure out if it is independent, dependent (moieties) or unused."

CModelEntity::CModelEntity(const std::string & name,
                           const CCopasiContainer * pParent,
                           const std::string & type,
                           const unsigned C_INT32 & flag):
    CCopasiContainer(name, pParent, type, (flag | CCopasiObject::Container | CCopasiObject::ValueDbl)),
    mKey(""),
    mpValueAccess(NULL),
    mpValueData(NULL),
    mpIValue(NULL),
    mRate(0.0),
    mStatus(FIXED),
    mUsed(true),
    mpModel(NULL)
{
  initObjects();

  *mpIValue = 1.0;
  *mpValueData = std::numeric_limits<C_FLOAT64>::quiet_NaN();

  CONSTRUCTOR_TRACE;
}

CModelEntity::CModelEntity(const CModelEntity & src,
                           const CCopasiContainer * pParent):
    CCopasiContainer(src, pParent),
    mKey(""),
    mpValueAccess(NULL),
    mpValueData(NULL),
    mpIValue(NULL),
    mRate(src.mRate),
    mStatus(FIXED),
    mUsed(src.mUsed),
    mpModel(NULL)
{
  initObjects();

  setStatus(src.mStatus);

  *mpValueData = *src.mpValueData;
  *mpIValue = *src.mpIValue;

  CONSTRUCTOR_TRACE;
}

CModelEntity::~CModelEntity()
{
  if (mpModel)
    mpModel->getStateTemplate().remove(this);

  // After the above call we definitely own the data and
  // therfore must destroy them.

  pdelete(mpValueData);
  pdelete(mpIValue);

  DESTRUCTOR_TRACE;
}

const std::string & CModelEntity::getKey() const {return mKey;}

const C_FLOAT64 & CModelEntity::getValue() const {return *mpValueAccess;}

const C_FLOAT64 & CModelEntity::getInitialValue() const {return *mpIValue;}

const CModelEntity::Status & CModelEntity::getStatus() const {return mStatus;}

bool CModelEntity::compile()
{return true;}

void CModelEntity::calculate()
{}

/**
 * Return rate of production of this entity
 */
const C_FLOAT64 & CModelEntity::getRate() const
  {
    return mRate;
  }

//***********

void CModelEntity::setValue(const C_FLOAT64 & value)
{
  if (mStatus == FIXED) return;

  *mpValueData = value;

#ifdef COPASI_DEBUG
  //if (mStatus == FIXED)
  //std::cout << "warning: set the transient concentration on a fixed entity" << std::endl;
#endif
}

void CModelEntity::setInitialValue(const C_FLOAT64 & initialValue)
{
  *mpIValue = initialValue;

  if (mStatus != FIXED) return;
}

void CModelEntity::setRate(const C_FLOAT64 & rate)
{
  mRate = rate;
}

//  ******************

void CModelEntity::setStatus(const CModelEntity::Status & status)
{
  if (mStatus != status)
    {
      mStatus = status;
      this->setValuePtr(mpValueData);

      if (isFixed())
        {
          mDependencies.clear();
          mpValueReference->setDirectDependencies(mDependencies);
          mpValueReference->clearRefresh();
          mpRateReference->setDirectDependencies(mDependencies);
          mpRateReference->clearRefresh();
          mUsed = false;
        }
      else
        mUsed = true; // We will detect during compilation whether this is actually correct.
    }
}

void * CModelEntity::getValuePointer() const
{return const_cast<C_FLOAT64 *>(mpValueAccess);}

void CModelEntity::initObjects()
{
  C_FLOAT64 Dummy;

  mpValueReference =
    static_cast<CCopasiObjectReference<C_FLOAT64> *>(addObjectReference("Value",
        Dummy,
        CCopasiObject::ValueDbl));
  mpIValueReference =
    static_cast<CCopasiObjectReference<C_FLOAT64> *>(addObjectReference("InitialValue",
        Dummy,
        CCopasiObject::ValueDbl));

  mpRateReference =
    static_cast<CCopasiObjectReference<C_FLOAT64> *>(addObjectReference("Rate", mRate, CCopasiObject::ValueDbl));

  addObjectReference("SBMLId", mSBMLId, CCopasiObject::ValueString);

  mpModel = static_cast<CModel *>(getObjectAncestor("Model"));

  if (mpModel)
    {
      mpModel->getStateTemplate().add(this);
    }
  else
    {
      // This creates the needed values.
      setInitialValuePtr(NULL);
      setValuePtr(NULL);
    }
}

void CModelEntity::setInitialValuePtr(C_FLOAT64 * pInitialValue)
{
  mpIValue = pInitialValue;
  if (!mpIValue) mpIValue = new C_FLOAT64;
  mpIValueReference->setReference(*mpIValue);
}

void CModelEntity::setValuePtr(C_FLOAT64 * pValue)
{
  mpValueData = pValue;
  if (!mpValueData) mpValueData = new C_FLOAT64;

  if (mStatus == FIXED)
    mpValueAccess = mpIValue;
  else
    mpValueAccess = mpValueData;

  mpValueReference->setReference(*mpValueAccess);
}

bool CModelEntity::setObjectParent(const CCopasiContainer * pParent)
{
  CCopasiContainer::setObjectParent(pParent);
  CModel * pNewModel = static_cast<CModel *>(getObjectAncestor("Model"));

  if (mpModel == pNewModel) return true;

  C_FLOAT64 InitialValue = *mpIValue;
  C_FLOAT64 Value = *mpValueData;

  if (mpModel)
    {
      mpModel->getStateTemplate().remove(this);
    }
  else
    {
      pdelete(mpIValue);
      pdelete(mpValueData);
    }

  if (pNewModel)
    {
      pNewModel->getStateTemplate().add(this);
    }
  else
    {
      mpValueData = new C_FLOAT64;
      mpIValue = new C_FLOAT64;
    }

  mpModel = pNewModel;
  *mpIValue = InitialValue;
  *mpValueData = Value;

  return true;
}

void CModelEntity::setSBMLId(const std::string& id)
{
  this->mSBMLId = id;
}

const std::string& CModelEntity::getSBMLId() const
  {
    return this->mSBMLId;
  }

void CModelEntity::setUsed(const bool & used)
{mUsed = used;}

const bool & CModelEntity::isUsed() const
  {return mUsed;}

//********************************************************************+

CModelValue::CModelValue(const std::string & name,
                         const CCopasiContainer * pParent):
    CModelEntity(name, pParent, "ModelValue"),
    mpExpression(NULL)
{
  mKey = GlobalKeys.add("ModelValue", this);
  initObjects();

  CONSTRUCTOR_TRACE;
}

CModelValue::CModelValue(const CModelValue & src,
                         const CCopasiContainer * pParent):
    CModelEntity(src, pParent),
    mpExpression(src.isFixed() ? NULL : new CExpression(*src.mpExpression))
{
  mKey = GlobalKeys.add("ModelValue", this);
  initObjects();
  CONSTRUCTOR_TRACE;
}

CModelValue::~CModelValue()
{
  GlobalKeys.remove(mKey);
  pdelete(mpExpression);

  DESTRUCTOR_TRACE;
}

void CModelValue::initObjects()
{}

void CModelValue::setStatus(const CModelEntity::Status & status)
{
  CModelEntity::setStatus(status);

  std::set< const CCopasiObject * > NoDependencies;
  std::set< const CCopasiObject * > Self;
  Self.insert(this);

  if (isFixed())
    {
      pdelete(mpExpression);
    }
  else if (mpExpression == NULL)
    {
      mpExpression = new CExpression;
    }

  switch (getStatus())
    {
    case ASSIGNMENT:
        setDirectDependencies(mpExpression->getDirectDependencies());
      setRefresh(this, &CModelValue::calculate);
      mpValueReference->setDirectDependencies(Self);
      mpRateReference->setDirectDependencies(NoDependencies);
      break;

    case ODE:
      setDirectDependencies(mpExpression->getDirectDependencies());
      setRefresh(this, &CModelValue::calculate);
      mpValueReference->setDirectDependencies(NoDependencies);
      mpRateReference->setDirectDependencies(Self);
      break;

    case FIXED:
    default:
      setDirectDependencies(NoDependencies);
      clearRefresh();
      mpValueReference->setDirectDependencies(NoDependencies);
      mpRateReference->setDirectDependencies(NoDependencies);
      break;
    }
}

bool CModelValue::compile()
{
  if (isFixed()) return true;

  std::vector< CCopasiContainer * > listOfContainer;
  listOfContainer.push_back(getObjectAncestor("Model"));

  bool success = mpExpression->compile(listOfContainer);

  setDirectDependencies(mpExpression->getDirectDependencies());

  return success;
}

void CModelValue::calculate()
{
  switch (getStatus())
    {
    case ASSIGNMENT:
      *mpValueData = mpExpression->calcValue();
      break;

    case ODE:
      mRate = mpExpression->calcValue();
      break;

    default:
      break;
    }
}

bool CModelValue::setExpression(const std::string & expression)
{
  if (isFixed()) return false;

  if (mpExpression == NULL)
    mpExpression = new CExpression;

  return mpExpression->setInfix(expression);
}

std::string CModelValue::getExpression() const
  {
    if (isFixed() || mpExpression == NULL)
      return "";

    return mpExpression->getInfix();
  }

std::ostream & operator<<(std::ostream &os, const CModelValue & d)
{
  os << "    ++++CModelValue: " << d.getObjectName() << std::endl;
  os << "        mValue " << *d.mpValueAccess << " mIValue " << *d.mpIValue << std::endl;
  os << "        mRate " << d.mRate << " mStatus " << d.getStatus() << std::endl;
  os << "    ----CModelValue " << std::endl;

  return os;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <cmath>
#include <cstring>
#include "io/BmpIO.hpp"
#include "matrix/Matrix"
#include "improc/Filter.hpp"
#include "improc/Kernels.hpp"
#include "Util.hpp"

using namespace sipl;

void parse_commandline(int argc, char** argv);

// Actions available
enum class ActionType { SOBEL, PREWITT, CANNY, UNKNOWN };

// Globals for paths & action type
std::string g_infile;
std::string g_outfile;
uint8_t g_threshold = 0;
double g_sigma = 0;
double g_t1 = 0;
double g_t2 = 0;
ActionType g_action = ActionType::UNKNOWN;

int main(int argc, char** argv)
{
    if (argc < 5) {
        std::cout << "Usage:" << std::endl;
        std::cout << "    " << argv[0]
                  << " -i inputFileName -o outputFileName {-s t} | {-p t} | "
                     "{-c sigma t0 t1 t2}"
                  << std::endl;
        std::exit(1);
    }

    parse_commandline(argc, argv);

    // Read input files
    const auto img = BmpIO::read(g_infile);

    // Perform relevant action
    switch (g_action) {
    case ActionType::SOBEL: {
        auto grad = sobel(img);
        auto clipped = grad.clip(util::min<uint8_t>, util::max<uint8_t>);
        auto thresh = threshold_binary(clipped.as_type<uint8_t>(), g_threshold);
        BmpIO::write(thresh, g_outfile);
        break;
    }
    case ActionType::PREWITT: {
        auto grad = prewitt(img);
        auto clipped = grad.clip(util::min<uint8_t>, util::max<uint8_t>);
        auto thresh = threshold_binary(clipped.as_type<uint8_t>(), g_threshold);
        BmpIO::write(thresh, g_outfile);
        break;
    }
    case ActionType::CANNY: {
        auto thinned = canny(img, g_sigma, g_t1, g_t2);
        BmpIO::write(thinned, g_outfile);
        break;
    }
    case ActionType::UNKNOWN:
        std::cerr << "[error]: unknown action type" << std::endl;
        std::exit(1);
        break;
    }
}

void parse_commandline(int32_t argc, char** argv)
{
    int32_t i = 1;
    while (argv[i] != nullptr && i < argc) {
        if (std::strncmp(argv[i], "-i", std::strlen(argv[i])) == 0) {
            ++i;
            g_infile = std::string(argv[i]);
        } else if (std::strncmp(argv[i], "-o", std::strlen(argv[i])) == 0) {
            ++i;
            g_outfile = std::string(argv[i]);
        } else if (std::strncmp(argv[i], "-s", std::strlen(argv[i])) == 0) {
            ++i;
            g_action = ActionType::SOBEL;
            g_threshold = uint8_t(std::stoi(argv[i]));
        } else if (std::strncmp(argv[i], "-p", std::strlen(argv[i])) == 0) {
            ++i;
            g_action = ActionType::PREWITT;
            g_threshold = std::stoi(argv[i]);
        } else if (std::strncmp(argv[i], "-c", std::strlen(argv[i])) == 0) {
            ++i;
            g_action = ActionType::CANNY;
            g_sigma = std::stod(argv[i++]);
            g_t1 = std::stod(argv[i++]);
            g_t2 = std::stod(argv[i++]);
        } else {
            g_action = ActionType::UNKNOWN;
        }
        ++i;
    }
}
<commit_msg>Change variable name<commit_after>#include <iostream>
#include <cmath>
#include <cstring>
#include "io/BmpIO.hpp"
#include "matrix/Matrix"
#include "improc/Filter.hpp"
#include "improc/Kernels.hpp"
#include "Util.hpp"

using namespace sipl;

void parse_commandline(int argc, char** argv);

// Actions available
enum class ActionType { SOBEL, PREWITT, CANNY, UNKNOWN };

// Globals for paths & action type
std::string g_infile;
std::string g_outfile;
uint8_t g_threshold = 0;
double g_sigma = 0;
// double g_t0 = 0;
double g_t1 = 0;
double g_t2 = 0;
ActionType g_action = ActionType::UNKNOWN;

int main(int argc, char** argv)
{
    if (argc < 5) {
        std::cout << "Usage:" << std::endl;
        std::cout << "    " << argv[0]
                  << " -i inputFileName -o outputFileName {-s t} | {-p t} | "
                     "{-c sigma t0 t1 t2}"
                  << std::endl;
        std::exit(1);
    }

    parse_commandline(argc, argv);

    // Read input files
    const auto img = BmpIO::read(g_infile);

    // Perform relevant action
    switch (g_action) {
    case ActionType::SOBEL: {
        auto grad = sobel(img);
        auto clipped = grad.clip(util::min<uint8_t>, util::max<uint8_t>);
        auto thresh = threshold_binary(clipped.as_type<uint8_t>(), g_threshold);
        BmpIO::write(thresh, g_outfile);
        break;
    }
    case ActionType::PREWITT: {
        auto grad = prewitt(img);
        auto clipped = grad.clip(util::min<uint8_t>, util::max<uint8_t>);
        auto thresh = threshold_binary(clipped.as_type<uint8_t>(), g_threshold);
        BmpIO::write(thresh, g_outfile);
        break;
    }
    case ActionType::CANNY: {
        auto filtered = canny(img, g_sigma, g_t1, g_t2);
        BmpIO::write(filtered, g_outfile);
        break;
    }
    case ActionType::UNKNOWN:
        std::cerr << "[error]: unknown action type" << std::endl;
        std::exit(1);
        break;
    }
}

void parse_commandline(int32_t argc, char** argv)
{
    int32_t i = 1;
    while (argv[i] != nullptr && i < argc) {
        if (std::strncmp(argv[i], "-i", std::strlen(argv[i])) == 0) {
            ++i;
            g_infile = std::string(argv[i]);
        } else if (std::strncmp(argv[i], "-o", std::strlen(argv[i])) == 0) {
            ++i;
            g_outfile = std::string(argv[i]);
        } else if (std::strncmp(argv[i], "-s", std::strlen(argv[i])) == 0) {
            ++i;
            g_action = ActionType::SOBEL;
            g_threshold = uint8_t(std::stoi(argv[i]));
        } else if (std::strncmp(argv[i], "-p", std::strlen(argv[i])) == 0) {
            ++i;
            g_action = ActionType::PREWITT;
            g_threshold = std::stoi(argv[i]);
        } else if (std::strncmp(argv[i], "-c", std::strlen(argv[i])) == 0) {
            ++i;
            g_action = ActionType::CANNY;
            g_sigma = std::stod(argv[i++]);
            // g_t0 = std::stod(argv[i++]);
            g_t1 = std::stod(argv[i++]);
            g_t2 = std::stod(argv[i++]);
        } else {
            g_action = ActionType::UNKNOWN;
        }
        ++i;
    }
}
<|endoftext|>


<commit_before><commit_msg>Update initial fight pattern<commit_after><|endoftext|>


<commit_before>#include "navier_solver.hpp"
#include <fstream>

using namespace mfem;
using namespace navier;

struct s_FlowContext
{
   int order = 5;
   double kin_vis = 1.0 / 40.0;
   double t_final = 10e-5;
   double dt = 1e-5;
} ctx;

void vel_kovasznay(const Vector &x, double t, Vector &u)
{
   double xi = x(0);
   double yi = x(1);

   double reynolds = 1.0 / ctx.kin_vis;
   double lam = 0.5 * reynolds
                - sqrt(0.25 * reynolds * reynolds + 4.0 * M_PI * M_PI);

   u(0) = 1.0 - exp(lam * xi) * cos(2.0 * M_PI * yi);
   u(1) = lam / (2.0 * M_PI) * exp(lam * xi) * sin(2.0 * M_PI * yi);
}

double pres_kovasznay(const Vector &x)
{
   double xi = x(0);
   double yi = x(1);

   double reynolds = 1.0 / ctx.kin_vis;
   double lam = 0.5 * reynolds
                - sqrt(0.25 * reynolds * reynolds + 4.0 * M_PI * M_PI);

   return -0.5 * exp(2.0 * lam * xi);
}

int main(int argc, char *argv[])
{
   MPI_Session mpi(argc, argv);

   int serial_refinements = 0;

   Mesh *mesh = new Mesh(2, 4, Element::QUADRILATERAL, false, 1.5, 2.0);

   mesh->EnsureNodes();
   GridFunction *nodes = mesh->GetNodes();
   *nodes -= 0.5;

   for (int i = 0; i < serial_refinements; ++i)
   {
      mesh->UniformRefinement();
   }

   if (mpi.Root())
   {
      std::cout << "Number of elements: " << mesh->GetNE() << std::endl;
   }

   auto *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
   delete mesh;

   // Create the flow solver.
   NavierSolver flowsolver(pmesh, ctx.order, ctx.kin_vis);

   // Set the initial condition.
   // This is completely user customizeable.
   ParGridFunction *u_ic = flowsolver.GetCurrentVelocity();
   VectorFunctionCoefficient u_excoeff(pmesh->Dimension(), vel_kovasznay);
   u_ic->ProjectCoefficient(u_excoeff);

   FunctionCoefficient p_excoeff(pres_kovasznay);

   // Add Dirichlet boundary conditions to velocity space restricted to
   // selected attributes on the mesh.
   Array<int> attr(pmesh->bdr_attributes.Max());
   attr = 1;
   flowsolver.AddVelDirichletBC(vel_kovasznay, attr);

   double t = 0.0;
   double dt = ctx.dt;
   double t_final = ctx.t_final;
   bool last_step = false;

   flowsolver.Setup(dt);

   double err_u = 0.0;
   double err_p = 0.0;
   ParGridFunction *u_gf = nullptr;
   ParGridFunction *p_gf = nullptr;

   for (int step = 0; !last_step; ++step)
   {
      if (t + dt >= t_final - dt / 2)
      {
         last_step = true;
      }

      flowsolver.Step(t, dt, step);

      // Compare against exact solution of velocity and pressure.
      u_gf = flowsolver.GetCurrentVelocity();
      p_gf = flowsolver.GetCurrentPressure();
      u_excoeff.SetTime(t);
      p_excoeff.SetTime(t);
      err_u = u_gf->ComputeL2Error(u_excoeff);
      err_p = p_gf->ComputeL2Error(p_excoeff);

      if (mpi.Root())
      {
         printf("%.5E %.5E %.5E %.5E err\n", t, dt, err_u, err_p);
         fflush(stdout);
      }
   }

   char vishost[] = "localhost";
   int  visport   = 19916;
   socketstream sol_sock(vishost, visport);
   sol_sock.precision(8);
   sol_sock << "parallel " << mpi.WorldSize() << " " << mpi.WorldRank() << "\n";
   sol_sock << "solution\n" << *pmesh << *u_ic << std::flush;

   flowsolver.PrintTimingData();

   delete pmesh;

   return 0;
}
<commit_msg>fine tune kovasznay example<commit_after>#include "navier_solver.hpp"
#include <fstream>

using namespace mfem;
using namespace navier;

struct s_FlowContext
{
   int order = 9;
   double kin_vis = 1.0 / 40.0;
   double t_final = 100 * 0.001;
   double dt = 0.001;
   double reference_pressure = 0.0;
   double reynolds = 1.0 / kin_vis;
   double lam = 0.5 * reynolds
                - sqrt(0.25 * reynolds * reynolds + 4.0 * M_PI * M_PI);
} ctx;

void vel_kovasznay(const Vector &x, double t, Vector &u)
{
   double xi = x(0);
   double yi = x(1);

   u(0) = 1.0 - exp(ctx.lam * xi) * cos(2.0 * M_PI * yi);
   u(1) = ctx.lam / (2.0 * M_PI) * exp(ctx.lam * xi) * sin(2.0 * M_PI * yi);
}

double pres_kovasznay(const Vector &x, double t)
{
   double xi = x(0);
   double yi = x(1);

   return 0.5 * (1.0 - exp(2.0 * ctx.lam * xi)) + ctx.reference_pressure;
}

int main(int argc, char *argv[])
{
   MPI_Session mpi(argc, argv);

   int serial_refinements = 1;

   Mesh *mesh = new Mesh(2, 4, Element::QUADRILATERAL, false, 1.5, 2.0);

   mesh->EnsureNodes();
   GridFunction *nodes = mesh->GetNodes();
   *nodes -= 0.5;

   for (int i = 0; i < serial_refinements; ++i)
   {
      mesh->UniformRefinement();
   }

   if (mpi.Root())
   {
      std::cout << "Number of elements: " << mesh->GetNE() << std::endl;
   }

   auto *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
   delete mesh;

   // Create the flow solver.
   NavierSolver flowsolver(pmesh, ctx.order, ctx.kin_vis);

   // Set the initial condition.
   // This is completely user customizeable.
   ParGridFunction *u_ic = flowsolver.GetCurrentVelocity();
   VectorFunctionCoefficient u_excoeff(pmesh->Dimension(), vel_kovasznay);
   u_ic->ProjectCoefficient(u_excoeff);

   FunctionCoefficient p_excoeff(pres_kovasznay);

   // Add Dirichlet boundary conditions to velocity space restricted to
   // selected attributes on the mesh.
   Array<int> attr(pmesh->bdr_attributes.Max());
   attr = 1;
   flowsolver.AddVelDirichletBC(vel_kovasznay, attr);
   flowsolver.AddPresDirichletBC(pres_kovasznay, attr);

   double t = 0.0;
   double dt = ctx.dt;
   double t_final = ctx.t_final;
   bool last_step = false;

   flowsolver.Setup(dt);

   double err_u = 0.0;
   double err_p = 0.0;
   ParGridFunction *u_gf = nullptr;
   ParGridFunction *p_gf = nullptr;

   for (int step = 0; !last_step; ++step)
   {
      if (t + dt >= t_final - dt / 2)
      {
         last_step = true;
      }

      flowsolver.Step(t, dt, step);

      // Compare against exact solution of velocity and pressure.
      u_gf = flowsolver.GetCurrentVelocity();
      p_gf = flowsolver.GetCurrentPressure();

      u_excoeff.SetTime(t);
      p_excoeff.SetTime(t);
      err_u = u_gf->ComputeL2Error(u_excoeff);
      err_p = p_gf->ComputeL2Error(p_excoeff);

      if (mpi.Root())
      {
         printf("%.5E %.5E %.5E %.5E err\n", t, dt, err_u, err_p);
         fflush(stdout);
      }
   }

   char vishost[] = "localhost";
   int visport = 19916;
   socketstream sol_sock(vishost, visport);
   sol_sock.precision(8);
   sol_sock << "parallel " << mpi.WorldSize() << " " << mpi.WorldRank() << "\n";
   sol_sock << "solution\n" << *pmesh << *u_ic << std::flush;

   flowsolver.PrintTimingData();

   delete pmesh;

   return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "navier_solver.hpp"
#include <fstream>

using namespace mfem;
using namespace navier;

struct s_NavierContext
{
   int ser_ref_levels = 1;
   int order = 6;
   double kinvis = 1.0 / 40.0;
   double t_final = 10 * 0.001;
   double dt = 0.001;
   double reference_pressure = 0.0;
   double reynolds = 1.0 / kinvis;
   double lam = 0.5 * reynolds
                - sqrt(0.25 * reynolds * reynolds + 4.0 * M_PI * M_PI);
   bool pa = true;
   bool ni = false;
   bool visualization = false;
   bool checkres = false;
} ctx;

void vel_kovasznay(const Vector &x, double t, Vector &u)
{
   double xi = x(0);
   double yi = x(1);

   u(0) = 1.0 - exp(ctx.lam * xi) * cos(2.0 * M_PI * yi);
   u(1) = ctx.lam / (2.0 * M_PI) * exp(ctx.lam * xi) * sin(2.0 * M_PI * yi);
}

double pres_kovasznay(const Vector &x, double t)
{
   double xi = x(0);

   return 0.5 * (1.0 - exp(2.0 * ctx.lam * xi)) + ctx.reference_pressure;
}

int main(int argc, char *argv[])
{
   MPI_Session mpi(argc, argv);

   OptionsParser args(argc, argv);
   args.AddOption(&ctx.ser_ref_levels,
                  "-rs",
                  "--refine-serial",
                  "Number of times to refine the mesh uniformly in serial.");
   args.AddOption(&ctx.order,
                  "-o",
                  "--order",
                  "Order (degree) of the finite elements.");
   args.AddOption(&ctx.dt, "-dt", "--time-step", "Time step.");
   args.AddOption(&ctx.t_final, "-tf", "--final-time", "Final time.");
   args.AddOption(&ctx.pa,
                  "-pa",
                  "--enable-pa",
                  "-no-pi",
                  "--disable-pi",
                  "Enable partial assembly.");
   args.AddOption(&ctx.ni,
                  "-ni",
                  "--enable-ni",
                  "-no-ni",
                  "--disable-ni",
                  "Enable numerical integration rules.");
   args.AddOption(&ctx.visualization,
                  "-vis",
                  "--visualization",
                  "-no-vis",
                  "--no-visualization",
                  "Enable or disable GLVis visualization.");
   args.AddOption(
      &ctx.checkres,
      "-cr",
      "--checkresult",
      "-no-cr",
      "--no-checkresult",
      "Enable or disable checking of the result. Returns -1 on failure.");
   args.Parse();
   if (!args.Good())
   {
      if (mpi.Root())
      {
         args.PrintUsage(mfem::out);
      }
      MPI_Finalize();
      return 1;
   }
   if (mpi.Root())
   {
      args.PrintOptions(mfem::out);
   }

   Mesh *mesh = new Mesh(2, 4, Element::QUADRILATERAL, false, 1.5, 2.0);

   mesh->EnsureNodes();
   GridFunction *nodes = mesh->GetNodes();
   *nodes -= 0.5;

   for (int i = 0; i < ctx.ser_ref_levels; ++i)
   {
      mesh->UniformRefinement();
   }

   if (mpi.Root())
   {
      std::cout << "Number of elements: " << mesh->GetNE() << std::endl;
   }

   auto *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
   delete mesh;

   // Create the flow solver.
   NavierSolver flowsolver(pmesh, ctx.order, ctx.kinvis);
   flowsolver.EnablePA(ctx.pa);
   flowsolver.EnableNI(ctx.ni);

   // Set the initial condition.
   // This is completely user customizeable.
   ParGridFunction *u_ic = flowsolver.GetCurrentVelocity();
   VectorFunctionCoefficient u_excoeff(pmesh->Dimension(), vel_kovasznay);
   u_ic->ProjectCoefficient(u_excoeff);

   FunctionCoefficient p_excoeff(pres_kovasznay);

   // Add Dirichlet boundary conditions to velocity space restricted to
   // selected attributes on the mesh.
   Array<int> attr(pmesh->bdr_attributes.Max());
   attr = 1;
   flowsolver.AddVelDirichletBC(vel_kovasznay, attr);

   double t = 0.0;
   double dt = ctx.dt;
   double t_final = ctx.t_final;
   bool last_step = false;

   flowsolver.Setup(dt);

   double err_u = 0.0;
   double err_p = 0.0;
   ParGridFunction *u_gf = nullptr;
   ParGridFunction *p_gf = nullptr;

   ParGridFunction p_ex_gf(p_gf->ParFESpace());
   GridFunctionCoefficient p_ex_gf_coeff(&p_ex_gf);

   for (int step = 0; !last_step; ++step)
   {
      if (t + dt >= t_final - dt / 2)
      {
         last_step = true;
      }

      flowsolver.Step(t, dt, step);

      // Compare against exact solution of velocity and pressure.
      u_gf = flowsolver.GetCurrentVelocity();
      p_gf = flowsolver.GetCurrentPressure();

      u_excoeff.SetTime(t);
      p_excoeff.SetTime(t);

      // Remove mean value from exact pressure solution.
      p_ex_gf.ProjectCoefficient(p_excoeff);
      flowsolver.MeanZero(p_ex_gf);

      err_u = u_gf->ComputeL2Error(u_excoeff);
      err_p = p_gf->ComputeL2Error(p_ex_gf_coeff);

      if (mpi.Root())
      {
         printf("%.2d %.2E %.2E %.5E %.5E err\n", ctx.order, t, dt, err_u, err_p);
         fflush(stdout);
      }
   }

   if (ctx.visualization)
   {
      char vishost[] = "localhost";
      int visport = 19916;
      socketstream sol_sock(vishost, visport);
      sol_sock.precision(8);
      sol_sock << "parallel " << mpi.WorldSize() << " " << mpi.WorldRank()
               << "\n";
      sol_sock << "solution\n" << *pmesh << *u_ic << std::flush;
   }

   flowsolver.PrintTimingData();

   // Test if the result for the test run is as expected.
   if (ctx.checkres)
   {
      double tol = 1e-6;
      if (err_u > tol || err_p > tol)
      {
         if (mpi.Root())
         {
            mfem::out << "Result has a larger error than expected."
                      << std::endl;
         }
         return -1;
      }
   }

   delete pmesh;

   return 0;
}
<commit_msg>Do not get an FESpace from a nullptr<commit_after>// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.

#include "navier_solver.hpp"
#include <fstream>

using namespace mfem;
using namespace navier;

struct s_NavierContext
{
   int ser_ref_levels = 1;
   int order = 6;
   double kinvis = 1.0 / 40.0;
   double t_final = 10 * 0.001;
   double dt = 0.001;
   double reference_pressure = 0.0;
   double reynolds = 1.0 / kinvis;
   double lam = 0.5 * reynolds
                - sqrt(0.25 * reynolds * reynolds + 4.0 * M_PI * M_PI);
   bool pa = true;
   bool ni = false;
   bool visualization = false;
   bool checkres = false;
} ctx;

void vel_kovasznay(const Vector &x, double t, Vector &u)
{
   double xi = x(0);
   double yi = x(1);

   u(0) = 1.0 - exp(ctx.lam * xi) * cos(2.0 * M_PI * yi);
   u(1) = ctx.lam / (2.0 * M_PI) * exp(ctx.lam * xi) * sin(2.0 * M_PI * yi);
}

double pres_kovasznay(const Vector &x, double t)
{
   double xi = x(0);

   return 0.5 * (1.0 - exp(2.0 * ctx.lam * xi)) + ctx.reference_pressure;
}

int main(int argc, char *argv[])
{
   MPI_Session mpi(argc, argv);

   OptionsParser args(argc, argv);
   args.AddOption(&ctx.ser_ref_levels,
                  "-rs",
                  "--refine-serial",
                  "Number of times to refine the mesh uniformly in serial.");
   args.AddOption(&ctx.order,
                  "-o",
                  "--order",
                  "Order (degree) of the finite elements.");
   args.AddOption(&ctx.dt, "-dt", "--time-step", "Time step.");
   args.AddOption(&ctx.t_final, "-tf", "--final-time", "Final time.");
   args.AddOption(&ctx.pa,
                  "-pa",
                  "--enable-pa",
                  "-no-pi",
                  "--disable-pi",
                  "Enable partial assembly.");
   args.AddOption(&ctx.ni,
                  "-ni",
                  "--enable-ni",
                  "-no-ni",
                  "--disable-ni",
                  "Enable numerical integration rules.");
   args.AddOption(&ctx.visualization,
                  "-vis",
                  "--visualization",
                  "-no-vis",
                  "--no-visualization",
                  "Enable or disable GLVis visualization.");
   args.AddOption(
      &ctx.checkres,
      "-cr",
      "--checkresult",
      "-no-cr",
      "--no-checkresult",
      "Enable or disable checking of the result. Returns -1 on failure.");
   args.Parse();
   if (!args.Good())
   {
      if (mpi.Root())
      {
         args.PrintUsage(mfem::out);
      }
      MPI_Finalize();
      return 1;
   }
   if (mpi.Root())
   {
      args.PrintOptions(mfem::out);
   }

   Mesh *mesh = new Mesh(2, 4, Element::QUADRILATERAL, false, 1.5, 2.0);

   mesh->EnsureNodes();
   GridFunction *nodes = mesh->GetNodes();
   *nodes -= 0.5;

   for (int i = 0; i < ctx.ser_ref_levels; ++i)
   {
      mesh->UniformRefinement();
   }

   if (mpi.Root())
   {
      std::cout << "Number of elements: " << mesh->GetNE() << std::endl;
   }

   auto *pmesh = new ParMesh(MPI_COMM_WORLD, *mesh);
   delete mesh;

   // Create the flow solver.
   NavierSolver flowsolver(pmesh, ctx.order, ctx.kinvis);
   flowsolver.EnablePA(ctx.pa);
   flowsolver.EnableNI(ctx.ni);

   // Set the initial condition.
   // This is completely user customizeable.
   ParGridFunction *u_ic = flowsolver.GetCurrentVelocity();
   VectorFunctionCoefficient u_excoeff(pmesh->Dimension(), vel_kovasznay);
   u_ic->ProjectCoefficient(u_excoeff);

   FunctionCoefficient p_excoeff(pres_kovasznay);

   // Add Dirichlet boundary conditions to velocity space restricted to
   // selected attributes on the mesh.
   Array<int> attr(pmesh->bdr_attributes.Max());
   attr = 1;
   flowsolver.AddVelDirichletBC(vel_kovasznay, attr);

   double t = 0.0;
   double dt = ctx.dt;
   double t_final = ctx.t_final;
   bool last_step = false;

   flowsolver.Setup(dt);

   double err_u = 0.0;
   double err_p = 0.0;
   ParGridFunction *u_gf = nullptr;
   ParGridFunction *p_gf = nullptr;

   ParGridFunction p_ex_gf(flowsolver.GetCurrentPressure()->ParFESpace());
   GridFunctionCoefficient p_ex_gf_coeff(&p_ex_gf);

   for (int step = 0; !last_step; ++step)
   {
      if (t + dt >= t_final - dt / 2)
      {
         last_step = true;
      }

      flowsolver.Step(t, dt, step);

      // Compare against exact solution of velocity and pressure.
      u_gf = flowsolver.GetCurrentVelocity();
      p_gf = flowsolver.GetCurrentPressure();

      u_excoeff.SetTime(t);
      p_excoeff.SetTime(t);

      // Remove mean value from exact pressure solution.
      p_ex_gf.ProjectCoefficient(p_excoeff);
      flowsolver.MeanZero(p_ex_gf);

      err_u = u_gf->ComputeL2Error(u_excoeff);
      err_p = p_gf->ComputeL2Error(p_ex_gf_coeff);

      if (mpi.Root())
      {
         printf("%.2d %.2E %.2E %.5E %.5E err\n", ctx.order, t, dt, err_u, err_p);
         fflush(stdout);
      }
   }

   if (ctx.visualization)
   {
      char vishost[] = "localhost";
      int visport = 19916;
      socketstream sol_sock(vishost, visport);
      sol_sock.precision(8);
      sol_sock << "parallel " << mpi.WorldSize() << " " << mpi.WorldRank()
               << "\n";
      sol_sock << "solution\n" << *pmesh << *u_ic << std::flush;
   }

   flowsolver.PrintTimingData();

   // Test if the result for the test run is as expected.
   if (ctx.checkres)
   {
      double tol = 1e-6;
      if (err_u > tol || err_p > tol)
      {
         if (mpi.Root())
         {
            mfem::out << "Result has a larger error than expected."
                      << std::endl;
         }
         return -1;
      }
   }

   delete pmesh;

   return 0;
}
<|endoftext|>


<commit_before>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "RhoLogSink.h"

#include "common/RhoFile.h"
#include "common/StringConverter.h"
#include "common/RhodesApp.h"
#include "net/RawSocket.h"
#include "net/URI.h"

#if defined( OS_SYMBIAN )
#include <e32debug.h>
#endif

#if defined(OS_MACOSX) && !defined(RHODES_EMULATOR)

extern "C" void rho_ios_log_console_output(const char* message);

#endif

namespace rho {

CLogFileSink::CLogFileSink(const LogSettings& oSettings)
    : m_pFile(0), m_pPosFile(0), m_oLogConf(oSettings), m_nCirclePos(-1), m_nFileLogSize(0)
{

}

CLogFileSink::~CLogFileSink()
{
	if(m_pFile)
		delete m_pFile;
}

void CLogFileSink::writeLogMessage( String& strMsg ){
    unsigned int len = strMsg.length();

    if ( !m_pFile )
        m_pFile = new common::CRhoFile();

    if ( !m_pFile->isOpened() ){
        m_pFile->open( getLogConf().getLogFilePath().c_str(), common::CRhoFile::OpenForAppend );
        m_nFileLogSize = m_pFile->size();
        loadLogPosition();
    }

    if ( getLogConf().getMaxLogFileSize() > 0 )
    {
        if ( ( m_nCirclePos >= 0 && m_nCirclePos + len > getLogConf().getMaxLogFileSize() ) ||
             ( m_nCirclePos < 0 && m_nFileLogSize + len > getLogConf().getMaxLogFileSize() ) )
        {
            m_pFile->truncate(m_pFile->getPos());
            m_pFile->movePosToStart();
            m_nFileLogSize = 0;
            m_nCirclePos = 0;
        }
    }

    int nWritten = m_pFile->write( strMsg.c_str(), len );
    m_pFile->flush();

    if ( m_nCirclePos >= 0 )
        m_nCirclePos += nWritten;
    else
        m_nFileLogSize += nWritten;

    saveLogPosition();
}

int CLogFileSink::getCurPos()
{
    return m_nCirclePos >= 0 ? m_nCirclePos : m_nFileLogSize;
}

void CLogFileSink::clear(){
    if ( m_pFile )    {
        delete m_pFile;
        m_pFile = NULL;
    }

    common::CRhoFile().deleteFile(getLogConf().getLogFilePath().c_str());
    String strPosPath = getLogConf().getLogFilePath() + "_pos";
    common::CRhoFile().deleteFile(strPosPath.c_str());
}

void CLogFileSink::loadLogPosition(){
    if ( !m_pPosFile )
        m_pPosFile = new common::CRhoFile();

    if ( !m_pPosFile->isOpened() ){
        String strPosPath = getLogConf().getLogFilePath() + "_pos";
        m_pPosFile->open( strPosPath.c_str(), common::CRhoFile::OpenForReadWrite );
    }

    if ( !m_pPosFile->isOpened() )
        return;

    String strPos;
    m_pPosFile->movePosToStart();
    m_pPosFile->readString(strPos);
    if ( strPos.length() == 0 )
        return;

    m_nCirclePos = atoi(strPos.c_str());
    if ( m_nCirclePos < 0 || m_nCirclePos > (int)m_nFileLogSize )
    	m_nCirclePos = -1;

    if ( m_nCirclePos >= 0 )
        m_pFile->setPosTo( m_nCirclePos );
}

void CLogFileSink::saveLogPosition(){
    if ( m_nCirclePos < 0 )
        return;

    if ( m_nCirclePos > (int)getLogConf().getMaxLogFileSize() )
    	return;

    String strPos = common::convertToStringA(m_nCirclePos);
    for( int i = strPos.length(); i < 10; i++ )
    	strPos += ' ';

    m_pPosFile->movePosToStart();
    m_pPosFile->write( strPos.c_str(), strPos.length() );
    m_pPosFile->flush();
}

#ifndef min
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif

void CLogOutputSink::writeLogMessage( String& strMsg )
{
    if ( strMsg.length() > 1 && strMsg[strMsg.length()-2] == '\r' )
        strMsg.erase(strMsg.length()-2,1);

    const char* szMsg = strMsg.c_str();

#if defined( OS_WINDOWS_DESKTOP )
		::OutputDebugStringA(szMsg);
#elif defined( OS_PLATFORM_MOTCE )
		::OutputDebugStringW(common::convertToStringW(strMsg).c_str());
#elif defined(OS_WP8)
		::OutputDebugStringW(common::convertToStringW(strMsg).c_str());
#elif defined( OS_SYMBIAN )
        TPtrC8 des((const TUint8*)szMsg);
      	RDebug::RawPrint(des);
        return;
#elif defined(OS_MACOSX) && !defined(RHODES_EMULATOR)
        rho_ios_log_console_output(szMsg);
#endif

#if !defined( OS_PLATFORM_MOTCE ) && !(defined(OS_MACOSX) && !defined(RHODES_EMULATOR))
    for( int n = 0; n < (int)strMsg.length(); n+= 100 )
        fwrite(szMsg+n, 1, min(100,strMsg.length()-n) , stdout );

    fflush(stdout);
#endif
}

CLogSocketSink::CLogSocketSink(const LogSettings& oSettings)
{
	m_URL = oSettings.getLogURL();

    CThreadQueue::setLogCategory(LogCategory("NO_LOGGING"));
    setPollInterval(QUEUE_POLL_INTERVAL_INFINITE);
    start(epLow);
}

CLogSocketSink::~CLogSocketSink()
{
	//wait till all commands will be sent to server
    CRhoThread::stop(2000);
}

void CLogSocketSink::setUrl(String url)
{
	m_URL = url;
}

void CLogSocketSink::writeLogMessage( String& strMsg )
{
	addQueueCommand(new LogCommand(m_URL.c_str(), strMsg.c_str()));
}

void CLogSocketSink::processCommand(IQueueCommand* pCmd)
{
    LogCommand *cmd = (LogCommand *)pCmd;

    /*
      Checking CRhodesApp instance is needed because net request requires it to be valid.
      If socket sink is initialized from ext manager, log messages could occur before app instance is set so we will crash.
    */
    if (!cmd || (common::CRhodesApp::getInstance()==0))
        return;
#if defined(APP_BUILD_CAPABILITY_SHARED_RUNTIME)

	getNet().doRequest( "GET", cmd->m_url+"?LogSeverity="+cmd->m_body[0]+"&LogComment="+net::URI::urlEncode(cmd->m_body), String(), 0, 0 );
#else
	getNet().doRequest( "POST", cmd->m_url, cmd->m_body, 0, 0 );
#endif
}

}
<commit_msg>Remote log crash has been fixed.<commit_after>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "RhoLogSink.h"

#include "common/RhoFile.h"
#include "common/StringConverter.h"
#include "common/RhodesApp.h"
#include "net/RawSocket.h"
#include "net/URI.h"

#if defined( OS_SYMBIAN )
#include <e32debug.h>
#endif

#if defined(OS_MACOSX) && !defined(RHODES_EMULATOR)

extern "C" void rho_ios_log_console_output(const char* message);

#endif

namespace rho {

CLogFileSink::CLogFileSink(const LogSettings& oSettings)
    : m_pFile(0), m_pPosFile(0), m_oLogConf(oSettings), m_nCirclePos(-1), m_nFileLogSize(0)
{

}

CLogFileSink::~CLogFileSink()
{
	if(m_pFile)
		delete m_pFile;
}

void CLogFileSink::writeLogMessage( String& strMsg ){
    unsigned int len = strMsg.length();

    if ( !m_pFile )
        m_pFile = new common::CRhoFile();

    if ( !m_pFile->isOpened() ){
        m_pFile->open( getLogConf().getLogFilePath().c_str(), common::CRhoFile::OpenForAppend );
        m_nFileLogSize = m_pFile->size();
        loadLogPosition();
    }

    if ( getLogConf().getMaxLogFileSize() > 0 )
    {
        if ( ( m_nCirclePos >= 0 && m_nCirclePos + len > getLogConf().getMaxLogFileSize() ) ||
             ( m_nCirclePos < 0 && m_nFileLogSize + len > getLogConf().getMaxLogFileSize() ) )
        {
            m_pFile->truncate(m_pFile->getPos());
            m_pFile->movePosToStart();
            m_nFileLogSize = 0;
            m_nCirclePos = 0;
        }
    }

    int nWritten = m_pFile->write( strMsg.c_str(), len );
    m_pFile->flush();

    if ( m_nCirclePos >= 0 )
        m_nCirclePos += nWritten;
    else
        m_nFileLogSize += nWritten;

    saveLogPosition();
}

int CLogFileSink::getCurPos()
{
    return m_nCirclePos >= 0 ? m_nCirclePos : m_nFileLogSize;
}

void CLogFileSink::clear(){
    if ( m_pFile )    {
        delete m_pFile;
        m_pFile = NULL;
    }

    common::CRhoFile().deleteFile(getLogConf().getLogFilePath().c_str());
    String strPosPath = getLogConf().getLogFilePath() + "_pos";
    common::CRhoFile().deleteFile(strPosPath.c_str());
}

void CLogFileSink::loadLogPosition(){
    if ( !m_pPosFile )
        m_pPosFile = new common::CRhoFile();

    if ( !m_pPosFile->isOpened() ){
        String strPosPath = getLogConf().getLogFilePath() + "_pos";
        m_pPosFile->open( strPosPath.c_str(), common::CRhoFile::OpenForReadWrite );
    }

    if ( !m_pPosFile->isOpened() )
        return;

    String strPos;
    m_pPosFile->movePosToStart();
    m_pPosFile->readString(strPos);
    if ( strPos.length() == 0 )
        return;

    m_nCirclePos = atoi(strPos.c_str());
    if ( m_nCirclePos < 0 || m_nCirclePos > (int)m_nFileLogSize )
    	m_nCirclePos = -1;

    if ( m_nCirclePos >= 0 )
        m_pFile->setPosTo( m_nCirclePos );
}

void CLogFileSink::saveLogPosition(){
    if ( m_nCirclePos < 0 )
        return;

    if ( m_nCirclePos > (int)getLogConf().getMaxLogFileSize() )
    	return;

    String strPos = common::convertToStringA(m_nCirclePos);
    for( int i = strPos.length(); i < 10; i++ )
    	strPos += ' ';

    m_pPosFile->movePosToStart();
    m_pPosFile->write( strPos.c_str(), strPos.length() );
    m_pPosFile->flush();
}

#ifndef min
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif

void CLogOutputSink::writeLogMessage( String& strMsg )
{
    if ( strMsg.length() > 1 && strMsg[strMsg.length()-2] == '\r' )
        strMsg.erase(strMsg.length()-2,1);

    const char* szMsg = strMsg.c_str();

#if defined( OS_WINDOWS_DESKTOP )
		::OutputDebugStringA(szMsg);
#elif defined( OS_PLATFORM_MOTCE )
		::OutputDebugStringW(common::convertToStringW(strMsg).c_str());
#elif defined(OS_WP8)
		::OutputDebugStringW(common::convertToStringW(strMsg).c_str());
#elif defined( OS_SYMBIAN )
        TPtrC8 des((const TUint8*)szMsg);
      	RDebug::RawPrint(des);
        return;
#elif defined(OS_MACOSX) && !defined(RHODES_EMULATOR)
        rho_ios_log_console_output(szMsg);
#endif

#if !defined( OS_PLATFORM_MOTCE ) && !(defined(OS_MACOSX) && !defined(RHODES_EMULATOR))
    for( int n = 0; n < (int)strMsg.length(); n+= 100 )
        fwrite(szMsg+n, 1, min(100,strMsg.length()-n) , stdout );

    fflush(stdout);
#endif
}

CLogSocketSink::CLogSocketSink(const LogSettings& oSettings)
{
	m_URL = oSettings.getLogURL();

    CThreadQueue::setLogCategory(LogCategory("NO_LOGGING"));
    setPollInterval(QUEUE_POLL_INTERVAL_INFINITE);
#if !defined( OS_WINDOWS_DESKTOP )
    start(epLow);
#endif
}

CLogSocketSink::~CLogSocketSink()
{
	//wait till all commands will be sent to server
#if !defined( OS_WINDOWS_DESKTOP )
    CRhoThread::stop(2000);
#endif
}

void CLogSocketSink::setUrl(String url)
{
	m_URL = url;
}

void CLogSocketSink::writeLogMessage( String& strMsg )
{
	addQueueCommand(new LogCommand(m_URL.c_str(), strMsg.c_str()));
}

void CLogSocketSink::processCommand(IQueueCommand* pCmd)
{
    LogCommand *cmd = (LogCommand *)pCmd;

    /*
      Checking CRhodesApp instance is needed because net request requires it to be valid.
      If socket sink is initialized from ext manager, log messages could occur before app instance is set so we will crash.
    */
    if (!cmd || (common::CRhodesApp::getInstance()==0))
        return;
#if defined(APP_BUILD_CAPABILITY_SHARED_RUNTIME)

	getNet().doRequest( "GET", cmd->m_url+"?LogSeverity="+cmd->m_body[0]+"&LogComment="+net::URI::urlEncode(cmd->m_body), String(), 0, 0 );
#else
	getNet().doRequest( "POST", cmd->m_url, cmd->m_body, 0, 0 );
#endif
}

}
<|endoftext|>


<commit_before>
#include <jni.h>

extern "C" {
  void init(JNIEnv *env, jobject local_store_java, jobject asset_manager, int width, int height);
  void update();
  void touch(int touch_id, int action, double x, double y);
}

#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <GLES/gl.h>

#include "gameengine/android/modules/ad_engine_android.h"
#include "gameengine/android/modules/analytics_engine_android.h"
#include "gameengine/android/modules/game_engine_factory_android.h"
#include "gameengine/android/modules/local_store_android.h"
#include "gameengine/game_engine.h"
#include "gameengine/game_engine.h"
#include "soundengine/sound_player.h"

static sp<GameEngine> game_engine_;

void init(JNIEnv *env, jobject local_store_java, jobject asset_manager, int width, int height) {
  glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  glDepthMask(false);
  glEnable(GL_CULL_FACE);
  glEnable(GL_BLEND);
  glEnable(GL_TEXTURE_2D);
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);

  // TODO This shouldn't be hardcoded. Rethink this anyways.

  game_engine_.reset(new GameEngine());

  Texture2D::SetScreenHeight(height);
  game_engine_->set_screen_size(screen_size_make(width, height));

  game_engine_->set_platform_type(kPlatformTypePhone);
  game_engine_->set_platform_resolution(kPlatformResolutionHigh);

  sp<GameEngineFactory> factory = sp<GameEngineFactory>(new GameEngineFactoryAndroid());
  game_engine_->set_factory(factory);

  sp<LocalStore> local_store = sp<LocalStore>(new LocalStoreAndroid(env, local_store_java));
  game_engine_->set_local_store(local_store);

  sp<AdEngine> ad_engine = sp<AdEngine>(new AdEngineAndroid());
  game_engine_->set_ad_engine(ad_engine);

  sp<AnalyticsEngine> analytics_engine = sp<AnalyticsEngine>(new AnalyticsEngineAndroid());
  game_engine_->set_analytics_engine(analytics_engine);

  AAssetManager *mgr = AAssetManager_fromJava(env, asset_manager);
  assert(NULL != mgr);
  // TODO casting is bad
  ((SoundPlayerImpl *)SoundPlayer::instance())->setAssetManager(mgr);

  sharkengine_init(game_engine_);
}

void update() {
  game_engine_->Update();

    int backingWidth_ = 640;
    int backingHeight_ = 1138;

    glViewport(0, 0, backingWidth_, backingHeight_);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(0, backingWidth_, 0, backingHeight_, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

  game_engine_->Render();
}

#include "gameengine/touch.h"
#include <vector>
using std::vector;

void touch(int touch_id, int action, double x, double y) {
  Touch touch;
  touch.set_location(game_engine_->screen_point_to_game_point(screen_point_make(x, y)));
  touch.set_identifier((void *)touch_id);
  if (action == 0) {
    game_engine_->AddTouchBegan(touch);
  } else if (action == 1) {
    game_engine_->AddTouchEnded(touch);
  } else if (action == 2) {
    game_engine_->AddTouchMoved(touch);
  }
}
<commit_msg>[Android] Fix issue with NULL Touch identifiers.<commit_after>
#include <jni.h>

extern "C" {
  void init(JNIEnv *env, jobject local_store_java, jobject asset_manager, int width, int height);
  void update();
  void touch(int touch_id, int action, double x, double y);
}

#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <GLES/gl.h>

#include "gameengine/android/modules/ad_engine_android.h"
#include "gameengine/android/modules/analytics_engine_android.h"
#include "gameengine/android/modules/game_engine_factory_android.h"
#include "gameengine/android/modules/local_store_android.h"
#include "gameengine/game_engine.h"
#include "gameengine/game_engine.h"
#include "soundengine/sound_player.h"

static sp<GameEngine> game_engine_;

void init(JNIEnv *env, jobject local_store_java, jobject asset_manager, int width, int height) {
  glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  glDepthMask(false);
  glEnable(GL_CULL_FACE);
  glEnable(GL_BLEND);
  glEnable(GL_TEXTURE_2D);
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  glEnableClientState(GL_VERTEX_ARRAY);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);

  // TODO This shouldn't be hardcoded. Rethink this anyways.

  game_engine_.reset(new GameEngine());

  Texture2D::SetScreenHeight(height);
  game_engine_->set_screen_size(screen_size_make(width, height));

  game_engine_->set_platform_type(kPlatformTypePhone);
  game_engine_->set_platform_resolution(kPlatformResolutionHigh);

  sp<GameEngineFactory> factory = sp<GameEngineFactory>(new GameEngineFactoryAndroid());
  game_engine_->set_factory(factory);

  sp<LocalStore> local_store = sp<LocalStore>(new LocalStoreAndroid(env, local_store_java));
  game_engine_->set_local_store(local_store);

  sp<AdEngine> ad_engine = sp<AdEngine>(new AdEngineAndroid());
  game_engine_->set_ad_engine(ad_engine);

  sp<AnalyticsEngine> analytics_engine = sp<AnalyticsEngine>(new AnalyticsEngineAndroid());
  game_engine_->set_analytics_engine(analytics_engine);

  AAssetManager *mgr = AAssetManager_fromJava(env, asset_manager);
  assert(NULL != mgr);
  // TODO casting is bad
  ((SoundPlayerImpl *)SoundPlayer::instance())->setAssetManager(mgr);

  sharkengine_init(game_engine_);
}

void update() {
  game_engine_->Update();

    int backingWidth_ = 640;
    int backingHeight_ = 1138;

    glViewport(0, 0, backingWidth_, backingHeight_);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(0, backingWidth_, 0, backingHeight_, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

  game_engine_->Render();
}

#include "gameengine/touch.h"
#include <vector>
using std::vector;

void touch(int touch_id, int action, double x, double y) {
  Touch touch;
  touch.set_location(game_engine_->screen_point_to_game_point(screen_point_make(x, y)));
  touch.set_identifier((void *)(touch_id + 100));  // We don't want NULL identifiers, so add 100.
  if (action == 0) {
    game_engine_->AddTouchBegan(touch);
  } else if (action == 1) {
    game_engine_->AddTouchEnded(touch);
  } else if (action == 2) {
    game_engine_->AddTouchMoved(touch);
  }
}
<|endoftext|>