<commit_before>#include "bulkDataCallback.h"

BulkDataCallback::BulkDataCallback()
{
    ACS_TRACE("BulkDataCallback::BulkDataCallback");

    state_m = CB_UNS;
    substate_m = CB_SUB_UNS;

    dim_m = 0;
    count_m = 0;

    loop_m = 5;
    waitPeriod_m.set(0L, 400000L);

    frameCount_m = 0;

    bufParam_p = 0;

    timeout_m = false;
    working_m = false;
    error_m = false;

    errorCounter_m = 0;
    errComp_p = 0;
}

BulkDataCallback::~BulkDataCallback()
{
    ACS_TRACE("BulkDataCallback::~BulkDataCallback");

    if (error_m == true)
	{
	if (errComp_p != 0)
	    delete errComp_p;
	}

}

int BulkDataCallback::handle_start(void)
{
    //ACS_TRACE("BulkDataCallback::handle_start");

    // cout << "BulkDataCallback::handle_start - state_m: " << state_m << endl;

    //if(timeout_m == true)
    //ACS_SHORT_LOG((LM_INFO,"BulkDataCallback::handle_start - timeout_m == true !!!"));

    timeout_m = false;

    if (error_m == true)
	{
	if (errComp_p != 0)
	    delete errComp_p;
	}

    // error is cleared
    error_m = false;

    state_m = CB_UNS;
    substate_m = CB_SUB_UNS;

    frameCount_m = 1; // we need to wait for 1 following frame before doing anything else

    return 0;
}

int BulkDataCallback::handle_stop (void)
{
    //ACS_TRACE("BulkDataCallback::handle_stop");

    // cout << "CCCCCCCCCCCCCCCCC enter stop state " << state_m << " " << substate_m << endl;

    try
	{
	int locLoop;
	int res;

	locLoop = loop_m;
	while ( (frameCount_m != 0) && locLoop > 0)
	    {
	    ACE_OS::sleep(waitPeriod_m);
	    locLoop--;
	    } // we didn't receive the first frame yet

	if(state_m == CB_UNS)
	    {

	    int res = cbStop();
	    errorCounter_m = 0;
	    return res;
	    }

	if((state_m == CB_SEND_PARAM) || (state_m == CB_SEND_DATA))
	    {

	    if  (substate_m == CB_SUB_INIT)
		{
		substate_m = CB_SUB_UNS;
		return 0;
		}

	    locLoop = loop_m;
	    while((count_m != dim_m) && locLoop > 0)
		{
		ACE_OS::sleep(waitPeriod_m);
		locLoop--;
		}

	    if ( locLoop == 0 )
		{
		ACS_SHORT_LOG((LM_INFO,"BulkDataCallback::handle_stop timeout expired, not all data received"));

		timeout_m = true;

		//cleaning the recv buffer

		ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH> *svch = dynamic_cast<ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH> *>(handler_);

		char buf[BUFSIZ];
		int bufSize = sizeof(buf);
		//cout << "sssssss: " << bufSize << endl;
		int nn = 1;
		while(nn > 0)
		    {
		    nn = svch->peer().recv(buf,bufSize);
		    //cout << "nnnnnnn: " << nn << endl;
		    }

		//return -1;
		}

	    if(state_m == CB_SEND_PARAM)
		{
		//res ignored by reactor
		if (dim_m != 0)
		    res = cbStart(bufParam_p);

		if(bufParam_p)
		    bufParam_p->release();
		}

	    state_m = CB_UNS;
	    substate_m = CB_SUB_UNS;

	    return 0;
	    }

	}
    catch(ACSErr::ACSbaseExImpl &ex)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(ex,__FILE__,__LINE__,"BulkDataCallback::handle_stop");
	err.log();

	/* TBD what do to after several attempts ? */
	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }

	// add to the completion
	errComp_p = new AVCbErrorCompletion(err, __FILE__, __LINE__, "BulkDataCallback::handle_stop");

	error_m = true;
	}
    catch(CORBA::Exception &ex)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(__FILE__,__LINE__,"BulkDataCallback::handle_stop");
	err.addData("CORBA::Exception", ex._info());
	err.log();

	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }
	error_m = true;
	}
    catch(...)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(__FILE__,__LINE__,"BulkDataCallback::handle_stop");
	err.addData("UNKNOWN Exception", "Unknown ex in BulkDataCallback::handle_stop");
	err.log();

	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }
	error_m = true;
	}

    return 0;
}

int BulkDataCallback::handle_destroy (void)
{
    //ACS_TRACE("BulkDataCallback::handle_destroy");

    //cout << "BulkDataCallback::handle_destroy" << endl;

    if (error_m == true)
	{
	if (errComp_p != 0)
	    delete errComp_p;
	}
    error_m = false;

    delete this;

    return 0;
}

int BulkDataCallback::receive_frame (ACE_Message_Block *frame, TAO_AV_frame_info *frame_info, const ACE_Addr &)
{
    working_m = true;

/*
    if(error_m == true)
	{
	cleanRecvBuffer();
	return 0;
	}
*/

    //ACS_TRACE("BulkDataCallback::receive_frame");
    //ACS_SHORT_LOG((LM_INFO,"BulkDataCallback::receive_frame for flow %s", flowname_m.c_str()));

    // cout << "BulkDataCallback::receive_frame - state_m: " << state_m << endl;

    if(timeout_m == true)
	ACS_SHORT_LOG((LM_INFO, "BulkDataCallback::receive_frame - timeout_m true !!!"));

    try
	{
	CORBA::ULong val1, val2;
	int res;

	if(state_m == CB_UNS)
	    {
	    char tmp[255];
	    ACE_OS::strcpy(tmp, frame->rd_ptr());

	    string strDataInfo(tmp);

	    istringstream iss(strDataInfo);

	    iss >> val1 >> val2;

	    // cout << "CCCCCCCCCCCCCCC " << val1 << " " << val2 << endl;

	    if(val1 == 1)
		{
		state_m = CB_SEND_PARAM;
		substate_m = CB_SUB_INIT;

		if(val2 != 0)
		    bufParam_p = new ACE_Message_Block(val2);
		else
		    bufParam_p = 0;
		}
	    else if(val1 == 2)
		{
		state_m = CB_SEND_DATA;
		substate_m = CB_SUB_INIT;
		}
	    else
		{
		state_m = CB_UNS;
		substate_m = CB_SUB_UNS;
		}

	    dim_m = val2;
	    count_m = 0;

	    frameCount_m = 0;
	    working_m = false;

	    return 0;
	    }

	if(state_m == CB_SEND_PARAM)
	    {

	    if ( dim_m == 0 )
		{
		res = cbStart();
		errorCounter_m = 0;
		working_m = false;
		return 0;
		}

	    bufParam_p->copy(frame->rd_ptr(),frame->length());

	    count_m += frame->length();
	    errorCounter_m = 0;
	    working_m = false;
	    return 0;
	    }

	if (state_m == CB_SEND_DATA)
	    {
	    res = cbReceive(frame);
//	    if(timeout_m == true)
//		{
//		//cout << "!!!!!!! in receive_frame timeout_m == true after timeout - set it to false" << endl;
//		timeout_m = false;
//		}
	    count_m += frame->length();
	    errorCounter_m = 0;
	    working_m = false;
	    return 0;
	    }

	}
    catch(ACSErr::ACSbaseExImpl &ex)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(ex,__FILE__,__LINE__,"BulkDataCallback::receive_frame");
	err.log();

	/* TBD what do to after several attempts ? */
	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }
	error_m = true;
	}
    catch(CORBA::Exception &ex)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(__FILE__,__LINE__,"BulkDataCallback::receive_frame");
	err.addData("CORBA::Exception", ex._info());
	err.log();

	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }

	// add to the completion
	errComp_p = new AVCbErrorCompletion(err, __FILE__, __LINE__, "BulkDataCallback::handle_stop");

	error_m = true;
	}
    catch(...)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(__FILE__,__LINE__,"BulkDataCallback::receive_frame");
	err.addData("UNKNOWN Exception", "Unknown ex in BulkDataCallback::receive_frame");
	err.log();

	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }
	error_m = true;
	}

    working_m = false;
    return 0;
}

void BulkDataCallback::setFlowname (const char * flowname_p)
{
    ACS_TRACE("BulkDataCallback::setFlowname");
    //ACS_SHORT_LOG((LM_INFO,"RRRRRRRRRRRRRRRRR BulkDataCallback::flowname for flow %s", flow_name));
    flowname_m = flowname_p;

    string flwName(flowname_p);
    string flwNumber(flwName, 4, 1);

    flowNumber_m = atol(flwNumber.c_str());
}

void BulkDataCallback::setSleepTime(ACE_Time_Value locWaitPeriod)
{
    ACS_TRACE("BulkDataCallback::setSleepTime");

    waitPeriod_m = locWaitPeriod;
}

void BulkDataCallback::setSafeTimeout(CORBA::ULong locLoop)
{
    ACS_TRACE("BulkDataCallback::setSafeTimeout");

    loop_m = locLoop;
}

CORBA::Boolean BulkDataCallback::isTimeout()
{
    ACS_TRACE("BulkDataCallback::isTimeout");

    return timeout_m;
}

CORBA::Boolean BulkDataCallback::isWorking()
{
    ACS_TRACE("BulkDataCallback::isWorking");

    return working_m;
}

CORBA::Boolean BulkDataCallback::isError()
{
//    ACS_TRACE("BulkDataCallback::isError");

    return error_m;
}

CompletionImpl *BulkDataCallback::getErrorCompletion()
{
    ACS_TRACE("BulkDataCallback::getErrorCompletion");

    // error is cleared; completion cannot be retrieved two times
    error_m = false;

    return errComp_p;
}

void BulkDataCallback::cleanRecvBuffer()
{
    ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH> *svch = dynamic_cast<ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH> *>(handler_);

    char buf[BUFSIZ];
    int bufSize = sizeof(buf);
    int nn = 1;
    while(nn > 0)
	{
	nn = svch->peer().recv(buf,bufSize);
	}

}
<commit_msg>corrected bug<commit_after>#include "bulkDataCallback.h"

BulkDataCallback::BulkDataCallback()
{
    ACS_TRACE("BulkDataCallback::BulkDataCallback");

    state_m = CB_UNS;
    substate_m = CB_SUB_UNS;

    dim_m = 0;
    count_m = 0;

    loop_m = 5;
    waitPeriod_m.set(0L, 400000L);

    frameCount_m = 0;

    bufParam_p = 0;

    timeout_m = false;
    working_m = false;
    error_m = false;

    errorCounter_m = 0;
    errComp_p = 0;
}

BulkDataCallback::~BulkDataCallback()
{
    ACS_TRACE("BulkDataCallback::~BulkDataCallback");

    if (error_m == true)
	{
	if (errComp_p != 0)
	    delete errComp_p;
	}

}

int BulkDataCallback::handle_start(void)
{
    //ACS_TRACE("BulkDataCallback::handle_start");

    // cout << "BulkDataCallback::handle_start - state_m: " << state_m << endl;

    //if(timeout_m == true)
    //ACS_SHORT_LOG((LM_INFO,"BulkDataCallback::handle_start - timeout_m == true !!!"));

    timeout_m = false;

    if (error_m == true)
	{
	if (errComp_p != 0)
	    delete errComp_p;
	}

    // error is cleared
    error_m = false;

    state_m = CB_UNS;
    substate_m = CB_SUB_UNS;

    frameCount_m = 1; // we need to wait for 1 following frame before doing anything else

    return 0;
}

int BulkDataCallback::handle_stop (void)
{
    //ACS_TRACE("BulkDataCallback::handle_stop");

    // cout << "CCCCCCCCCCCCCCCCC enter stop state " << state_m << " " << substate_m << endl;

    try
	{
	int locLoop;
	int res;

	locLoop = loop_m;
	while ( (frameCount_m != 0) && locLoop > 0)
	    {
	    ACE_OS::sleep(waitPeriod_m);
	    locLoop--;
	    } // we didn't receive the first frame yet

	if(state_m == CB_UNS)
	    {

	    int res = cbStop();
	    errorCounter_m = 0;
	    return res;
	    }

	if((state_m == CB_SEND_PARAM) || (state_m == CB_SEND_DATA))
	    {

	    if  (substate_m == CB_SUB_INIT)
		{
		substate_m = CB_SUB_UNS;
		return 0;
		}

	    locLoop = loop_m;
	    while((count_m != dim_m) && locLoop > 0)
		{
		ACE_OS::sleep(waitPeriod_m);
		locLoop--;
		}

	    if ( locLoop == 0 )
		{
		ACS_SHORT_LOG((LM_INFO,"BulkDataCallback::handle_stop timeout expired, not all data received"));

		timeout_m = true;

		//cleaning the recv buffer

		ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH> *svch = dynamic_cast<ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH> *>(handler_);

		char buf[BUFSIZ];
		int bufSize = sizeof(buf);
		//cout << "sssssss: " << bufSize << endl;
		int nn = 1;
		while(nn > 0)
		    {
		    nn = svch->peer().recv(buf,bufSize);
		    //cout << "nnnnnnn: " << nn << endl;
		    }
		//return -1;
		}

	    if(state_m == CB_SEND_PARAM)
		{
		//res ignored by reactor
		if (dim_m != 0)
		    res = cbStart(bufParam_p);

		if(bufParam_p)
		    bufParam_p->release();
		}

	    state_m = CB_UNS;
	    substate_m = CB_SUB_UNS;

	    return 0;
	    }

	}
    catch(ACSErr::ACSbaseExImpl &ex)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(ex,__FILE__,__LINE__,"BulkDataCallback::handle_stop");
	err.log();

	/* TBD what do to after several attempts ? */
	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }

	// add to the completion
	errComp_p = new AVCbErrorCompletion(err, __FILE__, __LINE__, "BulkDataCallback::handle_stop");

	error_m = true;
	}
    catch(CORBA::Exception &ex)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(__FILE__,__LINE__,"BulkDataCallback::handle_stop");
	err.addData("CORBA::Exception", ex._info());
	err.log();

	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }
	error_m = true;
	}
    catch(...)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(__FILE__,__LINE__,"BulkDataCallback::handle_stop");
	err.addData("UNKNOWN Exception", "Unknown ex in BulkDataCallback::handle_stop");
	err.log();

	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }
	error_m = true;
	}

    return 0;
}

