<commit_before>/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <ndb_global.h>
#include <ndb_opts.h>

#include <mgmapi.h>
#include <NdbMain.h>
#include <NdbOut.hpp>
#include <NdbSleep.h>
#include <kernel/ndb_limits.h>
#include "../include/mgmcommon/LocalConfig.hpp"

#include <NDBT.hpp>

int
waitClusterStatus(const char* _addr, ndb_mgm_node_status _status, unsigned int _timeout);

static const char* opt_connect_str= 0;
static int _no_contact = 0;
static int _timeout = 120;
static struct my_option my_long_options[] =
{
  NDB_STD_OPTS("ndb_desc"),
  { "no-contact", 'n', "Wait for cluster no contact",
    (gptr*) &_no_contact, (gptr*) &_no_contact, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
  { "timeout", 't', "Timeout to wait",
    (gptr*) &_timeout, (gptr*) &_timeout, 0,
    GET_INT, REQUIRED_ARG, 120, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void print_version()
{
  printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
}
static void usage()
{
  print_version();
  my_print_help(my_long_options);
  my_print_variables(my_long_options);
}
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
	       char *argument)
{
  switch (optid) {
  case '#':
    DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_drop_table.trace");
    break;
  case 'V':
    print_version();
    exit(0);
  case '?':
    usage();
    exit(0);
  }
  return 0;
}

int main(int argc, char** argv){
  NDB_INIT(argv[0]);
  const char *load_default_groups[]= { "ndb_tools",0 };
  load_defaults("my",load_default_groups,&argc,&argv);
  const char* _hostName = NULL;
  int ho_error;
  if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
    return NDBT_ProgramExit(NDBT_WRONGARGS);

  char buf[255];
  _hostName = argv[0];

  if (_hostName == NULL){
    LocalConfig lcfg;
    if(!lcfg.init())
    {
      lcfg.printError();
      lcfg.printUsage();
      g_err  << "Error parsing local config file" << endl;
      return NDBT_ProgramExit(NDBT_FAILED);
    }

    for (unsigned i = 0; i<lcfg.ids.size();i++)
    {
      MgmtSrvrId * m = &lcfg.ids[i];

      switch(m->type){
      case MgmId_TCP:
	snprintf(buf, 255, "%s:%d", m->name.c_str(), m->port);
	_hostName = buf;
	break;
      case MgmId_File:
	break;
      default:
	break;
      }
      if (_hostName != NULL)
	break;
    }
    if (_hostName == NULL)
    {
      g_err << "No management servers configured in local config file" << endl;
      return NDBT_ProgramExit(NDBT_FAILED);
    }
  }

  if (_no_contact) {
    if (waitClusterStatus(_hostName, NDB_MGM_NODE_STATUS_NO_CONTACT, _timeout) != 0)
      return NDBT_ProgramExit(NDBT_FAILED);
  } else if (waitClusterStatus(_hostName, NDB_MGM_NODE_STATUS_STARTED, _timeout) != 0)
    return NDBT_ProgramExit(NDBT_FAILED);

  return NDBT_ProgramExit(NDBT_OK);
}

#define MGMERR(h) \
  ndbout << "latest_error="<<ndb_mgm_get_latest_error(h) \
	 << ", line="<<ndb_mgm_get_latest_error_line(h) \
	 << endl;

NdbMgmHandle handle= NULL;

Vector<ndb_mgm_node_state> ndbNodes;
Vector<ndb_mgm_node_state> mgmNodes;
Vector<ndb_mgm_node_state> apiNodes;

int
getStatus(){
  int retries = 0;
  struct ndb_mgm_cluster_state * status;
  struct ndb_mgm_node_state * node;

  ndbNodes.clear();
  mgmNodes.clear();
  apiNodes.clear();

  while(retries < 10){
    status = ndb_mgm_get_status(handle);
    if (status == NULL){
      ndbout << "status==NULL, retries="<<retries<<endl;
      MGMERR(handle);
      retries++;
      continue;
    }
    int count = status->no_of_nodes;
    for (int i = 0; i < count; i++){
      node = &status->node_states[i];
      switch(node->node_type){
      case NDB_MGM_NODE_TYPE_NDB:
	ndbNodes.push_back(*node);
	break;
      case NDB_MGM_NODE_TYPE_MGM:
	mgmNodes.push_back(*node);
	break;
      case NDB_MGM_NODE_TYPE_API:
	apiNodes.push_back(*node);
	break;
      default:
	if(node->node_status == NDB_MGM_NODE_STATUS_UNKNOWN ||
	   node->node_status == NDB_MGM_NODE_STATUS_NO_CONTACT){
	  retries++;
	  ndbNodes.clear();
	  mgmNodes.clear();
	  apiNodes.clear();
	  free(status);
	  status = NULL;
          count = 0;

	  ndbout << "kalle"<< endl;
	  break;
	}
	abort();
	break;
      }
    }
    if(status == 0){
      ndbout << "status == 0" << endl;
      continue;
    }
    free(status);
    return 0;
  }

  g_err  << "getStatus failed" << endl;
  return -1;
}

int
waitClusterStatus(const char* _addr,
		  ndb_mgm_node_status _status,
		  unsigned int _timeout)
{
  int _startphase = -1;

  int _nodes[MAX_NDB_NODES];
  int _num_nodes = 0;

  handle = ndb_mgm_create_handle();
  if (handle == NULL){
    g_err << "handle == NULL" << endl;
    return -1;
  }
  g_info << "Connecting to mgmsrv at " << _addr << endl;
  if (ndb_mgm_connect(handle, _addr) == -1) {
    MGMERR(handle);
    g_err  << "Connection to " << _addr << " failed" << endl;
    return -1;
  }

  if (getStatus() != 0)
    return -1;

  // Collect all nodes into nodes
  for (size_t i = 0; i < ndbNodes.size(); i++){
    _nodes[i] = ndbNodes[i].node_id;
    _num_nodes++;
  }

  unsigned int attempts = 0;
  unsigned int resetAttempts = 0;
  const unsigned int MAX_RESET_ATTEMPTS = 10;
  bool allInState = false;
  while (allInState == false){
    if (_timeout > 0 && attempts > _timeout){
      /**
       * Timeout has expired waiting for the nodes to enter
       * the state we want
       */
      bool waitMore = false;
      /**
       * Make special check if we are waiting for
       * cluster to become started
       */
      if(_status == NDB_MGM_NODE_STATUS_STARTED){
	waitMore = true;
	/**
	 * First check if any node is not starting
	 * then it's no idea to wait anymore
	 */
	for (size_t n = 0; n < ndbNodes.size(); n++){
	  if (ndbNodes[n].node_status != NDB_MGM_NODE_STATUS_STARTED &&
	      ndbNodes[n].node_status != NDB_MGM_NODE_STATUS_STARTING)
	    waitMore = false;

	}
      }

      if (!waitMore || resetAttempts > MAX_RESET_ATTEMPTS){
	g_err << "waitNodeState("
	      << ndb_mgm_get_node_status_string(_status)
	      <<", "<<_startphase<<")"
	      << " timeout after " << attempts <<" attemps" << endl;
	return -1;
      }

      g_err << "waitNodeState("
	    << ndb_mgm_get_node_status_string(_status)
	    <<", "<<_startphase<<")"
	    << " resetting number of attempts "
	    << resetAttempts << endl;
      attempts = 0;
      resetAttempts++;

    }

    allInState = true;
    if (getStatus() != 0){
      g_err << "getStatus != 0" << endl;
      return -1;
    }

    // ndbout << "waitNodeState; _num_nodes = " << _num_nodes << endl;
    // for (int i = 0; i < _num_nodes; i++)
    //   ndbout << " node["<<i<<"] =" <<_nodes[i] << endl;

    for (int i = 0; i < _num_nodes; i++){
      ndb_mgm_node_state* ndbNode = NULL;
      for (size_t n = 0; n < ndbNodes.size(); n++){
	if (ndbNodes[n].node_id == _nodes[i])
	  ndbNode = &ndbNodes[n];
      }

      if(ndbNode == NULL){
	allInState = false;
	continue;
      }

      g_info << "State node " << ndbNode->node_id << " "
	     << ndb_mgm_get_node_status_string(ndbNode->node_status)<< endl;

      assert(ndbNode != NULL);

      if(_status == NDB_MGM_NODE_STATUS_STARTING &&
	 ((ndbNode->node_status == NDB_MGM_NODE_STATUS_STARTING &&
	   ndbNode->start_phase >= _startphase) ||
	  (ndbNode->node_status == NDB_MGM_NODE_STATUS_STARTED)))
	continue;

      if (_status == NDB_MGM_NODE_STATUS_STARTING){
	g_info << "status = "
	       << ndb_mgm_get_node_status_string(ndbNode->node_status)
	       <<", start_phase="<<ndbNode->start_phase<<endl;
	if (ndbNode->node_status !=  _status) {
	  if (ndbNode->node_status < _status)
	    allInState = false;
	  else
	    g_info << "node_status(" << (unsigned)ndbNode->node_status
		   << ") != _status("<< (unsigned)_status << ")" <<endl;
	} else if (ndbNode->start_phase < _startphase)
	  allInState = false;
      } else {
	if (ndbNode->node_status !=  _status)
	  allInState = false;
      }
    }
    g_info << "Waiting for cluster enter state "
	    << ndb_mgm_get_node_status_string(_status)<< endl;
    NdbSleep_SecSleep(1);
    attempts++;
  }
  return 0;
}

template class Vector<ndb_mgm_node_state>;
<commit_msg>waiter.cpp:   fixed so that connectring option works<commit_after>/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <ndb_global.h>
#include <ndb_opts.h>

#include <mgmapi.h>
#include <NdbMain.h>
#include <NdbOut.hpp>
#include <NdbSleep.h>
#include <kernel/ndb_limits.h>
#include "../include/mgmcommon/LocalConfig.hpp"

#include <NDBT.hpp>

int
waitClusterStatus(const char* _addr, ndb_mgm_node_status _status, unsigned int _timeout);

static const char* opt_connect_str= 0;
static int _no_contact = 0;
static int _timeout = 120;
static struct my_option my_long_options[] =
{
  NDB_STD_OPTS("ndb_desc"),
  { "no-contact", 'n', "Wait for cluster no contact",
    (gptr*) &_no_contact, (gptr*) &_no_contact, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
  { "timeout", 't', "Timeout to wait",
    (gptr*) &_timeout, (gptr*) &_timeout, 0,
    GET_INT, REQUIRED_ARG, 120, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
static void print_version()
{
  printf("MySQL distrib %s, for %s (%s)\n",MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE);
}
static void usage()
{
  print_version();
  my_print_help(my_long_options);
  my_print_variables(my_long_options);
}
static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
	       char *argument)
{
  switch (optid) {
  case '#':
    DBUG_PUSH(argument ? argument : "d:t:O,/tmp/ndb_drop_table.trace");
    break;
  case 'V':
    print_version();
    exit(0);
  case '?':
    usage();
    exit(0);
  }
  return 0;
}

int main(int argc, char** argv){
  NDB_INIT(argv[0]);
  const char *load_default_groups[]= { "ndb_tools",0 };
  load_defaults("my",load_default_groups,&argc,&argv);
  const char* _hostName = NULL;
  int ho_error;
  if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)))
    return NDBT_ProgramExit(NDBT_WRONGARGS);

  char buf[255];
  _hostName = argv[0];

  if (_hostName == NULL){
    LocalConfig lcfg;
    if(!lcfg.init(opt_connect_str, 0))
    {
      lcfg.printError();
      lcfg.printUsage();
      g_err  << "Error parsing local config file" << endl;
      return NDBT_ProgramExit(NDBT_FAILED);
    }

    for (unsigned i = 0; i<lcfg.ids.size();i++)
    {
      MgmtSrvrId * m = &lcfg.ids[i];

      switch(m->type){
      case MgmId_TCP:
	snprintf(buf, 255, "%s:%d", m->name.c_str(), m->port);
	_hostName = buf;
	break;
      case MgmId_File:
	break;
      default:
	break;
      }
      if (_hostName != NULL)
	break;
    }
    if (_hostName == NULL)
    {
      g_err << "No management servers configured in local config file" << endl;
      return NDBT_ProgramExit(NDBT_FAILED);
    }
  }

  if (_no_contact) {
    if (waitClusterStatus(_hostName, NDB_MGM_NODE_STATUS_NO_CONTACT, _timeout) != 0)
      return NDBT_ProgramExit(NDBT_FAILED);
  } else if (waitClusterStatus(_hostName, NDB_MGM_NODE_STATUS_STARTED, _timeout) != 0)
    return NDBT_ProgramExit(NDBT_FAILED);

  return NDBT_ProgramExit(NDBT_OK);
}

#define MGMERR(h) \
  ndbout << "latest_error="<<ndb_mgm_get_latest_error(h) \
	 << ", line="<<ndb_mgm_get_latest_error_line(h) \
	 << endl;

NdbMgmHandle handle= NULL;

Vector<ndb_mgm_node_state> ndbNodes;
Vector<ndb_mgm_node_state> mgmNodes;
Vector<ndb_mgm_node_state> apiNodes;

int
getStatus(){
  int retries = 0;
  struct ndb_mgm_cluster_state * status;
  struct ndb_mgm_node_state * node;

  ndbNodes.clear();
  mgmNodes.clear();
  apiNodes.clear();

  while(retries < 10){
    status = ndb_mgm_get_status(handle);
    if (status == NULL){
      ndbout << "status==NULL, retries="<<retries<<endl;
      MGMERR(handle);
      retries++;
      continue;
    }
    int count = status->no_of_nodes;
    for (int i = 0; i < count; i++){
      node = &status->node_states[i];
      switch(node->node_type){
      case NDB_MGM_NODE_TYPE_NDB:
	ndbNodes.push_back(*node);
	break;
      case NDB_MGM_NODE_TYPE_MGM:
	mgmNodes.push_back(*node);
	break;
      case NDB_MGM_NODE_TYPE_API:
	apiNodes.push_back(*node);
	break;
      default:
	if(node->node_status == NDB_MGM_NODE_STATUS_UNKNOWN ||
	   node->node_status == NDB_MGM_NODE_STATUS_NO_CONTACT){
	  retries++;
	  ndbNodes.clear();
	  mgmNodes.clear();
	  apiNodes.clear();
	  free(status);
	  status = NULL;
          count = 0;

	  ndbout << "kalle"<< endl;
	  break;
	}
	abort();
	break;
      }
    }
    if(status == 0){
      ndbout << "status == 0" << endl;
      continue;
    }
    free(status);
    return 0;
  }

  g_err  << "getStatus failed" << endl;
  return -1;
}

int
waitClusterStatus(const char* _addr,
		  ndb_mgm_node_status _status,
		  unsigned int _timeout)
{
  int _startphase = -1;

  int _nodes[MAX_NDB_NODES];
  int _num_nodes = 0;

  handle = ndb_mgm_create_handle();
  if (handle == NULL){
    g_err << "handle == NULL" << endl;
    return -1;
  }
  g_info << "Connecting to mgmsrv at " << _addr << endl;
  if (ndb_mgm_connect(handle, _addr) == -1) {
    MGMERR(handle);
    g_err  << "Connection to " << _addr << " failed" << endl;
    return -1;
  }

  if (getStatus() != 0)
    return -1;

  // Collect all nodes into nodes
  for (size_t i = 0; i < ndbNodes.size(); i++){
    _nodes[i] = ndbNodes[i].node_id;
    _num_nodes++;
  }

  unsigned int attempts = 0;
  unsigned int resetAttempts = 0;
  const unsigned int MAX_RESET_ATTEMPTS = 10;
  bool allInState = false;
  while (allInState == false){
    if (_timeout > 0 && attempts > _timeout){
      /**
       * Timeout has expired waiting for the nodes to enter
       * the state we want
       */
      bool waitMore = false;
      /**
       * Make special check if we are waiting for
       * cluster to become started
       */
      if(_status == NDB_MGM_NODE_STATUS_STARTED){
	waitMore = true;
	/**
	 * First check if any node is not starting
	 * then it's no idea to wait anymore
	 */
	for (size_t n = 0; n < ndbNodes.size(); n++){
	  if (ndbNodes[n].node_status != NDB_MGM_NODE_STATUS_STARTED &&
	      ndbNodes[n].node_status != NDB_MGM_NODE_STATUS_STARTING)
	    waitMore = false;

	}
      }

      if (!waitMore || resetAttempts > MAX_RESET_ATTEMPTS){
	g_err << "waitNodeState("
	      << ndb_mgm_get_node_status_string(_status)
	      <<", "<<_startphase<<")"
	      << " timeout after " << attempts <<" attemps" << endl;
	return -1;
      }

      g_err << "waitNodeState("
	    << ndb_mgm_get_node_status_string(_status)
	    <<", "<<_startphase<<")"
	    << " resetting number of attempts "
	    << resetAttempts << endl;
      attempts = 0;
      resetAttempts++;

    }

    allInState = true;
    if (getStatus() != 0){
      g_err << "getStatus != 0" << endl;
      return -1;
    }

    // ndbout << "waitNodeState; _num_nodes = " << _num_nodes << endl;
    // for (int i = 0; i < _num_nodes; i++)
    //   ndbout << " node["<<i<<"] =" <<_nodes[i] << endl;

    for (int i = 0; i < _num_nodes; i++){
      ndb_mgm_node_state* ndbNode = NULL;
      for (size_t n = 0; n < ndbNodes.size(); n++){
	if (ndbNodes[n].node_id == _nodes[i])
	  ndbNode = &ndbNodes[n];
      }

      if(ndbNode == NULL){
	allInState = false;
	continue;
      }

      g_info << "State node " << ndbNode->node_id << " "
	     << ndb_mgm_get_node_status_string(ndbNode->node_status)<< endl;

      assert(ndbNode != NULL);

      if(_status == NDB_MGM_NODE_STATUS_STARTING &&
	 ((ndbNode->node_status == NDB_MGM_NODE_STATUS_STARTING &&
	   ndbNode->start_phase >= _startphase) ||
	  (ndbNode->node_status == NDB_MGM_NODE_STATUS_STARTED)))
	continue;

      if (_status == NDB_MGM_NODE_STATUS_STARTING){
	g_info << "status = "
	       << ndb_mgm_get_node_status_string(ndbNode->node_status)
	       <<", start_phase="<<ndbNode->start_phase<<endl;
	if (ndbNode->node_status !=  _status) {
	  if (ndbNode->node_status < _status)
	    allInState = false;
	  else
	    g_info << "node_status(" << (unsigned)ndbNode->node_status
		   << ") != _status("<< (unsigned)_status << ")" <<endl;
	} else if (ndbNode->start_phase < _startphase)
	  allInState = false;
      } else {
	if (ndbNode->node_status !=  _status)
	  allInState = false;
      }
    }
    g_info << "Waiting for cluster enter state "
	    << ndb_mgm_get_node_status_string(_status)<< endl;
    NdbSleep_SecSleep(1);
    attempts++;
  }
  return 0;
}

template class Vector<ndb_mgm_node_state>;
<|endoftext|>


<commit_before>/**
 * @author: Jeff Thompson
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_INTEREST_HPP
#define	NDN_INTEREST_HPP

#include "Name.hpp"
#include "PublisherPublicKeyDigest.hpp"
#include "c/Interest.h"

namespace ndn {

/**
 * An ExcludeEntry holds an ndn_ExcludeType, and if it is a COMPONENT, it holds the component value.
 */
class ExcludeEntry {
public:
  /**
   * Create an ExcludeEntry of type ndn_Exclude_ANY
   */
  ExcludeEntry()
  : type_(ndn_Exclude_ANY)
  {
  }

