<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban
// =============================================================================
//
// Base class for the chassis vehicle subsystem.
//
// =============================================================================

#include "chrono/assets/ChSphereShape.h"

#include "chrono_vehicle/ChChassis.h"

namespace chrono {
namespace vehicle {

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChChassis::ChChassis(const std::string& name, bool fixed) : ChPart(name), m_fixed(fixed) {}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChVector<> ChChassis::GetPointAcceleration(const ChVector<>& locpos) const {
    ChVector<> acc_abs = m_body->GetFrame_REF_to_abs().PointAccelerationLocalToParent(locpos);
    return m_body->GetFrame_REF_to_abs().TransformDirectionParentToLocal(acc_abs);
}

// -----------------------------------------------------------------------------
// Return the global driver position
// -----------------------------------------------------------------------------
ChVector<> ChChassis::GetDriverPos() const {
    return m_body->GetCoord().TransformPointLocalToParent(GetLocalDriverCoordsys().pos);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChChassis::Initialize(ChSystem* system, const ChCoordsys<>& chassisPos, double chassisFwdVel) {
    m_body = std::shared_ptr<ChBodyAuxRef>(system->NewBodyAuxRef());
    m_body->SetIdentifier(0);
    m_body->SetName("chassis");
    m_body->SetMass(GetMass());
    m_body->SetFrame_COG_to_REF(ChFrame<>(GetLocalPosCOM(), ChQuaternion<>(1, 0, 0, 0)));
    m_body->SetInertia(GetInertia());
    m_body->SetBodyFixed(m_fixed);

    m_body->SetFrame_REF_to_abs(ChFrame<>(chassisPos));
    m_body->SetPos_dt(chassisFwdVel * chassisPos.TransformDirectionLocalToParent(ChVector<>(1, 0, 0)));

    system->Add(m_body);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChChassis::AddVisualizationAssets(VisualizationType vis) {
    if (vis == VisualizationType::NONE)
        return;

    auto sphere = std::make_shared<ChSphereShape>();
    sphere->GetSphereGeometry().rad = 0.1;
    sphere->Pos = GetLocalPosCOM();
    m_body->AddAsset(sphere);
}

void ChChassis::RemoveVisualizationAssets() {
    m_body->GetAssets().clear();
}

}  // end namespace vehicle
}  // end namespace chrono
<commit_msg>Fix bug in expressing the vehicle driver location in global frame<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban
// =============================================================================
//
// Base class for the chassis vehicle subsystem.
//
// =============================================================================

#include "chrono/assets/ChSphereShape.h"

#include "chrono_vehicle/ChChassis.h"

namespace chrono {
namespace vehicle {

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChChassis::ChChassis(const std::string& name, bool fixed) : ChPart(name), m_fixed(fixed) {}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChVector<> ChChassis::GetPointAcceleration(const ChVector<>& locpos) const {
    ChVector<> acc_abs = m_body->GetFrame_REF_to_abs().PointAccelerationLocalToParent(locpos);
    return m_body->GetFrame_REF_to_abs().TransformDirectionParentToLocal(acc_abs);
}

// -----------------------------------------------------------------------------
// Return the global driver position
// -----------------------------------------------------------------------------
ChVector<> ChChassis::GetDriverPos() const {
    return m_body->GetFrame_REF_to_abs().TransformPointLocalToParent(GetLocalDriverCoordsys().pos);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChChassis::Initialize(ChSystem* system, const ChCoordsys<>& chassisPos, double chassisFwdVel) {
    m_body = std::shared_ptr<ChBodyAuxRef>(system->NewBodyAuxRef());
    m_body->SetIdentifier(0);
    m_body->SetName("chassis");
    m_body->SetMass(GetMass());
    m_body->SetFrame_COG_to_REF(ChFrame<>(GetLocalPosCOM(), ChQuaternion<>(1, 0, 0, 0)));
    m_body->SetInertia(GetInertia());
    m_body->SetBodyFixed(m_fixed);

    m_body->SetFrame_REF_to_abs(ChFrame<>(chassisPos));
    m_body->SetPos_dt(chassisFwdVel * chassisPos.TransformDirectionLocalToParent(ChVector<>(1, 0, 0)));

    system->Add(m_body);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChChassis::AddVisualizationAssets(VisualizationType vis) {
    if (vis == VisualizationType::NONE)
        return;

    auto sphere = std::make_shared<ChSphereShape>();
    sphere->GetSphereGeometry().rad = 0.1;
    sphere->Pos = GetLocalPosCOM();
    m_body->AddAsset(sphere);
}

void ChChassis::RemoveVisualizationAssets() {
    m_body->GetAssets().clear();
}

}  // end namespace vehicle
}  // end namespace chrono
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "bzfsAPI.h"
#include "PyBZFlag.h"

namespace Python
{

void
TickHandler::process (bz_EventData *eventData)
{
	PyObject *listeners = parent->GetListeners (bz_eTickEvent);

	if (listeners == NULL || !PyList_Check (listeners)) {
		// FIXME - throw error
		fprintf (stderr, "tick listeners is not a list!\n");
		return;
	}
	int size = PyList_Size (listeners);
	fprintf (stderr, "there are %d tick listeners\n", size);
	for (int i = 0; i < size; i++) {
		PyObject *handler = PyList_GetItem (listeners, i);
		if (!PyCallable_Check (handler)) {
			// FIXME - throw error
			fprintf (stderr, "tick listener is not callable\n");
			return;
		}
		PyEval_CallObject (handler, NULL);
	}
}

static PyObject *SendTextMessage (PyObject *self, PyObject *args, PyObject *keywords);
static PyObject *FireWorldWeapon (PyObject *self, PyObject *args);
static PyObject *GetCurrentTime  (PyObject *self, PyObject *args);

static struct PyMethodDef methods[] =
{
	// FIXME - docstrings
	{"SendTextMessage", (PyCFunction) SendTextMessage, METH_VARARGS | METH_KEYWORDS, NULL},
	{"FireWorldWeapon", (PyCFunction) FireWorldWeapon, METH_VARARGS,                 NULL},
	{"GetCurrentTime",  (PyCFunction) GetCurrentTime,  METH_NOARGS,                  NULL},
	{NULL,              (PyCFunction) NULL,            0,                            NULL},
};

BZFlag *BZFlag::instance = NULL;
int BZFlag::References = 0;

BZFlag *
BZFlag::GetInstance ()
{
	if (instance == NULL)
		instance = new BZFlag ();
	References++;
	return instance;
}

void
BZFlag::DeRef ()
{
	References--;
}

void
CreateHandlerList (PyObject *dict, int event)
{
	PyDict_SetItem (dict, PyInt_FromLong (event), PyList_New (0));
}

BZFlag::BZFlag ()
{
	module = Py_InitModule3 ("BZFlag", methods, NULL);
	Py_INCREF (Py_None);
	Py_INCREF (Py_False);
	Py_INCREF (Py_True);

	// Create and add submodules
	event_sub = new Event ();
	team_sub  = new Team ();

	PyModule_AddObject (module, "Event", event_sub->GetSubModule ());
	PyModule_AddObject (module, "Team",   team_sub->GetSubModule ());

	// Register event handlers
	tick_handler.parent = this;
	bz_registerGeneralEvent (bz_eTickEvent, &tick_handler);

	// Create the dictionary for all the event handlers. Key is the int
	// event ID, value is a list of callables for our callbacks. Marshalling
	// is handled by the individual event handler classes
	event_listeners = PyDict_New ();
	CreateHandlerList (event_listeners, bz_eTickEvent);

	PyModule_AddObject (module, "Events", event_listeners);
}

PyObject *
BZFlag::GetListeners (int event)
{
	PyObject *o = PyInt_FromLong (event);
	PyObject *ret = PyDict_GetItem (event_listeners, o);
	Py_DECREF (o);

	return ret;
}

static PyObject *
SendTextMessage (PyObject *self, PyObject *args, PyObject *keywords)
{
	int to, from;
	char *message;

	static char *kwlist[] = {"to", "from", "message", NULL};

	if (!PyArg_ParseTupleAndKeywords (args, keywords, "iis", kwlist, &to, &from, &message)) {
		fprintf (stderr, "couldn't parse args\n");
		// FIXME - throw error
		return NULL;
	}

	printf ("SendTextMessage (%d, %d, %s)\n", to, from, message);
	bool result = bz_sendTextMessage (to, from, message);
	return Py_None;
}

static PyObject *
FireWorldWeapon (PyObject *self, PyObject *args)
{
	printf ("FireWorldWeapon ()\n");
	return Py_None;
}

static PyObject *
GetCurrentTime (PyObject *self, PyObject *args)
{
	printf ("GetCurrentTime ()\n");
	return Py_None;
}

};
<commit_msg>get rid of debug output<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "bzfsAPI.h"
#include "PyBZFlag.h"

namespace Python
{

void
TickHandler::process (bz_EventData *eventData)
{
	PyObject *listeners = parent->GetListeners (bz_eTickEvent);

	if (listeners == NULL || !PyList_Check (listeners)) {
		// FIXME - throw error
		fprintf (stderr, "tick listeners is not a list!\n");
		return;
	}
	int size = PyList_Size (listeners);
	for (int i = 0; i < size; i++) {
		PyObject *handler = PyList_GetItem (listeners, i);
		if (!PyCallable_Check (handler)) {
			// FIXME - throw error
			fprintf (stderr, "tick listener is not callable\n");
			return;
		}
		PyEval_CallObject (handler, NULL);
	}
}

static PyObject *SendTextMessage (PyObject *self, PyObject *args, PyObject *keywords);
static PyObject *FireWorldWeapon (PyObject *self, PyObject *args);
static PyObject *GetCurrentTime  (PyObject *self, PyObject *args);

static struct PyMethodDef methods[] =
{
	// FIXME - docstrings
	{"SendTextMessage", (PyCFunction) SendTextMessage, METH_VARARGS | METH_KEYWORDS, NULL},
	{"FireWorldWeapon", (PyCFunction) FireWorldWeapon, METH_VARARGS,                 NULL},
	{"GetCurrentTime",  (PyCFunction) GetCurrentTime,  METH_NOARGS,                  NULL},
	{NULL,              (PyCFunction) NULL,            0,                            NULL},
};

BZFlag *BZFlag::instance = NULL;
int BZFlag::References = 0;

BZFlag *
BZFlag::GetInstance ()
{
	if (instance == NULL)
		instance = new BZFlag ();
	References++;
	return instance;
}

void
BZFlag::DeRef ()
{
	References--;
}

void
CreateHandlerList (PyObject *dict, int event)
{
	PyDict_SetItem (dict, PyInt_FromLong (event), PyList_New (0));
}

BZFlag::BZFlag ()
{
	module = Py_InitModule3 ("BZFlag", methods, NULL);
	Py_INCREF (Py_None);
	Py_INCREF (Py_False);
	Py_INCREF (Py_True);

	// Create and add submodules
	event_sub = new Event ();
	team_sub  = new Team ();

	PyModule_AddObject (module, "Event", event_sub->GetSubModule ());
	PyModule_AddObject (module, "Team",   team_sub->GetSubModule ());

	// Register event handlers
	tick_handler.parent = this;
	bz_registerGeneralEvent (bz_eTickEvent, &tick_handler);

	// Create the dictionary for all the event handlers. Key is the int
	// event ID, value is a list of callables for our callbacks. Marshalling
	// is handled by the individual event handler classes
	event_listeners = PyDict_New ();
	CreateHandlerList (event_listeners, bz_eTickEvent);

	PyModule_AddObject (module, "Events", event_listeners);
}

PyObject *
BZFlag::GetListeners (int event)
{
	PyObject *o = PyInt_FromLong (event);
	PyObject *ret = PyDict_GetItem (event_listeners, o);
	Py_DECREF (o);

	return ret;
}

static PyObject *
SendTextMessage (PyObject *self, PyObject *args, PyObject *keywords)
{
	int to, from;
	char *message;

	static char *kwlist[] = {"to", "from", "message", NULL};

	if (!PyArg_ParseTupleAndKeywords (args, keywords, "iis", kwlist, &to, &from, &message)) {
		fprintf (stderr, "couldn't parse args\n");
		// FIXME - throw error
		return NULL;
	}

	printf ("SendTextMessage (%d, %d, %s)\n", to, from, message);
	bool result = bz_sendTextMessage (to, from, message);
	return Py_None;
}

static PyObject *
FireWorldWeapon (PyObject *self, PyObject *args)
{
	printf ("FireWorldWeapon ()\n");
	return Py_None;
}

static PyObject *
GetCurrentTime (PyObject *self, PyObject *args)
{
	printf ("GetCurrentTime ()\n");
	return Py_None;
}

};
<|endoftext|>


<commit_before>/**************************************************************************\
**
**  tStorm.cpp: Functions for class tStorm.
**
**  A tStorm object generates random storms assuming an exponential
**  distribution of rainfall intensity, storm duration, and time to the
**  next storm. It is essentially an implementation of the model of
**  P. Eagleson, 1978b, Water Resources Research. Its services include
**  reading the necessary parameters from a tInputFile, generating a new
**  storm, and reporting its various values.
**
**  $Id: tStorm.cpp,v 1.17 2000-03-14 16:54:42 gtucker Exp $
\**************************************************************************/

#include <math.h>
#include "../Mathutil/mathutil.h"
#include "tStorm.h"

/**************************************************************************\
**
**  tStorm::tStorm:  Constructor for storms. The default constructor
**                   assigns a value of unity to storm depth, duration,
**                   and interstorm duration. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( int optvar )
{
   optVariable = optvar;
   optSinVar = 0;
   pMean = 1.0;
   stdurMean = 1.0;
   istdurMean = 1.0;
   p = 1.0;
   stdur = 1.0;
   istdur = 1.0;
   endtm = 999999999999999;
   //srand( 0 );
}

/**************************************************************************\
**
**  tStorm::tStorm:  The constructor that's really used assigns values for
**                   mean storm depth, duration, and interstorm duration,
**                   initializes current depth, etc, to the mean values,
**                   and initializes the random number generator. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( double mp, double ms, double mis, unsigned sd, int optvar, double et )
{
   optVariable = optvar;
   optSinVar = 0;
   pMean = mp;
   stdurMean = ms;
   istdurMean = mis;
   p = pMean;
   stdur = stdurMean;
   istdur = istdurMean;
   seed = sd;
   endtm = et;
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::tStorm
**
**  Alternative constructor that reads parameters directly from a tInputFile
**  object. Reads option for variable storms (normally this is "yes"---that's
**  the point of these objects---but a user may wish to switch off variation
**  as a test), mean values for rainfall intensity, duration, and interstorm
**  period, and a random seed to initialize the random number generator.
**    Also reads an option for long-term sinusoidal variations in the mean
**  values, and if the option is selected, reads the relevant parameters.
**  Variables p0, stdur0, and istdur0 are the mean values of the means;
**  pdev, stdurdev, and istdurdev are the range of variation (e.g., if pMean
**  were to fluctuate between 5 and 10, p0 would be 7.5 and pdev 2.5).
**
**  Modifications:
**   - 3/00 initialization now includes creation of ".storm" file for storm
**     history (GT)
**
\**************************************************************************/
tStorm::tStorm( tInputFile &infile )
{
   // Read + set parameters for storm intensity, duration, and spacing
   optVariable = infile.ReadItem( optVariable, "OPTVAR" );
   pMean = infile.ReadItem( pMean, "PMEAN" );
   stdurMean = infile.ReadItem( stdurMean, "STDUR" );
   istdurMean = infile.ReadItem( istdurMean, "ISTDUR" );
   p = pMean;
   stdur = stdurMean;
   istdur = istdurMean;

   endtm = infile.ReadItem( endtm, "RUNTIME" );
   double help;

   help = infile.ReadItem( help, "OPTREADINPUT" );
   if(help>0){
      help = infile.ReadItem( help, "INPUTTIME" );
      endtm += help;
   }

   // Handle option for sinuidoil variation in means
   optSinVar = infile.ReadItem( optSinVar, "OPTSINVAR" );
   if( optSinVar )
   {
      p0 = pMean;
      stdur0 = stdurMean;
      istdur0 = istdurMean;
      twoPiLam = (2.0*PI)/(infile.ReadItem( twoPiLam, "PERIOD" ));
      pdev = infile.ReadItem( pdev, "MAXPMEAN" ) - pMean;
      if( pdev<0 ) cerr << "Warning: MAXPMEAN < PMEAN !";
      else if( pdev > pMean ) cerr << "Warning: MINPMEAN < 0 !";
      stdurdev = infile.ReadItem( stdurdev, "MAXSTDURMN" ) - stdurMean;
      if( stdurdev<0 ) cerr << "Warning: MAXSTDURMN < STDURMN !";
      else if( stdurdev > stdurMean ) cerr << "Warning: MINSTDURMN < 0 !";
      istdurdev = infile.ReadItem( istdurdev, "MAXISTDURMN" ) - istdurMean;
      if( istdurdev<0 ) cerr << "Warning: MAXISTDURMN < ISTDURMN !";
      else if( istdurdev > istdurMean ) cerr << "Warning: MINISTDURMN < 0 !";
   }

   // If variable storms used, create a file for writing them
   if( optVariable )
   {
      char fname[87];
      infile.ReadItem( fname, "OUTFILENAME" );
      strcat( fname, ".storm" );
      stormfile.open( fname );
      if( !stormfile.good() )
          cerr << "Warning: unable to create storm data file '"
               << fname << "'\n";
   }

   // Read and initialize seed for random number generation
   seed = infile.ReadItem( seed, "SEED" );
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::GenerateStorm
**
**  Generates a new storm by drawing new values of p, stdur, and istdur from
**  an exponential distribution and updating the random seed.
**    If the minp parameter is greater than zero, the function will keep
**  picking storms until it finds one with p>minp. The total elapsed time,
**  including the rejected storms and their associated interstorm periods,
**  is stored istdur.
**
**  Inputs:      minp -- minimum value of rainfall rate p (default 0)
**               mind -- minimum storm depth to produce runoff (default 0)
**               tm -- current time in simulation
**  Members updated:  p, stdur, istdur take on new random values (if optVar)
**                    pMean, stdurMean, istdurMean adjusted (if optSinVar)
**  Assumptions:  pMean > 0
**
**  Modifications:
**   - changed AND to OR in while loop, GT 5/99
**   - added to while loop an additional check to see if time has run out,
**     NG 2/00
**   - added output of time, storm intensity, & duration to ".storm" file
**     GT 3/00
**
\**************************************************************************/
void tStorm::GenerateStorm( double tm, double minp, double mind )
{
   // If option for sinusoidal variation is on, adjust the means
   // Also set values for current storm to the means, in case option for
   // random storms is off.
   if( optSinVar )
   {
      double sinfn = sin( tm*twoPiLam );
      pMean = p0 + pdev*sinfn;
      //cout << "pMean = " << pMean << endl;
      stdurMean = stdur0 + stdurdev*sinfn;
      istdurMean = istdur0 + istdurdev*sinfn;
      p = pMean;
      stdur = stdurMean;
      istdur = istdurMean;
   }

   // If option for random storms is on, pick a storm at random.
   // Keep picking and accumulating time until the storm depth or intensity
   // is greater than the minimum value needed to produce runoff.

   if( optVariable )
   {
      stdur = 0;
      istdur = 0;
      do
      {
         p = pMean*ExpDev( &seed );
         istdur += istdurMean*ExpDev( &seed ) + stdur;
         stdur = stdurMean*ExpDev( &seed );
         //cout << "P " << p << "  ST " << stdur << "  IST " << istdur
         //     << "  DP " << p*stdur << " minp " << minp << " mind " <<mind <<
         //            endl;
         //srand( seed );
      } while( (p<=minp || (p*stdur)<=mind) && (tm+istdur+stdur<endtm) );
      stormfile << tm << " " << p << " " << stdur << endl;
   }
}

/**************************************************************************\
**
**  tStorm::ExpDev:  Finds a random number with an exponential distribution
**                   (adapted from Numerical Recipes).
**
\**************************************************************************/
double tStorm::ExpDev( long *idum )
{
    double dum;

    do
        dum = ran3( idum );
    while( dum==0.0 );
    return -log(dum);
}

/**************************************************************************\
**
**  tStorm "get" routines: return various variables
**
\**************************************************************************/

double tStorm::getStormDuration() { return stdur; }
double tStorm::interstormDur() { return istdur; }
double tStorm::getRainrate() { return p; }
double tStorm::getMeanStormDur() const {return stdurMean;}
double tStorm::getMeanInterstormDur() const {return istdurMean;}
double tStorm::getMeanPrecip() const {return pMean;}

/**************************************************************************\
**
**  GammaDev
**
**  Returns a random variable drawn from a Gamma distribution with parameter m.
**
**  (Note: not actually called; provided for future use).
**
\**************************************************************************/
double tStorm::GammaDev(double m, long * idum)
{
  double x, y,z, c,t,b,u,w,v;

  if (m<1)
    {
      c = 1/m;
      t = 0.07 + 0.75*sqrt(1-m);
      b = 1 + exp(-t)*m/t;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum);
          w = ran3(idum);
          v = b *u;
          if (v<=1)
            {
              x  = t * pow(v, c);
              accept = ((w<=((2-x)/(2+x))) || (w<=exp(-x)));
            }
          else
            {
              x = -log(c*t*(b-v));
              y = x/t;
              accept = (((w*(m + y - m*y)) <= 1) || (w<= ( pow(y, (m-1)))));
            }
        }
    }
  else
    {
      b = m-1;
      c = 3*m - 0.75;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum); v = ran3(idum);
          w = u* ( 1-u);
          y = sqrt(c/w) * (u - 0.5);
          x = b + y;
          if ( x>= 0)
            {
              z = 64*( pow(w,3))*v*v;
              accept = (z <= ( 1 - 2*y*y/x)) || ( log(z) <= (2*(b*log(x/b) - y)));
            }
        }
    }
  return x;
}

<commit_msg>make g++ happy: add <string.h> and make sure it doesn't think big values like 10^9 are integers<commit_after>/**************************************************************************\
**
**  tStorm.cpp: Functions for class tStorm.
**
**  A tStorm object generates random storms assuming an exponential
**  distribution of rainfall intensity, storm duration, and time to the
**  next storm. It is essentially an implementation of the model of
**  P. Eagleson, 1978b, Water Resources Research. Its services include
**  reading the necessary parameters from a tInputFile, generating a new
**  storm, and reporting its various values.
**
**  $Id: tStorm.cpp,v 1.18 2000-05-10 19:46:11 gtucker Exp $
\**************************************************************************/

#include <math.h>
#include <string.h>
#include "../Mathutil/mathutil.h"
#include "tStorm.h"

/**************************************************************************\
**
**  tStorm::tStorm:  Constructor for storms. The default constructor
**                   assigns a value of unity to storm depth, duration,
**                   and interstorm duration. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( int optvar )
{
   optVariable = optvar;
   optSinVar = 0;
   pMean = 1.0;
   stdurMean = 1.0;
   istdurMean = 1.0;
   p = 1.0;
   stdur = 1.0;
   istdur = 1.0;
   endtm = 1.0e9;
   //srand( 0 );
}

/**************************************************************************\
**
**  tStorm::tStorm:  The constructor that's really used assigns values for
**                   mean storm depth, duration, and interstorm duration,
**                   initializes current depth, etc, to the mean values,
**                   and initializes the random number generator. (Note:
**                   this constructor does not allow option for sinusoidal
**                   variation in means).
**
\**************************************************************************/
tStorm::tStorm( double mp, double ms, double mis, unsigned sd, int optvar, double et )
{
   optVariable = optvar;
   optSinVar = 0;
   pMean = mp;
   stdurMean = ms;
   istdurMean = mis;
   p = pMean;
   stdur = stdurMean;
   istdur = istdurMean;
   seed = sd;
   endtm = et;
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::tStorm
**
**  Alternative constructor that reads parameters directly from a tInputFile
**  object. Reads option for variable storms (normally this is "yes"---that's
**  the point of these objects---but a user may wish to switch off variation
**  as a test), mean values for rainfall intensity, duration, and interstorm
**  period, and a random seed to initialize the random number generator.
**    Also reads an option for long-term sinusoidal variations in the mean
**  values, and if the option is selected, reads the relevant parameters.
**  Variables p0, stdur0, and istdur0 are the mean values of the means;
**  pdev, stdurdev, and istdurdev are the range of variation (e.g., if pMean
**  were to fluctuate between 5 and 10, p0 would be 7.5 and pdev 2.5).
**
**  Modifications:
**   - 3/00 initialization now includes creation of ".storm" file for storm
**     history (GT)
**
\**************************************************************************/
tStorm::tStorm( tInputFile &infile )
{
   // Read + set parameters for storm intensity, duration, and spacing
   optVariable = infile.ReadItem( optVariable, "OPTVAR" );
   pMean = infile.ReadItem( pMean, "PMEAN" );
   stdurMean = infile.ReadItem( stdurMean, "STDUR" );
   istdurMean = infile.ReadItem( istdurMean, "ISTDUR" );
   p = pMean;
   stdur = stdurMean;
   istdur = istdurMean;

   endtm = infile.ReadItem( endtm, "RUNTIME" );
   double help;

   help = infile.ReadItem( help, "OPTREADINPUT" );
   if(help>0){
      help = infile.ReadItem( help, "INPUTTIME" );
      endtm += help;
   }

   // Handle option for sinuidoil variation in means
   optSinVar = infile.ReadItem( optSinVar, "OPTSINVAR" );
   if( optSinVar )
   {
      p0 = pMean;
      stdur0 = stdurMean;
      istdur0 = istdurMean;
      twoPiLam = (2.0*PI)/(infile.ReadItem( twoPiLam, "PERIOD" ));
      pdev = infile.ReadItem( pdev, "MAXPMEAN" ) - pMean;
      if( pdev<0 ) cerr << "Warning: MAXPMEAN < PMEAN !";
      else if( pdev > pMean ) cerr << "Warning: MINPMEAN < 0 !";
      stdurdev = infile.ReadItem( stdurdev, "MAXSTDURMN" ) - stdurMean;
      if( stdurdev<0 ) cerr << "Warning: MAXSTDURMN < STDURMN !";
      else if( stdurdev > stdurMean ) cerr << "Warning: MINSTDURMN < 0 !";
      istdurdev = infile.ReadItem( istdurdev, "MAXISTDURMN" ) - istdurMean;
      if( istdurdev<0 ) cerr << "Warning: MAXISTDURMN < ISTDURMN !";
      else if( istdurdev > istdurMean ) cerr << "Warning: MINISTDURMN < 0 !";
   }

   // If variable storms used, create a file for writing them
   if( optVariable )
   {
      char fname[87];
      infile.ReadItem( fname, "OUTFILENAME" );
      strcat( fname, ".storm" );
      stormfile.open( fname );
      if( !stormfile.good() )
          cerr << "Warning: unable to create storm data file '"
               << fname << "'\n";
   }

   // Read and initialize seed for random number generation
   seed = infile.ReadItem( seed, "SEED" );
   //srand( seed );
}

/**************************************************************************\
**
**  tStorm::GenerateStorm
**
**  Generates a new storm by drawing new values of p, stdur, and istdur from
**  an exponential distribution and updating the random seed.
**    If the minp parameter is greater than zero, the function will keep
**  picking storms until it finds one with p>minp. The total elapsed time,
**  including the rejected storms and their associated interstorm periods,
**  is stored istdur.
**
**  Inputs:      minp -- minimum value of rainfall rate p (default 0)
**               mind -- minimum storm depth to produce runoff (default 0)
**               tm -- current time in simulation
**  Members updated:  p, stdur, istdur take on new random values (if optVar)
**                    pMean, stdurMean, istdurMean adjusted (if optSinVar)
**  Assumptions:  pMean > 0
**
**  Modifications:
**   - changed AND to OR in while loop, GT 5/99
**   - added to while loop an additional check to see if time has run out,
**     NG 2/00
**   - added output of time, storm intensity, & duration to ".storm" file
**     GT 3/00
**
\**************************************************************************/
void tStorm::GenerateStorm( double tm, double minp, double mind )
{
   // If option for sinusoidal variation is on, adjust the means
   // Also set values for current storm to the means, in case option for
   // random storms is off.
   if( optSinVar )
   {
      double sinfn = sin( tm*twoPiLam );
      pMean = p0 + pdev*sinfn;
      //cout << "pMean = " << pMean << endl;
      stdurMean = stdur0 + stdurdev*sinfn;
      istdurMean = istdur0 + istdurdev*sinfn;
      p = pMean;
      stdur = stdurMean;
      istdur = istdurMean;
   }

   // If option for random storms is on, pick a storm at random.
   // Keep picking and accumulating time until the storm depth or intensity
   // is greater than the minimum value needed to produce runoff.

   if( optVariable )
   {
      stdur = 0;
      istdur = 0;
      do
      {
         p = pMean*ExpDev( &seed );
         istdur += istdurMean*ExpDev( &seed ) + stdur;
         stdur = stdurMean*ExpDev( &seed );
         //cout << "P " << p << "  ST " << stdur << "  IST " << istdur
         //     << "  DP " << p*stdur << " minp " << minp << " mind " <<mind <<
         //            endl;
         //srand( seed );
      } while( (p<=minp || (p*stdur)<=mind) && (tm+istdur+stdur<endtm) );
      stormfile << tm << " " << p << " " << stdur << endl;
   }
}

/**************************************************************************\
**
**  tStorm::ExpDev:  Finds a random number with an exponential distribution
**                   (adapted from Numerical Recipes).
**
\**************************************************************************/
double tStorm::ExpDev( long *idum )
{
    double dum;

    do
        dum = ran3( idum );
    while( dum==0.0 );
    return -log(dum);
}

/**************************************************************************\
**
**  tStorm "get" routines: return various variables
**
\**************************************************************************/

double tStorm::getStormDuration() { return stdur; }
double tStorm::interstormDur() { return istdur; }
double tStorm::getRainrate() { return p; }
double tStorm::getMeanStormDur() const {return stdurMean;}
double tStorm::getMeanInterstormDur() const {return istdurMean;}
double tStorm::getMeanPrecip() const {return pMean;}

/**************************************************************************\
**
**  GammaDev
**
**  Returns a random variable drawn from a Gamma distribution with parameter m.
**
**  (Note: not actually called; provided for future use).
**
\**************************************************************************/
double tStorm::GammaDev(double m, long * idum)
{
  double x, y,z, c,t,b,u,w,v;

  if (m<1)
    {
      c = 1/m;
      t = 0.07 + 0.75*sqrt(1-m);
      b = 1 + exp(-t)*m/t;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum);
          w = ran3(idum);
          v = b *u;
          if (v<=1)
            {
              x  = t * pow(v, c);
              accept = ((w<=((2-x)/(2+x))) || (w<=exp(-x)));
            }
          else
            {
              x = -log(c*t*(b-v));
              y = x/t;
              accept = (((w*(m + y - m*y)) <= 1) || (w<= ( pow(y, (m-1)))));
            }
        }
    }
  else
    {
      b = m-1;
      c = 3*m - 0.75;
      int accept = 0;
      while (accept == 0)
        {
          u = ran3(idum); v = ran3(idum);
          w = u* ( 1-u);
          y = sqrt(c/w) * (u - 0.5);
          x = b + y;
          if ( x>= 0)
            {
              z = 64*( pow(w,3))*v*v;
              accept = (z <= ( 1 - 2*y*y/x)) || ( log(z) <= (2*(b*log(x/b) - y)));
            }
        }
    }
  return x;
}