int BulkDataCallback::handle_destroy (void)
{
    //ACS_TRACE("BulkDataCallback::handle_destroy");

    //cout << "BulkDataCallback::handle_destroy" << endl;

    if (error_m == true)
	{
	if (errComp_p != 0)
	    delete errComp_p;
	}
    error_m = false;

    delete this;

    return 0;
}

int BulkDataCallback::receive_frame (ACE_Message_Block *frame, TAO_AV_frame_info *frame_info, const ACE_Addr &)
{
    working_m = true;

    if(error_m == true)
	{
	cleanRecvBuffer();
	working_m = false;
	return 0;
	}

    //ACS_TRACE("BulkDataCallback::receive_frame");
    //ACS_SHORT_LOG((LM_INFO,"BulkDataCallback::receive_frame for flow %s", flowname_m.c_str()));

    // cout << "BulkDataCallback::receive_frame - state_m: " << state_m << endl;

    if(timeout_m == true)
	ACS_SHORT_LOG((LM_INFO, "BulkDataCallback::receive_frame - timeout_m true !!!"));

    try
	{
	CORBA::ULong val1, val2;
	int res;

	if(state_m == CB_UNS)
	    {
	    char tmp[255];
	    ACE_OS::strcpy(tmp, frame->rd_ptr());

	    string strDataInfo(tmp);

	    istringstream iss(strDataInfo);

	    iss >> val1 >> val2;

	    // cout << "CCCCCCCCCCCCCCC " << val1 << " " << val2 << endl;

	    if(val1 == 1)
		{
		state_m = CB_SEND_PARAM;
		substate_m = CB_SUB_INIT;

		if(val2 != 0)
		    bufParam_p = new ACE_Message_Block(val2);
		else
		    bufParam_p = 0;
		}
	    else if(val1 == 2)
		{
		state_m = CB_SEND_DATA;
		substate_m = CB_SUB_INIT;
		}
	    else
		{
		state_m = CB_UNS;
		substate_m = CB_SUB_UNS;
		}

	    dim_m = val2;
	    count_m = 0;

	    frameCount_m = 0;
	    working_m = false;

	    return 0;
	    }

	if(state_m == CB_SEND_PARAM)
	    {

	    if ( dim_m == 0 )
		{
		res = cbStart();
		errorCounter_m = 0;
		working_m = false;
		return 0;
		}

	    bufParam_p->copy(frame->rd_ptr(),frame->length());

	    count_m += frame->length();
	    errorCounter_m = 0;
	    working_m = false;
	    return 0;
	    }

	if (state_m == CB_SEND_DATA)
	    {
	    res = cbReceive(frame);
//	    if(timeout_m == true)
//		{
//		//cout << "!!!!!!! in receive_frame timeout_m == true after timeout - set it to false" << endl;
//		timeout_m = false;
//		}
	    count_m += frame->length();
	    errorCounter_m = 0;
	    working_m = false;
	    return 0;
	    }

	}
    catch(ACSErr::ACSbaseExImpl &ex)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(ex,__FILE__,__LINE__,"BulkDataCallback::receive_frame");
	err.log();

	/* TBD what do to after several attempts ? */
	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }

	// add to the completion
	errComp_p = new AVCbErrorCompletion(err, __FILE__, __LINE__, "BulkDataCallback::handle_stop");

	error_m = true;
	}
    catch(CORBA::Exception &ex)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(__FILE__,__LINE__,"BulkDataCallback::receive_frame");
	err.addData("CORBA::Exception", ex._info());
	err.log();

	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }

	error_m = true;
	}
    catch(...)
	{
	AVCallbackErrorExImpl err = AVCallbackErrorExImpl(__FILE__,__LINE__,"BulkDataCallback::receive_frame");
	err.addData("UNKNOWN Exception", "Unknown ex in BulkDataCallback::receive_frame");
	err.log();

	errorCounter_m++;
	if(errorCounter_m == maxErrorRepetition)
	    {
	    errorCounter_m = 0;
	    //return 0;
	    }
	error_m = true;
	}

    working_m = false;
    return 0;
}

void BulkDataCallback::setFlowname (const char * flowname_p)
{
    ACS_TRACE("BulkDataCallback::setFlowname");
    //ACS_SHORT_LOG((LM_INFO,"RRRRRRRRRRRRRRRRR BulkDataCallback::flowname for flow %s", flow_name));
    flowname_m = flowname_p;

    string flwName(flowname_p);
    string flwNumber(flwName, 4, 1);

    flowNumber_m = atol(flwNumber.c_str());
}

void BulkDataCallback::setSleepTime(ACE_Time_Value locWaitPeriod)
{
    ACS_TRACE("BulkDataCallback::setSleepTime");

    waitPeriod_m = locWaitPeriod;
}

void BulkDataCallback::setSafeTimeout(CORBA::ULong locLoop)
{
    ACS_TRACE("BulkDataCallback::setSafeTimeout");

    loop_m = locLoop;
}

CORBA::Boolean BulkDataCallback::isTimeout()
{
    ACS_TRACE("BulkDataCallback::isTimeout");

    return timeout_m;
}

CORBA::Boolean BulkDataCallback::isWorking()
{
    ACS_TRACE("BulkDataCallback::isWorking");

    return working_m;
}

CORBA::Boolean BulkDataCallback::isError()
{
//    ACS_TRACE("BulkDataCallback::isError");

    return error_m;
}

CompletionImpl *BulkDataCallback::getErrorCompletion()
{
    ACS_TRACE("BulkDataCallback::getErrorCompletion");

    // error is cleared; completion cannot be retrieved two times
    error_m = false;

    return errComp_p;
}

void BulkDataCallback::cleanRecvBuffer()
{
    ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH> *svch = dynamic_cast<ACE_Svc_Handler<ACE_SOCK_STREAM,ACE_NULL_SYNCH> *>(handler_);

    char buf[BUFSIZ];
    int bufSize = sizeof(buf);
    int nn = 1;
    while(nn > 0)
	{
	nn = svch->peer().recv(buf,bufSize);
	}

}
<|endoftext|>


<commit_before>#include "main.hpp"

void GridlabDFederate::initialize( void )
{
  GridlabDFederateATRCallback gldfedATRCb( *this );
  putAdvanceTimeRequest(  _currentTime, gldfedATRCb );

  readyToPopulate();
  readyToRun();
}

void GridlabDFederate::execute( void )
{
  // update class variables
  _currentTime += 1;

  // init temporary variables
  InteractionRoot::SP interactionRootSP;

  char tmpBuf[1024];
  std::string gld_url_base = "http://" +
    _gld_ip + ":" +
    _gld_port + "/";
  gld_obj object;
  int intf_retval = 0;
  std::string gld_url, date, time;

  // STEP GLD
  date = "2000-01-01 ";
  sprintf( tmpBuf,
	   "%02d:%02d:%02d",
	   (int)( ( _currentTime / 60 ) / 60 ),
	   (int)( _currentTime / 60 ),
	   (int)fmod(_currentTime, 60));
  time = std::string(tmpBuf);
  gld_url = gld_url_base + "control/pauseat=" + date + time;
  intf_retval = call_gld(gld_url, object);

  // GET MESSAGES HERE FROM HLA
  while ( (interactionRootSP = getNextInteraction() ) != 0 )
    {
      boost::shared_ptr<GridlabDInput> gldSP( boost::static_pointer_cast<GridlabDInput>( interactionRootSP ) );
      std::string objectName = gldSP->get_ObjectName();
      std::string parameterName = gldSP->get_Parameter();
      double value = gldSP->get_Value();
      std::string units = gldSP->get_Units();
      int operation = gldSP->get_Operation();

      // operation:
      //  0 : GET
      //  1 : SET
      //  ... : UNDEFINED

      std::cout <<
	"GLDFederate: Received GridlabDInput interaction: " <<
	objectName << "/" << parameterName << ": " << value << units << ": " << operation <<
	std::endl;

      // SEND DATA TO GLD; GET DATA FROM GLD
      memset(tmpBuf, 0, 1024);
      sprintf(tmpBuf, "%f", value);
      gld_url = gld_url_base + objectName + "/" + parameterName;
      if (operation == 1)
	gld_url += "=" + std::string(tmpBuf) + units;
      intf_retval = call_gld(gld_url, object);
      if (intf_retval) // everything went well
	{
	  if (object.has_data)
	    {
	      GridlabDOutputSP output = create_GridlabDOutput();
	      output->set_ObjectName( object.object );
	      output->set_Parameter( object.name );
	      // need to split the value into value and units
	      char *pEnd = 0;
	      value = strtod(object.value.c_str(), &pEnd);
	      output->set_Value( value );
	      if (pEnd)
		{
		  output->set_Units( std::string(pEnd) ); // there is always a space between the value and units
		}
	      output->set_Operation( 0 );
	      std::cout <<
		"GLDFederate: Sending GridlabDOutput interaction: " <<
		output->get_ObjectName() << "/" <<
		output->get_Parameter() << ": " <<
		output->get_Value() <<
		output->get_Units() << ": " <<
		output->get_Operation() <<
		std::endl;
	      output->sendInteraction( getRTI(), _currentTime + getLookAhead() );
	    }
	}
    }

  // Advance Time
  GridlabDFederateATRCallback gldfedATRcb( *this );
  putAdvanceTimeRequest( _currentTime, gldfedATRcb );
}

bool GridlabDFederate::call_gld(std::string gld_url,
				gld_obj& ret_obj)   // in-out param
{
  ret_obj.has_data = false;
  ret_obj.type = "";
  ret_obj.object = "";
  ret_obj.name = "";
  ret_obj.value = "";

  // std::cout << "Connecting to: " << gld_url << std::endl;
  using namespace boost::network;
  http::client client;
  http::client::request request(gld_url);
  request << header("Connection", "close");
  http::client::response response = client.get(request);

  std::string text = body(response);

  if (text.length())
    {
      rapidxml::xml_document<> doc;
      doc.parse<0>((char *)text.c_str());

      rapidxml::xml_node<> *_type = doc.first_node("property");
      rapidxml::xml_node<> *_name, *_val, *_object;

      if (_type)
	{
	  _object = _type->first_node("object");
	  _name = _type->first_node("name");
	  _val = _type->first_node("value");

	  ret_obj.has_data = true;
	  ret_obj.type = "property";
	  ret_obj.object = _object->value();
	  ret_obj.name = _name->value();
	  ret_obj.value = _val->value();
	}
      else
	{
	  _type = doc.first_node("globalvar");
	  _name = _type->first_node("name");
	  _val = _type->first_node("value");

	  ret_obj.has_data = true;
	  ret_obj.type = "globalvar";
	  ret_obj.name = _name->value();
	  ret_obj.value = _val->value();
	}
    }
  return true;
}

int main(int argc, char** argv)
{
  pid_t pID = fork();
  if (pID == 0)
    {
      char *args[4];

      char process[] = "/usr/local/bin/gridlabd";
      char model[] = "/home/c2wt/Projects/c2wt/examples/GridlabDHelloWorld/models/gridlab-d/IEEE_13_Node_With_Houses.glm";
      char option[] = "--server";
      args[0] = process;
      args[1] = model;
      args[2] = option;
      args[3] = 0;

      execv(args[0], args);
    }

  std::cout << "Creating GridlabDFederate Object" << std::endl;
  GridlabDFederate gldfed( argc, argv );
  std::cout << "GridlabDFederate created" << std::endl;

  std::cout << "Initializing GridlabDFederate" << std::endl;
  gldfed.initialize();
  std::cout << "GridlabDFederate initialized" << std::endl;

  std::cout << "Running GridlabDFederate" << std::endl;
  gldfed.run();

  kill(0, SIGKILL);

  return 0;
}
<commit_msg>minor update for output.<commit_after>#include "main.hpp"

void GridlabDFederate::initialize( void )
{
  GridlabDFederateATRCallback gldfedATRCb( *this );
  putAdvanceTimeRequest(  _currentTime, gldfedATRCb );

  readyToPopulate();
  readyToRun();
}