  /**
   * Create an ExcludeEntry of type ndn_Exclude_COMPONENT
   */
  ExcludeEntry(unsigned char *component, unsigned int componentLen)
  : type_(ndn_Exclude_COMPONENT), component_(component, component + componentLen)
  {
  }

  /**
   * Set the type in the excludeEntryStruct and to point to this component, without copying any memory.
   * WARNING: The resulting pointer in excludeEntryStruct is invalid after a further use of this object which could reallocate memory.
   * @param excludeEntryStruct the C ndn_NameComponent struct to receive the pointer
   */
  void get(struct ndn_ExcludeEntry &excludeEntryStruct) const
  {
    excludeEntryStruct.type = type_;
    if (type_ == ndn_Exclude_COMPONENT) {
      excludeEntryStruct.componentLength = component_.size();
      excludeEntryStruct.component = (unsigned char *)&component_[0];
    }
  }

  ndn_ExcludeType getType() const { return type_; }

  const std::vector<unsigned char> &getComponent() const { return component_; }

private:
  ndn_ExcludeType type_;
  std::vector<unsigned char> component_; /**< only used if type_ is ndn_Exclude_COMPONENT */
};

/**
 * An Exclude holds a vector of ExcludeEntry.
 */
class Exclude {
public:
  /**
   * Create a new Exclude with no entries.
   */
  Exclude() {
  }

  unsigned int getEntryCount() const {
    return entries_.size();
  }

  const ExcludeEntry &getEntry(unsigned int i) const { return entries_[i]; }

  /**
   * Set the excludeStruct to point to the entries in this Exclude, without copying any memory.
   * WARNING: The resulting pointers in excludeStruct are invalid after a further use of this object which could reallocate memory.
   * @param excludeStruct a C ndn_Exclude struct where the entries array is already allocated
   */
  void get(struct ndn_Exclude &excludeStruct) const;

  /**
   * Clear this Exclude, and set the entries by copying from the ndn_Exclude struct.
   * @param excludeStruct a C ndn_Exclude struct
   */
  void set(const struct ndn_Exclude &excludeStruct);

  /**
   * Add a new entry of type ndn_Exclude_ANY
   */
  void addAny()
  {
    entries_.push_back(ExcludeEntry());
  }

  /**
   * Add a new entry of type ndn_Exclude_COMPONENT, copying from component of length compnentLength
   */
  void addComponent(unsigned char *component, unsigned int componentLen)
  {
    entries_.push_back(ExcludeEntry(component, componentLen));
  }

  /**
   * Clear all the entries.
   */
  void clear() {
    entries_.clear();
  }

private:
	std::vector<ExcludeEntry> entries_;
};

/**
 * An Interest holds a Name and other fields for an interest.
 */
class Interest {
public:
  void encode(std::vector<unsigned char> &output, WireFormat &wireFormat) const
  {
    wireFormat.encodeInterest(*this, output);
  }
  void encode(std::vector<unsigned char> &output) const
  {
    encode(output, BinaryXMLWireFormat::instance());
  }
  void decode(const unsigned char *input, unsigned int inputLength, WireFormat &wireFormat)
  {
    wireFormat.decodeInterest(*this, input, inputLength);
  }
  void decode(const unsigned char *input, unsigned int inputLength)
  {
    decode(input, inputLength, BinaryXMLWireFormat::instance());
  }
  void decode(const std::vector<unsigned char> &input, WireFormat &wireFormat)
  {
    decode(&input[0], input.size(), wireFormat);
  }
  void decode(const std::vector<unsigned char> &input)
  {
    decode(&input[0], input.size());
  }

  /**
   * Set the interestStruct to point to the components in this interest, without copying any memory.
   * WARNING: The resulting pointers in interestStruct are invalid after a further use of this object which could reallocate memory.
   * @param interestStruct a C ndn_Interest struct where the name components array is already allocated.
   */
  void get(struct ndn_Interest &interestStruct) const;

  Name &getName() { return name_; }
  const Name &getName() const { return name_; }

  int getMinSuffixComponents() const { return minSuffixComponents_; }

  int getMaxSuffixComponents() const { return maxSuffixComponents_; }

  PublisherPublicKeyDigest &getPublisherPublicKeyDigest() { return publisherPublicKeyDigest_; }
  const PublisherPublicKeyDigest &getPublisherPublicKeyDigest() const { return publisherPublicKeyDigest_; }

  Exclude &getExclude() { return exclude_; }
  const Exclude &getExclude() const { return exclude_; }

  int getChildSelector() const { return childSelector_; }

  int getAnswerOriginKind() const { return answerOriginKind_; }

  int getScope() const { return scope_; }

  int getInterestLifetime() const { return interestLifetime_; }

  const std::vector<unsigned char> getNonce() const { return nonce_; }

  /**
   * Clear this interest, and set the values by copying from the interest struct.
   * @param interestStruct a C ndn_Interest struct
   */
  void set(const struct ndn_Interest &interestStruct);

  void setMinSuffixComponents(int value) { minSuffixComponents_ = value; }

  void setMaxSuffixComponents(int value) { maxSuffixComponents_ = value; }

  void setChildSelector(int value) { childSelector_ = value; }

  void setAnswerOriginKind(int value) { answerOriginKind_ = value; }

  void setScope(int value) { scope_ = value; }

  void setInterestLifetime(int value) { interestLifetime_ = value; }

  void setNonce(const std::vector<unsigned char> &value) { nonce_ = value; }

private:

  Name name_;
	int minSuffixComponents_;
	int maxSuffixComponents_;
	PublisherPublicKeyDigest publisherPublicKeyDigest_;
  Exclude exclude_;
	int childSelector_;
	int answerOriginKind_;
	int scope_;
	int interestLifetime_;
	std::vector<unsigned char> nonce_;
};

}

#endif
<commit_msg>In the Interest constructor, set int values to -1<commit_after>/**
 * @author: Jeff Thompson
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_INTEREST_HPP
#define	NDN_INTEREST_HPP

#include "Name.hpp"
#include "PublisherPublicKeyDigest.hpp"
#include "c/Interest.h"

namespace ndn {

/**
 * An ExcludeEntry holds an ndn_ExcludeType, and if it is a COMPONENT, it holds the component value.
 */