<|endoftext|>


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

#include "chrome/browser/renderer_host/blob_dispatcher_host.h"

#include "chrome/browser/child_process_security_policy.h"
#include "chrome/browser/chrome_blob_storage_context.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/common/render_messages.h"
#include "googleurl/src/gurl.h"
#include "ipc/ipc_message.h"
#include "webkit/blob/blob_data.h"
#include "webkit/blob/blob_storage_controller.h"

BlobDispatcherHost::BlobDispatcherHost(
    int process_id,
    ChromeBlobStorageContext* blob_storage_context)
    : process_id_(process_id),
      blob_storage_context_(blob_storage_context) {
}

BlobDispatcherHost::~BlobDispatcherHost() {
}

void BlobDispatcherHost::Shutdown() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  // Unregister all the blob URLs that are previously registered in this
  // process.
  for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin();
       iter != blob_urls_.end(); ++iter) {
    blob_storage_context_->controller()->UnregisterBlobUrl(GURL(*iter));
  }
}

bool BlobDispatcherHost::OnMessageReceived(const IPC::Message& message,
                                           bool* msg_is_ok) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  *msg_is_ok = true;
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(BlobDispatcherHost, message, *msg_is_ok)
    IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterBlobUrl, OnRegisterBlobUrl)
    IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterBlobUrlFrom, OnRegisterBlobUrlFrom)
    IPC_MESSAGE_HANDLER(ViewHostMsg_UnregisterBlobUrl, OnUnregisterBlobUrl)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