void GridlabDFederate::execute( void )
{
  // update class variables
  _currentTime += 1;

  // init temporary variables
  InteractionRoot::SP interactionRootSP;

  char tmpBuf[1024];
  std::string gld_url_base = "http://" +
    _gld_ip + ":" +
    _gld_port + "/";
  gld_obj object;
  int intf_retval = 0;
  std::string gld_url, date, time;

  // STEP GLD
  date = "2000-01-01 ";
  sprintf( tmpBuf,
	   "%02d:%02d:%02d",
	   (int)( ( _currentTime / 60 ) / 60 ),
	   (int)( _currentTime / 60 ),
	   (int)fmod(_currentTime, 60));
  time = std::string(tmpBuf);
  gld_url = gld_url_base + "control/pauseat=" + date + time;
  std::cout <<
    "GLDFederate: Stepping GLD to " <<
    date + time <<
    std::endl;
  intf_retval = call_gld(gld_url, object);

  // GET MESSAGES HERE FROM HLA
  while ( (interactionRootSP = getNextInteraction() ) != 0 )
    {
      boost::shared_ptr<GridlabDInput> gldSP( boost::static_pointer_cast<GridlabDInput>( interactionRootSP ) );
      std::string objectName = gldSP->get_ObjectName();
      std::string parameterName = gldSP->get_Parameter();
      double value = gldSP->get_Value();
      std::string units = gldSP->get_Units();
      int operation = gldSP->get_Operation();

      // operation:
      //  0 : GET
      //  1 : SET
      //  ... : UNDEFINED

      std::cout <<
	"GLDFederate: Received GridlabDInput interaction: " <<
	objectName << "/" << parameterName << ": " << value << units << ": " << operation <<
	std::endl;

      // SEND DATA TO GLD; GET DATA FROM GLD
      memset(tmpBuf, 0, 1024);
      sprintf(tmpBuf, "%f", value);
      gld_url = gld_url_base + objectName + "/" + parameterName;
      if (operation == 1)
	gld_url += "=" + std::string(tmpBuf) + units;
      intf_retval = call_gld(gld_url, object);
      if (intf_retval) // everything went well
	{
	  if (object.has_data)
	    {
	      GridlabDOutputSP output = create_GridlabDOutput();
	      output->set_ObjectName( object.object );
	      output->set_Parameter( object.name );
	      // need to split the value into value and units
	      char *pEnd = 0;
	      value = strtod(object.value.c_str(), &pEnd);
	      output->set_Value( value );
	      if (pEnd)
		{
		  output->set_Units( std::string(pEnd) ); // there is always a space between the value and units
		}
	      output->set_Operation( 0 );
	      std::cout <<
		"GLDFederate: Sending GridlabDOutput interaction: " <<
		output->get_ObjectName() << "/" <<
		output->get_Parameter() << ": " <<
		output->get_Value() <<
		output->get_Units() << ": " <<
		output->get_Operation() <<
		std::endl;
	      output->sendInteraction( getRTI(), _currentTime + getLookAhead() );
	    }
	}
    }

  // Advance Time
  GridlabDFederateATRCallback gldfedATRcb( *this );
  putAdvanceTimeRequest( _currentTime, gldfedATRcb );
}

bool GridlabDFederate::call_gld(std::string gld_url,
				gld_obj& ret_obj)   // in-out param
{
  ret_obj.has_data = false;
  ret_obj.type = "";
  ret_obj.object = "";
  ret_obj.name = "";
  ret_obj.value = "";

  // std::cout << "Connecting to: " << gld_url << std::endl;
  using namespace boost::network;
  http::client client;
  http::client::request request(gld_url);
  request << header("Connection", "close");
  http::client::response response = client.get(request);

  std::string text = body(response);

  if (text.length())
    {
      rapidxml::xml_document<> doc;
      doc.parse<0>((char *)text.c_str());

      rapidxml::xml_node<> *_type = doc.first_node("property");
      rapidxml::xml_node<> *_name, *_val, *_object;

      if (_type)
	{
	  _object = _type->first_node("object");
	  _name = _type->first_node("name");
	  _val = _type->first_node("value");

	  ret_obj.has_data = true;
	  ret_obj.type = "property";
	  ret_obj.object = _object->value();
	  ret_obj.name = _name->value();
	  ret_obj.value = _val->value();
	}
      else
	{
	  _type = doc.first_node("globalvar");
	  _name = _type->first_node("name");
	  _val = _type->first_node("value");

	  ret_obj.has_data = true;
	  ret_obj.type = "globalvar";
	  ret_obj.name = _name->value();
	  ret_obj.value = _val->value();
	}
    }
  return true;
}

int main(int argc, char** argv)
{
  pid_t pID = fork();
  if (pID == 0)
    {
      char *args[4];

      char process[] = "/usr/local/bin/gridlabd";
      char model[] = "/home/c2wt/Projects/c2wt/examples/GridlabDHelloWorld/models/gridlab-d/IEEE_13_Node_With_Houses.glm";
      char option[] = "--server";
      args[0] = process;
      args[1] = model;
      args[2] = option;
      args[3] = 0;

      execv(args[0], args);
    }

  std::cout << "Creating GridlabDFederate Object" << std::endl;
  GridlabDFederate gldfed( argc, argv );
  std::cout << "GridlabDFederate created" << std::endl;

  std::cout << "Initializing GridlabDFederate" << std::endl;
  gldfed.initialize();
  std::cout << "GridlabDFederate initialized" << std::endl;

  std::cout << "Running GridlabDFederate" << std::endl;
  gldfed.run();

  kill(0, SIGKILL);

  return 0;
}
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2007-12-11 14:46:19 +0100 (Di, 11 Dez 2007) $
Version:   $Revision: 13129 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

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

#include "mitkNavigationDataRecorder.h"
#include <fstream>

#include <mitkTimeStamp.h>
#include <tinyxml.h>

#include <itksys/SystemTools.hxx>

mitk::NavigationDataRecorder::NavigationDataRecorder()
{
  //set default values
  m_NumberOfInputs = 0;
  m_RecordingMode = NormalFile;
  m_Recording = false;
  m_NumberOfRecordedFiles = 0;
  m_Stream = NULL;
  m_FileName = "";
  m_SystemTimeClock = RealTimeClock::New();
  m_OutputFormat = mitk::NavigationDataRecorder::xml;
  m_RecordCounter = 0;
  m_RecordCountLimit = -1;

  //To get a start time
  mitk::TimeStamp::GetInstance()->Start(this);

}

mitk::NavigationDataRecorder::~NavigationDataRecorder()
{
}

void mitk::NavigationDataRecorder::GenerateData()
{

}

void mitk::NavigationDataRecorder::AddNavigationData( const NavigationData* nd )
{
  // Process object is not const-correct so the const_cast is required here
  this->SetNthInput(m_NumberOfInputs,
    const_cast< mitk::NavigationData * >( nd ) );

  m_NumberOfInputs++;

  this->Modified();
}

void mitk::NavigationDataRecorder::SetRecordingMode( RecordingMode mode )
{
  m_RecordingMode = mode;
  this->Modified();
}

void mitk::NavigationDataRecorder::Update()
{
  if (m_Recording)
  {
    DataObjectPointerArray inputs = this->GetInputs(); //get all inputs
    mitk::NavigationData::TimeStampType timestamp=0.0; // timestamp for mitk time
    timestamp = mitk::TimeStamp::GetInstance()->GetElapsed();

    mitk::NavigationData::TimeStampType sysTimestamp = 0.0; // timestamp for system time
    sysTimestamp = m_SystemTimeClock->GetCurrentStamp();

    // cast system time double value to stringstream to avoid low precision rounding
    std::ostringstream strs;
    strs.precision(15); // rounding precision for system time double value
    strs << sysTimestamp;
    std::string sysTimeStr = strs.str();

    //if csv-mode: write csv header and timpstamp at beginning
    if (m_OutputFormat == mitk::NavigationDataRecorder::csv)
      {
      //write header only when it's the first line
      if (m_firstLine)
        {
        m_firstLine = false;
        *m_Stream << "TimeStamp";
        for (unsigned int index = 0; index < inputs.size(); index++){ *m_Stream << ";Valid_Tool" << index <<
                                                                                ";X_Tool" << index <<
                                                                                ";Y_Tool" << index <<
                                                                                ";Z_Tool" << index <<
                                                                                ";QX_Tool" << index <<
                                                                                ";QY_Tool" << index <<
                                                                                ";QZ_Tool" << index <<
                                                                                ";QR_Tool" << index;}
        *m_Stream << "\n";
        }
      //write timestamp (always)
      *m_Stream << timestamp;
      }

    //write tool data for every tool
    for (unsigned int index = 0; index < inputs.size(); index++)
    {
      mitk::NavigationData* nd = dynamic_cast<mitk::NavigationData*>(inputs[index].GetPointer());
      nd->Update(); // call update to propagate update to previous filters

      mitk::NavigationData::PositionType position;
      mitk::NavigationData::OrientationType orientation(0.0, 0.0, 0.0, 0.0);
      mitk::NavigationData::CovarianceMatrixType matrix;

      bool hasPosition = true;
      bool hasOrientation = true;
      bool dataValid = false;

      position.Fill(0.0);
      matrix.SetIdentity();

      position = nd->GetPosition();
      orientation = nd->GetOrientation();
      matrix = nd->GetCovErrorMatrix();

      hasPosition = nd->GetHasPosition();
      hasOrientation = nd->GetHasOrientation();
      dataValid = nd->IsDataValid();

      //use this one if you want the timestamps of the source
      //timestamp = nd->GetTimeStamp();

      //a timestamp is never < 0! this case happens only if you are using the timestamp of the nd object instead of getting a new one
      if (timestamp >= 0)
      {
        if (this->m_OutputFormat == mitk::NavigationDataRecorder::xml)
          {
          TiXmlElement* elem = new TiXmlElement("ND");

          elem->SetDoubleAttribute("Time", timestamp);
          elem->SetAttribute("SystemTime", sysTimeStr); // tag for system time
          elem->SetDoubleAttribute("Tool", index);
          elem->SetDoubleAttribute("X", position[0]);
          elem->SetDoubleAttribute("Y", position[1]);
          elem->SetDoubleAttribute("Z", position[2]);

          elem->SetDoubleAttribute("QX", orientation[0]);
          elem->SetDoubleAttribute("QY", orientation[1]);
          elem->SetDoubleAttribute("QZ", orientation[2]);
          elem->SetDoubleAttribute("QR", orientation[3]);

          elem->SetDoubleAttribute("C00", matrix[0][0]);
          elem->SetDoubleAttribute("C01", matrix[0][1]);
          elem->SetDoubleAttribute("C02", matrix[0][2]);
          elem->SetDoubleAttribute("C03", matrix[0][3]);
          elem->SetDoubleAttribute("C04", matrix[0][4]);
          elem->SetDoubleAttribute("C05", matrix[0][5]);
          elem->SetDoubleAttribute("C10", matrix[1][0]);
          elem->SetDoubleAttribute("C11", matrix[1][1]);
          elem->SetDoubleAttribute("C12", matrix[1][2]);
          elem->SetDoubleAttribute("C13", matrix[1][3]);
          elem->SetDoubleAttribute("C14", matrix[1][4]);
          elem->SetDoubleAttribute("C15", matrix[1][5]);

          if (dataValid)
            elem->SetAttribute("Valid",1);
          else
            elem->SetAttribute("Valid",0);

          if (hasOrientation)
            elem->SetAttribute("hO",1);
          else
            elem->SetAttribute("hO",0);

          if (hasPosition)
            elem->SetAttribute("hP",1);
          else
            elem->SetAttribute("hP",0);

          *m_Stream << "        " << *elem << std::endl;

          delete elem;
          }
        else if (this->m_OutputFormat == mitk::NavigationDataRecorder::csv)
          {
          *m_Stream << ";" << dataValid << ";" << position[0] << ";" << position[1] << ";" << position[2] << ";" << orientation[0] << ";" << orientation[1] << ";" << orientation[2] << ";" << orientation[3];
          }
      }
    }
    if (this->m_OutputFormat == mitk::NavigationDataRecorder::csv)
    {
      *m_Stream << "\n";
    }
  }
  m_RecordCounter++;
  if ((m_RecordCountLimit<=m_RecordCounter)&&(m_RecordCountLimit != -1)) {StopRecording();}
}