class ExcludeEntry {
public:
  /**
   * Create an ExcludeEntry of type ndn_Exclude_ANY
   */
  ExcludeEntry()
  : type_(ndn_Exclude_ANY)
  {
  }

  /**
   * Create an ExcludeEntry of type ndn_Exclude_COMPONENT
   */
  ExcludeEntry(unsigned char *component, unsigned int componentLen)
  : type_(ndn_Exclude_COMPONENT), component_(component, component + componentLen)
  {
  }

  /**
   * Set the type in the excludeEntryStruct and to point to this component, without copying any memory.
   * WARNING: The resulting pointer in excludeEntryStruct is invalid after a further use of this object which could reallocate memory.
   * @param excludeEntryStruct the C ndn_NameComponent struct to receive the pointer
   */
  void get(struct ndn_ExcludeEntry &excludeEntryStruct) const
  {
    excludeEntryStruct.type = type_;
    if (type_ == ndn_Exclude_COMPONENT) {
      excludeEntryStruct.componentLength = component_.size();
      excludeEntryStruct.component = (unsigned char *)&component_[0];
    }
  }

  ndn_ExcludeType getType() const { return type_; }

  const std::vector<unsigned char> &getComponent() const { return component_; }

private:
  ndn_ExcludeType type_;
  std::vector<unsigned char> component_; /**< only used if type_ is ndn_Exclude_COMPONENT */
};

/**
 * An Exclude holds a vector of ExcludeEntry.
 */
class Exclude {
public:
  /**
   * Create a new Exclude with no entries.
   */
  Exclude() {
  }

  unsigned int getEntryCount() const {
    return entries_.size();
  }

  const ExcludeEntry &getEntry(unsigned int i) const { return entries_[i]; }

  /**
   * Set the excludeStruct to point to the entries in this Exclude, without copying any memory.
   * WARNING: The resulting pointers in excludeStruct are invalid after a further use of this object which could reallocate memory.
   * @param excludeStruct a C ndn_Exclude struct where the entries array is already allocated
   */
  void get(struct ndn_Exclude &excludeStruct) const;

  /**
   * Clear this Exclude, and set the entries by copying from the ndn_Exclude struct.
   * @param excludeStruct a C ndn_Exclude struct
   */
  void set(const struct ndn_Exclude &excludeStruct);

  /**
   * Add a new entry of type ndn_Exclude_ANY
   */
  void addAny()
  {
    entries_.push_back(ExcludeEntry());
  }

  /**
   * Add a new entry of type ndn_Exclude_COMPONENT, copying from component of length compnentLength
   */
  void addComponent(unsigned char *component, unsigned int componentLen)
  {
    entries_.push_back(ExcludeEntry(component, componentLen));
  }

  /**
   * Clear all the entries.
   */
  void clear() {
    entries_.clear();
  }

private:
	std::vector<ExcludeEntry> entries_;
};

/**
 * An Interest holds a Name and other fields for an interest.
 */
class Interest {
public:
  Interest()
  {
  	minSuffixComponents_ = -1;
	  maxSuffixComponents_ = -1;
	  childSelector_ = -1;
	  answerOriginKind_ = -1;
	  scope_ = -1;
	  interestLifetime_ = -1;
  }

  void encode(std::vector<unsigned char> &output, WireFormat &wireFormat) const
  {
    wireFormat.encodeInterest(*this, output);
  }
  void encode(std::vector<unsigned char> &output) const
  {
    encode(output, BinaryXMLWireFormat::instance());
  }
  void decode(const unsigned char *input, unsigned int inputLength, WireFormat &wireFormat)
  {
    wireFormat.decodeInterest(*this, input, inputLength);
  }
  void decode(const unsigned char *input, unsigned int inputLength)
  {
    decode(input, inputLength, BinaryXMLWireFormat::instance());
  }
  void decode(const std::vector<unsigned char> &input, WireFormat &wireFormat)
  {
    decode(&input[0], input.size(), wireFormat);
  }
  void decode(const std::vector<unsigned char> &input)
  {
    decode(&input[0], input.size());
  }

  /**
   * Set the interestStruct to point to the components in this interest, without copying any memory.
   * WARNING: The resulting pointers in interestStruct are invalid after a further use of this object which could reallocate memory.
   * @param interestStruct a C ndn_Interest struct where the name components array is already allocated.
   */
  void get(struct ndn_Interest &interestStruct) const;

  Name &getName() { return name_; }
  const Name &getName() const { return name_; }

  int getMinSuffixComponents() const { return minSuffixComponents_; }

  int getMaxSuffixComponents() const { return maxSuffixComponents_; }

  PublisherPublicKeyDigest &getPublisherPublicKeyDigest() { return publisherPublicKeyDigest_; }
  const PublisherPublicKeyDigest &getPublisherPublicKeyDigest() const { return publisherPublicKeyDigest_; }

  Exclude &getExclude() { return exclude_; }
  const Exclude &getExclude() const { return exclude_; }

  int getChildSelector() const { return childSelector_; }

  int getAnswerOriginKind() const { return answerOriginKind_; }

  int getScope() const { return scope_; }

  int getInterestLifetime() const { return interestLifetime_; }

  const std::vector<unsigned char> getNonce() const { return nonce_; }

  /**
   * Clear this interest, and set the values by copying from the interest struct.
   * @param interestStruct a C ndn_Interest struct
   */
  void set(const struct ndn_Interest &interestStruct);

  void setMinSuffixComponents(int value) { minSuffixComponents_ = value; }

  void setMaxSuffixComponents(int value) { maxSuffixComponents_ = value; }

  void setChildSelector(int value) { childSelector_ = value; }

  void setAnswerOriginKind(int value) { answerOriginKind_ = value; }

  void setScope(int value) { scope_ = value; }

  void setInterestLifetime(int value) { interestLifetime_ = value; }

  void setNonce(const std::vector<unsigned char> &value) { nonce_ = value; }

private:

  Name name_;
	int minSuffixComponents_;
	int maxSuffixComponents_;
	PublisherPublicKeyDigest publisherPublicKeyDigest_;
  Exclude exclude_;
	int childSelector_;
	int answerOriginKind_;
	int scope_;
	int interestLifetime_;
	std::vector<unsigned char> nonce_;
};

}

#endif
<|endoftext|>


<commit_before>/*************************************************************************
 *                                                                       *
 *  I|*j^3Cl|a   "+!*%                  qt          Nd   gW              *
 *  l]{y+l?MM*  !#Wla\NNP               NW          MM   I|              *
 *        PW    ?E|    tWg              Wg  sC!     AW           ~@v~    *
 *       NC     ?M!    yN|  WW     MK   MW@K1Y%M@   RM   #Q    QP@tim    *
 *     CM|      |WQCljAE|   MD     Mg   RN     cM~  NM   WQ   MQ         *
 *    #M        aQ?         MW     M3   Mg      Q(  HQ   YR  IM|         *
 *   Dq         {Ql         MH    iMX   Mg     MM   QP   QM   Eg         *
 * !EWNaPRag2$  +M"          $WNaHaN%   MQE$%EXW    QQ   CM    %M%a$D    *
 *                                                                       *
 *               Website: https://github.com/zpublic/zpublic             *
 *                                                                       *
 ************************************************************************/
#pragma once
#include "win_utils_header.h"
#include "usid.hpp"
#include "register.hpp"

namespace zl
{
namespace WinUtils
{
    /**
     * @brief ʵ˳صĲӿ
     * @note ӿб:
     *      AddRegRun           עrun
     *      AddRegRunOnce       עrunonce
     *
     *      DelRegRun           עrun
     *      DelRegRunOnce       עrunonce
     */
    class ZLAutorun
    {
    public:
        enum UserType { ALL_USER, SINGLE_USER };

        /**
         * @brief һעrun
         * @param[in] t         ָAllUserǵû,˴SINGLE_USER,ͨlpUserSidָû
         * @param[in] lpValName ֵ
         * @param[in] lpVal     ֵ
         * @param[in] dwValType ֵ
         * @param[in] lpUserSid ûSID, NULLʱ, ΪǰûSID.ֵڲtΪSINGLE_USERʱЧ
         * @param[in] bWow64    64λض
         * @return ɹTRUE, ʧܷFALSE
         */
        static BOOL AddRegRun(
            UserType    t,
            LPCTSTR     lpValName,
            LPCTSTR     lpVal,
            DWORD       dwValType = REG_EXPAND_SZ,
            LPCTSTR     lpUserSid = NULL,
            BOOL        bWow64    = TRUE)
        {
            if (!lpValName || !lpVal)
                return FALSE;

            BOOL bReturn = FALSE;
            LPCTSTR lpKeyBase = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
            switch (t)
            {
            case ALL_USER:
                bReturn = _SetRegStringAllUser(lpKeyBase, lpValName, lpVal, dwValType, bWow64);
                break;
            case SINGLE_USER:
                bReturn = _SetRegStringSingleUser(lpUserSid, lpKeyBase, lpValName, lpVal, dwValType, bWow64);
                break;
            }
            return bReturn;
        }

        static BOOL AddRegRunOnce(
            UserType    t,
            LPCTSTR     lpValName,
            LPCTSTR     lpVal,
            DWORD       dwValType = REG_EXPAND_SZ,
            LPCTSTR     lpUserSid = NULL,
            BOOL        bWow64    = TRUE)
        {
            if (!lpValName || !lpVal)
                return FALSE;

            BOOL bReturn = FALSE;
            LPCTSTR lpKeyBase = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Runonce");
            switch (t)
            {
            case ALL_USER:
                bReturn = _SetRegStringAllUser(lpKeyBase, lpValName, lpVal, dwValType, bWow64);
                break;
            case SINGLE_USER:
                bReturn = _SetRegStringSingleUser(lpUserSid, lpKeyBase, lpValName, lpVal, dwValType, bWow64);
                break;
            }
            return bReturn;
        }

        static BOOL DelRegRun(
            UserType    t,
            LPCTSTR     lpValName,
            LPCTSTR     lpUserSid = NULL,
            BOOL        bWow64    = TRUE)
        {
            BOOL    bReturn   = FALSE;
            LPCTSTR lpKeyBase = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
            switch (t)
            {
            case ALL_USER:
                bReturn = _DelRegStringAllUser(lpKeyBase, lpValName, bWow64);
                break;
            case SINGLE_USER:
                bReturn = _DelRegStringSingleUser(lpUserSid, lpKeyBase, lpValName, bWow64);
                break;
            default:
                break;
            }
            return bReturn;
        }

        static BOOL DelRegRunOnce(
            UserType    t,
            LPCTSTR     lpValName,
            LPCTSTR     lpUserSid = NULL,
            BOOL        bWow64    = TRUE)
        {
            BOOL    bReturn   = FALSE;
            LPCTSTR lpKeyBase = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Runonce");
            switch (t)
            {
            case ALL_USER:
                bReturn = _DelRegStringAllUser(lpKeyBase, lpValName, bWow64);
                break;
            case SINGLE_USER:
                bReturn = _DelRegStringSingleUser(lpUserSid, lpKeyBase, lpValName, bWow64);
                break;
            default:
                break;
            }
            return bReturn;
        }

    private:
        static BOOL _SetRegStringAllUser(
            LPCTSTR lpSubKey,
            LPCTSTR lpValName,
            LPCTSTR lpVal,
            DWORD   dwValType,
            BOOL    bWow64)
        {
            BOOL bReturn = FALSE;

            ZLRegister reg;
            if (reg.Open(HKEY_LOCAL_MACHINE, lpSubKey, TRUE, bWow64 ? KEY_WRITE : KEY_WOW64_64KEY | KEY_WRITE))
            {
                if (REG_SZ == dwValType)
                {
                    bReturn = reg.Write(lpValName, lpVal);
                }
                else if (REG_EXPAND_SZ == dwValType)
                {
                    bReturn = reg.WriteExpandString(lpValName, lpVal);
                }
                reg.Close();
            }
            return bReturn;
        }

        static BOOL _SetRegStringSingleUser(
            LPCTSTR lpUserSid,
            LPCTSTR lpSubKey,
            LPCTSTR lpValName,
            LPCTSTR lpVal,
            DWORD   dwValType,
            BOOL    bWow64)
        {
            BOOL    bReturn = FALSE;
            CString sUserSid;
            if (lpUserSid)
            {
                sUserSid = lpUserSid;
            }
            else if (ZLUsid::GetCurrentUserSID(sUserSid))
            {
            }
            else
            {
                goto Exit0;
            }

            {
                CString sSubKey;
                sSubKey.Format(_T("%s\\%s"), sUserSid, lpSubKey);
                ZLRegister reg;
                if (reg.Open(HKEY_USERS, sSubKey, TRUE, bWow64 ? KEY_WRITE : KEY_WOW64_64KEY | KEY_WRITE))
                {
                    if (REG_SZ == dwValType)
                    {
                        bReturn = reg.Write(lpValName, lpVal);
                    }
                    else if (REG_EXPAND_SZ == dwValType)
                    {
                        bReturn = reg.WriteExpandString(lpValName, lpVal);
                    }
                    reg.Close();
                }
            }
Exit0:
            return bReturn;
        }