// Check if the child process has been granted permission to register the files.
bool BlobDispatcherHost::CheckPermission(
    webkit_blob::BlobData* blob_data) const {
  ChildProcessSecurityPolicy* policy =
      ChildProcessSecurityPolicy::GetInstance();
  for (std::vector<webkit_blob::BlobData::Item>::const_iterator iter =
           blob_data->items().begin();
       iter != blob_data->items().end(); ++iter) {
    if (iter->type() == webkit_blob::BlobData::TYPE_FILE) {
      if (!policy->CanReadFile(process_id_, iter->file_path()))
        return false;
    }
  }
  return true;
}

void BlobDispatcherHost::OnRegisterBlobUrl(
    const GURL& url, const scoped_refptr<webkit_blob::BlobData>& blob_data) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  if (!CheckPermission(blob_data.get()))
    return;
  blob_storage_context_->controller()->RegisterBlobUrl(url, blob_data);
  blob_urls_.insert(url.spec());
}

void BlobDispatcherHost::OnRegisterBlobUrlFrom(
    const GURL& url, const GURL& src_url) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  blob_storage_context_->controller()->RegisterBlobUrlFrom(url, src_url);
  blob_urls_.insert(src_url.spec());
}

void BlobDispatcherHost::OnUnregisterBlobUrl(const GURL& url) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  blob_storage_context_->controller()->UnregisterBlobUrl(url);
  blob_urls_.erase(url.spec());
}
<commit_msg>Fix a leak. We weren't keeping track of 'public' blob urls properly.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/renderer_host/blob_dispatcher_host.h"