void mitk::NavigationDataRecorder::StartRecording()
{
  if (m_Recording)
  {
    std::cout << "Already recording please stop before start new recording session" << std::endl;
    return;
  }

  if (m_Stream == NULL)
  {
    std::stringstream ss;
    std::ostream* stream;

    //An existing extension will be cut and replaced with .xml
    std::string tmpPath = itksys::SystemTools::GetFilenamePath(m_FileName);
    m_FileName = itksys::SystemTools::GetFilenameWithoutExtension(m_FileName);
    if (m_OutputFormat == mitk::NavigationDataRecorder::csv) ss << tmpPath << "/" <<  m_FileName << "-" << m_NumberOfRecordedFiles << ".csv";
    else ss << tmpPath << "/" <<  m_FileName << "-" << m_NumberOfRecordedFiles << ".xml";
    switch(m_RecordingMode)
    {
      case Console:
        stream = &std::cout;
        break;
      case NormalFile:

        //Check if there is a file name and path
        if (m_FileName == "")
        {
          stream = &std::cout;
          std::cout << "No file name or file path set the output is redirected to the console";
        }
        else
        {
          stream = new std::ofstream(ss.str().c_str());
        }

        break;
      case ZipFile:
        stream = &std::cout;
        std::cout << "Sorry no ZipFile support yet";
        break;
      default:
        stream = &std::cout;
        break;
    }
    m_firstLine = true;
    m_RecordCounter = 0;
    StartRecording(stream);
  }

}
void mitk::NavigationDataRecorder::StartRecording(std::ostream* stream)
{
  if (m_Recording)
  {
    std::cout << "Already recording please stop before start new recording session" << std::endl;
    return;
  }

  m_Stream = stream;
  m_Stream->precision(10);

  //TODO store date and GMT time
  if (m_Stream)
  {
    if (m_OutputFormat == mitk::NavigationDataRecorder::xml)
      {
      *m_Stream << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" << std::endl;
      /**m_Stream << "<Version Ver=\"1\" />" << std::endl;*/
      // should be a generic version, meaning a member variable, which has the actual version
      *m_Stream << "    " << "<Data ToolCount=\"" << (m_NumberOfInputs) << "\" version=\"1.0\">" << std::endl;
      }
    m_Recording = true;
  }
}
void mitk::NavigationDataRecorder::StopRecording()
{
  if (!m_Recording)
  {
    std::cout << "You have to start a recording first" << std::endl;
    return;
  }

  if ((m_Stream) && (m_OutputFormat == mitk::NavigationDataRecorder::xml))
  {
    *m_Stream << "</Data>" << std::endl;
  }

  m_NumberOfRecordedFiles++;
  m_Recording = false;
  m_Stream->flush();
  m_Stream = NULL;
}<commit_msg>changed tag name "ND" to unambiguous name NaviagtionData<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Language:  C++
Date:      $Date: 2007-12-11 14:46:19 +0100 (Di, 11 Dez 2007) $
Version:   $Revision: 13129 $

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

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

#include "mitkNavigationDataRecorder.h"
#include <fstream>

#include <mitkTimeStamp.h>
#include <tinyxml.h>

#include <itksys/SystemTools.hxx>

mitk::NavigationDataRecorder::NavigationDataRecorder()
{
  //set default values
  m_NumberOfInputs = 0;
  m_RecordingMode = NormalFile;
  m_Recording = false;
  m_NumberOfRecordedFiles = 0;
  m_Stream = NULL;
  m_FileName = "";
  m_SystemTimeClock = RealTimeClock::New();
  m_OutputFormat = mitk::NavigationDataRecorder::xml;
  m_RecordCounter = 0;
  m_RecordCountLimit = -1;

  //To get a start time
  mitk::TimeStamp::GetInstance()->Start(this);

}

mitk::NavigationDataRecorder::~NavigationDataRecorder()
{
}

void mitk::NavigationDataRecorder::GenerateData()
{

}

void mitk::NavigationDataRecorder::AddNavigationData( const NavigationData* nd )
{
  // Process object is not const-correct so the const_cast is required here
  this->SetNthInput(m_NumberOfInputs,
    const_cast< mitk::NavigationData * >( nd ) );

  m_NumberOfInputs++;

  this->Modified();
}

void mitk::NavigationDataRecorder::SetRecordingMode( RecordingMode mode )
{
  m_RecordingMode = mode;
  this->Modified();
}

void mitk::NavigationDataRecorder::Update()
{
  if (m_Recording)
  {
    DataObjectPointerArray inputs = this->GetInputs(); //get all inputs
    mitk::NavigationData::TimeStampType timestamp=0.0; // timestamp for mitk time
    timestamp = mitk::TimeStamp::GetInstance()->GetElapsed();

    mitk::NavigationData::TimeStampType sysTimestamp = 0.0; // timestamp for system time
    sysTimestamp = m_SystemTimeClock->GetCurrentStamp();

    // cast system time double value to stringstream to avoid low precision rounding
    std::ostringstream strs;
    strs.precision(15); // rounding precision for system time double value
    strs << sysTimestamp;
    std::string sysTimeStr = strs.str();

    //if csv-mode: write csv header and timpstamp at beginning
    if (m_OutputFormat == mitk::NavigationDataRecorder::csv)
      {
      //write header only when it's the first line
      if (m_firstLine)
        {
        m_firstLine = false;
        *m_Stream << "TimeStamp";
        for (unsigned int index = 0; index < inputs.size(); index++){ *m_Stream << ";Valid_Tool" << index <<
                                                                                ";X_Tool" << index <<
                                                                                ";Y_Tool" << index <<
                                                                                ";Z_Tool" << index <<
                                                                                ";QX_Tool" << index <<
                                                                                ";QY_Tool" << index <<
                                                                                ";QZ_Tool" << index <<
                                                                                ";QR_Tool" << index;}
        *m_Stream << "\n";
        }
      //write timestamp (always)
      *m_Stream << timestamp;
      }

    //write tool data for every tool
    for (unsigned int index = 0; index < inputs.size(); index++)
    {
      mitk::NavigationData* nd = dynamic_cast<mitk::NavigationData*>(inputs[index].GetPointer());
      nd->Update(); // call update to propagate update to previous filters

      mitk::NavigationData::PositionType position;
      mitk::NavigationData::OrientationType orientation(0.0, 0.0, 0.0, 0.0);
      mitk::NavigationData::CovarianceMatrixType matrix;

      bool hasPosition = true;
      bool hasOrientation = true;
      bool dataValid = false;

      position.Fill(0.0);
      matrix.SetIdentity();

      position = nd->GetPosition();
      orientation = nd->GetOrientation();
      matrix = nd->GetCovErrorMatrix();

      hasPosition = nd->GetHasPosition();
      hasOrientation = nd->GetHasOrientation();
      dataValid = nd->IsDataValid();

      //use this one if you want the timestamps of the source
      //timestamp = nd->GetTimeStamp();

      //a timestamp is never < 0! this case happens only if you are using the timestamp of the nd object instead of getting a new one
      if (timestamp >= 0)
      {
        if (this->m_OutputFormat == mitk::NavigationDataRecorder::xml)
          {
          TiXmlElement* elem = new TiXmlElement("NavigationData");

          elem->SetDoubleAttribute("Time", timestamp);
          elem->SetAttribute("SystemTime", sysTimeStr); // tag for system time
          elem->SetDoubleAttribute("Tool", index);
          elem->SetDoubleAttribute("X", position[0]);
          elem->SetDoubleAttribute("Y", position[1]);
          elem->SetDoubleAttribute("Z", position[2]);

          elem->SetDoubleAttribute("QX", orientation[0]);
          elem->SetDoubleAttribute("QY", orientation[1]);
          elem->SetDoubleAttribute("QZ", orientation[2]);
          elem->SetDoubleAttribute("QR", orientation[3]);

          elem->SetDoubleAttribute("C00", matrix[0][0]);
          elem->SetDoubleAttribute("C01", matrix[0][1]);
          elem->SetDoubleAttribute("C02", matrix[0][2]);
          elem->SetDoubleAttribute("C03", matrix[0][3]);
          elem->SetDoubleAttribute("C04", matrix[0][4]);
          elem->SetDoubleAttribute("C05", matrix[0][5]);
          elem->SetDoubleAttribute("C10", matrix[1][0]);
          elem->SetDoubleAttribute("C11", matrix[1][1]);
          elem->SetDoubleAttribute("C12", matrix[1][2]);
          elem->SetDoubleAttribute("C13", matrix[1][3]);
          elem->SetDoubleAttribute("C14", matrix[1][4]);
          elem->SetDoubleAttribute("C15", matrix[1][5]);

          if (dataValid)
            elem->SetAttribute("Valid",1);
          else
            elem->SetAttribute("Valid",0);

          if (hasOrientation)
            elem->SetAttribute("hO",1);
          else
            elem->SetAttribute("hO",0);

          if (hasPosition)
            elem->SetAttribute("hP",1);
          else
            elem->SetAttribute("hP",0);

          *m_Stream << "        " << *elem << std::endl;

          delete elem;
          }
        else if (this->m_OutputFormat == mitk::NavigationDataRecorder::csv)
          {
          *m_Stream << ";" << dataValid << ";" << position[0] << ";" << position[1] << ";" << position[2] << ";" << orientation[0] << ";" << orientation[1] << ";" << orientation[2] << ";" << orientation[3];
          }
      }
    }
    if (this->m_OutputFormat == mitk::NavigationDataRecorder::csv)
    {
      *m_Stream << "\n";
    }
  }
  m_RecordCounter++;
  if ((m_RecordCountLimit<=m_RecordCounter)&&(m_RecordCountLimit != -1)) {StopRecording();}
}

void mitk::NavigationDataRecorder::StartRecording()
{
  if (m_Recording)
  {
    std::cout << "Already recording please stop before start new recording session" << std::endl;
    return;
  }

  if (m_Stream == NULL)
  {
    std::stringstream ss;
    std::ostream* stream;

    //An existing extension will be cut and replaced with .xml
    std::string tmpPath = itksys::SystemTools::GetFilenamePath(m_FileName);
    m_FileName = itksys::SystemTools::GetFilenameWithoutExtension(m_FileName);
    if (m_OutputFormat == mitk::NavigationDataRecorder::csv) ss << tmpPath << "/" <<  m_FileName << "-" << m_NumberOfRecordedFiles << ".csv";
    else ss << tmpPath << "/" <<  m_FileName << "-" << m_NumberOfRecordedFiles << ".xml";
    switch(m_RecordingMode)
    {
      case Console:
        stream = &std::cout;
        break;
      case NormalFile:

        //Check if there is a file name and path
        if (m_FileName == "")
        {
          stream = &std::cout;
          std::cout << "No file name or file path set the output is redirected to the console";
        }
        else
        {
          stream = new std::ofstream(ss.str().c_str());
        }

        break;
      case ZipFile:
        stream = &std::cout;
        std::cout << "Sorry no ZipFile support yet";
        break;
      default:
        stream = &std::cout;
        break;
    }
    m_firstLine = true;
    m_RecordCounter = 0;
    StartRecording(stream);
  }

}
void mitk::NavigationDataRecorder::StartRecording(std::ostream* stream)
{
  if (m_Recording)
  {
    std::cout << "Already recording please stop before start new recording session" << std::endl;
    return;
  }

  m_Stream = stream;
  m_Stream->precision(10);

  //TODO store date and GMT time
  if (m_Stream)
  {
    if (m_OutputFormat == mitk::NavigationDataRecorder::xml)
      {
      *m_Stream << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" << std::endl;
      /**m_Stream << "<Version Ver=\"1\" />" << std::endl;*/
      // should be a generic version, meaning a member variable, which has the actual version
      *m_Stream << "    " << "<Data ToolCount=\"" << (m_NumberOfInputs) << "\" version=\"1.0\">" << std::endl;
      }
    m_Recording = true;
  }
}
void mitk::NavigationDataRecorder::StopRecording()
{
  if (!m_Recording)
  {
    std::cout << "You have to start a recording first" << std::endl;
    return;
  }

  if ((m_Stream) && (m_OutputFormat == mitk::NavigationDataRecorder::xml))
  {
    *m_Stream << "</Data>" << std::endl;
  }

  m_NumberOfRecordedFiles++;
  m_Recording = false;
  m_Stream->flush();
  m_Stream = NULL;
}<|endoftext|>


<commit_before>/// HEADER
#include "time_plot.h"

/// PROJECT
#include <csapex/msg/io.h>
#include <csapex_opencv/cv_mat_message.h>
#include <csapex/param/parameter_factory.h>
#include <csapex/model/node_modifier.h>
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/msg/generic_value_message.hpp>
#include <csapex/view/utility/QtCvImageConverter.h>
#include <csapex/msg/generic_vector_message.hpp>

/// SYSTEM
#include <qwt_scale_engine.h>

CSAPEX_REGISTER_CLASS(csapex::TimePlot, csapex::Node)

using namespace csapex;
using namespace csapex::connection_types;

void TimePlot::setup(NodeModifier &node_modifier)
{
    in_  = node_modifier.addMultiInput<double, GenericVectorMessage>("Double");
    out_ = node_modifier.addOutput<CvMatMessage>("Plot");
    initialize_ = true;
    num_plots_ = 1;
    basic_line_color_changed_ = true;
    color_line_.resize(1);
}