        static BOOL _DelRegStringAllUser(LPCTSTR lpSubKey ,LPCTSTR lpValName, BOOL bWow64)
        {
            BOOL bReturn = FALSE;
            ZLRegister reg;
            if (reg.Open(HKEY_LOCAL_MACHINE, lpSubKey, FALSE, bWow64 ? KEY_WRITE : KEY_WOW64_64KEY | KEY_WRITE))
            {
                bReturn = reg.DeleteValue(lpValName);
                reg.Close();
            }
            return bReturn;
        }

        static BOOL _DelRegStringSingleUser(LPCTSTR lpUserSid, LPCTSTR lpSubKey, LPCTSTR lpValName, BOOL bWow64)
        {
            BOOL bReturn = FALSE;
            CString sUserSid;
            if (lpUserSid)
            {
                sUserSid = lpUserSid;
            }
            else if (ZLUsid::GetCurrentUserSID(sUserSid))
            {
            }
            else
            {
                goto Exit0;
            }

            {
                ZLRegister reg;
                CString sSubKey;
                sSubKey.Format(_T("%s\\%s"), sUserSid, lpSubKey);
                if (reg.Open(HKEY_USERS, sSubKey, FALSE, bWow64 ? KEY_WRITE : KEY_WOW64_64KEY | KEY_WRITE))
                {
                    bReturn = reg.DeleteValue(lpValName);
                    reg.Close();
                }
            }

Exit0:
            return bReturn;
        }
    };

}
}
<commit_msg>* 完善启动项相关功能的注释<commit_after>/*************************************************************************
 *                                                                       *
 *  I|*j^3Cl|a   "+!*%                  qt          Nd   gW              *
 *  l]{y+l?MM*  !#Wla\NNP               NW          MM   I|              *
 *        PW    ?E|    tWg              Wg  sC!     AW           ~@v~    *
 *       NC     ?M!    yN|  WW     MK   MW@K1Y%M@   RM   #Q    QP@tim    *
 *     CM|      |WQCljAE|   MD     Mg   RN     cM~  NM   WQ   MQ         *
 *    #M        aQ?         MW     M3   Mg      Q(  HQ   YR  IM|         *
 *   Dq         {Ql         MH    iMX   Mg     MM   QP   QM   Eg         *
 * !EWNaPRag2$  +M"          $WNaHaN%   MQE$%EXW    QQ   CM    %M%a$D    *
 *                                                                       *
 *               Website: https://github.com/zpublic/zpublic             *
 *                                                                       *
 ************************************************************************/

/**
 * @file
 * @brief ϵͳ
 * @date 2014-07-09
 */

#pragma once
#include "win_utils_header.h"
#include "usid.hpp"
#include "register.hpp"

namespace zl
{
namespace WinUtils
{
    /**
     * @brief ṩwindows,ɾ,Ĳ
     */
    class ZLAutorun
    {
    public:
        enum UserType { ALL_USER, SINGLE_USER };

        /**
         * @brief עrunһ
         * @param[in] t         ָAllUserǵû,˴SINGLE_USER,ͨlpUserSidָû
         * @param[in] lpValName ֵ
         * @param[in] lpVal     ֵ
         * @param[in] dwValType ֵ
         * @param[in] lpUserSid ûSID, NULLʱ, ΪǰûSID.ֵڲtΪSINGLE_USERʱЧ
         * @param[in] bWow64    64λض
         * @return ɹTRUE, ʧܷFALSE
         */
        static BOOL AddRegRun(
            UserType    t,
            LPCTSTR     lpValName,
            LPCTSTR     lpVal,
            DWORD       dwValType = REG_EXPAND_SZ,
            LPCTSTR     lpUserSid = NULL,
            BOOL        bWow64    = TRUE)
        {
            if (!lpValName || !lpVal)
                return FALSE;

            BOOL bReturn = FALSE;
            LPCTSTR lpKeyBase = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
            switch (t)
            {
            case ALL_USER:
                bReturn = _SetRegStringAllUser(lpKeyBase, lpValName, lpVal, dwValType, bWow64);
                break;
            case SINGLE_USER:
                bReturn = _SetRegStringSingleUser(lpUserSid, lpKeyBase, lpValName, lpVal, dwValType, bWow64);
                break;
            }
            return bReturn;
        }

        /**
         * @brief עrunonceһ
         * @see AddRegRun
         */
        static BOOL AddRegRunOnce(
            UserType    t,
            LPCTSTR     lpValName,
            LPCTSTR     lpVal,
            DWORD       dwValType = REG_EXPAND_SZ,
            LPCTSTR     lpUserSid = NULL,
            BOOL        bWow64    = TRUE)
        {
            if (!lpValName || !lpVal)
                return FALSE;

            BOOL bReturn = FALSE;
            LPCTSTR lpKeyBase = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Runonce");
            switch (t)
            {
            case ALL_USER:
                bReturn = _SetRegStringAllUser(lpKeyBase, lpValName, lpVal, dwValType, bWow64);
                break;
            case SINGLE_USER:
                bReturn = _SetRegStringSingleUser(lpUserSid, lpKeyBase, lpValName, lpVal, dwValType, bWow64);
                break;
            }
            return bReturn;
        }

        /**
         * @brief ɾעrunָ
         * @param[in] t         ָAllUserǵû,˴SINGLE_USER,ͨlpUserSidָû
         * @param[in] lpValName ֵ
         * @param[in] lpUserSid ûSID, NULLʱ, ΪǰûSID.ֵڲtΪSINGLE_USERʱЧ
         * @param[in] bWow64    64λض
         * @return ɹTRUE, ʧܷFALSE
         */
        static BOOL DelRegRun(
            UserType    t,
            LPCTSTR     lpValName,
            LPCTSTR     lpUserSid = NULL,
            BOOL        bWow64    = TRUE)
        {
            BOOL    bReturn   = FALSE;
            LPCTSTR lpKeyBase = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
            switch (t)
            {
            case ALL_USER:
                bReturn = _DelRegStringAllUser(lpKeyBase, lpValName, bWow64);
                break;
            case SINGLE_USER:
                bReturn = _DelRegStringSingleUser(lpUserSid, lpKeyBase, lpValName, bWow64);
                break;
            default:
                break;
            }
            return bReturn;
        }

        /**
         * @brief ɾעrunonceָ
         * @see DelRegRun
         */
        static BOOL DelRegRunOnce(
            UserType    t,
            LPCTSTR     lpValName,
            LPCTSTR     lpUserSid = NULL,
            BOOL        bWow64    = TRUE)
        {
            BOOL    bReturn   = FALSE;
            LPCTSTR lpKeyBase = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Runonce");
            switch (t)
            {
            case ALL_USER:
                bReturn = _DelRegStringAllUser(lpKeyBase, lpValName, bWow64);
                break;
            case SINGLE_USER:
                bReturn = _DelRegStringSingleUser(lpUserSid, lpKeyBase, lpValName, bWow64);
                break;
            default:
                break;
            }
            return bReturn;
        }

    private:
        static BOOL _SetRegStringAllUser(
            LPCTSTR lpSubKey,
            LPCTSTR lpValName,
            LPCTSTR lpVal,
            DWORD   dwValType,
            BOOL    bWow64)
        {
            BOOL bReturn = FALSE;

            ZLRegister reg;
            if (reg.Open(HKEY_LOCAL_MACHINE, lpSubKey, TRUE, bWow64 ? KEY_WRITE : KEY_WOW64_64KEY | KEY_WRITE))
            {
                if (REG_SZ == dwValType)
                {
                    bReturn = reg.Write(lpValName, lpVal);
                }
                else if (REG_EXPAND_SZ == dwValType)
                {
                    bReturn = reg.WriteExpandString(lpValName, lpVal);
                }
                reg.Close();
            }
            return bReturn;
        }

        static BOOL _SetRegStringSingleUser(
            LPCTSTR lpUserSid,
            LPCTSTR lpSubKey,
            LPCTSTR lpValName,
            LPCTSTR lpVal,
            DWORD   dwValType,
            BOOL    bWow64)
        {
            BOOL    bReturn = FALSE;
            CString sUserSid;
            if (lpUserSid)
            {
                sUserSid = lpUserSid;
            }
            else if (ZLUsid::GetCurrentUserSID(sUserSid))
            {
            }
            else
            {
                goto Exit0;
            }

            {
                CString sSubKey;
                sSubKey.Format(_T("%s\\%s"), sUserSid, lpSubKey);
                ZLRegister reg;
                if (reg.Open(HKEY_USERS, sSubKey, TRUE, bWow64 ? KEY_WRITE : KEY_WOW64_64KEY | KEY_WRITE))
                {
                    if (REG_SZ == dwValType)
                    {
                        bReturn = reg.Write(lpValName, lpVal);
                    }
                    else if (REG_EXPAND_SZ == dwValType)
                    {
                        bReturn = reg.WriteExpandString(lpValName, lpVal);
                    }
                    reg.Close();
                }
            }
Exit0:
            return bReturn;
        }

        static BOOL _DelRegStringAllUser(LPCTSTR lpSubKey ,LPCTSTR lpValName, BOOL bWow64)
        {
            BOOL bReturn = FALSE;
            ZLRegister reg;
            if (reg.Open(HKEY_LOCAL_MACHINE, lpSubKey, FALSE, bWow64 ? KEY_WRITE : KEY_WOW64_64KEY | KEY_WRITE))
            {
                bReturn = reg.DeleteValue(lpValName);
                reg.Close();
            }
            return bReturn;
        }

        static BOOL _DelRegStringSingleUser(LPCTSTR lpUserSid, LPCTSTR lpSubKey, LPCTSTR lpValName, BOOL bWow64)
        {
            BOOL bReturn = FALSE;
            CString sUserSid;
            if (lpUserSid)
            {
                sUserSid = lpUserSid;
            }
            else if (ZLUsid::GetCurrentUserSID(sUserSid))
            {
            }
            else
            {
                goto Exit0;
            }

            {
                ZLRegister reg;
                CString sSubKey;
                sSubKey.Format(_T("%s\\%s"), sUserSid, lpSubKey);
                if (reg.Open(HKEY_USERS, sSubKey, FALSE, bWow64 ? KEY_WRITE : KEY_WOW64_64KEY | KEY_WRITE))
                {
                    bReturn = reg.DeleteValue(lpValName);
                    reg.Close();
                }
            }

Exit0:
            return bReturn;
        }
    };

}
}
<|endoftext|>


<commit_before>/******************************************************************************
Copyright (c) 2020 Georgia Institute of Technology
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.

Author : Saeed Rashidi (saeed.rashidi@gatech.edu)
*******************************************************************************/
#ifndef __LAYER_HH__
#define __LAYER_HH__

#include <map>
#include <math.h>
#include <fstream>
#include <chrono>
#include <ctime>
#include <tuple>
#include <cstdint>
#include <iostream>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
//#include "astra-sim/system/Sys.hh"
//#include "astra-sim/workload/Workload.hh"

namespace AstraSim{
class DataSet;
class Workload;
class Layer:public Callable,public StreamStat{
public:
    std::string id;
    int layer_num;
    Sys *generator;
    Workload *workload;

    int fwd_pass_compute_time;
    ComType fwd_pass_comm_type;
    int fwd_pass_comm_size;
    Tick fwd_update_time;

    int input_grad_compute_time;
    ComType input_grad_comm_type;
    int input_grad_comm_size;
    Tick input_grad_update_time;

    int weight_grad_compute_time;
    ComType weight_grad_comm_type;
    int weight_grad_comm_size;
    Tick weight_grad_update_time;

    bool needs_fwd_in_bckwd_initiation;
    bool is_checkpoint;
    ParallelismPolicy specific_parallellism;

    int lookup_table_size;
    int collective_counter;

    //DataSet *fwd_pass_dataset;
    //DataSet *input_grad_dataset;
    //DataSet *weight_grad_dataset;

    std::map<int,DataSet*> fwd_pass_datasets;
    std::list<Tick> started_waiting_for_fwd_pass;
    std::map<int,DataSet*> input_grad_datasets;
    std::list<Tick> started_waiting_for_input_grad;
    std::map<int,DataSet*> weight_grad_datasets;
    std::list<Tick> started_waiting_for_weight_grad;

    //reports
    Tick total_forward_pass_compute;
    Tick total_input_grad_compute;
    Tick total_weight_grad_compute;
    Tick total_weight_grad_comm;
    Tick total_input_grad_comm;
    Tick total_fwd_comm;