#include "chrome/browser/child_process_security_policy.h"
#include "chrome/browser/chrome_blob_storage_context.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/common/render_messages.h"
#include "googleurl/src/gurl.h"
#include "ipc/ipc_message.h"
#include "webkit/blob/blob_data.h"
#include "webkit/blob/blob_storage_controller.h"

BlobDispatcherHost::BlobDispatcherHost(
    int process_id,
    ChromeBlobStorageContext* blob_storage_context)
    : process_id_(process_id),
      blob_storage_context_(blob_storage_context) {
}

BlobDispatcherHost::~BlobDispatcherHost() {
}

void BlobDispatcherHost::Shutdown() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  // Unregister all the blob URLs that are previously registered in this
  // process.
  for (base::hash_set<std::string>::const_iterator iter = blob_urls_.begin();
       iter != blob_urls_.end(); ++iter) {
    blob_storage_context_->controller()->UnregisterBlobUrl(GURL(*iter));
  }
}

bool BlobDispatcherHost::OnMessageReceived(const IPC::Message& message,
                                           bool* msg_is_ok) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));

  *msg_is_ok = true;
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(BlobDispatcherHost, message, *msg_is_ok)
    IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterBlobUrl, OnRegisterBlobUrl)
    IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterBlobUrlFrom, OnRegisterBlobUrlFrom)
    IPC_MESSAGE_HANDLER(ViewHostMsg_UnregisterBlobUrl, OnUnregisterBlobUrl)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

// Check if the child process has been granted permission to register the files.
bool BlobDispatcherHost::CheckPermission(
    webkit_blob::BlobData* blob_data) const {
  ChildProcessSecurityPolicy* policy =
      ChildProcessSecurityPolicy::GetInstance();
  for (std::vector<webkit_blob::BlobData::Item>::const_iterator iter =
           blob_data->items().begin();
       iter != blob_data->items().end(); ++iter) {
    if (iter->type() == webkit_blob::BlobData::TYPE_FILE) {
      if (!policy->CanReadFile(process_id_, iter->file_path()))
        return false;
    }
  }
  return true;
}

void BlobDispatcherHost::OnRegisterBlobUrl(
    const GURL& url, const scoped_refptr<webkit_blob::BlobData>& blob_data) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  if (!CheckPermission(blob_data.get()))
    return;
  blob_storage_context_->controller()->RegisterBlobUrl(url, blob_data);
  blob_urls_.insert(url.spec());
}

void BlobDispatcherHost::OnRegisterBlobUrlFrom(
    const GURL& url, const GURL& src_url) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  blob_storage_context_->controller()->RegisterBlobUrlFrom(url, src_url);
  blob_urls_.insert(url.spec());
}

void BlobDispatcherHost::OnUnregisterBlobUrl(const GURL& url) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  blob_storage_context_->controller()->UnregisterBlobUrl(url);
  blob_urls_.erase(url.spec());
}
<|endoftext|>