void TimePlot::setupParameters(Parameterizable &parameters)
{
    parameters.addParameter(param::ParameterFactory::declareRange
                            ("~plot/width",
                             128, 4096, 640, 1),
                            [this](param::Parameter* p) {
        width_ = p->as<int>();
        update();
    });
    parameters.addParameter(param::ParameterFactory::declareRange
                            ("~plot/height",
                             128, 4096, 320, 1),
                            [this](param::Parameter* p) {
        height_ = p->as<int>();
        update();
    });

    auto setColor = [this](QColor& color) {
        return [&](param::Parameter* p) {
            std::vector<int> c = p->as<std::vector<int>>();
            color.setRed(c[0]);
            color.setGreen(c[1]);
            color.setBlue(c[2]);

            update();
        };
    };

    std::function<void(param::Parameter* p)> setLineColors= [this](param::Parameter* p){
        std::vector<int> c = p->as<std::vector<int>>();
        basic_line_color_.setRed(c[0]);
        basic_line_color_.setGreen(c[1]);
        basic_line_color_.setBlue(c[2]);
        calculateLineColors();
        basic_line_color_changed_ = true;
        update();
    };

    parameters.addParameter(param::ParameterFactory::declareColorParameter(
                                "~plot/color/background", 255, 255, 255),
                            setColor(color_bg_));
    parameters.addParameter(param::ParameterFactory::declareColorParameter(
                                "~plot/color/line", 100, 100, 255),
                            setLineColors);
    parameters.addParameter(param::ParameterFactory::declareColorParameter(
                                "~plot/color/fill", 200, 200, 200),
                            setColor(color_fill_));
    parameters.addParameter(param::ParameterFactory::declareRange(
                                "~plot/line/width", 0.0, 10.0, 0.0, 0.01),
                            line_width_);

    parameters.addParameter(param::ParameterFactory::declareBool
                            ("~output/time/relative",
                             param::ParameterDescription("Use time relative to the first entry"),
                             true),
                            time_relative_);
    parameters.addParameter(param::ParameterFactory::declareBool
                            ("~output/time/seconds",
                             param::ParameterDescription("Convert the time to seconds"),
                             true),
                            time_seconds_);

    parameters.addParameter(param::ParameterFactory::declareTrigger("reset"),
                            [this](param::Parameter*) {
        reset();
    });
}

void TimePlot::process()
{
    timepoint time = std::chrono::system_clock::now();
    double value;
    if(msg::isValue<double>(in_)) {
        value = msg::getValue<double>(in_);
        if(initialize_){
            data_v_.resize(1);
            num_plots_ = 1;
            initialize_ = false;
            color_line_.resize(1);
            calculateLineColors();
        }
        data_v_.at(0).push_back(value);

    }
    else {
        GenericVectorMessage::ConstPtr message = msg::getMessage<GenericVectorMessage>(in_);
        apex_assert(std::dynamic_pointer_cast<GenericValueMessage<double>>(message->nestedType()));
        if(initialize_){
            num_plots_ = message->nestedValueCount();
            data_v_.resize(num_plots_);
            color_line_.resize(num_plots_);
            calculateLineColors();
            initialize_ = false;
        }
        for(std::size_t num_plot = 0; num_plot < num_plots_; ++num_plot){
            auto pval = std::dynamic_pointer_cast<GenericValueMessage<double> const>(message->nestedValue(num_plot));
            if(pval){
                double val = pval->value;
                data_v_.at(num_plot).push_back(val);
            }
//            double val = tval->
        }

    }

    double ms = std::chrono::duration_cast<std::chrono::microseconds>(time.time_since_epoch()).count();

    data_t_raw_.push_back(ms);

    preparePlot();

    if(msg::isConnected(out_)) {
        renderAndSend();
    }

    display_request();
}

void TimePlot::reset()
{
    data_t_raw_.clear();
    data_v_.clear();
    initialize_ = true;
    num_plots_ = 1;
    init();
}

void TimePlot::init()
{
    auto now = std::chrono::system_clock::now();
    start_t_ = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
}

void TimePlot::preparePlot()
{
    std::size_t n = data_t_raw_.size();
    data_t_.resize(n, 0.0);

    double time_offset = time_relative_ ? data_t_raw_.front() : 0.0;
    double time_scale = time_seconds_ ? 1e-6 : 1.0;

    for(std::size_t i = 0; i < n; ++i) {
        data_t_[i] = (data_t_raw_[i] - time_offset) * time_scale;
    }

    std::vector<double> min_list;
    std::vector<double> max_list;
    for(auto data: data_v_) {
        if(data.size() != 0) {
            min_list.push_back(std::min(0.0, *std::min_element(data.begin(), data.end())));
            max_list.push_back(std::max(0.0, *std::max_element(data.begin(), data.end())));
        }
    }

    double min = std::min(0.0, *std::min_element(min_list.begin(), min_list.end()));
    double max = std::max(0.0, *std::max_element(max_list.begin(), max_list.end()));

    x_map.setScaleInterval(data_t_.front(), data_t_.back());
    y_map.setScaleInterval(min - 1, max + 1);
}

void TimePlot::renderAndSend()
{
    QImage image(width_, height_, QImage::Format_RGB32);
    QPainter painter;
    painter.begin(&image);
    painter.fillRect(image.rect(), color_bg_);

    QRect r(0, 0, image.width(), image.height());

    x_map.setPaintInterval( r.left(), r.right() );
    y_map.setPaintInterval( r.bottom(), r.top() );

    if(basic_line_color_changed_) {
        calculateLineColors();
    }

    QwtPlotCurve curve[data_v_.size()];
    for(std::size_t  num_plot= 0; num_plot < data_v_.size(); ++num_plot) {
        painter.setRenderHint( QPainter::Antialiasing,
                               curve[num_plot].testRenderHint( QwtPlotItem::RenderAntialiased ) );
        painter.setRenderHint( QPainter::HighQualityAntialiasing,
                               curve[num_plot].testRenderHint( QwtPlotItem::RenderAntialiased ) );
        curve[num_plot].setBaseline(0.0);

        curve[num_plot].setPen(color_line_.at(num_plot), line_width_);
        curve[num_plot].setStyle(QwtPlotCurve::Lines);

        curve[num_plot].setBrush(QBrush(color_fill_, Qt::SolidPattern));

        curve[num_plot].setRawSamples(data_t_.data(), data_v_.at(num_plot).data(), data_t_.size());
        curve[num_plot].draw(&painter, x_map, y_map, r);
    }

    QwtLinearScaleEngine e;
    QwtPlotScaleItem scale_time(QwtScaleDraw::TopScale, y_map.s1());
    scale_time.setScaleDiv(e.divideScale(x_map.s1(), x_map.s2(), 10, 10));

    QwtPlotScaleItem scale_value(QwtScaleDraw::RightScale, x_map.s1());
    scale_value.setScaleDiv(e.divideScale(y_map.s1(), y_map.s2(), 10, 10));

    scale_time.draw(&painter, x_map, y_map, r);
    scale_value.draw(&painter, x_map, y_map, r);

    CvMatMessage::Ptr out_msg = std::make_shared<CvMatMessage>(enc::bgr, 0);
    out_msg->value = QtCvImageConverter::Converter<QImage>::QImage2Mat(image);

    msg::publish(out_, out_msg);
}

int TimePlot::getWidth() const
{
    return width_;
}

int TimePlot::getHeight() const
{
    return height_;
}

double TimePlot::getLineWidth() const
{
    return line_width_;
}

QColor TimePlot::getBackgroundColor() const
{
    return color_bg_;
}
QColor TimePlot::getLineColor(std::size_t idx) const
{
    return color_line_[idx];
}
QColor TimePlot::getFillColor() const
{
    return color_fill_;
}

const double* TimePlot::getTData() const
{
    return data_t_.data();
}
const double* TimePlot::getVData(std::size_t idx) const
{
    return data_v_.at(idx).data();
}
std::size_t TimePlot::getVDataCountNumCurves() const
{
    return data_v_.size();
}
std::size_t TimePlot::getCount() const
{
    return data_t_.size();
}

const QwtScaleMap& TimePlot::getXMap() const
{
    return x_map;
}
const QwtScaleMap& TimePlot::getYMap() const
{
    return y_map;
}

void TimePlot::calculateLineColors()
{
    int r,g,b,a;
    basic_line_color_.getRgb(&r,&g,&b,&a);
    QColor color;
    color.setRed(r);
    color.setGreen(g);
    color.setBlue(b);
    int h,s,v;
    color.getHsv(&h,&s,&v);

    for(std::size_t i = 0; i < num_plots_; ++i) {

        double hnew =  h + i * 360/num_plots_;
        while (hnew > 359 || hnew < 0) {
            if(hnew > 359) {
                hnew -= 360;
            }
            else if(hnew < 0) {
                hnew += 360;
            }

        }
        color.setHsv(hnew,s,v);
        color_line_[i] = color;
    }

    basic_line_color_changed_ = false;
    update();
}
<commit_msg>minor<commit_after>/// HEADER
#include "time_plot.h"

/// PROJECT
#include <csapex/msg/io.h>
#include <csapex_opencv/cv_mat_message.h>
#include <csapex/param/parameter_factory.h>
#include <csapex/model/node_modifier.h>
#include <csapex/utility/register_apex_plugin.h>
#include <csapex/msg/generic_value_message.hpp>
#include <csapex/view/utility/QtCvImageConverter.h>
#include <csapex/msg/generic_vector_message.hpp>

/// SYSTEM
#include <qwt_scale_engine.h>

CSAPEX_REGISTER_CLASS(csapex::TimePlot, csapex::Node)

using namespace csapex;
using namespace csapex::connection_types;

void TimePlot::setup(NodeModifier &node_modifier)
{
    in_  = node_modifier.addMultiInput<double, GenericVectorMessage>("Double");
    out_ = node_modifier.addOutput<CvMatMessage>("Plot");
    initialize_ = true;
    num_plots_ = 1;
    basic_line_color_changed_ = true;
    color_line_.resize(1);
}

void TimePlot::setupParameters(Parameterizable &parameters)
{
    parameters.addParameter(param::ParameterFactory::declareRange
                            ("~plot/width",
                             128, 4096, 640, 1),
                            [this](param::Parameter* p) {
        width_ = p->as<int>();
        update();
    });
    parameters.addParameter(param::ParameterFactory::declareRange
                            ("~plot/height",
                             128, 4096, 320, 1),
                            [this](param::Parameter* p) {
        height_ = p->as<int>();
        update();
    });

    auto setColor = [this](QColor& color) {
        return [&](param::Parameter* p) {
            std::vector<int> c = p->as<std::vector<int>>();
            color.setRed(c[0]);
            color.setGreen(c[1]);
            color.setBlue(c[2]);

            update();
        };
    };

    std::function<void(param::Parameter* p)> setLineColors= [this](param::Parameter* p){
        std::vector<int> c = p->as<std::vector<int>>();
        basic_line_color_.setRed(c[0]);
        basic_line_color_.setGreen(c[1]);
        basic_line_color_.setBlue(c[2]);
        calculateLineColors();
        basic_line_color_changed_ = true;
        update();
    };

    parameters.addParameter(param::ParameterFactory::declareColorParameter(
                                "~plot/color/background", 255, 255, 255),
                            setColor(color_bg_));
    parameters.addParameter(param::ParameterFactory::declareColorParameter(
                                "~plot/color/line", 100, 100, 255),
                            setLineColors);
    parameters.addParameter(param::ParameterFactory::declareColorParameter(
                                "~plot/color/fill", 200, 200, 200),
                            setColor(color_fill_));
    parameters.addParameter(param::ParameterFactory::declareRange(
                                "~plot/line/width", 0.0, 10.0, 0.0, 0.01),
                            line_width_);

    parameters.addParameter(param::ParameterFactory::declareBool
                            ("~output/time/relative",
                             param::ParameterDescription("Use time relative to the first entry"),
                             true),
                            time_relative_);
    parameters.addParameter(param::ParameterFactory::declareBool
                            ("~output/time/seconds",
                             param::ParameterDescription("Convert the time to seconds"),
                             true),
                            time_seconds_);

    parameters.addParameter(param::ParameterFactory::declareTrigger("reset"),
                            [this](param::Parameter*) {
        reset();
    });
}

void TimePlot::process()
{
    timepoint time = std::chrono::system_clock::now();
    double value;
    if(msg::isValue<double>(in_)) {
        value = msg::getValue<double>(in_);
        if(initialize_){
            data_v_.resize(1);
            num_plots_ = 1;
            initialize_ = false;
            color_line_.resize(1);
            calculateLineColors();
        }
        data_v_.at(0).push_back(value);

    }
    else {
        GenericVectorMessage::ConstPtr message = msg::getMessage<GenericVectorMessage>(in_);
        apex_assert(std::dynamic_pointer_cast<GenericValueMessage<double>>(message->nestedType()));
        if(initialize_){
            num_plots_ = message->nestedValueCount();
            data_v_.resize(num_plots_);
            color_line_.resize(num_plots_);
            calculateLineColors();
            initialize_ = false;
        }
        for(std::size_t num_plot = 0; num_plot < num_plots_; ++num_plot){
            auto pval = std::dynamic_pointer_cast<GenericValueMessage<double> const>(message->nestedValue(num_plot));
            if(pval){
                double val = pval->value;
                data_v_.at(num_plot).push_back(val);
            }
//            double val = tval->
        }

    }

    double ms = std::chrono::duration_cast<std::chrono::microseconds>(time.time_since_epoch()).count();

    data_t_raw_.push_back(ms);

    preparePlot();

    if(msg::isConnected(out_)) {
        renderAndSend();
    }

    display_request();
}