    Tick last_fwd_finished;
    Tick last_wg_finished;
    Tick last_ig_finished;

    Tick total_waiting_for_wg_comm;
    Tick total_waiting_for_ig_comm;
    Tick total_waiting_for_fwd_comm;

    CollectiveBarrier fwd_barrier;
    CollectiveBarrier wg_barrier;
    CollectiveBarrier ig_barrier;

    Layer(std::string id,int layer_num,Sys *generator,Workload *workload,int fwd_pass_compute_time,ComType fwd_pass_comm_type,
          int fwd_pass_comm_size,int input_grad_compute_time,ComType input_grad_comm_type,int input_grad_comm_size,
          int weight_grad_compute_time,ComType weight_grad_comm_type,int weight_grad_comm_size,int weight_grad_update_time);
    void call(EventType event,CallData *mdata);
    Tick get_fwd_pass_compute();
    Tick get_input_grad_compute();
    Tick get_weight_grad_compute();
    void increment_waiting_for_wg();
    void increment_waiting_for_ig();
    void increment_waiting_for_fwd();
    bool is_fwd_pass_comm_finished();
    bool is_input_grad_comm_finished();
    bool is_weight_grad_comm_finished();
    bool is_fwd_pass_comm_finished_blocking();
    bool is_input_grad_comm_finished_blocking();
    bool is_weight_grad_comm_finished_blocking();
    LayerData report(std::string run_name,int layer_num,int total_rows,int stat_row,CSVWriter *detailed,CSVWriter *EndToEnd,double &total_compute,double &total_exposed, bool seprate_log);
    void issue_forward_pass_comm(bool local,bool vertical,bool horizontal,SchedulingPolicy pref_scheduling,
                                 CollectiveBarrier barrier);
    void issue_input_grad_comm(bool local,bool vertical,bool horizontal,SchedulingPolicy pref_scheduling,
                               CollectiveBarrier barrier);
    void issue_weight_grad_comm(bool local,bool vertical,bool horizontal,SchedulingPolicy pref_scheduling,
                                CollectiveBarrier barrier);
};
}
#endif
<commit_msg>workload modules seprated<commit_after>/******************************************************************************
Copyright (c) 2020 Georgia Institute of Technology
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.

Author : Saeed Rashidi (saeed.rashidi@gatech.edu)
*******************************************************************************/
#ifndef __LAYER_HH__
#define __LAYER_HH__

#include <map>
#include <math.h>
#include <fstream>
#include <chrono>
#include <ctime>
#include <tuple>
#include <cstdint>
#include <iostream>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "astra-sim/system/Sys.hh"
//#include "astra-sim/workload/Workload.hh"

namespace AstraSim{
class Workload;
class Layer:public Callable,public StreamStat{
public:
    std::string id;
    int layer_num;
    Sys *generator;
    Workload *workload;

    int fwd_pass_compute_time;
    ComType fwd_pass_comm_type;
    int fwd_pass_comm_size;
    Tick fwd_update_time;

    int input_grad_compute_time;
    ComType input_grad_comm_type;
    int input_grad_comm_size;
    Tick input_grad_update_time;

    int weight_grad_compute_time;
    ComType weight_grad_comm_type;
    int weight_grad_comm_size;
    Tick weight_grad_update_time;

    bool needs_fwd_in_bckwd_initiation;
    bool is_checkpoint;
    ParallelismPolicy specific_parallellism;

    int lookup_table_size;
    int collective_counter;

    //DataSet *fwd_pass_dataset;
    //DataSet *input_grad_dataset;
    //DataSet *weight_grad_dataset;

    std::map<int,DataSet*> fwd_pass_datasets;
    std::list<Tick> started_waiting_for_fwd_pass;
    std::map<int,DataSet*> input_grad_datasets;
    std::list<Tick> started_waiting_for_input_grad;
    std::map<int,DataSet*> weight_grad_datasets;
    std::list<Tick> started_waiting_for_weight_grad;

    //reports
    Tick total_forward_pass_compute;
    Tick total_input_grad_compute;
    Tick total_weight_grad_compute;
    Tick total_weight_grad_comm;
    Tick total_input_grad_comm;
    Tick total_fwd_comm;

    Tick last_fwd_finished;
    Tick last_wg_finished;
    Tick last_ig_finished;

    Tick total_waiting_for_wg_comm;
    Tick total_waiting_for_ig_comm;
    Tick total_waiting_for_fwd_comm;

    CollectiveBarrier fwd_barrier;
    CollectiveBarrier wg_barrier;
    CollectiveBarrier ig_barrier;

    Layer(std::string id,int layer_num,Sys *generator,Workload *workload,int fwd_pass_compute_time,ComType fwd_pass_comm_type,
          int fwd_pass_comm_size,int input_grad_compute_time,ComType input_grad_comm_type,int input_grad_comm_size,
          int weight_grad_compute_time,ComType weight_grad_comm_type,int weight_grad_comm_size,int weight_grad_update_time);
    void call(EventType event,CallData *mdata);
    Tick get_fwd_pass_compute();
    Tick get_input_grad_compute();
    Tick get_weight_grad_compute();
    void increment_waiting_for_wg();
    void increment_waiting_for_ig();
    void increment_waiting_for_fwd();
    bool is_fwd_pass_comm_finished();
    bool is_input_grad_comm_finished();
    bool is_weight_grad_comm_finished();
    bool is_fwd_pass_comm_finished_blocking();
    bool is_input_grad_comm_finished_blocking();
    bool is_weight_grad_comm_finished_blocking();
    LayerData report(std::string run_name,int layer_num,int total_rows,int stat_row,CSVWriter *detailed,CSVWriter *EndToEnd,double &total_compute,double &total_exposed, bool seprate_log);
    void issue_forward_pass_comm(bool local,bool vertical,bool horizontal,SchedulingPolicy pref_scheduling,
                                 CollectiveBarrier barrier);
    void issue_input_grad_comm(bool local,bool vertical,bool horizontal,SchedulingPolicy pref_scheduling,
                               CollectiveBarrier barrier);
    void issue_weight_grad_comm(bool local,bool vertical,bool horizontal,SchedulingPolicy pref_scheduling,
                                CollectiveBarrier barrier);
};
}
#endif
<|endoftext|>


<commit_before>//!
//! @file   HydraulicFlowSourceQ.hpp
//! @author FluMeS
//! @date   2009-12-21
//!
//! @brief Contains a Hydraulic Flow Source Component of Q-type
//!
//$Id$

#ifndef HYDRAULICFLOWSOURCEQ_HPP_INCLUDED
#define HYDRAULICFLOWSOURCEQ_HPP_INCLUDED

#include <iostream>
#include "../../ComponentEssentials.h"

//!
//! @brief
//! @ingroup HydraulicComponents
//!
class HydraulicFlowSourceQ : public ComponentQ
{
private:
    double mFlow;
    enum {P1,in};

public:
    static Component *Creator()
    {
        std::cout << "running flowsourceQ creator" << std::endl;
        return new HydraulicFlowSourceQ("FlowSourceQ");
    }

    HydraulicFlowSourceQ(const string name,
                         const double flow     = 1.0e-3,
                         const double timestep = 0.001)
	: ComponentQ(name, timestep)
    {
        mTypeName = "HydraulicFlowSourceQ";
        mFlow = flow;

        addPowerPort("P1", "NodeHydraulic");
        addReadPort("in", "NodeSignal");

        registerParameter("Flow", "Flöde", "m^3/s", mFlow);
    }

	void initialize()
	{
        //Nothing to initilize
	}

    void simulateOneTimestep()
    {
        //Get variable values from nodes
		double c  = mPortPtrs[P1]->readNode(NodeHydraulic::WAVEVARIABLE);
        double Zc = mPortPtrs[P1]->readNode(NodeHydraulic::CHARIMP);

        //Flow source equations
        double q;
        if (mPortPtrs[in]->isConnected())
        {
            q = mPortPtrs[in]->readNode(NodeSignal::VALUE);         //Control signal exist!
        }
        else
        {
            q = mFlow;              //No control signal, use parameter...
        }
        double p = c + mFlow*Zc;

        //Write new values to nodes
        mPortPtrs[P1]->writeNode(NodeHydraulic::MASSFLOW, q);
        mPortPtrs[P1]->writeNode(NodeHydraulic::PRESSURE, p);
    }
};

#endif // HYDRAULICFLOWSOURCEQ_HPP_INCLUDED
<commit_msg>Hydraulic/HydraulicFlowSourceQ.hpp<commit_after>//!
//! @file   HydraulicFlowSourceQ.hpp
//! @author FluMeS
//! @date   2009-12-21
//!
//! @brief Contains a Hydraulic Flow Source Component of Q-type
//!
//$Id$

#ifndef HYDRAULICFLOWSOURCEQ_HPP_INCLUDED
#define HYDRAULICFLOWSOURCEQ_HPP_INCLUDED

#include <iostream>
#include "../../ComponentEssentials.h"

//!
//! @brief
//! @ingroup HydraulicComponents
//!
class HydraulicFlowSourceQ : public ComponentQ
{
private:
    double mFlow;
    Port *mpP1, *mpP2;

public:
    static Component *Creator()
    {
        return new HydraulicFlowSourceQ("FlowSourceQ");
    }

    HydraulicFlowSourceQ(const string name,
                         const double flow     = 1.0e-3,
                         const double timestep = 0.001)
	: ComponentQ(name, timestep)
    {
        mTypeName = "HydraulicFlowSourceQ";
        mFlow = flow;

        mpIn = addReadPort("in", "NodeSignal");
        mpP1 = addPowerPort("P1", "NodeHydraulic");

        registerParameter("Flow", "Flöde", "m^3/s", mFlow);
    }

	void initialize()
	{
        //Nothing to initilize
	}

    void simulateOneTimestep()
    {
        //Get variable values from nodes
        double c  = mpP1->readNode(NodeHydraulic::WAVEVARIABLE);
        double Zc = mpP1->readNode(NodeHydraulic::CHARIMP);

        //Flow source equations
        double q;
        if (mpIn->isConnected())
        {
            q = mpIn->readNode(NodeSignal::VALUE);         //Control signal exist!
        }
        else
        {
            q = mFlow;              //No control signal, use parameter...
        }
        double p = c + mFlow*Zc;

        //Write new values to nodes
        mpP1->writeNode(NodeHydraulic::MASSFLOW, q);
        mpP1->writeNode(NodeHydraulic::PRESSURE, p);
    }
};

#endif // HYDRAULICFLOWSOURCEQ_HPP_INCLUDED
<|endoftext|>


<commit_before>// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-