<commit_before>/*
 * opencog/cython/PythonModule.h
 *
 * Copyright (C) 2013 by OpenCog Foundation
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "PyIncludeWrapper.h"

#include <boost/filesystem/operations.hpp>

#include <opencog/util/Config.h>
#include <opencog/util/misc.h>
#include <opencog/util/foreach.h>
#include <opencog/atomspace/AtomSpace.h>

#include "PyMindAgent.h"
#include "PyRequest.h"
#include "PythonEval.h"
#include "PythonModule.h"

#include "agent_finder_types.h"
#include "agent_finder_api.h"

using std::vector;
using std::string;

using namespace opencog;

//#define DPRINTF printf
#define DPRINTF(...)

DECLARE_MODULE(PythonModule);

static const char* DEFAULT_PYTHON_MODULE_PATHS[] =
{
    PROJECT_BINARY_DIR"/opencog/cython", // bindings
    PROJECT_SOURCE_DIR"/opencog/python", // opencog modules written in python
    PROJECT_SOURCE_DIR"/tests/cython",   // for testing
    DATADIR"/python",                    // install directory
    #ifndef WIN32
    "/usr/local/share/opencog/python",
    "/usr/share/opencog/python",
    #endif // !WIN32
    NULL
};

// Factories

Agent* PythonAgentFactory::create() const
{
    logger().info() << "Creating python agent " << _pySrcModuleName << "." << _pyClassName;
    PyMindAgent* pma = new PyMindAgent(_pySrcModuleName, _pyClassName);
    return pma;
}

Request* PythonRequestFactory::create() const
{
    logger().info() << "Creating python request " << _pySrcModuleName << "." << _pyClassName;
    PyRequest* pma = new PyRequest(_pySrcModuleName, _pyClassName, _cci);
    return pma;
}

// ------

PythonModule::PythonModule() : Module()
{
}

static bool already_loaded = false;

PythonModule::~PythonModule()
{
    logger().info("[PythonModule] destructor");
    unregisterAgentsAndRequests();
    do_load_py_unregister();

    // PyFinalize crashes unless we carefully restore stuff...
    PyEval_AcquireLock();
    PyThreadState_Swap(_mainstate);
    PyErr_Clear();
    Py_Finalize();
    already_loaded = false;
}

bool PythonModule::unregisterAgentsAndRequests()
{
    // Requires GIL
    foreach (std::string s, _agentNames) {
        DPRINTF("Deleting all instances of %s\n", s.c_str());
        cogserver().unregisterAgent(s);
    }
    foreach (std::string s, _requestNames) {
        DPRINTF("Unregistering requests of id %s\n", s.c_str());
        cogserver().unregisterRequest(s);
    }

    return true;
}

void PythonModule::init()
{
    // Avoid hard crash if already loaded.
    if (already_loaded) return;
    already_loaded = true;

    logger().info("[PythonModule] Initialising Python CogServer module.");

    // Start up Python (this init method skips registering signal handlers)
    if (!Py_IsInitialized())
        Py_InitializeEx(0);
    if (!PyEval_ThreadsInitialized()) {
        PyEval_InitThreads();
        // Without this, pyFinalize() crashes
        _mainstate = PyThreadState_Get();
        // Without this, pyshell hangs and does nothing.
        PyEval_ReleaseLock();
    }

    // Add our module directories to the Python interprator's path
    const char** config_paths = DEFAULT_PYTHON_MODULE_PATHS;

    PyObject* sysPath = PySys_GetObject((char*)"path");

    // Default paths for python modules
    for (int i = 0; config_paths[i] != NULL; ++i) {
        boost::filesystem::path modulePath(config_paths[i]);
        if (boost::filesystem::exists(modulePath))
            PyList_Append(sysPath, PyString_FromString(modulePath.string().c_str()));
    }

    // Add custom paths for python modules from the config file if available
    if (config().has("PYTHON_EXTENSION_DIRS")) {
        std::vector<std::string> pythonpaths;
        // For debugging current path
        tokenize(config()["PYTHON_EXTENSION_DIRS"], std::back_inserter(pythonpaths), ", ");
        for (std::vector<std::string>::const_iterator it = pythonpaths.begin();
             it != pythonpaths.end(); ++it) {
            boost::filesystem::path modulePath(*it);
            if (boost::filesystem::exists(modulePath)) {
                PyList_Append(sysPath, PyString_FromString(modulePath.string().c_str()));
            } else {
                logger().warn("PythonEval::%s Could not find custom python extension directory: %s ",
                               __FUNCTION__,
                               (*it).c_str()
                               );
            }
        }
    }

    if (import_agent_finder() == -1) {
        PyErr_Print();
        logger().error() << "[PythonModule] Failed to load helper python module";
        return;
    }
    logger().debug("Python sys.path is: " + get_path_as_string());

    if (config().has("PYTHON_PRELOAD")) preloadModules();
    do_load_py_register();

}

bool PythonModule::preloadModules()
{
    // requires GIL
    std::vector<std::string> pythonmodules;
    tokenize(config()["PYTHON_PRELOAD"], std::back_inserter(pythonmodules), ", ");
    for (std::vector<std::string>::const_iterator it = pythonmodules.begin();
         it != pythonmodules.end(); ++it) {
        std::list<std::string> args;
        args.push_back(*it);
        logger().info("[PythonModule] Preloading python module " + *it);
        std::string result = do_load_py(NULL,args);
        logger().info("[PythonModule] " + result);
    }
    return true;
}

/// do_load_py -- load python code, given a file name. (Implements the loadpy command)
///
/// It is expected that the file contains a python module. The module
/// should implement either a mind-agent, or it should contain a 'request'
/// (shell command, written in python). Mind agents must inherit from
/// the python class opencog.cogserver.MindAgent, while requests/commnds
/// must inherit from opencog.cogserver.Request
//
std::string PythonModule::do_load_py(Request *dummy, std::list<std::string> args)
{
    if (args.size() == 0) return "Please specify Python module to load.";
    std::string moduleName = args.front();

    std::ostringstream oss;
    if (moduleName.substr(moduleName.size()-3,3) == ".py") {
        oss << "Warning: Python module name should be "
            << "passed without .py extension" << std::endl;
        moduleName.replace(moduleName.size()-3,3,"");
    }

    requests_and_agents_t thingsInModule = load_req_agent_module(moduleName);
    if (thingsInModule.err_string.size() > 0) {
        return thingsInModule.err_string;
    }

    // If there are agents, load them.
    if (thingsInModule.agents.size() > 0) {
        bool first = true;
        oss << "Python MindAgents found: ";
        foreach(std::string s, thingsInModule.agents) {
            if (!first) {
                oss << ", ";
                first = false;
            }

            // Register agent with cogserver using dotted name:
            // module.AgentName
            std::string dottedName = moduleName + "." + s;

            // register the agent with a custom factory that knows how to
            // instantiate new Python MindAgents
            cogserver().registerAgent(dottedName, new PythonAgentFactory(moduleName,s));

            // save a list of Python agents that we've added to the CogServer
            _agentNames.push_back(dottedName);
            oss << s;
        }
        oss << "." << std::endl;
    } else {
        oss << "No subclasses of opencog.cogserver.MindAgent found.\n";
    }

    // Now load the commands/requests, if any.
    if (thingsInModule.requests.size() > 0) {
        bool first = true;
        oss << "Python Requests found: ";
        for (size_t i=0; i< thingsInModule.requests.size(); i++) {
            std::string s = thingsInModule.requests[i];
            std::string short_desc = thingsInModule.req_summary[i];
            std::string long_desc = thingsInModule.req_description[i];
            bool is_shell = thingsInModule.req_is_shell[i];

            // CogServer commands in Python
            // Register request with cogserver using dotted name: module.RequestName
            std::string dottedName = moduleName + "." + s;
            // register the agent with a custom factory that knows how to
            cogserver().registerRequest(dottedName,
                new PythonRequestFactory(moduleName, s, short_desc, long_desc, is_shell));
            // save a list of Python agents that we've added to the CogServer
            _requestNames.push_back(dottedName);

            if (!first) { oss << ", "; first = false; }
            oss << s;
        }
        oss << ".";
    } else {
        oss << "No subclasses of opencog.cogserver.Request found.\n";
    }

    // Return info on what requests and mindagents were found
    // This gets printed out to the user at the shell prompt.
    return oss.str();
}

<commit_msg>Temporarily calling the instance member of PythonEval in PytonModule to address the issues with python sys object<commit_after>/*
 * opencog/cython/PythonModule.h
 *
 * Copyright (C) 2013 by OpenCog Foundation
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#include "PyIncludeWrapper.h"

#include <boost/filesystem/operations.hpp>

#include <opencog/util/Config.h>
#include <opencog/util/misc.h>
#include <opencog/util/foreach.h>
#include <opencog/atomspace/AtomSpace.h>

#include "PyMindAgent.h"
#include "PyRequest.h"
#include "PythonEval.h"
#include "PythonModule.h"

#include "agent_finder_types.h"
#include "agent_finder_api.h"

using std::vector;
using std::string;

using namespace opencog;

//#define DPRINTF printf
#define DPRINTF(...)

DECLARE_MODULE(PythonModule);

static const char* DEFAULT_PYTHON_MODULE_PATHS[] =
{
    PROJECT_BINARY_DIR"/opencog/cython", // bindings
    PROJECT_SOURCE_DIR"/opencog/python", // opencog modules written in python
    PROJECT_SOURCE_DIR"/tests/cython",   // for testing
    DATADIR"/python",                    // install directory
    #ifndef WIN32
    "/usr/local/share/opencog/python",
    "/usr/share/opencog/python",
    #endif // !WIN32
    NULL
};

// Factories

Agent* PythonAgentFactory::create() const
{
    logger().info() << "Creating python agent " << _pySrcModuleName << "." << _pyClassName;
    PyMindAgent* pma = new PyMindAgent(_pySrcModuleName, _pyClassName);
    return pma;
}

Request* PythonRequestFactory::create() const
{
    logger().info() << "Creating python request " << _pySrcModuleName << "." << _pyClassName;
    PyRequest* pma = new PyRequest(_pySrcModuleName, _pyClassName, _cci);
    return pma;
}

// ------

PythonModule::PythonModule() : Module()
{
}

static bool already_loaded = false;

PythonModule::~PythonModule()
{
    logger().info("[PythonModule] destructor");
    unregisterAgentsAndRequests();
    do_load_py_unregister();

    // PyFinalize crashes unless we carefully restore stuff...
    PyEval_AcquireLock();
    PyThreadState_Swap(_mainstate);
    PyErr_Clear();
    Py_Finalize();
    already_loaded = false;
}

bool PythonModule::unregisterAgentsAndRequests()
{
    // Requires GIL
    foreach (std::string s, _agentNames) {
        DPRINTF("Deleting all instances of %s\n", s.c_str());
        cogserver().unregisterAgent(s);
    }
    foreach (std::string s, _requestNames) {
        DPRINTF("Unregistering requests of id %s\n", s.c_str());
        cogserver().unregisterRequest(s);
    }

    return true;
}

void PythonModule::init()
{
    // Avoid hard crash if already loaded.
    if (already_loaded) return;
    already_loaded = true;

    logger().info("[PythonModule] Initialising Python CogServer module.");

    // Start up Python (this init method skips registering signal handlers)
    if (!Py_IsInitialized())
        Py_InitializeEx(0);
    if (!PyEval_ThreadsInitialized()) {
        PyEval_InitThreads();
        // Without this, pyFinalize() crashes
        _mainstate = PyThreadState_Get();
        // Without this, pyshell hangs and does nothing.
        PyEval_ReleaseLock();
    }

    // Add our module directories to the Python interprator's path
    const char** config_paths = DEFAULT_PYTHON_MODULE_PATHS;

    PyObject* sysPath = PySys_GetObject((char*)"path");

    // Default paths for python modules
    for (int i = 0; config_paths[i] != NULL; ++i) {
        boost::filesystem::path modulePath(config_paths[i]);
        if (boost::filesystem::exists(modulePath))
            PyList_Append(sysPath, PyString_FromString(modulePath.string().c_str()));
    }

    // Add custom paths for python modules from the config file if available
    if (config().has("PYTHON_EXTENSION_DIRS")) {
        std::vector<std::string> pythonpaths;
        // For debugging current path
        tokenize(config()["PYTHON_EXTENSION_DIRS"], std::back_inserter(pythonpaths), ", ");
        for (std::vector<std::string>::const_iterator it = pythonpaths.begin();
             it != pythonpaths.end(); ++it) {
            boost::filesystem::path modulePath(*it);
            if (boost::filesystem::exists(modulePath)) {
                PyList_Append(sysPath, PyString_FromString(modulePath.string().c_str()));
            } else {
                logger().warn("PythonEval::%s Could not find custom python extension directory: %s ",
                               __FUNCTION__,
                               (*it).c_str()
                               );
            }
        }
    }

    PythonEval::instance();

    if (import_agent_finder() == -1) {
        PyErr_Print();
        logger().error() << "[PythonModule] Failed to load helper python module";
        return;
    }
    logger().debug("Python sys.path is: " + get_path_as_string());

    if (config().has("PYTHON_PRELOAD")) preloadModules();
    do_load_py_register();

}

bool PythonModule::preloadModules()
{
    // requires GIL
    std::vector<std::string> pythonmodules;
    tokenize(config()["PYTHON_PRELOAD"], std::back_inserter(pythonmodules), ", ");
    for (std::vector<std::string>::const_iterator it = pythonmodules.begin();
         it != pythonmodules.end(); ++it) {
        std::list<std::string> args;
        args.push_back(*it);
        logger().info("[PythonModule] Preloading python module " + *it);
        std::string result = do_load_py(NULL,args);
        logger().info("[PythonModule] " + result);
    }
    return true;
}

/// do_load_py -- load python code, given a file name. (Implements the loadpy command)
///
/// It is expected that the file contains a python module. The module
/// should implement either a mind-agent, or it should contain a 'request'
/// (shell command, written in python). Mind agents must inherit from
/// the python class opencog.cogserver.MindAgent, while requests/commnds
/// must inherit from opencog.cogserver.Request
//
std::string PythonModule::do_load_py(Request *dummy, std::list<std::string> args)
{
    if (args.size() == 0) return "Please specify Python module to load.";
    std::string moduleName = args.front();

    std::ostringstream oss;
    if (moduleName.substr(moduleName.size()-3,3) == ".py") {
        oss << "Warning: Python module name should be "
            << "passed without .py extension" << std::endl;
        moduleName.replace(moduleName.size()-3,3,"");
    }

    requests_and_agents_t thingsInModule = load_req_agent_module(moduleName);
    if (thingsInModule.err_string.size() > 0) {
        return thingsInModule.err_string;
    }

    // If there are agents, load them.
    if (thingsInModule.agents.size() > 0) {
        bool first = true;
        oss << "Python MindAgents found: ";
        foreach(std::string s, thingsInModule.agents) {
            if (!first) {
                oss << ", ";
                first = false;
            }

            // Register agent with cogserver using dotted name:
            // module.AgentName
            std::string dottedName = moduleName + "." + s;

            // register the agent with a custom factory that knows how to
            // instantiate new Python MindAgents
            cogserver().registerAgent(dottedName, new PythonAgentFactory(moduleName,s));

            // save a list of Python agents that we've added to the CogServer
            _agentNames.push_back(dottedName);
            oss << s;
        }
        oss << "." << std::endl;
    } else {
        oss << "No subclasses of opencog.cogserver.MindAgent found.\n";
    }

    // Now load the commands/requests, if any.
    if (thingsInModule.requests.size() > 0) {
        bool first = true;
        oss << "Python Requests found: ";
        for (size_t i=0; i< thingsInModule.requests.size(); i++) {
            std::string s = thingsInModule.requests[i];
            std::string short_desc = thingsInModule.req_summary[i];
            std::string long_desc = thingsInModule.req_description[i];
            bool is_shell = thingsInModule.req_is_shell[i];

            // CogServer commands in Python
            // Register request with cogserver using dotted name: module.RequestName
            std::string dottedName = moduleName + "." + s;
            // register the agent with a custom factory that knows how to
            cogserver().registerRequest(dottedName,
                new PythonRequestFactory(moduleName, s, short_desc, long_desc, is_shell));
            // save a list of Python agents that we've added to the CogServer
            _requestNames.push_back(dottedName);

            if (!first) { oss << ", "; first = false; }
            oss << s;
        }
        oss << ".";
    } else {
        oss << "No subclasses of opencog.cogserver.Request found.\n";
    }

    // Return info on what requests and mindagents were found
    // This gets printed out to the user at the shell prompt.
    return oss.str();
}

<|endoftext|>


<commit_before>/*
 * SchemeSmobNew.c
 *
 * Scheme small objects (SMOBS) --creating new atoms -- for opencog.
 *
 * Copyright (c) 2008 Linas Vepstas <linas@linas.org>
 */