void TimePlot::reset()
{
    data_t_raw_.clear();
    data_v_.clear();
    initialize_ = true;
    num_plots_ = 1;
    init();
}

void TimePlot::init()
{
    auto now = std::chrono::system_clock::now();
    start_t_ = std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
}

void TimePlot::preparePlot()
{
    std::size_t n = data_t_raw_.size();
    data_t_.resize(n, 0.0);
    color_fill_.setAlpha(100);

    double time_offset = time_relative_ ? data_t_raw_.front() : 0.0;
    double time_scale = time_seconds_ ? 1e-6 : 1.0;

    for(std::size_t i = 0; i < n; ++i) {
        data_t_[i] = (data_t_raw_[i] - time_offset) * time_scale;
    }

    std::vector<double> min_list;
    std::vector<double> max_list;
    for(auto data: data_v_) {
        if(data.size() != 0) {
            min_list.push_back(std::min(0.0, *std::min_element(data.begin(), data.end())));
            max_list.push_back(std::max(0.0, *std::max_element(data.begin(), data.end())));
        }
    }

    double min = std::min(0.0, *std::min_element(min_list.begin(), min_list.end()));
    double max = std::max(0.0, *std::max_element(max_list.begin(), max_list.end()));

    x_map.setScaleInterval(data_t_.front(), data_t_.back());
    y_map.setScaleInterval(min - 1, max + 1);
}

void TimePlot::renderAndSend()
{
    QImage image(width_, height_, QImage::Format_RGB32);
    QPainter painter;
    painter.begin(&image);
    painter.fillRect(image.rect(), color_bg_);

    QRect r(0, 0, image.width(), image.height());

    x_map.setPaintInterval( r.left(), r.right() );
    y_map.setPaintInterval( r.bottom(), r.top() );

    if(basic_line_color_changed_) {
        calculateLineColors();
    }

    QwtPlotCurve curve[data_v_.size()];
    for(std::size_t  num_plot= 0; num_plot < data_v_.size(); ++num_plot) {
        painter.setRenderHint( QPainter::Antialiasing,
                               curve[num_plot].testRenderHint( QwtPlotItem::RenderAntialiased ) );
        painter.setRenderHint( QPainter::HighQualityAntialiasing,
                               curve[num_plot].testRenderHint( QwtPlotItem::RenderAntialiased ) );
        curve[num_plot].setBaseline(0.0);

        curve[num_plot].setPen(color_line_.at(num_plot), line_width_);
        curve[num_plot].setStyle(QwtPlotCurve::Lines);

        curve[num_plot].setBrush(QBrush(color_fill_, Qt::SolidPattern));

        curve[num_plot].setRawSamples(data_t_.data(), data_v_.at(num_plot).data(), data_t_.size());
        curve[num_plot].draw(&painter, x_map, y_map, r);
    }

    QwtLinearScaleEngine e;
    QwtPlotScaleItem scale_time(QwtScaleDraw::TopScale, y_map.s1());
    scale_time.setScaleDiv(e.divideScale(x_map.s1(), x_map.s2(), 10, 10));

    QwtPlotScaleItem scale_value(QwtScaleDraw::RightScale, x_map.s1());
    scale_value.setScaleDiv(e.divideScale(y_map.s1(), y_map.s2(), 10, 10));

    scale_time.draw(&painter, x_map, y_map, r);
    scale_value.draw(&painter, x_map, y_map, r);

    CvMatMessage::Ptr out_msg = std::make_shared<CvMatMessage>(enc::bgr, 0);
    out_msg->value = QtCvImageConverter::Converter<QImage>::QImage2Mat(image);

    msg::publish(out_, out_msg);
}

int TimePlot::getWidth() const
{
    return width_;
}

int TimePlot::getHeight() const
{
    return height_;
}

double TimePlot::getLineWidth() const
{
    return line_width_;
}

QColor TimePlot::getBackgroundColor() const
{
    return color_bg_;
}
QColor TimePlot::getLineColor(std::size_t idx) const
{
    return color_line_[idx];
}
QColor TimePlot::getFillColor() const
{
    return color_fill_;
}

const double* TimePlot::getTData() const
{
    return data_t_.data();
}
const double* TimePlot::getVData(std::size_t idx) const
{
    return data_v_.at(idx).data();
}
std::size_t TimePlot::getVDataCountNumCurves() const
{
    return data_v_.size();
}
std::size_t TimePlot::getCount() const
{
    return data_t_.size();
}

const QwtScaleMap& TimePlot::getXMap() const
{
    return x_map;
}
const QwtScaleMap& TimePlot::getYMap() const
{
    return y_map;
}

void TimePlot::calculateLineColors()
{
    int r,g,b,a;
    basic_line_color_.getRgb(&r,&g,&b,&a);
    QColor color;
    color.setRed(r);
    color.setGreen(g);
    color.setBlue(b);
    int h,s,v;
    color.getHsv(&h,&s,&v);

    for(std::size_t i = 0; i < num_plots_; ++i) {

        double hnew =  h + i * 360/num_plots_;
        while (hnew > 359 || hnew < 0) {
            if(hnew > 359) {
                hnew -= 360;
            }
            else if(hnew < 0) {
                hnew += 360;
            }

        }
        color.setHsv(hnew,s,v);
        color_line_[i] = color;
    }

    basic_line_color_changed_ = false;
    update();
}
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright © 2018-2019 Ruben Van Boxem
 *
 * 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.
 **/

/*
 * Boost.Spirit.X3 std::variant compatibility
 * See https://github.com/boostorg/spirit/issues/270#issuecomment-439160933.
 * This is incomplete, yet enables the enough functionality for its uses here.
 */

#ifndef SKUI_CSS_GRAMMAR_X3_STDVARIANT_H
#define SKUI_CSS_GRAMMAR_X3_STDVARIANT_H

#include <variant>

#include <boost/mpl/vector.hpp>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
#include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
#include <boost/spirit/home/x3/support/traits/variant_find_substitute.hpp>
#include <boost/spirit/home/x3/support/traits/variant_has_substitute.hpp>

// Based on: boost/spirit/home/x3/support/traits/variant_find_substitute.hpp
namespace boost::spirit::x3::traits
{
  template<typename... Ts> struct is_variant<std::variant<Ts...>> : mpl::true_ {};

  template<typename... Ts, typename Attribute>
  struct variant_find_substitute<std::variant<Ts...>, Attribute>
  {
    using variant_type = std::variant<Ts...>;
    using types = mpl::vector<Ts...>;
    using end = typename mpl::end<types>::type;

    using iter_1 = typename mpl::find_if<types, is_same<mpl::_1, Attribute>>::type;

    using iter = typename mpl::eval_if<is_same<iter_1, end>,
                                       mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute>>,
                                       mpl::identity<iter_1>>::type;

    using type = typename mpl::eval_if<is_same<iter, end>,
                                       mpl::identity<Attribute>,
                                       mpl::deref<iter>>::type;
  };

  template<typename... Ts>
  struct variant_find_substitute<std::variant<Ts...>, std::variant<Ts...>> : mpl::identity<std::variant<Ts...>> {};

  template<typename... Ts, typename Attribute>
  struct variant_has_substitute_impl<std::variant<Ts...>, Attribute>
  {
    // Find a type from the variant that can be a substitute for Attribute.
    // return true_ if one is found, else false_

    using types = mpl::vector<Ts...>;

    using end = typename mpl::end<types>::type;

    using iter_1 = typename mpl::find_if<types, is_same<mpl::_1, Attribute>>::type;

    using iter = typename mpl::eval_if<is_same<iter_1, end>,
                                       mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute>>,
                                       mpl::identity<iter_1>>::type;

    using type = mpl::not_<is_same<iter, end>>;
  };
}

#endif
<commit_msg>Let std::variant work when BOOST_SPIRIT_X3_DEBUG is defined.<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright © 2018-2019 Ruben Van Boxem
 *
 * 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.
 **/

/*
 * Boost.Spirit.X3 std::variant compatibility
 * See https://github.com/boostorg/spirit/issues/270#issuecomment-439160933.
 * This is incomplete, yet enables the enough functionality for its uses here.
 */

#ifndef SKUI_CSS_GRAMMAR_X3_STDVARIANT_H
#define SKUI_CSS_GRAMMAR_X3_STDVARIANT_H

#include <variant>

#include <boost/mpl/vector.hpp>
#include <boost/spirit/home/x3/support/traits/is_variant.hpp>
#include <boost/spirit/home/x3/support/traits/tuple_traits.hpp>
#include <boost/spirit/home/x3/support/traits/variant_find_substitute.hpp>
#include <boost/spirit/home/x3/support/traits/variant_has_substitute.hpp>

// Based on: boost/spirit/home/x3/support/traits/variant_find_substitute.hpp
namespace boost::spirit::x3::traits
{
  template<typename... Ts> struct is_variant<std::variant<Ts...>> : mpl::true_ {};

  template<typename... Ts, typename Attribute>
  struct variant_find_substitute<std::variant<Ts...>, Attribute>
  {
    using variant_type = std::variant<Ts...>;
    using types = mpl::vector<Ts...>;
    using end = typename mpl::end<types>::type;

    using iter_1 = typename mpl::find_if<types, is_same<mpl::_1, Attribute>>::type;

    using iter = typename mpl::eval_if<is_same<iter_1, end>,
                                       mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute>>,
                                       mpl::identity<iter_1>>::type;

    using type = typename mpl::eval_if<is_same<iter, end>,
                                       mpl::identity<Attribute>,
                                       mpl::deref<iter>>::type;
  };

  template<typename... Ts>
  struct variant_find_substitute<std::variant<Ts...>, std::variant<Ts...>> : mpl::identity<std::variant<Ts...>> {};

  template<typename... Ts, typename Attribute>
  struct variant_has_substitute_impl<std::variant<Ts...>, Attribute>
  {
    // Find a type from the variant that can be a substitute for Attribute.
    // return true_ if one is found, else false_

    using types = mpl::vector<Ts...>;

    using end = typename mpl::end<types>::type;

    using iter_1 = typename mpl::find_if<types, is_same<mpl::_1, Attribute>>::type;

    using iter = typename mpl::eval_if<is_same<iter_1, end>,
                                       mpl::find_if<types, traits::is_substitute<mpl::_1, Attribute>>,
                                       mpl::identity<iter_1>>::type;

    using type = mpl::not_<is_same<iter, end>>;
  };

  template<typename Out, typename... Ts>
  void print_attribute(Out& out, const std::variant<Ts...>& variant)
  {
    std::visit([&out](const auto& value) { out << value; }, variant);
  }
}

#endif
<|endoftext|>


<commit_before><commit_msg>Use more ScopedTempDirs.<commit_after><|endoftext|>


<commit_before><commit_msg>Mark AutomatedUITestBase.OpenCloseBrowserWindowWithAccelerator as a flakey crash, as it has been failing on vista debug bots consistently.<commit_after><|endoftext|>


<commit_before>#include "Image.h"
#include "ImageLoader.h"

#include "dataset/TPNode.h"
#include "render/GL10.h"
#include "render/Shader.h"
#include "render/ShaderMgr.h"
//#include "render/DynamicTexture.h"
#include "render/DynamicTexAndFont.h"
#include "render/RenderList.h"
#include "common/tools.h"
#include "common/Exception.h"
#include "common/Math.h"
#include "common/Config.h"
#include "common/SettingData.h"
#include "common/TodoConfig.h"

#include <fstream>
#include <SOIL/SOIL.h>
#include <easyimage.h>
#include <wx/filename.h>

//#define USE_SOIL