/* Copyright (C) 2008 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <giomm/contenttype.h>
#include <gio/gio.h>

namespace Gio
{

bool content_type_equals(const Glib::ustring& type1, const Glib::ustring& type2)
{
  return g_content_type_equals(type1.c_str(), type2.c_str());
}

bool content_type_is_a(const Glib::ustring& type, const Glib::ustring& supertype)
{
  return g_content_type_is_a(type.c_str(), supertype.c_str());
}

bool content_type_is_unknown(const Glib::ustring& type)
{
  return g_content_type_is_unknown(type.c_str());
}

Glib::ustring content_type_get_description(const Glib::ustring& type)
{
  return Glib::convert_return_gchar_ptr_to_ustring(g_content_type_get_description(type.c_str()));
}

Glib::ustring content_type_get_mime_type(const Glib::ustring& type)
{
  return Glib::convert_return_gchar_ptr_to_ustring(g_content_type_get_mime_type(type.c_str()));
}

Glib::RefPtr<Gio::Icon> content_type_get_icon(const Glib::ustring& type)
{
  //TODO: Does g_content_type_get_icon() return a reference?
  //It currently has no implementation so it's hard to know. murrayc.
  return Glib::wrap(g_content_type_get_icon(type.c_str()));
}

bool content_type_can_be_executable(const Glib::ustring& type)
{
  return g_content_type_can_be_executable(type.c_str());
}

Glib::ustring content_type_from_mime_type(const Glib::ustring& mime_type)
{
  return Glib::convert_return_gchar_ptr_to_ustring(g_content_type_from_mime_type(mime_type.c_str()));
}

Glib::ustring content_type_guess(const std::string& filename,
  const std::basic_string<guchar>& data, bool& result_uncertain)
{
  gboolean c_result_uncertain = FALSE;
  gchar* cresult = g_content_type_guess(filename.c_str(), data.c_str(),
    data.size(), &c_result_uncertain);
  result_uncertain = c_result_uncertain;
  return Glib::convert_return_gchar_ptr_to_ustring(cresult);
}

Glib::ustring content_type_guess(const std::string& filename,
  const guchar* data, gsize data_size, bool& result_uncertain)
{
  gboolean c_result_uncertain = FALSE;
  gchar* cresult = g_content_type_guess(filename.c_str(), data,
    data_size, &c_result_uncertain);
  result_uncertain = c_result_uncertain;
  return Glib::convert_return_gchar_ptr_to_ustring(cresult);
}

Glib::ustring content_type_guess(const std::string& filename,
  const std::string& data, bool& result_uncertain)
{
  gboolean c_result_uncertain = FALSE;
  gchar* cresult = g_content_type_guess(filename.c_str(), (const guchar*)data.c_str(),
    data.size(), &c_result_uncertain);
  result_uncertain = c_result_uncertain;
  return Glib::convert_return_gchar_ptr_to_ustring(cresult);
}

Glib::StringArrayHandle content_type_guess_for_tree(const Glib::RefPtr<const File>& root)
{
  return Glib::StringArrayHandle(g_content_type_guess_for_tree(const_cast<GFile*>(root->gobj())),
    Glib::OWNERSHIP_DEEP);
}

Glib::ListHandle<Glib::ustring> content_types_get_registered()
{
  return Glib::ListHandle<Glib::ustring>(g_content_types_get_registered(),
    Glib::OWNERSHIP_DEEP);
}

} // namespace Gio
<commit_msg>Bug 581811 - Gio::content_type_guess() miss the version with a NULL filename<commit_after>// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*-

/* Copyright (C) 2008 The gtkmm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <giomm/contenttype.h>
#include <gio/gio.h>

namespace Gio
{

bool content_type_equals(const Glib::ustring& type1, const Glib::ustring& type2)
{
  return g_content_type_equals(type1.c_str(), type2.c_str());
}

bool content_type_is_a(const Glib::ustring& type, const Glib::ustring& supertype)
{
  return g_content_type_is_a(type.c_str(), supertype.c_str());
}

bool content_type_is_unknown(const Glib::ustring& type)
{
  return g_content_type_is_unknown(type.c_str());
}

Glib::ustring content_type_get_description(const Glib::ustring& type)
{
  return Glib::convert_return_gchar_ptr_to_ustring(g_content_type_get_description(type.c_str()));
}

Glib::ustring content_type_get_mime_type(const Glib::ustring& type)
{
  return Glib::convert_return_gchar_ptr_to_ustring(g_content_type_get_mime_type(type.c_str()));
}

Glib::RefPtr<Gio::Icon> content_type_get_icon(const Glib::ustring& type)
{
  //TODO: Does g_content_type_get_icon() return a reference?
  //It currently has no implementation so it's hard to know. murrayc.
  return Glib::wrap(g_content_type_get_icon(type.c_str()));
}

bool content_type_can_be_executable(const Glib::ustring& type)
{
  return g_content_type_can_be_executable(type.c_str());
}

Glib::ustring content_type_from_mime_type(const Glib::ustring& mime_type)
{
  return Glib::convert_return_gchar_ptr_to_ustring(g_content_type_from_mime_type(mime_type.c_str()));
}

Glib::ustring content_type_guess(const std::string& filename,
  const std::basic_string<guchar>& data, bool& result_uncertain)
{
  gboolean c_result_uncertain = FALSE;
  const gchar *c_filename = filename.empty () ? NULL : filename.c_str ();
  gchar* cresult = g_content_type_guess(c_filename, data.c_str(),
    data.size(), &c_result_uncertain);
  result_uncertain = c_result_uncertain;
  return Glib::convert_return_gchar_ptr_to_ustring(cresult);
}

Glib::ustring content_type_guess(const std::string& filename,
  const guchar* data, gsize data_size, bool& result_uncertain)
{
  gboolean c_result_uncertain = FALSE;
  const gchar *c_filename = filename.empty () ? NULL : filename.c_str ();
  gchar* cresult = g_content_type_guess(c_filename, data,
    data_size, &c_result_uncertain);
  result_uncertain = c_result_uncertain;
  return Glib::convert_return_gchar_ptr_to_ustring(cresult);
}

Glib::ustring content_type_guess(const std::string& filename,
  const std::string& data, bool& result_uncertain)
{
  gboolean c_result_uncertain = FALSE;
  const gchar *c_filename = filename.empty () ? NULL : filename.c_str ();
  gchar* cresult = g_content_type_guess(c_filename, (const guchar*)data.c_str(),
    data.size(), &c_result_uncertain);
  result_uncertain = c_result_uncertain;
  return Glib::convert_return_gchar_ptr_to_ustring(cresult);
}

Glib::StringArrayHandle content_type_guess_for_tree(const Glib::RefPtr<const File>& root)
{
  return Glib::StringArrayHandle(g_content_type_guess_for_tree(const_cast<GFile*>(root->gobj())),
    Glib::OWNERSHIP_DEEP);
}

Glib::ListHandle<Glib::ustring> content_types_get_registered()
{
  return Glib::ListHandle<Glib::ustring>(g_content_types_get_registered(),
    Glib::OWNERSHIP_DEEP);
}

} // namespace Gio
<|endoftext|>


<commit_before>#include <tetra/TicTocClock.hpp>

#include <algorithm>
#include <iostream>
#include <list>

using namespace std;
using namespace tetra;

class Behavior;
class BehaviorList;
using OwnedBehavior = std::unique_ptr<Behavior>;

/**
 * A behavior is a chunk of code which executes in a BehaviorList.
 * Behaviors are provided a pointer to their parent list before their
 * onStart method is first called.
 */
class Behavior
{
public:
    bool complete = false;
    bool blocking = false;
    BehaviorList* parentList;

    virtual void run(double dt) = 0;
    virtual void onStart();
    virtual void onEnd();

    Behavior* insertInFrontOfMe(OwnedBehavior&& ownedBehavior);
};

void Behavior::onStart() {}
void Behavior::onEnd() {}

/**
 * The BehaviorList is a collection of behaviors which are executed each time
 * run() is invoked.
 */
class BehaviorList
{
public:
    /**
     * Insert the owned behavior before the here pointer.
     * If the 'here' pointer cannot be found then the behavior is inserted at the
     * end of the list.
     */
    Behavior* insertBefore(const Behavior* here, OwnedBehavior&& action);

    /**
     * Insert the owned behavior after the 'here' pointer.
     * If the 'here' pointer cannot be found in the behavior list then the provided
     * behavior is inserted at the end of the list.
     */
    Behavior* insertAfter(const Behavior* here, OwnedBehavior&& action);

    /**
     * Push the provided behavior onto the front of the behavior list.
     */
    Behavior* pushFront(OwnedBehavior&& action);

    /**
     * Execute the behaviors in the behavior list, stopping at the end of the list
     * or after the first blocking Behavior executes.
     */
    void run(double dt);

    /**
     * Returns true as long as there are any behaviors which have not completed.
     */
    bool running() const;
private:
    using BehaviorCollection = std::list<OwnedBehavior>;
    BehaviorCollection behaviors;

    /**
     * Insert the action at a location, set the parentList, and call onStart.
     */
    Behavior* insertAt(BehaviorCollection::iterator location, OwnedBehavior&& action);
};

Behavior*
Behavior::insertInFrontOfMe(OwnedBehavior&& ownedBehavior)
{
    return this->parentList->insertBefore(this, move(ownedBehavior));
}

class Delay : public Behavior
{
public:
    Delay(double duration);

    virtual void run(double dt) override;

    static unique_ptr<Delay> forSeconds(double duration);
private:
    const double duration;
    double elapsed;
};

Delay::Delay(double duration)
    : duration{duration}
    , elapsed{0.0f}
{
    this->blocking = true;
}

void
Delay::run(double dt)
{
    elapsed += dt;
    if (elapsed >= duration)
    {
        this->complete = true;
    }
}

unique_ptr<Delay>
Delay::forSeconds(double duration)
{
    return unique_ptr<Delay>{new Delay{duration}};
}

class Echo : public Behavior
{
public:
    Echo(const std::string& msg);

    virtual void run(double dt) override;

    static unique_ptr<Echo> message(const string& msg);
private:
    const std::string msg;
};

unique_ptr<Echo>
Echo::message(const string& msg)
{
    return unique_ptr<Echo>{new Echo{msg}};
}

Echo::Echo(const std::string& msg)
    : msg{msg}
{ }

void
Echo::run(double dt)
{
    cout << msg << endl;
    this->complete = true;
}

class MyTurboBehavior : public Behavior
{
public:
    virtual void onStart() override
    {
        cout << " -> starting my turbo behavior" << "\n"
             << " -> So pretend to gather some resources or something"
             << endl;
    }

    virtual void onEnd() override
    {
        cout << " -> ending my turbo behavior" << "\n"
             << " -> so pretend to clean things up or something"
             << endl;
    }

    virtual void run(double dt) override
    {
        cout << " -> count is " << this->count << " wait 1 second" << endl;

        this->insertInFrontOfMe(Delay::forSeconds(1.0));
        this->insertInFrontOfMe(
            Echo::message("finished delay for count " + to_string(this->count))
        );
        this->count -= 1;

        if (this->count == 0)
        {
            this->complete = true;
            return;
        }
    }

    static unique_ptr<MyTurboBehavior> turbo()
    {
        return unique_ptr<MyTurboBehavior>{new MyTurboBehavior{}};
    }
private:
    int count = 5;
};

int main()
{
    // Lets use this to track the total execution time
    auto totalTimer = HighResTicToc{};

    // Lets use this for tracking time per frame
    auto timer = HighResTicToc{};

    // Create the behavior list and push my turbo action into it
    auto mylist = BehaviorList{};
    mylist.pushFront(MyTurboBehavior::turbo());

    while(mylist.running())
    {
        mylist.run(timer.ticToc());
    }

    cout << "completed in " << totalTimer.toc() << " seconds" << endl;
    /*
     * Did you notice that the total time is _more_ than 5 seconds?!
     * This is actually not incorrect behavior, there are two factors at play here:
     *
     * 1 - The delay is inserted by my turbo behavior _before_ itself.
     *     This means that the delay only starts burning down on the next frame.
     *     This means that a delay of 1 second which is created this frame, will
     *     actually end 1 second + ~16 milliseconds from now.
     *     The behavior is expected -- once the delay starts ticking it expires
     *     after 1 second.
     *
     * 2 - The c++ standard this_thread::sleep_for is used inside of the TicTocClock
     *     to sleep if the min duration hasn't been met.
     *     The sleep_for method is allowed to be somewhat inprecise and sleep for
     *     longer than requested. So depending on the std lib implementation and
     *     the underlying OS there is a bit of room for variablility.
     */
    return 0;
}

Behavior*
BehaviorList::insertBefore(const Behavior* here, OwnedBehavior&& action)
{
    auto insertIter = find_if(begin(this->behaviors), end(this->behaviors),
                              [&here](const OwnedBehavior& action)
                              {
                                  return action.get() == here;
                              });
    return this->insertAt(insertIter, move(action));
}

Behavior*
BehaviorList::insertAfter(const Behavior* here, OwnedBehavior&& action)
{
    auto insertIter = find_if(begin(this->behaviors), end(this->behaviors),
                              [&here](const OwnedBehavior& action)
                              {
                                  return action.get() == here;
                              });
    if (insertIter != end(this->behaviors))
    {
        insertIter++;
    }
    return this->insertAt(insertIter, move(action));
}

Behavior*
BehaviorList::pushFront(OwnedBehavior&& action)
{
    return insertAt(begin(this->behaviors), move(action));
}

Behavior*
BehaviorList::insertAt(BehaviorCollection::iterator location, OwnedBehavior&& action)
{
    auto insertedIter = this->behaviors.insert(location, move(action));
    auto actionPtr = insertedIter->get();
    actionPtr->parentList = this;
    actionPtr->onStart();
    return actionPtr;
}

void
BehaviorList::run(double dt)
{
    // For loop is stable even if behaviors insert elements because
    // std::list iterators are not invalidated when elements are inserted.
    // all removal happens after the update loop
    for (const auto& behavior : this->behaviors)
    {
        // don't allow a completed behavior to run or block others
        if (behavior->complete)
        {
            continue;
        }

        behavior->run(dt);
        if (behavior->blocking)
        {
            break;
        }
    }

    // move completed actions to the end of the list (note that stable partition
    // preserves relative ordering of behaviors)
    auto startOfCompleted =
        stable_partition(begin(this->behaviors), end(this->behaviors),
                         [](const OwnedBehavior& action)
                         {
                             return !action->complete;
                         });
    // run onEnd for completed actions
    for_each(startOfCompleted, end(this->behaviors), [](const OwnedBehavior& action)
    {
        action->onEnd();
    });
    // erase the ended actions
    this->behaviors.erase(startOfCompleted, end(this->behaviors));
}

bool
BehaviorList::running() const
{
    return !this->behaviors.empty();
}

<commit_msg>clean up output for actionlist<commit_after>#include <tetra/TicTocClock.hpp>

#include <algorithm>
#include <iostream>
#include <list>

using namespace std;
using namespace tetra;