#ifdef HAVE_GUILE

#include <vector>

#include <libguile.h>

#include <opencog/atomspace/Atom.h>
#include <opencog/atomspace/AtomSpace.h>
#include <opencog/atomspace/ClassServer.h>
#include <opencog/atomspace/Link.h>
#include <opencog/atomspace/Node.h>
#include <opencog/atomspace/TLB.h>
#include <opencog/guile/SchemeSmob.h>
#include <opencog/server/CogServer.h>

using namespace opencog;

/* ============================================================== */
/**
 * return atom->toString() for the corresponding atom.
 */
std::string SchemeSmob::to_string(SCM node)
{
	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, node))
		return handle_to_string(node);

	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_misc_tag, node))
		return misc_to_string(node);

	return "";
}

std::string SchemeSmob::handle_to_string(Handle h, int indent)
{
	if (Handle::UNDEFINED == h) return "#<Undefined atom handle>";

	Atom *atom = TLB::getAtom(h);
	if (NULL == atom) return "#<Invalid handle>";
	Node *node = dynamic_cast<Node *>(atom);
	Link *link = dynamic_cast<Link *>(atom);

#ifdef CRYPTIC_STYLE
	// output the olde-style opencog notation
	std::string ret = "#<";
	ret += atom->toString();
	ret += ">\n";
#endif

	// Print a scheme expression, so that the output can be saved
	// to file, and then restored, as needed.
	std::string ret = "";
	for (int i=0; i< indent; i++) ret += "   ";
	ret += "(";
	ret += classserver().getTypeName(atom->getType());
	if (node)
	{
		ret += " \"";
		ret += node->getName();
		ret += "\"";

		// Print the truth value only after the node name
		const TruthValue &tv = atom->getTruthValue();
		if (tv != TruthValue::DEFAULT_TV())
		{
			ret += " ";
			ret += tv_to_string (&tv);
		}
		ret += ")";
		return ret;
	}
	else if (link)
	{
		// If there's a truth value, print it before the other atoms
		const TruthValue &tv = atom->getTruthValue();
		if (tv != TruthValue::DEFAULT_TV())
		{
			ret += " ";
			ret += tv_to_string (&tv);
		}

		// print the outgoing link set.
		std::vector<Handle> oset = link->getOutgoingSet();
		unsigned int arity = oset.size();
		for (unsigned int i=0; i<arity; i++)
		{
			ret += " ";
			ret += handle_to_string(oset[i], (0==i)?0:indent+1);
			if (i != arity-1) ret += "\n";
		}
		ret += ")";
		return ret;
	}

	return ret;
}

std::string SchemeSmob::handle_to_string(SCM node)
{
	SCM shandle = SCM_SMOB_OBJECT(node);
	Handle h(scm_to_ulong(shandle));

	return handle_to_string(h, 0) + "\n";
}

/* ============================================================== */
/**
 * Wrapper -- given a handle, return the corresponding scheme object.
 * Note that smobs hold the integer value of the handle, and not the
 * C++ handle object itself.
 */
SCM SchemeSmob::handle_to_scm (Handle h)
{
	SCM shandle = scm_from_ulong(h.value());
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

Handle SchemeSmob::scm_to_handle (SCM sh)
{
	unsigned long uuid = (unsigned long) SCM_SMOB_OBJECT(sh);
	return Handle(uuid);
}

/* ============================================================== */
/**
 * Create a new scheme object, holding the atom handle
 */
SCM SchemeSmob::ss_atom (SCM shandle)
{
	if (scm_is_false(scm_integer_p(shandle)))
		scm_wrong_type_arg_msg("cog-atom", 1, shandle, "integer opencog handle");
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/* ============================================================== */
/**
 * Return handle of atom (the handle is the UUID integer)
 */
SCM SchemeSmob::ss_handle (SCM satom)
{
	if (!SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, satom))
		scm_wrong_type_arg_msg("cog-handle", 1, satom, "opencog atom");

	// Guhh. Handles are no longer unsigned ints, but are classes. :-(
	// return SCM_SMOB_OBJECT(satom);
	unsigned long uuid = (unsigned long) SCM_SMOB_OBJECT(satom);
	return scm_from_ulong(uuid);
}

/* ============================================================== */

SCM SchemeSmob::ss_atom_p (SCM s)
{
	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, s))
		return SCM_BOOL_T;
	return SCM_BOOL_F;
}

/* ============================================================== */
/**
 * Check that the arguments represent a value node, else throw errors.
 * Return the node type.
 */
Type SchemeSmob::validate_atom (SCM stype, const char *subrname)
{
	if (scm_is_true(scm_symbol_p(stype)))
		stype = scm_symbol_to_string(stype);

	if (scm_is_false(scm_string_p(stype)))
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog atom type");

	char * ct = scm_to_locale_string(stype);
	Type t = classserver().getType(ct);
	free(ct);

	// Make sure that the type is good
	if (NOTYPE == t)
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog atom type");

	return t;
}

Type SchemeSmob::validate_node (SCM stype, const char *subrname)
{
	Type t = validate_atom(stype, subrname);

	if (false == classserver().isA(t, NODE))
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog node type");

	return t;
}

std::string SchemeSmob::decode_string (SCM sname, const char *subrname, const char * msg)
{
	if (scm_is_false(scm_string_p(sname)))
		scm_wrong_type_arg_msg(subrname, 2, sname, msg);

	char * cname = scm_to_locale_string(sname);
	std::string name = cname;
	free(cname);
	return name;
}

/**
 * Create a new node, of named type stype, and string name sname
 */
SCM SchemeSmob::ss_new_node (SCM stype, SCM sname, SCM kv_pairs)
{
	Type t = validate_node(stype, "cog-new-node");
	std::string name = decode_string (sname, "cog-new-node", "string name for the node");

	// Now, create the actual node... in the actual atom space.
	const TruthValue *tv = get_tv_from_list(kv_pairs);
	if (!tv) tv = &TruthValue::DEFAULT_TV();

	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->addNode(t, name, *tv);

	return handle_to_scm (h);
}

/**
 * Return the indicated node, of named type stype, and string name sname
 * if it exists; else return nil if it does not exist.
 * If the node exists, *and* a truth value was specified, then change
 * the truth value.
 */
SCM SchemeSmob::ss_node (SCM stype, SCM sname, SCM kv_pairs)
{
	Type t = validate_node(stype, "cog-node");
	std::string name = decode_string (sname, "cog-node", "string name for the node");

	// Now, look for the actual node... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->getHandle(t, name);
	if (!TLB::isValidHandle(h)) return SCM_EOL; // NIL

	// If there was a truth value, change it.
	const TruthValue *tv = get_tv_from_list(kv_pairs);
	if (tv)
	{
		Atom *atom = TLB::getAtom(h);
		atom->setTruthValue(*tv);
	}
	return handle_to_scm (h);
}

/* ============================================================== */
/**
 * Verify that the arguments are appropriate for a link
 */
static Type verify_link (SCM stype, const char * subrname)
{
	if (scm_is_true(scm_symbol_p(stype)))
		stype = scm_symbol_to_string(stype);

	char * ct = scm_to_locale_string(stype);
	Type t = classserver().getType(ct);
	free(ct);

	// Make sure that the type is good
	if (NOTYPE == t)
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog atom type");

	if (false == classserver().isA(t, LINK))
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog link type");

	return t;
}

/**
 * Convert argument into a list of handles.
 */
std::vector<Handle>
SchemeSmob::decode_handle_list (SCM satom_list, const char * subrname)
{
	// Verify that second arg is an actual list. Allow null list.
	// (I think that there are legti null lists, right?)
	if (!scm_is_pair(satom_list) && !scm_is_null(satom_list))
		scm_wrong_type_arg_msg(subrname, 2, satom_list, "a list of atoms");

	const TruthValue *tv = NULL;
	std::vector<Handle> outgoing_set;
	SCM sl = satom_list;
	int pos = 2;
	while (scm_is_pair(sl))
	{
		SCM satom = SCM_CAR(sl);

		// Verify that the contents of the list are actual atoms.
		if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, satom))
		{
			// Get the handle  ... should we check for valid handles here?
			SCM shandle = SCM_SMOB_OBJECT(satom);
			Handle h(scm_to_ulong(shandle));
			outgoing_set.push_back(h);
		}
		else
		{
			// Its legit to have enmbedded truth values, just skip them.
			tv = get_tv_from_list(sl);
			if (tv == NULL)
			{
				// If its not an atom, and its not a truth value, its bad
				scm_wrong_type_arg_msg("cog-new-link", pos, satom, "opencog atom");
			}
		}
		sl = SCM_CDR(sl);
		pos++;
	}

	return outgoing_set;
}

/**
 * Create a new link, of named type stype, holding the indicated atom list
 */