namespace d2d
{

Image::Image()
	: m_pixels(NULL)
{
	m_textureID = 0;
	m_width = m_height = 0;
}

Image::~Image()
{
	ImageMgr::Instance()->removeItem(m_filepath);
	delete m_pixels;
}

bool Image::loadFromFile(const wxString& filepath)
{
	if (!wxFileName::FileExists(filepath)) {
		throw Exception("File: %s don't exist!", filepath.ToStdString().c_str());
	}

	m_filepath = filepath;

// 	m_region.xMin = - m_width * 0.5f;
// 	m_region.xMax =   m_width * 0.5f;
// 	m_region.yMin = - m_height * 0.5f;
// 	m_region.yMax =   m_height * 0.5f;

#ifdef NOT_LOAD_IMAGE
	return true;
#endif

 	reload();
 	if (m_textureID == 0)
 	{
//		assert(0);
//		m_width = m_height = 0;
 		return true;
 	}
 	else
 	{
#ifdef USE_SOIL
  		GL10::BindTexture(GL10::GL_TEXTURE_2D, m_textureID);
  		GL10::GetTexLevelParameteriv(GL10::GL_TEXTURE_2D, 0, GL10::GL_TEXTURE_WIDTH, &m_width);
  		GL10::GetTexLevelParameteriv(GL10::GL_TEXTURE_2D, 0, GL10::GL_TEXTURE_HEIGHT, &m_height);
  		GL10::BindTexture(GL10::GL_TEXTURE_2D, NULL);
#endif
		if (Config::Instance()->GetSettings().open_image_edge_clip)
		{
			eimage::ImageProcessor processor(this);
			d2d::Rect r = processor.trim();
			if (r.isValid()) {
				r.translate(d2d::Vector(-m_width*0.5f, -m_height*0.5f));
				m_region = r;
			}
		}
		else
		{
			m_region.xMin = - m_width * 0.5f;
			m_region.xMax =   m_width * 0.5f;
			m_region.yMin = - m_height * 0.5f;
			m_region.yMax =   m_height * 0.5f;
		}

// 		// todo
// 		DynamicTexture::Instance()->Insert(this);
		if (Config::Instance()->IsUseDTex()) {
			DynamicTexAndFont::Instance()->AddImage(this);
		}

 		return true;
 	}
}

void Image::reload()
{
#ifdef USE_SOIL
 	m_textureID = SOIL_load_OGL_texture
 		(
 		m_filepath.c_str(),
 		SOIL_LOAD_AUTO,
 		m_textureID,
 		SOIL_FLAG_INVERT_Y
 		);
#else
	m_pixels = ImageLoader::loadTexture(m_filepath.ToStdString(), m_width, m_height, m_textureID, m_channels);

 	m_region.xMin = - m_width * 0.5f;
 	m_region.xMax =   m_width * 0.5f;
 	m_region.yMin = - m_height * 0.5f;
 	m_region.yMax =   m_height * 0.5f;

#endif
}

void Image::draw(const Matrix& mt, const Rect& r) const
{
	////////////////////////////////////////////////////////////////////////////
	//// ԭʼ ֱӻ
 //   	ShaderMgr* shader = ShaderMgr::Instance();
 //   	shader->sprite();
 //
 //   	float tot_hw = m_width * 0.5f,
 //   		  tot_hh = m_height * 0.5f;
 //   	float txmin = (r.xMin + tot_hw) / m_width,
 //   		txmax = (r.xMax + tot_hw) / m_width,
 //   		tymin = (r.yMin + tot_hh) / m_height,
 //   		tymax = (r.yMax + tot_hh) / m_height;
 //
 // 	d2d::Vector vertices[4];
 // 	vertices[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
 // 	vertices[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
 // 	vertices[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
 // 	vertices[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);
 //
 // 	for (int i = 0; i < 4; ++i) {
 // 		scr.TransPosForRender(vertices[i]);
 // 	}
 //
 // 	float vb[16];
 // 	vb[0] = vertices[0].x;
 // 	vb[1] = vertices[0].y;
 // 	vb[2] = txmin;
 // 	vb[3] = tymin;
 // 	vb[4] = vertices[1].x;
 // 	vb[5] = vertices[1].y;
 // 	vb[6] = txmax;
 // 	vb[7] = tymin;
 // 	vb[8] = vertices[2].x;
 // 	vb[9] = vertices[2].y;
 // 	vb[10] = txmax;
 // 	vb[11] = tymax;
 // 	vb[12] = vertices[3].x;
 // 	vb[13] = vertices[3].y;
 // 	vb[14] = txmin;
 // 	vb[15] = tymax;
 //
 // 	shader->Draw(vb, m_textureID);

	//////////////////////////////////////////////////////////////////////////
//	renderlist
// 	d2d::Vector vertices[4];
// 	vertices[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
// 	vertices[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
// 	vertices[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
// 	vertices[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);
// 	for (int i = 0; i < 4; ++i) {
// 		scr.TransPosForRender(vertices[i]);
// 	}
//
// 	d2d::Vector texcoords[4];
// 	float tot_hw = m_width * 0.5f,
// 		tot_hh = m_height * 0.5f;
// 	float txmin = (r.xMin + tot_hw) / m_width,
// 		txmax = (r.xMax + tot_hw) / m_width,
// 		tymin = (r.yMin + tot_hh) / m_height,
// 		tymax = (r.yMax + tot_hh) / m_height;
// 	texcoords[0].set(txmin, tymin);
// 	texcoords[1].set(txmax, tymin);
// 	texcoords[2].set(txmax, tymax);
// 	texcoords[3].set(txmin, tymax);
//
// 	RenderList::Instance()->Insert(m_textureID, vertices, texcoords);

	//////////////////////////////////////////////////////////////////////////
	// dtex
 	d2d::Vector vertices[4];
 	vertices[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
 	vertices[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
 	vertices[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
 	vertices[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);

	int texid;
	d2d::Vector texcoords[4];
	float txmin, txmax, tymin, tymax;
	//DynamicTexture* dt = DynamicTexture::Instance();
	DynamicTexAndFont* dt = DynamicTexAndFont::Instance();
	const TPNode* n = dt->Query(m_filepath);
 	if (n)
 	{
 		float padding = dt->GetPadding();
 		int width = dt->GetWidth();
 		int height = dt->GetHeight();
 		texid = dt->GetTextureID();
 		txmin = (n->GetMinX()+padding+0.5f) / width;
 		txmax = (n->GetMaxX()-padding-0.5f) / width;
 		tymin = (n->GetMinY()+padding+0.5f) / height;
 		tymax = (n->GetMaxY()-padding-0.5f) / height;

		if (texid != 1) {
			wxLogDebug(_T("img dt's tex = %d"), texid);
		}

 		if (n->IsRotated())
 		{
 			d2d::Vector tmp = vertices[3];
 			vertices[3] = vertices[2];
 			vertices[2] = vertices[1];
 			vertices[1] = vertices[0];
 			vertices[0] = tmp;
 		}
 	}
 	else
	{
		wxLogDebug("Fail to insert dtex: %s", m_filepath.c_str());

		texid = m_textureID;
	 	d2d::Vector texcoords[4];
	 	float tot_hw = m_width * 0.5f,
	 		tot_hh = m_height * 0.5f;
	 	txmin = (r.xMin + tot_hw) / m_width;
	 	txmax = (r.xMax + tot_hw) / m_width;
	 	tymin = (r.yMin + tot_hh) / m_height;
	 	tymax = (r.yMax + tot_hh) / m_height;
	}
 	texcoords[0].set(txmin, tymin);
 	texcoords[1].set(txmax, tymin);
 	texcoords[2].set(txmax, tymax);
 	texcoords[3].set(txmin, tymax);

//	RenderList::Instance()->Insert(texid, vertices, texcoords);

	ShaderMgr* shader = ShaderMgr::Instance();
	shader->sprite();
	shader->Draw(vertices, texcoords, texid);
}

} // d2d<commit_msg>[FIXED] 打包是不读image，image范围不对，导致offset sprite错误<commit_after>#include "Image.h"
#include "ImageLoader.h"

#include "dataset/TPNode.h"
#include "render/GL10.h"
#include "render/Shader.h"
#include "render/ShaderMgr.h"
//#include "render/DynamicTexture.h"
#include "render/DynamicTexAndFont.h"
#include "render/RenderList.h"
#include "common/tools.h"
#include "common/Exception.h"
#include "common/Math.h"
#include "common/Config.h"
#include "common/SettingData.h"
#include "common/TodoConfig.h"

#include <fstream>
#include <SOIL/SOIL.h>
#include <easyimage.h>
#include <wx/filename.h>

//#define USE_SOIL

namespace d2d
{

Image::Image()
	: m_pixels(NULL)
{
	m_textureID = 0;
	m_width = m_height = 0;
}

Image::~Image()
{
	ImageMgr::Instance()->removeItem(m_filepath);
	delete m_pixels;
}

bool Image::loadFromFile(const wxString& filepath)
{
	if (filepath.Contains("1107_1") == 0) {
		int zz = 0;
	}

	if (!wxFileName::FileExists(filepath)) {
		throw Exception("File: %s don't exist!", filepath.ToStdString().c_str());
	}

	m_filepath = filepath;

#ifdef NOT_LOAD_IMAGE
	// todo
	m_region.xMin = m_region.xMax = m_region.yMin = m_region.yMax = 0;
	return true;
#endif

 	reload();
 	if (m_textureID == 0)
 	{
//		assert(0);
//		m_width = m_height = 0;
 		return true;
 	}
 	else
 	{
#ifdef USE_SOIL
  		GL10::BindTexture(GL10::GL_TEXTURE_2D, m_textureID);
  		GL10::GetTexLevelParameteriv(GL10::GL_TEXTURE_2D, 0, GL10::GL_TEXTURE_WIDTH, &m_width);
  		GL10::GetTexLevelParameteriv(GL10::GL_TEXTURE_2D, 0, GL10::GL_TEXTURE_HEIGHT, &m_height);
  		GL10::BindTexture(GL10::GL_TEXTURE_2D, NULL);
#endif
		if (Config::Instance()->GetSettings().open_image_edge_clip)
		{
			eimage::ImageProcessor processor(this);
			d2d::Rect r = processor.trim();
			if (r.isValid()) {
				r.translate(d2d::Vector(-m_width*0.5f, -m_height*0.5f));
				m_region = r;
			}
		}
		else
		{
			m_region.xMin = - m_width * 0.5f;
			m_region.xMax =   m_width * 0.5f;
			m_region.yMin = - m_height * 0.5f;
			m_region.yMax =   m_height * 0.5f;
		}

// 		// todo
// 		DynamicTexture::Instance()->Insert(this);
		if (Config::Instance()->IsUseDTex()) {
			DynamicTexAndFont::Instance()->AddImage(this);
		}

 		return true;
 	}
}

void Image::reload()
{
#ifdef USE_SOIL
 	m_textureID = SOIL_load_OGL_texture
 		(
 		m_filepath.c_str(),
 		SOIL_LOAD_AUTO,
 		m_textureID,
 		SOIL_FLAG_INVERT_Y
 		);
#else
	m_pixels = ImageLoader::loadTexture(m_filepath.ToStdString(), m_width, m_height, m_textureID, m_channels);

 	m_region.xMin = - m_width * 0.5f;
 	m_region.xMax =   m_width * 0.5f;
 	m_region.yMin = - m_height * 0.5f;
 	m_region.yMax =   m_height * 0.5f;

#endif
}

void Image::draw(const Matrix& mt, const Rect& r) const
{
	////////////////////////////////////////////////////////////////////////////
	//// ԭʼ ֱӻ
 //   	ShaderMgr* shader = ShaderMgr::Instance();
 //   	shader->sprite();
 //
 //   	float tot_hw = m_width * 0.5f,
 //   		  tot_hh = m_height * 0.5f;
 //   	float txmin = (r.xMin + tot_hw) / m_width,
 //   		txmax = (r.xMax + tot_hw) / m_width,
 //   		tymin = (r.yMin + tot_hh) / m_height,
 //   		tymax = (r.yMax + tot_hh) / m_height;
 //
 // 	d2d::Vector vertices[4];
 // 	vertices[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
 // 	vertices[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
 // 	vertices[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
 // 	vertices[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);
 //
 // 	for (int i = 0; i < 4; ++i) {
 // 		scr.TransPosForRender(vertices[i]);
 // 	}
 //
 // 	float vb[16];
 // 	vb[0] = vertices[0].x;
 // 	vb[1] = vertices[0].y;
 // 	vb[2] = txmin;
 // 	vb[3] = tymin;
 // 	vb[4] = vertices[1].x;
 // 	vb[5] = vertices[1].y;
 // 	vb[6] = txmax;
 // 	vb[7] = tymin;
 // 	vb[8] = vertices[2].x;
 // 	vb[9] = vertices[2].y;
 // 	vb[10] = txmax;
 // 	vb[11] = tymax;
 // 	vb[12] = vertices[3].x;
 // 	vb[13] = vertices[3].y;
 // 	vb[14] = txmin;
 // 	vb[15] = tymax;
 //
 // 	shader->Draw(vb, m_textureID);

	//////////////////////////////////////////////////////////////////////////
//	renderlist
// 	d2d::Vector vertices[4];
// 	vertices[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
// 	vertices[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
// 	vertices[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
// 	vertices[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);
// 	for (int i = 0; i < 4; ++i) {
// 		scr.TransPosForRender(vertices[i]);
// 	}
//
// 	d2d::Vector texcoords[4];
// 	float tot_hw = m_width * 0.5f,
// 		tot_hh = m_height * 0.5f;
// 	float txmin = (r.xMin + tot_hw) / m_width,
// 		txmax = (r.xMax + tot_hw) / m_width,
// 		tymin = (r.yMin + tot_hh) / m_height,
// 		tymax = (r.yMax + tot_hh) / m_height;
// 	texcoords[0].set(txmin, tymin);
// 	texcoords[1].set(txmax, tymin);
// 	texcoords[2].set(txmax, tymax);
// 	texcoords[3].set(txmin, tymax);
//
// 	RenderList::Instance()->Insert(m_textureID, vertices, texcoords);

	//////////////////////////////////////////////////////////////////////////
	// dtex
 	d2d::Vector vertices[4];
 	vertices[0] = Math::transVector(Vector(r.xMin, r.yMin), mt);
 	vertices[1] = Math::transVector(Vector(r.xMax, r.yMin), mt);
 	vertices[2] = Math::transVector(Vector(r.xMax, r.yMax), mt);
 	vertices[3] = Math::transVector(Vector(r.xMin, r.yMax), mt);

	int texid;
	d2d::Vector texcoords[4];
	float txmin, txmax, tymin, tymax;
	//DynamicTexture* dt = DynamicTexture::Instance();
	DynamicTexAndFont* dt = DynamicTexAndFont::Instance();
	const TPNode* n = dt->Query(m_filepath);
 	if (n)
 	{
 		float padding = dt->GetPadding();
 		int width = dt->GetWidth();
 		int height = dt->GetHeight();
 		texid = dt->GetTextureID();
 		txmin = (n->GetMinX()+padding+0.5f) / width;
 		txmax = (n->GetMaxX()-padding-0.5f) / width;
 		tymin = (n->GetMinY()+padding+0.5f) / height;
 		tymax = (n->GetMaxY()-padding-0.5f) / height;

		if (texid != 1) {
			wxLogDebug(_T("img dt's tex = %d"), texid);
		}

 		if (n->IsRotated())
 		{
 			d2d::Vector tmp = vertices[3];
 			vertices[3] = vertices[2];
 			vertices[2] = vertices[1];
 			vertices[1] = vertices[0];
 			vertices[0] = tmp;
 		}
 	}
 	else
	{
		wxLogDebug("Fail to insert dtex: %s", m_filepath.c_str());

		texid = m_textureID;
	 	d2d::Vector texcoords[4];
	 	float tot_hw = m_width * 0.5f,
	 		tot_hh = m_height * 0.5f;
	 	txmin = (r.xMin + tot_hw) / m_width;
	 	txmax = (r.xMax + tot_hw) / m_width;
	 	tymin = (r.yMin + tot_hh) / m_height;
	 	tymax = (r.yMax + tot_hh) / m_height;
	}
 	texcoords[0].set(txmin, tymin);
 	texcoords[1].set(txmax, tymin);
 	texcoords[2].set(txmax, tymax);
 	texcoords[3].set(txmin, tymax);

//	RenderList::Instance()->Insert(texid, vertices, texcoords);

	ShaderMgr* shader = ShaderMgr::Instance();
	shader->sprite();
	shader->Draw(vertices, texcoords, texid);
}

} // d2d<|endoftext|>


<commit_before>#include "kinetic_scroller.hpp"
#include "visual_params.hpp"

#include "indexer/scales.hpp"

#include "base/logging.hpp"

namespace df
{

double const kKineticDuration = 0.375;
double const kKineticFeedbackStart = 0.1;
double const kKineticFeedbackEnd = 0.5;
double const kKineticFadeoff = 5.0;
double const kKineticThreshold = 10.0;
double const kKineticInertia = 0.8;
double const kKineticMaxSpeed = 2000.0; // pixels per second

double CalculateKineticFeedback(ScreenBase const & modelView)
{
  double const kMinZoom = 1.0;
  double const kMaxZoom = scales::UPPER_STYLE_SCALE + 1.0;
  double const zoomLevel = my::clamp(fabs(log(modelView.GetScale()) / log(2.0)), kMinZoom, kMaxZoom);
  double const lerpCoef = 1.0 - ((zoomLevel - kMinZoom) / (kMaxZoom - kMinZoom));

  return kKineticFeedbackStart * lerpCoef + kKineticFeedbackEnd * (1.0 - lerpCoef);
}

class KineticScrollAnimation : public BaseModelViewAnimation
{
public:
  // startRect - mercator visible on screen rect in moment when user release fingers
  // direction - mercator space direction of moving. length(direction) - mercator distance on wich map will be offset
  KineticScrollAnimation(m2::AnyRectD const & startRect, m2::PointD const & direction, double duration)
    : BaseModelViewAnimation(duration)
    , m_targetCenter(startRect.GlobalCenter() + direction)
    , m_angle(startRect.Angle())
    , m_localRect(startRect.GetLocalRect())
    , m_direction(direction)
  {
  }

  m2::AnyRectD GetCurrentRect(ScreenBase const & screen) const override
  {
    // current position = target position - amplutide * e ^ (elapsed / duration)
    // we calculate current position not based on start position, but based on target position
    return m2::AnyRectD(m_targetCenter - m_direction * exp(-kKineticFadeoff * GetT()), m_angle, m_localRect);
  }

  m2::AnyRectD GetTargetRect(ScreenBase const & screen) const override
  {
    return GetCurrentRect(screen);
  }

private:
  m2::PointD m_targetCenter;
  ang::AngleD m_angle;
  m2::RectD m_localRect;
  m2::PointD m_direction;
};

KineticScroller::KineticScroller()
  : m_lastTimestamp(-1.0)
  , m_direction(m2::PointD::Zero())
{
}

void KineticScroller::InitGrab(ScreenBase const & modelView, double timeStamp)
{
  ASSERT_LESS(m_lastTimestamp, 0.0, ());
  m_lastTimestamp = timeStamp;
  m_lastRect = modelView.GlobalRect();
}

bool KineticScroller::IsActive() const
{
  return m_lastTimestamp > 0.0;
}

void KineticScroller::GrabViewRect(ScreenBase const & modelView, double timeStamp)
{
  // In KineitcScroller we store m_direction in mixed state
  // Direction in mercator space, and length(m_direction) in pixel space
  // We need same reaction on different zoom levels, and should calculate velocity on pixel space
  ASSERT_GREATER(m_lastTimestamp, 0.0, ());
  ASSERT_GREATER(timeStamp, m_lastTimestamp, ());
  double elapsed = timeStamp - m_lastTimestamp;

  m2::PointD lastCenter = m_lastRect.GlobalCenter();
  m2::PointD currentCenter = modelView.GlobalRect().GlobalCenter();
  double pxDeltaLength = (modelView.GtoP(currentCenter) - modelView.GtoP(lastCenter)).Length();
  m2::PointD delta = (currentCenter - lastCenter);
  if (!delta.IsAlmostZero())
    delta = delta.Normalize();

  // velocity on pixels
  double v = pxDeltaLength / elapsed;
  if (v > kKineticMaxSpeed)
    v = kKineticMaxSpeed;

  // at this point length(m_direction) already in pixel space, and delta normalized
  m_direction = delta * kKineticInertia * v + m_direction * (1.0 - kKineticInertia);

  m_lastTimestamp = timeStamp;
  m_lastRect = modelView.GlobalRect();
}

void KineticScroller::CancelGrab()
{
  m_lastTimestamp = -1;
  m_direction = m2::PointD::Zero();
}

unique_ptr<BaseModelViewAnimation> KineticScroller::CreateKineticAnimation(ScreenBase const & modelView)
{
  static double kVelocityThreshold = kKineticThreshold * VisualParams::Instance().GetVisualScale();
  if (m_direction.Length() < kVelocityThreshold)
    return unique_ptr<BaseModelViewAnimation>();

  // Before we start animation we have to convert length(m_direction) from pixel space to mercator space
  m2::PointD center = m_lastRect.GlobalCenter();
  double glbLength = CalculateKineticFeedback(modelView) * (modelView.PtoG(modelView.GtoP(center) + m_direction) - center).Length();
  m2::PointD glbDirection = m_direction.Normalize() * glbLength;
  m2::PointD targetCenter = center + glbDirection;
  if (!df::GetWorldRect().IsPointInside(targetCenter))
    return unique_ptr<BaseModelViewAnimation>();

  return unique_ptr<BaseModelViewAnimation>(new KineticScrollAnimation(m_lastRect, glbDirection, kKineticDuration));
}

} // namespace df
<commit_msg>Review fixes<commit_after>#include "kinetic_scroller.hpp"
#include "visual_params.hpp"

#include "indexer/scales.hpp"

#include "base/logging.hpp"

namespace df
{

double const kKineticDuration = 0.375;
double const kKineticFeedbackStart = 0.1;
double const kKineticFeedbackEnd = 0.5;
double const kKineticFadeoff = 5.0;
double const kKineticThreshold = 10.0;
double const kKineticInertia = 0.8;
double const kKineticMaxSpeed = 2000.0; // pixels per second

double CalculateKineticFeedback(ScreenBase const & modelView)
{
  double const kMinZoom = 1.0;
  double const kMaxZoom = scales::UPPER_STYLE_SCALE + 1.0;
  double const zoomLevel = my::clamp(fabs(log(modelView.GetScale()) / log(2.0)), kMinZoom, kMaxZoom);
  double const lerpCoef = 1.0 - ((zoomLevel - kMinZoom) / (kMaxZoom - kMinZoom));

  return kKineticFeedbackStart * lerpCoef + kKineticFeedbackEnd * (1.0 - lerpCoef);
}

class KineticScrollAnimation : public BaseModelViewAnimation
{
public:
  // startRect - mercator visible on screen rect in moment when user release fingers
  // direction - mercator space direction of moving. length(direction) - mercator distance on wich map will be offset
  KineticScrollAnimation(m2::AnyRectD const & startRect, m2::PointD const & direction, double duration)
    : BaseModelViewAnimation(duration)
    , m_targetCenter(startRect.GlobalCenter() + direction)
    , m_angle(startRect.Angle())
    , m_localRect(startRect.GetLocalRect())
    , m_direction(direction)
  {
  }

  m2::AnyRectD GetCurrentRect(ScreenBase const & screen) const override
  {
    // current position = target position - amplutide * e ^ (elapsed / duration)
    // we calculate current position not based on start position, but based on target position
    return m2::AnyRectD(m_targetCenter - m_direction * exp(-kKineticFadeoff * GetT()), m_angle, m_localRect);
  }

  m2::AnyRectD GetTargetRect(ScreenBase const & screen) const override
  {
    return GetCurrentRect(screen);
  }

private:
  m2::PointD m_targetCenter;
  ang::AngleD m_angle;
  m2::RectD m_localRect;
  m2::PointD m_direction;
};

KineticScroller::KineticScroller()
  : m_lastTimestamp(-1.0)
  , m_direction(m2::PointD::Zero())
{
}

void KineticScroller::InitGrab(ScreenBase const & modelView, double timeStamp)
{
  ASSERT_LESS(m_lastTimestamp, 0.0, ());
  m_lastTimestamp = timeStamp;
  m_lastRect = modelView.GlobalRect();
}

bool KineticScroller::IsActive() const
{
  return m_lastTimestamp > 0.0;
}

void KineticScroller::GrabViewRect(ScreenBase const & modelView, double timeStamp)
{
  // In KineitcScroller we store m_direction in mixed state
  // Direction in mercator space, and length(m_direction) in pixel space
  // We need same reaction on different zoom levels, and should calculate velocity on pixel space
  ASSERT_GREATER(m_lastTimestamp, 0.0, ());
  ASSERT_GREATER(timeStamp, m_lastTimestamp, ());
  double elapsed = timeStamp - m_lastTimestamp;

  m2::PointD lastCenter = m_lastRect.GlobalCenter();
  m2::PointD currentCenter = modelView.GlobalRect().GlobalCenter();
  double pxDeltaLength = (modelView.GtoP(currentCenter) - modelView.GtoP(lastCenter)).Length();
  m2::PointD delta = (currentCenter - lastCenter);
  if (!delta.IsAlmostZero())
    delta = delta.Normalize();

  // velocity on pixels
  double v = min(pxDeltaLength / elapsed, kKineticMaxSpeed);

  // at this point length(m_direction) already in pixel space, and delta normalized
  m_direction = delta * kKineticInertia * v + m_direction * (1.0 - kKineticInertia);

  m_lastTimestamp = timeStamp;
  m_lastRect = modelView.GlobalRect();
}

void KineticScroller::CancelGrab()
{
  m_lastTimestamp = -1;
  m_direction = m2::PointD::Zero();
}

unique_ptr<BaseModelViewAnimation> KineticScroller::CreateKineticAnimation(ScreenBase const & modelView)
{
  static double kVelocityThreshold = kKineticThreshold * VisualParams::Instance().GetVisualScale();
  if (m_direction.Length() < kVelocityThreshold)
    return unique_ptr<BaseModelViewAnimation>();

  // Before we start animation we have to convert length(m_direction) from pixel space to mercator space
  m2::PointD center = m_lastRect.GlobalCenter();
  double glbLength = CalculateKineticFeedback(modelView) * (modelView.PtoG(modelView.GtoP(center) + m_direction) - center).Length();
  m2::PointD glbDirection = m_direction.Normalize() * glbLength;
  m2::PointD targetCenter = center + glbDirection;
  if (!df::GetWorldRect().IsPointInside(targetCenter))
    return unique_ptr<BaseModelViewAnimation>();

  return unique_ptr<BaseModelViewAnimation>(new KineticScrollAnimation(m_lastRect, glbDirection, kKineticDuration));
}

} // namespace df
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include "../make_random_data/make_random_data.hpp"
#include "../sort/merge.hpp"
#include "../sort/selection.hpp"
#include "../sort/insertion.hpp"
#include "../sort/bubble.hpp"

#define SORT    merge
#define SIZE    10

int main(void)
{
    int *data = make_random_data(SIZE);

    for(int i = 0; i < SIZE; ++i) printf("%d\n", data[i]);
    putchar('\n');

    SORT(data, SIZE);

    for(int i = 0; i < SIZE; ++i) printf("%d\n", data[i]);

    free_random_data(data);

    return 0;
}
<commit_msg>Remove main_for_testing_sort.cpp<commit_after><|endoftext|>