class Behavior;
class BehaviorList;
using OwnedBehavior = std::unique_ptr<Behavior>;

/**
 * A behavior is a chunk of code which executes in a BehaviorList.
 * Behaviors are provided a pointer to their parent list before their
 * onStart method is first called.
 */
class Behavior
{
public:
    bool complete = false;
    bool blocking = false;
    BehaviorList* parentList;

    virtual void run(double dt) = 0;
    virtual void onStart();
    virtual void onEnd();

    Behavior* insertInFrontOfMe(OwnedBehavior&& ownedBehavior);
};

void Behavior::onStart() {}
void Behavior::onEnd() {}

/**
 * The BehaviorList is a collection of behaviors which are executed each time
 * run() is invoked.
 */
class BehaviorList
{
public:
    /**
     * Insert the owned behavior before the here pointer.
     * If the 'here' pointer cannot be found then the behavior is inserted at the
     * end of the list.
     */
    Behavior* insertBefore(const Behavior* here, OwnedBehavior&& action);

    /**
     * Insert the owned behavior after the 'here' pointer.
     * If the 'here' pointer cannot be found in the behavior list then the provided
     * behavior is inserted at the end of the list.
     */
    Behavior* insertAfter(const Behavior* here, OwnedBehavior&& action);

    /**
     * Push the provided behavior onto the front of the behavior list.
     */
    Behavior* pushFront(OwnedBehavior&& action);

    /**
     * Execute the behaviors in the behavior list, stopping at the end of the list
     * or after the first blocking Behavior executes.
     */
    void run(double dt);

    /**
     * Returns true as long as there are any behaviors which have not completed.
     */
    bool running() const;
private:
    using BehaviorCollection = std::list<OwnedBehavior>;
    BehaviorCollection behaviors;

    /**
     * Insert the action at a location, set the parentList, and call onStart.
     */
    Behavior* insertAt(BehaviorCollection::iterator location, OwnedBehavior&& action);
};

Behavior*
Behavior::insertInFrontOfMe(OwnedBehavior&& ownedBehavior)
{
    return this->parentList->insertBefore(this, move(ownedBehavior));
}

class Delay : public Behavior
{
public:
    Delay(double duration);

    virtual void run(double dt) override;

    static unique_ptr<Delay> forSeconds(double duration);
private:
    const double duration;
    double elapsed;
};

Delay::Delay(double duration)
    : duration{duration}
    , elapsed{0.0f}
{
    this->blocking = true;
}

void
Delay::run(double dt)
{
    elapsed += dt;
    if (elapsed >= duration)
    {
        this->complete = true;
    }
}

unique_ptr<Delay>
Delay::forSeconds(double duration)
{
    return unique_ptr<Delay>{new Delay{duration}};
}

class Echo : public Behavior
{
public:
    Echo(const std::string& msg);

    virtual void run(double dt) override;

    static unique_ptr<Echo> message(const string& msg);
private:
    const std::string msg;
};

unique_ptr<Echo>
Echo::message(const string& msg)
{
    return unique_ptr<Echo>{new Echo{msg}};
}

Echo::Echo(const std::string& msg)
    : msg{msg}
{ }

void
Echo::run(double dt)
{
    cout << msg << endl;
    this->complete = true;
}

class MyTurboBehavior : public Behavior
{
public:
    virtual void onStart() override
    {
        cout << " -> starting my turbo behavior" << endl;
    }

    virtual void onEnd() override
    {
        cout << " -> ending my turbo behavior" << endl;
    }

    virtual void run(double dt) override
    {
        cout << " -> count is " << this->count << " wait 1 second" << endl;

        this->insertInFrontOfMe(Delay::forSeconds(1.0));
        this->insertInFrontOfMe(
            Echo::message("finished wait for count " + to_string(this->count))
        );
        this->count -= 1;

        if (this->count == 0)
        {
            this->complete = true;
            return;
        }
    }

    static unique_ptr<MyTurboBehavior> turbo()
    {
        return unique_ptr<MyTurboBehavior>{new MyTurboBehavior{}};
    }
private:
    int count = 5;
};

int main()
{
    // Lets use this to track the total execution time
    auto totalTimer = HighResTicToc{};

    // Lets use this for tracking time per frame
    auto timer = HighResTicToc{};

    // Create the behavior list and push my turbo action into it
    auto mylist = BehaviorList{};
    mylist.pushFront(MyTurboBehavior::turbo());

    while(mylist.running())
    {
        mylist.run(timer.ticToc());
    }

    cout << "completed in " << totalTimer.toc() << " seconds" << endl;
    /*
     * Did you notice that the total time is _more_ than 5 seconds?!
     * This is actually not incorrect behavior, there are two factors at play here:
     *
     * 1 - The delay is inserted by my turbo behavior _before_ itself.
     *     This means that the delay only starts burning down on the next frame.
     *     This means that a delay of 1 second which is created this frame, will
     *     actually end 1 second + ~16 milliseconds from now.
     *     The behavior is expected -- once the delay starts ticking it expires
     *     after 1 second.
     *
     * 2 - The c++ standard this_thread::sleep_for is used inside of the TicTocClock
     *     to sleep if the min duration hasn't been met.
     *     The sleep_for method is allowed to be somewhat inprecise and sleep for
     *     longer than requested. So depending on the std lib implementation and
     *     the underlying OS there is a bit of room for variablility.
     */
    return 0;
}

Behavior*
BehaviorList::insertBefore(const Behavior* here, OwnedBehavior&& action)
{
    auto insertIter = find_if(begin(this->behaviors), end(this->behaviors),
                              [&here](const OwnedBehavior& action)
                              {
                                  return action.get() == here;
                              });
    return this->insertAt(insertIter, move(action));
}

Behavior*
BehaviorList::insertAfter(const Behavior* here, OwnedBehavior&& action)
{
    auto insertIter = find_if(begin(this->behaviors), end(this->behaviors),
                              [&here](const OwnedBehavior& action)
                              {
                                  return action.get() == here;
                              });
    if (insertIter != end(this->behaviors))
    {
        insertIter++;
    }
    return this->insertAt(insertIter, move(action));
}

Behavior*
BehaviorList::pushFront(OwnedBehavior&& action)
{
    return insertAt(begin(this->behaviors), move(action));
}

Behavior*
BehaviorList::insertAt(BehaviorCollection::iterator location, OwnedBehavior&& action)
{
    auto insertedIter = this->behaviors.insert(location, move(action));
    auto actionPtr = insertedIter->get();
    actionPtr->parentList = this;
    actionPtr->onStart();
    return actionPtr;
}

void
BehaviorList::run(double dt)
{
    // For loop is stable even if behaviors insert elements because
    // std::list iterators are not invalidated when elements are inserted.
    // all removal happens after the update loop
    for (const auto& behavior : this->behaviors)
    {
        // don't allow a completed behavior to run or block others
        if (behavior->complete)
        {
            continue;
        }

        behavior->run(dt);
        if (behavior->blocking)
        {
            break;
        }
    }

    // move completed actions to the end of the list (note that stable partition
    // preserves relative ordering of behaviors)
    auto startOfCompleted =
        stable_partition(begin(this->behaviors), end(this->behaviors),
                         [](const OwnedBehavior& action)
                         {
                             return !action->complete;
                         });
    // run onEnd for completed actions
    for_each(startOfCompleted, end(this->behaviors), [](const OwnedBehavior& action)
    {
        action->onEnd();
    });
    // erase the ended actions
    this->behaviors.erase(startOfCompleted, end(this->behaviors));
}

bool
BehaviorList::running() const
{
    return !this->behaviors.empty();
}

<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2006 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// bzflag common header
#include "common.h"

// interface header
#include "LaserSceneNode.h"

// system headers
#include <math.h>

// common implementation headers
#include "StateDatabase.h"
#include "BZDBCache.h"

// FIXME (SceneRenderer.cxx is in src/bzflag)
#include "SceneRenderer.h"

const GLfloat		LaserRadius = 0.1f;

LaserSceneNode::LaserSceneNode(const GLfloat pos[3], const GLfloat forward[3]) :
				texturing(false),
				renderNode(this)
{
  // prepare rendering info
  azimuth = (float)(180.0 / M_PI*atan2f(forward[1], forward[0]));
  elevation = (float)(-180.0 / M_PI*atan2f(forward[2], hypotf(forward[0],forward[1])));
  length = hypotf(forward[0], hypotf(forward[1], forward[2]));

  // setup sphere
  setCenter(pos);
  setRadius(length * length);

  OpenGLGStateBuilder builder(gstate);
  builder.setCulling(GL_NONE);
  gstate = builder.getState();

  first = false;
  setColor(1,1,1);
}

LaserSceneNode::~LaserSceneNode()
{
  // do nothing
}

void	LaserSceneNode::setColor ( GLfloat r, GLfloat g, GLfloat b )
{
	color[0] = r;
	color[1] = g;
	color[2] = b;
}

void			LaserSceneNode::setTexture(const int texture)
{
  OpenGLGStateBuilder builder(gstate);
  builder.setTexture(texture);
  builder.enableTexture(texture>=0);
  gstate = builder.getState();
}

bool			LaserSceneNode::cull(const ViewFrustum&) const
{
  // no culling
  return false;
}

void			LaserSceneNode::notifyStyleChange()
{
  texturing = BZDBCache::texture && BZDBCache::blend;
  OpenGLGStateBuilder builder(gstate);
  builder.enableTexture(texturing);
  if (BZDBCache::blend) {
    // add in contribution from laser
    builder.setBlending(GL_SRC_ALPHA, GL_ONE);
    builder.setSmoothing(BZDB.isTrue("smooth"));
  }
  else {
    builder.resetBlending();
    builder.setSmoothing(false);
  }
  gstate = builder.getState();
}

void			LaserSceneNode::addRenderNodes(
				SceneRenderer& renderer)
{
  renderer.addRenderNode(&renderNode, &gstate);
}

//
// LaserSceneNode::LaserRenderNode
//

GLfloat			LaserSceneNode::LaserRenderNode::geom[6][2];

LaserSceneNode::LaserRenderNode::LaserRenderNode(
				const LaserSceneNode* _sceneNode) :
				sceneNode(_sceneNode)
{
  // initialize geometry if first instance
  static bool init = false;
  if (!init) {
    init = true;
    for (int i = 0; i < 6; i++) {
      geom[i][0] = -LaserRadius * cosf((float)(2.0 * M_PI * double(i) / 6.0));
      geom[i][1] =  LaserRadius * sinf((float)(2.0 * M_PI * double(i) / 6.0));
    }
  }
}

LaserSceneNode::LaserRenderNode::~LaserRenderNode()
{
  // do nothing
}

void			LaserSceneNode::LaserRenderNode::render()
{
	if (RENDERER.useQuality() >= _EXPEREMENTAL_QUALITY)
		renderGeoLaser();
	else
		renderFlatLaser();
}

void LaserSceneNode::LaserRenderNode::renderGeoLaser ( void )
{
	const GLfloat length = sceneNode->length;
	const GLfloat* sphere = sceneNode->getSphere();
	glPushMatrix();
	glTranslatef(sphere[0], sphere[1], sphere[2]);
	glRotatef(sceneNode->azimuth, 0.0f, 0.0f, 1.0f);
	glRotatef(sceneNode->elevation, 0.0f, 1.0f, 0.0f);
	glRotatef(90, 0.0f, 1.0f, 0.0f);

	glDisable(GL_TEXTURE_2D);

	myColor4f(sceneNode->color[0], sceneNode->color[1], sceneNode->color[2], 0.5f);
	gluCylinder(gluNewQuadric(),0.125f,0.5f,length,10,1);
	addTriangleCount(20);

	myColor4f(sceneNode->color[0], sceneNode->color[1], sceneNode->color[2], 0.35f);
	gluCylinder(gluNewQuadric(),0.25f,0.5f,length,16,1);
	addTriangleCount(32);

	myColor4f(sceneNode->color[0], sceneNode->color[1], sceneNode->color[2], 0.25f);
	gluCylinder(gluNewQuadric(),0.5f,0.5f,length,24,1);
	addTriangleCount(48);

	myColor4f(sceneNode->color[0], sceneNode->color[1], sceneNode->color[2], 0.10f);
	gluCylinder(gluNewQuadric(),0.75f,0.75f,length,32,1);
	addTriangleCount(64);

	if (sceneNode->first)
	{
		myColor4f(sceneNode->color[0], sceneNode->color[1], sceneNode->color[2], 0.125f);
		gluSphere(gluNewQuadric(),1.5f,32,32);
		addTriangleCount(32*32*2);
	}

	glEnable(GL_TEXTURE_2D);
	glPopMatrix();
}