SCM SchemeSmob::ss_new_link (SCM stype, SCM satom_list)
{
	Type t = verify_link (stype, "cog-new-link");

	std::vector<Handle> outgoing_set;
	outgoing_set = decode_handle_list (satom_list, "cog-new-link");

	// Fish out a truth value, if its there.
	const TruthValue *tv = get_tv_from_list(satom_list);
	if (!tv) tv = &TruthValue::DEFAULT_TV();

	// Now, create the actual link... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->addLink(t, outgoing_set, *tv);
	return handle_to_scm (h);
}

/**
 * Return the indicated link, of named type stype, holding the
 * indicated atom list, if it exists; else return nil if
 * it does not exist.
 */
SCM SchemeSmob::ss_link (SCM stype, SCM satom_list)
{
	Type t = verify_link (stype, "cog-link");

	std::vector<Handle> outgoing_set;
	outgoing_set = decode_handle_list (satom_list, "cog-link");

	// Now, look to find the actual link... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->getHandle(t, outgoing_set);
	if (!TLB::isValidHandle(h)) return SCM_EOL; // NIL

	// If there was a truth value, change it.
	const TruthValue *tv = get_tv_from_list(satom_list);
	if (tv)
	{
		Atom *atom = TLB::getAtom(h);
		atom->setTruthValue(*tv);
	}
	return handle_to_scm (h);
}

/* ============================================================== */
/**
 * delete the atom, but only if it has no incoming links.
 */
SCM SchemeSmob::ss_delete (SCM satom)
{
	Handle h = verify_handle(satom, "cog-delete");

	AtomSpace *as = CogServer::getAtomSpace();
	bool rc = as->removeAtom(h, false);

	if (rc) return SCM_BOOL_T;
	return SCM_BOOL_F;
}

/* ============================================================== */
/**
 * delete the atom, and everything pointing to it.
 */
SCM SchemeSmob::ss_delete_recursive (SCM satom)
{
	Handle h = verify_handle(satom, "cog-delete-recursive");

	AtomSpace *as = CogServer::getAtomSpace();
	bool rc = as->removeAtom(h, true);

	if (rc) return SCM_BOOL_T;
	return SCM_BOOL_F;
}

#endif
/* ===================== END OF FILE ============================ */
<commit_msg>bug-fix in how scheme handle uuids are converted to opencog handles.<commit_after>/*
 * SchemeSmobNew.c
 *
 * Scheme small objects (SMOBS) --creating new atoms -- for opencog.
 *
 * Copyright (c) 2008 Linas Vepstas <linas@linas.org>
 */

#ifdef HAVE_GUILE

#include <vector>

#include <libguile.h>

#include <opencog/atomspace/Atom.h>
#include <opencog/atomspace/AtomSpace.h>
#include <opencog/atomspace/ClassServer.h>
#include <opencog/atomspace/Link.h>
#include <opencog/atomspace/Node.h>
#include <opencog/atomspace/TLB.h>
#include <opencog/guile/SchemeSmob.h>
#include <opencog/server/CogServer.h>

using namespace opencog;

/* ============================================================== */
/**
 * return atom->toString() for the corresponding atom.
 */
std::string SchemeSmob::to_string(SCM node)
{
	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, node))
		return handle_to_string(node);

	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_misc_tag, node))
		return misc_to_string(node);

	return "";
}

std::string SchemeSmob::handle_to_string(Handle h, int indent)
{
	if (Handle::UNDEFINED == h) return "#<Undefined atom handle>";

	Atom *atom = TLB::getAtom(h);
	if (NULL == atom) return "#<Invalid handle>";
	Node *node = dynamic_cast<Node *>(atom);
	Link *link = dynamic_cast<Link *>(atom);

#ifdef CRYPTIC_STYLE
	// output the olde-style opencog notation
	std::string ret = "#<";
	ret += atom->toString();
	ret += ">\n";
#endif

	// Print a scheme expression, so that the output can be saved
	// to file, and then restored, as needed.
	std::string ret = "";
	for (int i=0; i< indent; i++) ret += "   ";
	ret += "(";
	ret += classserver().getTypeName(atom->getType());
	if (node)
	{
		ret += " \"";
		ret += node->getName();
		ret += "\"";

		// Print the truth value only after the node name
		const TruthValue &tv = atom->getTruthValue();
		if (tv != TruthValue::DEFAULT_TV())
		{
			ret += " ";
			ret += tv_to_string (&tv);
		}
		ret += ")";
		return ret;
	}
	else if (link)
	{
		// If there's a truth value, print it before the other atoms
		const TruthValue &tv = atom->getTruthValue();
		if (tv != TruthValue::DEFAULT_TV())
		{
			ret += " ";
			ret += tv_to_string (&tv);
		}

		// print the outgoing link set.
		std::vector<Handle> oset = link->getOutgoingSet();
		unsigned int arity = oset.size();
		for (unsigned int i=0; i<arity; i++)
		{
			ret += " ";
			ret += handle_to_string(oset[i], (0==i)?0:indent+1);
			if (i != arity-1) ret += "\n";
		}
		ret += ")";
		return ret;
	}

	return ret;
}

std::string SchemeSmob::handle_to_string(SCM node)
{
	Handle h = scm_to_handle(node);
	return handle_to_string(h, 0) + "\n";
}

/* ============================================================== */
/**
 * Wrapper -- given a handle, return the corresponding scheme object.
 * Note that smobs hold the integer value of the handle, and not the
 * C++ handle object itself.
 */
SCM SchemeSmob::handle_to_scm (Handle h)
{
	SCM shandle = scm_from_ulong(h.value());
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

Handle SchemeSmob::scm_to_handle (SCM sh)
{
	SCM suuid = SCM_SMOB_OBJECT(sh);
	unsigned long uuid = scm_to_ulong(suuid);
	return Handle(uuid);
}

/* ============================================================== */
/**
 * Create a new scheme object, holding the atom handle
 */
SCM SchemeSmob::ss_atom (SCM shandle)
{
	if (scm_is_false(scm_integer_p(shandle)))
		scm_wrong_type_arg_msg("cog-atom", 1, shandle, "integer opencog handle");
	SCM_RETURN_NEWSMOB (cog_handle_tag, shandle);
}

/* ============================================================== */
/**
 * Return handle of atom (the handle is the UUID integer)
 */
SCM SchemeSmob::ss_handle (SCM satom)
{
	if (!SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, satom))
		scm_wrong_type_arg_msg("cog-handle", 1, satom, "opencog atom");

	// Guhh. Handles are no longer unsigned ints, but are classes. :-(
	// return SCM_SMOB_OBJECT(satom);
	unsigned long uuid = (unsigned long) SCM_SMOB_OBJECT(satom);
	return scm_from_ulong(uuid);
}

/* ============================================================== */

SCM SchemeSmob::ss_atom_p (SCM s)
{
	if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, s))
		return SCM_BOOL_T;
	return SCM_BOOL_F;
}

/* ============================================================== */
/**
 * Check that the arguments represent a value node, else throw errors.
 * Return the node type.
 */
Type SchemeSmob::validate_atom (SCM stype, const char *subrname)
{
	if (scm_is_true(scm_symbol_p(stype)))
		stype = scm_symbol_to_string(stype);

	if (scm_is_false(scm_string_p(stype)))
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog atom type");

	char * ct = scm_to_locale_string(stype);
	Type t = classserver().getType(ct);
	free(ct);

	// Make sure that the type is good
	if (NOTYPE == t)
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog atom type");

	return t;
}

Type SchemeSmob::validate_node (SCM stype, const char *subrname)
{
	Type t = validate_atom(stype, subrname);

	if (false == classserver().isA(t, NODE))
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog node type");

	return t;
}

std::string SchemeSmob::decode_string (SCM sname, const char *subrname, const char * msg)
{
	if (scm_is_false(scm_string_p(sname)))
		scm_wrong_type_arg_msg(subrname, 2, sname, msg);

	char * cname = scm_to_locale_string(sname);
	std::string name = cname;
	free(cname);
	return name;
}

/**
 * Create a new node, of named type stype, and string name sname
 */
SCM SchemeSmob::ss_new_node (SCM stype, SCM sname, SCM kv_pairs)
{
	Type t = validate_node(stype, "cog-new-node");
	std::string name = decode_string (sname, "cog-new-node", "string name for the node");

	// Now, create the actual node... in the actual atom space.
	const TruthValue *tv = get_tv_from_list(kv_pairs);
	if (!tv) tv = &TruthValue::DEFAULT_TV();

	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->addNode(t, name, *tv);

	return handle_to_scm (h);
}

/**
 * Return the indicated node, of named type stype, and string name sname
 * if it exists; else return nil if it does not exist.
 * If the node exists, *and* a truth value was specified, then change
 * the truth value.
 */
SCM SchemeSmob::ss_node (SCM stype, SCM sname, SCM kv_pairs)
{
	Type t = validate_node(stype, "cog-node");
	std::string name = decode_string (sname, "cog-node", "string name for the node");

	// Now, look for the actual node... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->getHandle(t, name);
	if (!TLB::isValidHandle(h)) return SCM_EOL; // NIL

	// If there was a truth value, change it.
	const TruthValue *tv = get_tv_from_list(kv_pairs);
	if (tv)
	{
		Atom *atom = TLB::getAtom(h);
		atom->setTruthValue(*tv);
	}
	return handle_to_scm (h);
}

/* ============================================================== */
/**
 * Verify that the arguments are appropriate for a link
 */
static Type verify_link (SCM stype, const char * subrname)
{
	if (scm_is_true(scm_symbol_p(stype)))
		stype = scm_symbol_to_string(stype);

	char * ct = scm_to_locale_string(stype);
	Type t = classserver().getType(ct);
	free(ct);

	// Make sure that the type is good
	if (NOTYPE == t)
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog atom type");

	if (false == classserver().isA(t, LINK))
		scm_wrong_type_arg_msg(subrname, 1, stype, "name of opencog link type");

	return t;
}

/**
 * Convert argument into a list of handles.
 */
std::vector<Handle>
SchemeSmob::decode_handle_list (SCM satom_list, const char * subrname)
{
	// Verify that second arg is an actual list. Allow null list.
	// (I think that there are legti null lists, right?)
	if (!scm_is_pair(satom_list) && !scm_is_null(satom_list))
		scm_wrong_type_arg_msg(subrname, 2, satom_list, "a list of atoms");

	const TruthValue *tv = NULL;
	std::vector<Handle> outgoing_set;
	SCM sl = satom_list;
	int pos = 2;
	while (scm_is_pair(sl))
	{
		SCM satom = SCM_CAR(sl);

		// Verify that the contents of the list are actual atoms.
		if (SCM_SMOB_PREDICATE(SchemeSmob::cog_handle_tag, satom))
		{
			// Get the handle  ... should we check for valid handles here?
			SCM shandle = SCM_SMOB_OBJECT(satom);
			Handle h(scm_to_ulong(shandle));
			outgoing_set.push_back(h);
		}
		else
		{
			// Its legit to have enmbedded truth values, just skip them.
			tv = get_tv_from_list(sl);
			if (tv == NULL)
			{
				// If its not an atom, and its not a truth value, its bad
				scm_wrong_type_arg_msg("cog-new-link", pos, satom, "opencog atom");
			}
		}
		sl = SCM_CDR(sl);
		pos++;
	}

	return outgoing_set;
}