void			LaserSceneNode::LaserRenderNode::renderFlatLaser()
{
  const GLfloat length = sceneNode->length;
  const GLfloat* sphere = sceneNode->getSphere();
  glPushMatrix();
    glTranslatef(sphere[0], sphere[1], sphere[2]);
    glRotatef(sceneNode->azimuth, 0.0f, 0.0f, 1.0f);
    glRotatef(sceneNode->elevation, 0.0f, 1.0f, 0.0f);

    if (sceneNode->texturing) {
      myColor3f(1.0f, 1.0f, 1.0f);
      glBegin(GL_TRIANGLE_FAN);
	glTexCoord2f(0.5f,  0.5f);
	glVertex3f(  0.0f,  0.0f,  0.0f);
	glTexCoord2f(0.0f,  0.0f);
	glVertex3f(  0.0f,  0.0f,  1.0f);
	glVertex3f(  0.0f,  1.0f,  0.0f);
	glVertex3f(  0.0f,  0.0f, -1.0f);
	glVertex3f(  0.0f, -1.0f,  0.0f);
	glVertex3f(  0.0f,  0.0f,  1.0f);
      glEnd(); // 6 verts -> 4 tris

      glBegin(GL_QUADS);
	glTexCoord2f(0.0f,  0.0f);
	glVertex3f(  0.0f,  0.0f,  1.0f);
	glTexCoord2f(0.0f,  1.0f);
	glVertex3f(length,  0.0f,  1.0f);
	glTexCoord2f(1.0f,  1.0f);
	glVertex3f(length,  0.0f, -1.0f);
	glTexCoord2f(1.0f,  0.0f);
	glVertex3f(  0.0f,  0.0f, -1.0f);

	glTexCoord2f(0.0f,  0.0f);
	glVertex3f(  0.0f,  1.0f,  0.0f);
	glTexCoord2f(0.0f,  1.0f);
	glVertex3f(length,  1.0f,  0.0f);
	glTexCoord2f(1.0f,  1.0f);
	glVertex3f(length, -1.0f,  0.0f);
	glTexCoord2f(1.0f,  0.0f);
	glVertex3f(  0.0f, -1.0f,  0.0f);
      glEnd(); // 8 verts -> 4 tris

      addTriangleCount(8);
    }

    else {
      // draw beam
      myColor4f(1.0f, 0.25f, 0.0f, 0.85f);
      glBegin(GL_QUAD_STRIP);
      {
	glVertex3f(  0.0f, geom[0][0], geom[0][1]);
	glVertex3f(length, geom[0][0], geom[0][1]);
	glVertex3f(  0.0f, geom[1][0], geom[1][1]);
	glVertex3f(length, geom[1][0], geom[1][1]);
	glVertex3f(  0.0f, geom[2][0], geom[2][1]);
	glVertex3f(length, geom[2][0], geom[2][1]);
	glVertex3f(  0.0f, geom[3][0], geom[3][1]);
	glVertex3f(length, geom[3][0], geom[3][1]);
	glVertex3f(  0.0f, geom[4][0], geom[4][1]);
	glVertex3f(length, geom[4][0], geom[4][1]);
	glVertex3f(  0.0f, geom[5][0], geom[5][1]);
	glVertex3f(length, geom[5][0], geom[5][1]);
	glVertex3f(  0.0f, geom[0][0], geom[0][1]);
	glVertex3f(length, geom[0][0], geom[0][1]);
      }
      glEnd(); // 14 verts -> 12 tris

      // also draw a line down the middle (so the beam is visible even
      // if very far away).  this will also give the beam an extra bright
      // center.
      glBegin(GL_LINES);
      {
	glVertex3f(  0.0f, 0.0f, 0.0f);
	glVertex3f(length, 0.0f, 0.0f);
      }
      glEnd(); // count 1 line as 1 tri

      addTriangleCount(13);
    }

  glPopMatrix();
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>cleanup the sizes on the geolaser, and add a little energy bulge on rico<commit_after>/* bzflag
 * Copyright (c) 1993 - 2006 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

// bzflag common header
#include "common.h"

// interface header
#include "LaserSceneNode.h"

// system headers
#include <math.h>

// common implementation headers
#include "StateDatabase.h"
#include "BZDBCache.h"

// FIXME (SceneRenderer.cxx is in src/bzflag)
#include "SceneRenderer.h"

const GLfloat		LaserRadius = 0.1f;

LaserSceneNode::LaserSceneNode(const GLfloat pos[3], const GLfloat forward[3]) :
				texturing(false),
				renderNode(this)
{
  // prepare rendering info
  azimuth = (float)(180.0 / M_PI*atan2f(forward[1], forward[0]));
  elevation = (float)(-180.0 / M_PI*atan2f(forward[2], hypotf(forward[0],forward[1])));
  length = hypotf(forward[0], hypotf(forward[1], forward[2]));

  // setup sphere
  setCenter(pos);
  setRadius(length * length);

  OpenGLGStateBuilder builder(gstate);
  builder.setCulling(GL_NONE);
  gstate = builder.getState();

  first = false;
  setColor(1,1,1);
}

LaserSceneNode::~LaserSceneNode()
{
  // do nothing
}

void	LaserSceneNode::setColor ( GLfloat r, GLfloat g, GLfloat b )
{
	color[0] = r;
	color[1] = g;
	color[2] = b;
}

void			LaserSceneNode::setTexture(const int texture)
{
  OpenGLGStateBuilder builder(gstate);
  builder.setTexture(texture);
  builder.enableTexture(texture>=0);
  gstate = builder.getState();
}

bool			LaserSceneNode::cull(const ViewFrustum&) const
{
  // no culling
  return false;
}

void			LaserSceneNode::notifyStyleChange()
{
  texturing = BZDBCache::texture && BZDBCache::blend;
  OpenGLGStateBuilder builder(gstate);
  builder.enableTexture(texturing);
  if (BZDBCache::blend) {
    // add in contribution from laser
    builder.setBlending(GL_SRC_ALPHA, GL_ONE);
    builder.setSmoothing(BZDB.isTrue("smooth"));
  }
  else {
    builder.resetBlending();
    builder.setSmoothing(false);
  }
  gstate = builder.getState();
}

void			LaserSceneNode::addRenderNodes(
				SceneRenderer& renderer)
{
  renderer.addRenderNode(&renderNode, &gstate);
}

//
// LaserSceneNode::LaserRenderNode
//

GLfloat			LaserSceneNode::LaserRenderNode::geom[6][2];

LaserSceneNode::LaserRenderNode::LaserRenderNode(
				const LaserSceneNode* _sceneNode) :
				sceneNode(_sceneNode)
{
  // initialize geometry if first instance
  static bool init = false;
  if (!init) {
    init = true;
    for (int i = 0; i < 6; i++) {
      geom[i][0] = -LaserRadius * cosf((float)(2.0 * M_PI * double(i) / 6.0));
      geom[i][1] =  LaserRadius * sinf((float)(2.0 * M_PI * double(i) / 6.0));
    }
  }
}

LaserSceneNode::LaserRenderNode::~LaserRenderNode()
{
  // do nothing
}

void			LaserSceneNode::LaserRenderNode::render()
{
	if (RENDERER.useQuality() >= _EXPEREMENTAL_QUALITY)
		renderGeoLaser();
	else
		renderFlatLaser();
}

void LaserSceneNode::LaserRenderNode::renderGeoLaser ( void )
{
	const GLfloat length = sceneNode->length;
	const GLfloat* sphere = sceneNode->getSphere();
	glPushMatrix();
	glTranslatef(sphere[0], sphere[1], sphere[2]);
	glRotatef(sceneNode->azimuth, 0.0f, 0.0f, 1.0f);
	glRotatef(sceneNode->elevation, 0.0f, 1.0f, 0.0f);
	glRotatef(90, 0.0f, 1.0f, 0.0f);

	glDisable(GL_TEXTURE_2D);

	//myColor4f(sceneNode->color[0], sceneNode->color[1], sceneNode->color[2], 0.85f);
	myColor4f(1, 1, 1, 0.85f);
	gluCylinder(gluNewQuadric(),0.125f,0.125f,length,10,1);
	addTriangleCount(20);

	myColor4f(sceneNode->color[0], sceneNode->color[1], sceneNode->color[2], 0.125f);
	gluCylinder(gluNewQuadric(),0.2f,0.2f,length,16,1);
	addTriangleCount(32);

	myColor4f(sceneNode->color[0], sceneNode->color[1], sceneNode->color[2], 0.125f);
	gluCylinder(gluNewQuadric(),0.4f,0.4f,length,24,1);
	addTriangleCount(48);

	myColor4f(sceneNode->color[0], sceneNode->color[1], sceneNode->color[2], 0.125f);
	gluCylinder(gluNewQuadric(),0.6f,0.6f,length,32,1);
	addTriangleCount(64);

	myColor4f(sceneNode->color[0], sceneNode->color[1], sceneNode->color[2], 0.125f);
	if (sceneNode->first)
	{
		gluSphere(gluNewQuadric(),1.0f,32,32);
		addTriangleCount(32*32*2);
	}
	else
	{
		gluSphere(gluNewQuadric(),0.75f,12,12);
		addTriangleCount(12*12*2);
	}

	glEnable(GL_TEXTURE_2D);
	glPopMatrix();
}

void			LaserSceneNode::LaserRenderNode::renderFlatLaser()
{
  const GLfloat length = sceneNode->length;
  const GLfloat* sphere = sceneNode->getSphere();
  glPushMatrix();
    glTranslatef(sphere[0], sphere[1], sphere[2]);
    glRotatef(sceneNode->azimuth, 0.0f, 0.0f, 1.0f);
    glRotatef(sceneNode->elevation, 0.0f, 1.0f, 0.0f);

    if (sceneNode->texturing) {
      myColor3f(1.0f, 1.0f, 1.0f);
      glBegin(GL_TRIANGLE_FAN);
	glTexCoord2f(0.5f,  0.5f);
	glVertex3f(  0.0f,  0.0f,  0.0f);
	glTexCoord2f(0.0f,  0.0f);
	glVertex3f(  0.0f,  0.0f,  1.0f);
	glVertex3f(  0.0f,  1.0f,  0.0f);
	glVertex3f(  0.0f,  0.0f, -1.0f);
	glVertex3f(  0.0f, -1.0f,  0.0f);
	glVertex3f(  0.0f,  0.0f,  1.0f);
      glEnd(); // 6 verts -> 4 tris

      glBegin(GL_QUADS);
	glTexCoord2f(0.0f,  0.0f);
	glVertex3f(  0.0f,  0.0f,  1.0f);
	glTexCoord2f(0.0f,  1.0f);
	glVertex3f(length,  0.0f,  1.0f);
	glTexCoord2f(1.0f,  1.0f);
	glVertex3f(length,  0.0f, -1.0f);
	glTexCoord2f(1.0f,  0.0f);
	glVertex3f(  0.0f,  0.0f, -1.0f);

	glTexCoord2f(0.0f,  0.0f);
	glVertex3f(  0.0f,  1.0f,  0.0f);
	glTexCoord2f(0.0f,  1.0f);
	glVertex3f(length,  1.0f,  0.0f);
	glTexCoord2f(1.0f,  1.0f);
	glVertex3f(length, -1.0f,  0.0f);
	glTexCoord2f(1.0f,  0.0f);
	glVertex3f(  0.0f, -1.0f,  0.0f);
      glEnd(); // 8 verts -> 4 tris

      addTriangleCount(8);
    }

    else {
      // draw beam
      myColor4f(1.0f, 0.25f, 0.0f, 0.85f);
      glBegin(GL_QUAD_STRIP);
      {
	glVertex3f(  0.0f, geom[0][0], geom[0][1]);
	glVertex3f(length, geom[0][0], geom[0][1]);
	glVertex3f(  0.0f, geom[1][0], geom[1][1]);
	glVertex3f(length, geom[1][0], geom[1][1]);
	glVertex3f(  0.0f, geom[2][0], geom[2][1]);
	glVertex3f(length, geom[2][0], geom[2][1]);
	glVertex3f(  0.0f, geom[3][0], geom[3][1]);
	glVertex3f(length, geom[3][0], geom[3][1]);
	glVertex3f(  0.0f, geom[4][0], geom[4][1]);
	glVertex3f(length, geom[4][0], geom[4][1]);
	glVertex3f(  0.0f, geom[5][0], geom[5][1]);
	glVertex3f(length, geom[5][0], geom[5][1]);
	glVertex3f(  0.0f, geom[0][0], geom[0][1]);
	glVertex3f(length, geom[0][0], geom[0][1]);
      }
      glEnd(); // 14 verts -> 12 tris

      // also draw a line down the middle (so the beam is visible even
      // if very far away).  this will also give the beam an extra bright
      // center.
      glBegin(GL_LINES);
      {
	glVertex3f(  0.0f, 0.0f, 0.0f);
	glVertex3f(length, 0.0f, 0.0f);
      }
      glEnd(); // count 1 line as 1 tri

      addTriangleCount(13);
    }

  glPopMatrix();
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>