/**
 * Create a new link, of named type stype, holding the indicated atom list
 */
SCM SchemeSmob::ss_new_link (SCM stype, SCM satom_list)
{
	Type t = verify_link (stype, "cog-new-link");

	std::vector<Handle> outgoing_set;
	outgoing_set = decode_handle_list (satom_list, "cog-new-link");

	// Fish out a truth value, if its there.
	const TruthValue *tv = get_tv_from_list(satom_list);
	if (!tv) tv = &TruthValue::DEFAULT_TV();

	// Now, create the actual link... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->addLink(t, outgoing_set, *tv);
	return handle_to_scm (h);
}

/**
 * Return the indicated link, of named type stype, holding the
 * indicated atom list, if it exists; else return nil if
 * it does not exist.
 */
SCM SchemeSmob::ss_link (SCM stype, SCM satom_list)
{
	Type t = verify_link (stype, "cog-link");

	std::vector<Handle> outgoing_set;
	outgoing_set = decode_handle_list (satom_list, "cog-link");

	// Now, look to find the actual link... in the actual atom space.
	AtomSpace *as = CogServer::getAtomSpace();
	Handle h = as->getHandle(t, outgoing_set);
	if (!TLB::isValidHandle(h)) return SCM_EOL; // NIL

	// If there was a truth value, change it.
	const TruthValue *tv = get_tv_from_list(satom_list);
	if (tv)
	{
		Atom *atom = TLB::getAtom(h);
		atom->setTruthValue(*tv);
	}
	return handle_to_scm (h);
}

/* ============================================================== */
/**
 * delete the atom, but only if it has no incoming links.
 */
SCM SchemeSmob::ss_delete (SCM satom)
{
	Handle h = verify_handle(satom, "cog-delete");

	AtomSpace *as = CogServer::getAtomSpace();
	bool rc = as->removeAtom(h, false);

	if (rc) return SCM_BOOL_T;
	return SCM_BOOL_F;
}

/* ============================================================== */
/**
 * delete the atom, and everything pointing to it.
 */
SCM SchemeSmob::ss_delete_recursive (SCM satom)
{
	Handle h = verify_handle(satom, "cog-delete-recursive");

	AtomSpace *as = CogServer::getAtomSpace();
	bool rc = as->removeAtom(h, true);

	if (rc) return SCM_BOOL_T;
	return SCM_BOOL_F;
}

#endif
/* ===================== END OF FILE ============================ */
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "DriverAccess.h"
#include "Public.h"

//------------------------------------------------------------------------------------------------

UsbDkDriverAccess::UsbDkDriverAccess()
{
    m_hDriver = CreateFile(USBDK_USERMODE_NAME,
                           GENERIC_READ | GENERIC_WRITE,
                           0,
                           NULL,
                           CREATE_ALWAYS,
                           FILE_ATTRIBUTE_NORMAL,
                           NULL);

    if (m_hDriver == INVALID_HANDLE_VALUE)
    {
        throw UsbDkDriverAccessException(TEXT("Failed to open device symlink"));
    }
}
//------------------------------------------------------------------------------------------------

UsbDkDriverAccess::~UsbDkDriverAccess()
{
    CloseHandle(m_hDriver);
}
//------------------------------------------------------------------------------------------------

void UsbDkDriverAccess::GetDevicesList(PUSB_DK_DEVICE_ID &DevicesArray, ULONG &NumberDevice)
{
    DevicesArray = nullptr;
    for (;;)
    {
        DWORD   bytesReturned;

        // get number of devices
        if (!DeviceIoControl(m_hDriver,
            IOCTL_USBDK_COUNT_DEVICES,
            nullptr,
            0,
            &NumberDevice,
            sizeof(NumberDevice),
            &bytesReturned,
            nullptr))
        {
            throw UsbDkDriverAccessException(TEXT("Counting devices failed"));
        }

        // get list of devices
        delete DevicesArray;
        DevicesArray = new USB_DK_DEVICE_ID[NumberDevice];

        if (!DeviceIoControl(m_hDriver,
            IOCTL_USBDK_ENUM_DEVICES,
            nullptr,
            0,
            DevicesArray,
            NumberDevice * sizeof(USB_DK_DEVICE_ID),
            &bytesReturned,
            nullptr))
        {
            DWORD err = GetLastError();
            if (err == ERROR_INSUFFICIENT_BUFFER || err == ERROR_MORE_DATA)
            {
                continue;
            }
            else
            {
                UsbDkDriverAccessException(TEXT("Enumiration devices failed in DeviceIoControl."), err);
            }
        }
        NumberDevice = bytesReturned / sizeof(USB_DK_DEVICE_ID);
        break;
    }
}
//------------------------------------------------------------------------------------------------
void UsbDkDriverAccess::ReleaseDeviceList(PUSB_DK_DEVICE_ID DevicesArray)
{
    delete[] DevicesArray;
}
//------------------------------------------------------------------------------------------------

void UsbDkDriverAccess::ResetDevice(USB_DK_DEVICE_ID &DeviceID)
{
    SendIoctlWithDeviceId(IOCTL_USBDK_RESET_DEVICE, DeviceID);
}
//------------------------------------------------------------------------------------------------

void UsbDkDriverAccess::AddRedirect(USB_DK_DEVICE_ID &DeviceID)
{
    SendIoctlWithDeviceId(IOCTL_USBDK_ADD_REDIRECT, DeviceID);
}
//------------------------------------------------------------------------------------------------

void UsbDkDriverAccess::RemoveRedirect(USB_DK_DEVICE_ID &DeviceID)
{
    SendIoctlWithDeviceId(IOCTL_USBDK_REMOVE_REDIRECT, DeviceID);
}
//------------------------------------------------------------------------------------------------

void UsbDkDriverAccess::SendIoctlWithDeviceId(DWORD ControlCode,
                                              USB_DK_DEVICE_ID &Id)
{
    DWORD   bytesReturned;
    if (!DeviceIoControl(m_hDriver, ControlCode, &Id, sizeof(Id),
                         nullptr, 0, &bytesReturned, nullptr))
    {
        throw UsbDkDriverAccessException(TEXT("Ioctl failed"));
    }
}
<commit_msg>UsbDkHelper: Trivial: improve printout<commit_after>#include "stdafx.h"
#include "DriverAccess.h"
#include "Public.h"

//------------------------------------------------------------------------------------------------

UsbDkDriverAccess::UsbDkDriverAccess()
{
    m_hDriver = CreateFile(USBDK_USERMODE_NAME,
                           GENERIC_READ | GENERIC_WRITE,
                           0,
                           NULL,
                           CREATE_ALWAYS,
                           FILE_ATTRIBUTE_NORMAL,
                           NULL);

    if (m_hDriver == INVALID_HANDLE_VALUE)
    {
        throw UsbDkDriverAccessException(TEXT("Failed to open device symlink"));
    }
}
//------------------------------------------------------------------------------------------------

UsbDkDriverAccess::~UsbDkDriverAccess()
{
    CloseHandle(m_hDriver);
}
//------------------------------------------------------------------------------------------------

void UsbDkDriverAccess::GetDevicesList(PUSB_DK_DEVICE_ID &DevicesArray, ULONG &NumberDevice)
{
    DevicesArray = nullptr;
    for (;;)
    {
        DWORD   bytesReturned;

        // get number of devices
        if (!DeviceIoControl(m_hDriver,
            IOCTL_USBDK_COUNT_DEVICES,
            nullptr,
            0,
            &NumberDevice,
            sizeof(NumberDevice),
            &bytesReturned,
            nullptr))
        {
            throw UsbDkDriverAccessException(TEXT("Counting devices failed"));
        }

        // get list of devices
        delete DevicesArray;
        DevicesArray = new USB_DK_DEVICE_ID[NumberDevice];

        if (!DeviceIoControl(m_hDriver,
            IOCTL_USBDK_ENUM_DEVICES,
            nullptr,
            0,
            DevicesArray,
            NumberDevice * sizeof(USB_DK_DEVICE_ID),
            &bytesReturned,
            nullptr))
        {
            DWORD err = GetLastError();
            if (err == ERROR_INSUFFICIENT_BUFFER || err == ERROR_MORE_DATA)
            {
                continue;
            }
            else
            {
                UsbDkDriverAccessException(TEXT("Enumeration failed in IOCTL_USBDK_ENUM_DEVICES."), err);
            }
        }
        NumberDevice = bytesReturned / sizeof(USB_DK_DEVICE_ID);
        break;
    }
}
//------------------------------------------------------------------------------------------------
void UsbDkDriverAccess::ReleaseDeviceList(PUSB_DK_DEVICE_ID DevicesArray)
{
    delete[] DevicesArray;
}
//------------------------------------------------------------------------------------------------

void UsbDkDriverAccess::ResetDevice(USB_DK_DEVICE_ID &DeviceID)
{
    SendIoctlWithDeviceId(IOCTL_USBDK_RESET_DEVICE, DeviceID);
}
//------------------------------------------------------------------------------------------------

void UsbDkDriverAccess::AddRedirect(USB_DK_DEVICE_ID &DeviceID)
{
    SendIoctlWithDeviceId(IOCTL_USBDK_ADD_REDIRECT, DeviceID);
}
//------------------------------------------------------------------------------------------------

void UsbDkDriverAccess::RemoveRedirect(USB_DK_DEVICE_ID &DeviceID)
{
    SendIoctlWithDeviceId(IOCTL_USBDK_REMOVE_REDIRECT, DeviceID);
}
//------------------------------------------------------------------------------------------------

void UsbDkDriverAccess::SendIoctlWithDeviceId(DWORD ControlCode,
                                              USB_DK_DEVICE_ID &Id)
{
    DWORD   bytesReturned;
    if (!DeviceIoControl(m_hDriver, ControlCode, &Id, sizeof(Id),
                         nullptr, 0, &bytesReturned, nullptr))
    {
        throw UsbDkDriverAccessException(TEXT("Ioctl failed"));
    }
}
<|endoftext|>