<commit_before>#include "SDLApplication.h"

#ifdef HX_MACOS
#include <CoreFoundation/CoreFoundation.h>
#endif

namespace lime {

	AutoGCRoot* Application::callback = 0;

	double Application::GetTicks () {

		return SDL_GetTicks ();

	}

	SDLApplication::SDLApplication () {

		SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER);

		currentUpdate = 0;
		lastUpdate = 0;
		nextUpdate = 0;

		KeyEvent keyEvent;
		MouseEvent mouseEvent;
		RenderEvent renderEvent;
		TouchEvent touchEvent;
		UpdateEvent updateEvent;
		WindowEvent windowEvent;

		#ifdef HX_MACOS
		CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL (CFBundleGetMainBundle ());
		char path[PATH_MAX];

		if (CFURLGetFileSystemRepresentation (resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) {

			chdir (path);

		}

		CFRelease (resourcesURL);
		#endif

	}

	SDLApplication::~SDLApplication () {

	}

	int SDLApplication::Exec () {

		Init ();

		while (active) {

			Update ();

		}

		return Quit ();

	}

	void SDLApplication::HandleEvent (SDL_Event* event) {

		switch (event->type) {

			case SDL_USEREVENT:

				currentUpdate = SDL_GetTicks ();
				updateEvent.deltaTime = currentUpdate - lastUpdate;
				lastUpdate = currentUpdate;

				while (nextUpdate <= currentUpdate) {

					nextUpdate += framePeriod;

				}

				UpdateEvent::Dispatch (&updateEvent);
				RenderEvent::Dispatch (&renderEvent);
				break;

			case SDL_JOYAXISMOTION:
			case SDL_JOYBALLMOTION:
			case SDL_JOYBUTTONDOWN:
			case SDL_JOYBUTTONUP:
			case SDL_JOYHATMOTION:
			case SDL_JOYDEVICEADDED:
			case SDL_JOYDEVICEREMOVED:

				//joy
				break;

			case SDL_KEYDOWN:
			case SDL_KEYUP:

				ProcessKeyEvent (event);
				break;

			case SDL_MOUSEMOTION:
			case SDL_MOUSEBUTTONDOWN:
			case SDL_MOUSEBUTTONUP:
			case SDL_MOUSEWHEEL:

				ProcessMouseEvent (event);
				break;

			case SDL_WINDOWEVENT:

				switch (event->window.event) {

					case SDL_WINDOWEVENT_SHOWN:
					case SDL_WINDOWEVENT_HIDDEN:
					case SDL_WINDOWEVENT_FOCUS_GAINED:
					case SDL_WINDOWEVENT_FOCUS_LOST:
					case SDL_WINDOWEVENT_MOVED:

						ProcessWindowEvent (event);
						break;

					case SDL_WINDOWEVENT_EXPOSED:

						RenderEvent::Dispatch (&renderEvent);
						break;

					case SDL_WINDOWEVENT_SIZE_CHANGED:

						ProcessWindowEvent (event);
						RenderEvent::Dispatch (&renderEvent);
						break;

					case SDL_WINDOWEVENT_CLOSE:

						ProcessWindowEvent (event);
						active = false;
						break;

				}

				break;

			case SDL_QUIT:

				//quit
				active = false;
				break;

		}

	}

	void SDLApplication::Init() {

		framePeriod = 1000.0 / 60.0;
		active = true;
		lastUpdate = SDL_GetTicks ();
		nextUpdate = lastUpdate;

	}

	void SDLApplication::ProcessKeyEvent (SDL_Event* event) {

		if (KeyEvent::callback) {

			switch (event->type) {

				case SDL_KEYDOWN: keyEvent.type = KEY_DOWN; break;
				case SDL_KEYUP: keyEvent.type = KEY_UP; break;

			}

			keyEvent.keyCode = event->key.keysym.sym;

			KeyEvent::Dispatch (&keyEvent);

		}

	}

	void SDLApplication::ProcessMouseEvent (SDL_Event* event) {

		if (MouseEvent::callback) {

			switch (event->type) {

				case SDL_MOUSEMOTION: mouseEvent.type = MOUSE_MOVE; break;
				case SDL_MOUSEBUTTONDOWN: mouseEvent.type = MOUSE_DOWN; break;
				case SDL_MOUSEBUTTONUP: mouseEvent.type = MOUSE_UP; break;
				case SDL_MOUSEWHEEL: mouseEvent.type = MOUSE_WHEEL; break;

			}

			if (event->type != SDL_MOUSEWHEEL) {

				mouseEvent.button = event->button.button - 1;
				mouseEvent.x = event->button.x;
				mouseEvent.y = event->button.y;

			} else {

				mouseEvent.x = event->wheel.x;
				mouseEvent.y = event->wheel.y;

			}

			MouseEvent::Dispatch (&mouseEvent);

		}

	}

	void SDLApplication::ProcessTouchEvent (SDL_Event* event) {

	}

	void SDLApplication::ProcessWindowEvent (SDL_Event* event) {

		if (WindowEvent::callback) {

			switch (event->window.event) {

				case SDL_WINDOWEVENT_SHOWN: windowEvent.type = WINDOW_ACTIVATE; break;
				case SDL_WINDOWEVENT_CLOSE: windowEvent.type = WINDOW_CLOSE; break;
				case SDL_WINDOWEVENT_HIDDEN: windowEvent.type = WINDOW_DEACTIVATE; break;
				case SDL_WINDOWEVENT_FOCUS_GAINED: windowEvent.type = WINDOW_FOCUS_IN; break;
				case SDL_WINDOWEVENT_FOCUS_LOST: windowEvent.type = WINDOW_FOCUS_OUT; break;

				case SDL_WINDOWEVENT_MOVED:

					windowEvent.type = WINDOW_MOVE;
					windowEvent.x = event->window.data1;
					windowEvent.y = event->window.data2;
					break;

				case SDL_WINDOWEVENT_SIZE_CHANGED:

					windowEvent.type = WINDOW_RESIZE;
					windowEvent.width = event->window.data1;
					windowEvent.height = event->window.data2;
					break;

			}

			WindowEvent::Dispatch (&windowEvent);

		}

	}

	int SDLApplication::Quit () {

		windowEvent.type = WINDOW_DEACTIVATE;
		WindowEvent::Dispatch (&windowEvent);

		SDL_Quit ();

		return 0;

	}

	static SDL_TimerID timerID = 0;
	bool timerActive = false;
	bool firstTime = true;

	Uint32 OnTimer (Uint32 interval, void *) {

		SDL_Event event;
		SDL_UserEvent userevent;
		userevent.type = SDL_USEREVENT;
		userevent.code = 0;
		userevent.data1 = NULL;
		userevent.data2 = NULL;
		event.type = SDL_USEREVENT;
		event.user = userevent;

		timerActive = false;
		timerID = 0;

		SDL_PushEvent (&event);

		return 0;

	}

	bool SDLApplication::Update () {

		SDL_Event event;
		event.type = -1;

		if (active && (firstTime || SDL_WaitEvent (&event))) {

			firstTime = false;

			HandleEvent (&event);
			event.type = -1;
			if (!active)
				return active;

			if (SDL_PollEvent (&event)) {

				HandleEvent (&event);
				event.type = -1;

			}

			currentUpdate = SDL_GetTicks ();

			if (currentUpdate >= nextUpdate) {

				SDL_RemoveTimer (timerID);
				OnTimer (0, 0);

			} else if (!timerActive) {

				timerActive = true;
				timerID = SDL_AddTimer (nextUpdate - currentUpdate, OnTimer, 0);

			}

		}

		return active;

	}

	Application* CreateApplication () {

		return new SDLApplication ();

	}

}

#ifdef ANDROID
int SDL_main (int argc, char *argv[]) { return 0; }
#endif<commit_msg>Setting key modifier value in SDL key event<commit_after>#include "SDLApplication.h"

#ifdef HX_MACOS
#include <CoreFoundation/CoreFoundation.h>
#endif

namespace lime {

	AutoGCRoot* Application::callback = 0;

	double Application::GetTicks () {

		return SDL_GetTicks ();

	}

	SDLApplication::SDLApplication () {

		SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER);

		currentUpdate = 0;
		lastUpdate = 0;
		nextUpdate = 0;

		KeyEvent keyEvent;
		MouseEvent mouseEvent;
		RenderEvent renderEvent;
		TouchEvent touchEvent;
		UpdateEvent updateEvent;
		WindowEvent windowEvent;

		#ifdef HX_MACOS
		CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL (CFBundleGetMainBundle ());
		char path[PATH_MAX];

		if (CFURLGetFileSystemRepresentation (resourcesURL, TRUE, (UInt8 *)path, PATH_MAX)) {

			chdir (path);

		}

		CFRelease (resourcesURL);
		#endif

	}

	SDLApplication::~SDLApplication () {

	}

	int SDLApplication::Exec () {

		Init ();

		while (active) {

			Update ();

		}

		return Quit ();

	}

	void SDLApplication::HandleEvent (SDL_Event* event) {

		switch (event->type) {

			case SDL_USEREVENT:

				currentUpdate = SDL_GetTicks ();
				updateEvent.deltaTime = currentUpdate - lastUpdate;
				lastUpdate = currentUpdate;

				while (nextUpdate <= currentUpdate) {

					nextUpdate += framePeriod;

				}

				UpdateEvent::Dispatch (&updateEvent);
				RenderEvent::Dispatch (&renderEvent);
				break;

			case SDL_JOYAXISMOTION:
			case SDL_JOYBALLMOTION:
			case SDL_JOYBUTTONDOWN:
			case SDL_JOYBUTTONUP:
			case SDL_JOYHATMOTION:
			case SDL_JOYDEVICEADDED:
			case SDL_JOYDEVICEREMOVED:

				//joy
				break;

			case SDL_KEYDOWN:
			case SDL_KEYUP:

				ProcessKeyEvent (event);
				break;

			case SDL_MOUSEMOTION:
			case SDL_MOUSEBUTTONDOWN:
			case SDL_MOUSEBUTTONUP:
			case SDL_MOUSEWHEEL:

				ProcessMouseEvent (event);
				break;

			case SDL_WINDOWEVENT:

				switch (event->window.event) {

					case SDL_WINDOWEVENT_SHOWN:
					case SDL_WINDOWEVENT_HIDDEN:
					case SDL_WINDOWEVENT_FOCUS_GAINED:
					case SDL_WINDOWEVENT_FOCUS_LOST:
					case SDL_WINDOWEVENT_MOVED:

						ProcessWindowEvent (event);
						break;

					case SDL_WINDOWEVENT_EXPOSED:

						RenderEvent::Dispatch (&renderEvent);
						break;

					case SDL_WINDOWEVENT_SIZE_CHANGED:

						ProcessWindowEvent (event);
						RenderEvent::Dispatch (&renderEvent);
						break;

					case SDL_WINDOWEVENT_CLOSE:

						ProcessWindowEvent (event);
						active = false;
						break;

				}

				break;

			case SDL_QUIT:

				//quit
				active = false;
				break;

		}

	}

	void SDLApplication::Init() {

		framePeriod = 1000.0 / 60.0;
		active = true;
		lastUpdate = SDL_GetTicks ();
		nextUpdate = lastUpdate;

	}

	void SDLApplication::ProcessKeyEvent (SDL_Event* event) {

		if (KeyEvent::callback) {

			switch (event->type) {

				case SDL_KEYDOWN: keyEvent.type = KEY_DOWN; break;
				case SDL_KEYUP: keyEvent.type = KEY_UP; break;

			}

			keyEvent.keyCode = event->key.keysym.sym;
			keyEvent.modifier = event->key.keysym.mod;

			KeyEvent::Dispatch (&keyEvent);

		}

	}

	void SDLApplication::ProcessMouseEvent (SDL_Event* event) {

		if (MouseEvent::callback) {

			switch (event->type) {

				case SDL_MOUSEMOTION: mouseEvent.type = MOUSE_MOVE; break;
				case SDL_MOUSEBUTTONDOWN: mouseEvent.type = MOUSE_DOWN; break;
				case SDL_MOUSEBUTTONUP: mouseEvent.type = MOUSE_UP; break;
				case SDL_MOUSEWHEEL: mouseEvent.type = MOUSE_WHEEL; break;

			}

			if (event->type != SDL_MOUSEWHEEL) {

				mouseEvent.button = event->button.button - 1;
				mouseEvent.x = event->button.x;
				mouseEvent.y = event->button.y;

			} else {

				mouseEvent.x = event->wheel.x;
				mouseEvent.y = event->wheel.y;

			}

			MouseEvent::Dispatch (&mouseEvent);

		}

	}

	void SDLApplication::ProcessTouchEvent (SDL_Event* event) {

	}

	void SDLApplication::ProcessWindowEvent (SDL_Event* event) {

		if (WindowEvent::callback) {

			switch (event->window.event) {

				case SDL_WINDOWEVENT_SHOWN: windowEvent.type = WINDOW_ACTIVATE; break;
				case SDL_WINDOWEVENT_CLOSE: windowEvent.type = WINDOW_CLOSE; break;
				case SDL_WINDOWEVENT_HIDDEN: windowEvent.type = WINDOW_DEACTIVATE; break;
				case SDL_WINDOWEVENT_FOCUS_GAINED: windowEvent.type = WINDOW_FOCUS_IN; break;
				case SDL_WINDOWEVENT_FOCUS_LOST: windowEvent.type = WINDOW_FOCUS_OUT; break;

				case SDL_WINDOWEVENT_MOVED:

					windowEvent.type = WINDOW_MOVE;
					windowEvent.x = event->window.data1;
					windowEvent.y = event->window.data2;
					break;

				case SDL_WINDOWEVENT_SIZE_CHANGED:

					windowEvent.type = WINDOW_RESIZE;
					windowEvent.width = event->window.data1;
					windowEvent.height = event->window.data2;
					break;

			}

			WindowEvent::Dispatch (&windowEvent);

		}

	}

	int SDLApplication::Quit () {

		windowEvent.type = WINDOW_DEACTIVATE;
		WindowEvent::Dispatch (&windowEvent);

		SDL_Quit ();

		return 0;

	}

	static SDL_TimerID timerID = 0;
	bool timerActive = false;
	bool firstTime = true;

	Uint32 OnTimer (Uint32 interval, void *) {

		SDL_Event event;
		SDL_UserEvent userevent;
		userevent.type = SDL_USEREVENT;
		userevent.code = 0;
		userevent.data1 = NULL;
		userevent.data2 = NULL;
		event.type = SDL_USEREVENT;
		event.user = userevent;

		timerActive = false;
		timerID = 0;

		SDL_PushEvent (&event);

		return 0;

	}

	bool SDLApplication::Update () {

		SDL_Event event;
		event.type = -1;

		if (active && (firstTime || SDL_WaitEvent (&event))) {

			firstTime = false;

			HandleEvent (&event);
			event.type = -1;
			if (!active)
				return active;

			if (SDL_PollEvent (&event)) {

				HandleEvent (&event);
				event.type = -1;

			}

			currentUpdate = SDL_GetTicks ();

			if (currentUpdate >= nextUpdate) {

				SDL_RemoveTimer (timerID);
				OnTimer (0, 0);

			} else if (!timerActive) {

				timerActive = true;
				timerID = SDL_AddTimer (nextUpdate - currentUpdate, OnTimer, 0);

			}

		}

		return active;

	}

	Application* CreateApplication () {

		return new SDLApplication ();

	}

}

#ifdef ANDROID
int SDL_main (int argc, char *argv[]) { return 0; }
#endif<|endoftext|>


<commit_before>#include <ros/ros.h>
//#include <gazebo_msgs/ApplyJointEffort.h>
#include <urdf/model.h>
#include <urdf_interface/joint.h>
#include <cstdlib>
#include <sys/time.h>
#include <time.h>
#include <geometry_msgs/Pose.h>
#include <geometry_msgs/Twist.h>
#include <atlas_gazebo_msgs/RobotState.h>
#include <lcm/lcm-cpp.hpp>
#include <lcmtypes/drc_lcmtypes.hpp>
#include <atlas_gazebo_msgs/ActuatorCmd.h>

#include <std_msgs/Float64.h>

double getTime_now()
{
  struct timeval tv;
  gettimeofday (&tv,NULL);
  return (int64_t) tv.tv_sec*1000000+tv.tv_usec;
}

class ActuatorCmdHandler{
  private:
    ros::Publisher actuator_cmd_pub;
    ros::Publisher body_twist_cmd_pub;
    ros::Publisher rot_scan_cmd_pub;

    ros::NodeHandle actuator_cmd_node;
  public:
  ActuatorCmdHandler(ros::NodeHandle &node): actuator_cmd_node(node)
  {
   actuator_cmd_pub = actuator_cmd_node.advertise<atlas_gazebo_msgs::ActuatorCmd>("actuator_cmd",10);
   body_twist_cmd_pub = actuator_cmd_node.advertise<geometry_msgs::Twist>("cmd_vel",10);

   rot_scan_cmd_pub = actuator_cmd_node.advertise<std_msgs::Float64>("/multisense_sl/set_spindle_speed",10);
  }
  ~ActuatorCmdHandler() {}

  void actuator_cmd_Callback(const lcm::ReceiveBuffer* rbuf,const std::string &channel,const drc::actuator_cmd_t* msg)//what is rbuf and channel here?
  {
    atlas_gazebo_msgs::ActuatorCmd actuator_cmd_msg;
                long t = msg->utime*1000; // from usec to nsec
    actuator_cmd_msg.header.stamp.fromNSec(t);
    actuator_cmd_msg.robot_name = msg->robot_name;
    for(std::vector<int>::size_type i=0;i!=msg->actuator_name.size();i++){//So varaibles in lcm message are all in vector type
      actuator_cmd_msg.actuator_name.push_back(msg->actuator_name.at(i));
      actuator_cmd_msg.actuator_effort.push_back(msg->actuator_effort.at(i));
      actuator_cmd_msg.effort_duration.push_back(msg->effort_duration.at(i));
    }
    if(ros::ok())
    {
      actuator_cmd_pub.publish(actuator_cmd_msg);
      //ros::spinOnce(); // required?
    }

  }

  void body_twist_cmd_Callback(const lcm::ReceiveBuffer* rbuf,const std::string &channel,const drc::twist_t* msg)//what is rbuf and channel here?
  {
    geometry_msgs::Twist body_twist_cmd_msg;
    //long t = msg->utime*1000; // from usec to nsec

    body_twist_cmd_msg.linear.x =  msg->linear_velocity.x;
    body_twist_cmd_msg.linear.y =  msg->linear_velocity.y;
    body_twist_cmd_msg.linear.z =  msg->linear_velocity.z;
    body_twist_cmd_msg.angular.x =  msg->angular_velocity.x;
    body_twist_cmd_msg.angular.y =  msg->angular_velocity.y;
    body_twist_cmd_msg.angular.z =  msg->angular_velocity.z;

    if(ros::ok())
    {
      body_twist_cmd_pub.publish(body_twist_cmd_msg);
      //ros::spinOnce(); // required?
    }

  }

  void rot_scan_rate_cmd_Callback(const lcm::ReceiveBuffer* rbuf,const std::string &channel,const drc::twist_timed_t* msg)
  {
    std_msgs::Float64 rot_scan_cmd_msg;
    rot_scan_cmd_msg.data = msg->angular_velocity.x;

    if(ros::ok())
    {
      rot_scan_cmd_pub.publish(rot_scan_cmd_msg);
      //ros::spinOnce(); // required?
    }

  }

};

int main(int argc,char** argv)
{
  ros::init(argc,argv,"actuator_cmd_publisher",ros::init_options::NoSigintHandler);
        ros::NodeHandle actuator_cmd_node;

  lcm::LCM listener;
  if(!listener.good())
             return 1;
  ActuatorCmdHandler handlerObject(actuator_cmd_node);

  //LCM subscription
  listener.subscribe("ACTUATOR_CMDS",&ActuatorCmdHandler::actuator_cmd_Callback,&handlerObject);
  listener.subscribe("NAV_CMDS",&ActuatorCmdHandler::body_twist_cmd_Callback,&handlerObject);

  listener.subscribe("ROTATING_SCAN_RATE_CMD",&ActuatorCmdHandler::rot_scan_rate_cmd_Callback,&handlerObject);

  while(0 == listener.handle());
  return 0;
}

//   lcm::LCM talker;
//   if(!talker.good())
//     return 1;
//   drc::actuator_cmd_t actuator_cmd;
//   actuator_cmd.timestamp = 0;
//   actuator_cmd.robot_name = "wheeled_atlas";
//   actuator_cmd.num_joints = 2;
//   actuator_cmd.joint_name.push_back("LShoulderRoll");
//   actuator_cmd.joint_name.push_back("RShoulderRoll");
//   actuator_cmd.joint_effort.push_back(12.0);
//   actuator_cmd.joint_effort.push_back(-12.0);
//   actuator_cmd.duration.push_back(0.1);
//   actuator_cmd.duration.push_back(0.1);
// //   lcm::LCM listener;
//   if(!listener.good())
//              return 1;
//   ActuatorCmdHandler handler;
//   listener.subscribe("ACTUATOR_CMDS",&ActuatorCmdHandler::actuator_cmd_Callback,&handler);
//   while(true)
//   {
//           talker.publish("ACTUATOR_CMDS",&actuator_cmd);
//     listener.handle();
//   }
//   return 0;
<commit_msg>minor changes for estop<commit_after>#include <ros/ros.h>
//#include <gazebo_msgs/ApplyJointEffort.h>
#include <urdf/model.h>
#include <urdf_interface/joint.h>
#include <cstdlib>
#include <sys/time.h>
#include <time.h>
#include <geometry_msgs/Pose.h>
#include <geometry_msgs/Twist.h>
#include <atlas_gazebo_msgs/RobotState.h>
#include <lcm/lcm-cpp.hpp>
#include <lcmtypes/drc_lcmtypes.hpp>
#include <atlas_gazebo_msgs/ActuatorCmd.h>

#include <std_msgs/Float64.h>

double getTime_now()
{
  struct timeval tv;
  gettimeofday (&tv,NULL);
  return (int64_t) tv.tv_sec*1000000+tv.tv_usec;
}

class ActuatorCmdHandler{
  private:
    ros::Publisher actuator_cmd_pub;
    ros::Publisher body_twist_cmd_pub;
    ros::Publisher rot_scan_cmd_pub;
    ros::Publisher gas_pedal_pub;
    ros::Publisher brake_pedal_pub;

    ros::NodeHandle actuator_cmd_node;
  public:
  ActuatorCmdHandler(ros::NodeHandle &node): actuator_cmd_node(node)
  {
   actuator_cmd_pub = actuator_cmd_node.advertise<atlas_gazebo_msgs::ActuatorCmd>("actuator_cmd",10);
   body_twist_cmd_pub = actuator_cmd_node.advertise<geometry_msgs::Twist>("cmd_vel",10);

   rot_scan_cmd_pub = actuator_cmd_node.advertise<std_msgs::Float64>("/multisense_sl/set_spindle_speed",10);
   gas_pedal_pub = actuator_cmd_node.advertise<std_msgs::Float64>("mit_golf_cart/gas_pedal/cmd", 1000);
   brake_pedal_pub = actuator_cmd_node.advertise<std_msgs::Float64>("mit_golf_cart/brake_pedal/cmd", 1000);
  }
  ~ActuatorCmdHandler() {}

  void actuator_cmd_Callback(const lcm::ReceiveBuffer* rbuf,const std::string &channel,const drc::actuator_cmd_t* msg)//what is rbuf and channel here?
  {
    atlas_gazebo_msgs::ActuatorCmd actuator_cmd_msg;
                long t = msg->utime*1000; // from usec to nsec
    actuator_cmd_msg.header.stamp.fromNSec(t);
    actuator_cmd_msg.robot_name = msg->robot_name;
    for(std::vector<int>::size_type i=0;i!=msg->actuator_name.size();i++){//So varaibles in lcm message are all in vector type
      actuator_cmd_msg.actuator_name.push_back(msg->actuator_name.at(i));
      actuator_cmd_msg.actuator_effort.push_back(msg->actuator_effort.at(i));
      actuator_cmd_msg.effort_duration.push_back(msg->effort_duration.at(i));
    }
    if(ros::ok())
    {
      actuator_cmd_pub.publish(actuator_cmd_msg);
      //ros::spinOnce(); // required?
    }

  }

  void body_twist_cmd_Callback(const lcm::ReceiveBuffer* rbuf,const std::string &channel,const drc::twist_t* msg)//what is rbuf and channel here?
  {
    geometry_msgs::Twist body_twist_cmd_msg;
    //long t = msg->utime*1000; // from usec to nsec

    body_twist_cmd_msg.linear.x =  msg->linear_velocity.x;
    body_twist_cmd_msg.linear.y =  msg->linear_velocity.y;
    body_twist_cmd_msg.linear.z =  msg->linear_velocity.z;
    body_twist_cmd_msg.angular.x =  msg->angular_velocity.x;
    body_twist_cmd_msg.angular.y =  msg->angular_velocity.y;
    body_twist_cmd_msg.angular.z =  msg->angular_velocity.z;

    if(ros::ok())
    {
      body_twist_cmd_pub.publish(body_twist_cmd_msg);
      //ros::spinOnce(); // required?
    }

  }

  void estop_Callback(const lcm::ReceiveBuffer* rbuf,const std::string &channel,const drc::nav_goal_timed_t* msg)//what is rbuf and channel here?
  {
    if(ros::ok()){
      std_msgs::Float64 msg;
      msg.data = 1.0;
      brake_pedal_pub.publish(msg);

      std_msgs::Float64 gasmsg;
      gasmsg.data = 0.0;
      gas_pedal_pub.publish(gasmsg);
    }
  }

  // Only here to Demo Estop:
  void rot_scan_rate_cmd_Callback(const lcm::ReceiveBuffer* rbuf,const std::string &channel,const drc::twist_timed_t* msg)
  {
    std_msgs::Float64 rot_scan_cmd_msg;
    rot_scan_cmd_msg.data = msg->angular_velocity.x;
    if(ros::ok()){
      rot_scan_cmd_pub.publish(rot_scan_cmd_msg);
    }
  }

};

int main(int argc,char** argv)
{
  ros::init(argc,argv,"actuator_cmd_publisher",ros::init_options::NoSigintHandler);
        ros::NodeHandle actuator_cmd_node;

  lcm::LCM listener;
  if(!listener.good())
             return 1;
  ActuatorCmdHandler handlerObject(actuator_cmd_node);

  //LCM subscription
  listener.subscribe("ACTUATOR_CMDS",&ActuatorCmdHandler::actuator_cmd_Callback,&handlerObject);
  listener.subscribe("NAV_CMDS",&ActuatorCmdHandler::body_twist_cmd_Callback,&handlerObject);

  listener.subscribe("ROTATING_SCAN_RATE_CMD",&ActuatorCmdHandler::rot_scan_rate_cmd_Callback,&handlerObject);

  // Only here to Demo Estop:
  listener.subscribe("NAV_GOAL_ESTOP",&ActuatorCmdHandler::estop_Callback,&handlerObject);

  while(0 == listener.handle());
  return 0;
}

//   lcm::LCM talker;
//   if(!talker.good())
//     return 1;
//   drc::actuator_cmd_t actuator_cmd;
//   actuator_cmd.timestamp = 0;
//   actuator_cmd.robot_name = "wheeled_atlas";
//   actuator_cmd.num_joints = 2;
//   actuator_cmd.joint_name.push_back("LShoulderRoll");
//   actuator_cmd.joint_name.push_back("RShoulderRoll");
//   actuator_cmd.joint_effort.push_back(12.0);
//   actuator_cmd.joint_effort.push_back(-12.0);
//   actuator_cmd.duration.push_back(0.1);
//   actuator_cmd.duration.push_back(0.1);
// //   lcm::LCM listener;
//   if(!listener.good())
//              return 1;
//   ActuatorCmdHandler handler;
//   listener.subscribe("ACTUATOR_CMDS",&ActuatorCmdHandler::actuator_cmd_Callback,&handler);
//   while(true)
//   {
//           talker.publish("ACTUATOR_CMDS",&actuator_cmd);
//     listener.handle();
//   }
//   return 0;
<|endoftext|>


<commit_before>#include "../TestCase.hpp"
#include <ctime>

WRD_TEST_START(MemRobustTest)
	class A : public Object {
	public:
		virtual const Class& getClass() const {
			static TClass<A> in;
			return in;
		}

		int age;
	};
	class B : public A {
	public:
		virtual const Class& getClass() const {
			static TClass<B> in;
			return in;
		}

		float grade;
	};
class PInstance : public Thing {
	Id _id;
	virtual Res& release() { return wasgood; }
};
class PNode : public PInstance {};
class PObject : public PNode {};
class PA : public PObject {
public:
	virtual const Class& getClass() const {
		static TClass<PA> in;
		return in;
	}

	int age;
};
class PB : public PA {
public:
	virtual const Class& getClass() const {
		static TClass<PB> in;
		return in;
	}

	float grade;
};
	class Sprint {
	public:
		static void run(int n)
		{
			PA* parr[100000] = {0, };
			time_t start = clock();
			int crc = 0;
			for(int i=0; i < n ;i++) {
				parr[i] = new PB();
				crc += (int) parr[i];
			}
			for(int i=0; i < n ;i++)
				delete parr[i];
			WRD_WARN("%d times new/delete : %f ms elapsed. crc=%d", n, ((float) clock() - start) / CLOCKS_PER_SEC*1000.0f, crc);

			crc = 0;
			A* arr[100000] = {0, };
			start = clock();
			for(int i=0; i < n ;i++) {
				arr[i] = new B();
				crc += (int) arr[i];
			}
			for(int i=0; i < n ;i++)
				delete arr[i];
			WRD_WARN("%d times mempool    : %f ms elapsed. crc=%d", n, ((float) clock() - start) / CLOCKS_PER_SEC*1000.0f, crc);
		}
	};

	Sprint::run(10);
	Sprint::run(100);
	Sprint::run(1000);
	Sprint::run(10000);
	Sprint::run(50000);
	return "";
WRD_TEST_END(MemRobustTest)
<commit_msg>- [ut] permissive error on linux.<commit_after>#include "../TestCase.hpp"
#include <ctime>

WRD_TEST_START(MemRobustTest)
	class A : public Object {
	public:
		virtual const Class& getClass() const {
			static TClass<A> in;
			return in;
		}

		int age;
	};
	class B : public A {
	public:
		virtual const Class& getClass() const {
			static TClass<B> in;
			return in;
		}

		float grade;
	};
class PInstance : public Thing {
	Id _id;
	virtual Res& release() { return wasgood; }
};
class PNode : public PInstance {};
class PObject : public PNode {};
class PA : public PObject {
public:
	virtual const Class& getClass() const {
		static TClass<PA> in;
		return in;
	}

	int age;
};
class PB : public PA {
public:
	virtual const Class& getClass() const {
		static TClass<PB> in;
		return in;
	}

	float grade;
};
	class Sprint {
	public:
		static void run(int n)
		{
			PA* parr[100000] = {0, };
			time_t start = clock();
			int crc = 0;
			for(int i=0; i < n ;i++) {
				parr[i] = new PB();
				crc += *(int*) parr[i];
			}
			for(int i=0; i < n ;i++)
				delete parr[i];
			WRD_WARN("%d times new/delete : %f ms elapsed. crc=%d", n, ((float) clock() - start) / CLOCKS_PER_SEC*1000.0f, crc);

			crc = 0;
			A* arr[100000] = {0, };
			start = clock();
			for(int i=0; i < n ;i++) {
				arr[i] = new B();
				crc += *(int*) arr[i];
			}
			for(int i=0; i < n ;i++)
				delete arr[i];
			WRD_WARN("%d times mempool    : %f ms elapsed. crc=%d", n, ((float) clock() - start) / CLOCKS_PER_SEC*1000.0f, crc);
		}
	};

	Sprint::run(10);
	Sprint::run(100);
	Sprint::run(1000);
	Sprint::run(10000);
	Sprint::run(50000);
	return "";
WRD_TEST_END(MemRobustTest)
<|endoftext|>


<commit_before>// Copyright 2019 The TCMalloc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tcmalloc/experiment.h"

#include <string.h>

#include "absl/base/macros.h"
#include "absl/strings/str_cat.h"
#include "tcmalloc/internal/environment.h"
#include "tcmalloc/internal/logging.h"

using tcmalloc::internal::kNumExperiments;
using tcmalloc::tcmalloc_internal::thread_safe_getenv;

namespace tcmalloc {
namespace {

const char kDelimiter = ',';
const char kExperiments[] = "BORG_EXPERIMENTS";
const char kEnableAll[] = "enable-all-known-experiments";
const char kDisableExperiments[] = "BORG_DISABLE_EXPERIMENTS";
const char kDisableAll[] = "all";

bool LookupExperimentID(absl::string_view label, Experiment* exp) {
  for (auto config : experiments) {
    if (config.name == label) {
      *exp = config.id;
      return true;
    }
  }

  return false;
}

const bool* GetSelectedExperiments() {
  static bool by_id[kNumExperiments];

  static const char* active_experiments = thread_safe_getenv(kExperiments);
  static const char* disabled_experiments =
      thread_safe_getenv(kDisableExperiments);
  static const bool* status = internal::SelectExperiments(
      by_id, active_experiments ? active_experiments : "",
      disabled_experiments ? disabled_experiments : "");
  return status;
}

template <typename F>
void ParseExperiments(absl::string_view labels, F f) {
  absl::string_view::size_type pos = 0;
  do {
    absl::string_view token;
    auto end = labels.find(kDelimiter, pos);
    if (end == absl::string_view::npos) {
      token = labels.substr(pos);
      pos = end;
    } else {
      token = labels.substr(pos, end - pos);
      pos = end + 1;
    }

    f(token);
  } while (pos != absl::string_view::npos);
}

}  // namespace

namespace internal {

const bool* SelectExperiments(bool* buffer, absl::string_view active,
                              absl::string_view disabled) {
  memset(buffer, 0, sizeof(*buffer) * kNumExperiments);

  if (active == kEnableAll) {
    std::fill(buffer, buffer + kNumExperiments, true);
  }

  ParseExperiments(active, [buffer](absl::string_view token) {
    Experiment id;
    if (LookupExperimentID(token, &id)) {
      buffer[static_cast<int>(id)] = true;
    }
  });

  if (disabled == kDisableAll) {
    memset(buffer, 0, sizeof(*buffer) * kNumExperiments);
  }

  ParseExperiments(disabled, [buffer](absl::string_view token) {
    Experiment id;
    if (LookupExperimentID(token, &id)) {
      buffer[static_cast<int>(id)] = false;
    }
  });

  return buffer;
}

}  // namespace internal

bool IsExperimentActive(Experiment exp) {
  ASSERT(static_cast<int>(exp) >= 0);
  ASSERT(exp < Experiment::kMaxExperimentID);

  return GetSelectedExperiments()[static_cast<int>(exp)];
}

void FillExperimentProperties(
    std::map<std::string, MallocExtension::Property>* result) {
  for (const auto& config : experiments) {
    (*result)[absl::StrCat("tcmalloc.experiment.", config.name)].value =
        IsExperimentActive(config.id) ? 1 : 0;
  }
}

absl::optional<Experiment> FindExperimentByName(absl::string_view name) {
  for (const auto& config : experiments) {
    if (name == config.name) {
      return config.id;
    }
  }

  return absl::nullopt;
}

void PrintExperiments(TCMalloc_Printer* printer) {
  // Index experiments by their positions in the experiments array, rather than
  // by experiment ID.
  static bool active[ABSL_ARRAYSIZE(experiments)];
  static const bool* status = []() {
    memset(active, 0, sizeof(active));
    const bool* by_id = GetSelectedExperiments();

    for (int i = 0; i < ABSL_ARRAYSIZE(experiments); i++) {
      const auto& config = experiments[i];
      active[i] = by_id[static_cast<int>(config.id)];
    }

    return active;
  }();

  printer->printf("MALLOC EXPERIMENTS:");
  for (int i = 0; i < ABSL_ARRAYSIZE(experiments); i++) {
    const char* value = status[i] ? "1" : "0";
    printer->printf(" %s=%s", experiments[i].name, value);
  }

  printer->printf("\n");
}

}  // namespace tcmalloc
<commit_msg>Use absl::string_view for constants compared to another string_view.<commit_after>// Copyright 2019 The TCMalloc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tcmalloc/experiment.h"

#include <string.h>

#include "absl/base/macros.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "tcmalloc/internal/environment.h"
#include "tcmalloc/internal/logging.h"

using tcmalloc::internal::kNumExperiments;
using tcmalloc::tcmalloc_internal::thread_safe_getenv;

namespace tcmalloc {
namespace {

const char kDelimiter = ',';
const char kExperiments[] = "BORG_EXPERIMENTS";
const char kDisableExperiments[] = "BORG_DISABLE_EXPERIMENTS";
constexpr absl::string_view kEnableAll = "enable-all-known-experiments";
constexpr absl::string_view kDisableAll = "all";

bool LookupExperimentID(absl::string_view label, Experiment* exp) {
  for (auto config : experiments) {
    if (config.name == label) {
      *exp = config.id;
      return true;
    }
  }

  return false;
}

const bool* GetSelectedExperiments() {
  static bool by_id[kNumExperiments];

  static const char* active_experiments = thread_safe_getenv(kExperiments);
  static const char* disabled_experiments =
      thread_safe_getenv(kDisableExperiments);
  static const bool* status = internal::SelectExperiments(
      by_id, active_experiments ? active_experiments : "",
      disabled_experiments ? disabled_experiments : "");
  return status;
}

template <typename F>
void ParseExperiments(absl::string_view labels, F f) {
  absl::string_view::size_type pos = 0;
  do {
    absl::string_view token;
    auto end = labels.find(kDelimiter, pos);
    if (end == absl::string_view::npos) {
      token = labels.substr(pos);
      pos = end;
    } else {
      token = labels.substr(pos, end - pos);
      pos = end + 1;
    }

    f(token);
  } while (pos != absl::string_view::npos);
}

}  // namespace

namespace internal {

const bool* SelectExperiments(bool* buffer, absl::string_view active,
                              absl::string_view disabled) {
  memset(buffer, 0, sizeof(*buffer) * kNumExperiments);

  if (active == kEnableAll) {
    std::fill(buffer, buffer + kNumExperiments, true);
  }

  ParseExperiments(active, [buffer](absl::string_view token) {
    Experiment id;
    if (LookupExperimentID(token, &id)) {
      buffer[static_cast<int>(id)] = true;
    }
  });

  if (disabled == kDisableAll) {
    memset(buffer, 0, sizeof(*buffer) * kNumExperiments);
  }

  ParseExperiments(disabled, [buffer](absl::string_view token) {
    Experiment id;
    if (LookupExperimentID(token, &id)) {
      buffer[static_cast<int>(id)] = false;
    }
  });

  return buffer;
}

}  // namespace internal

bool IsExperimentActive(Experiment exp) {
  ASSERT(static_cast<int>(exp) >= 0);
  ASSERT(exp < Experiment::kMaxExperimentID);

  return GetSelectedExperiments()[static_cast<int>(exp)];
}

void FillExperimentProperties(
    std::map<std::string, MallocExtension::Property>* result) {
  for (const auto& config : experiments) {
    (*result)[absl::StrCat("tcmalloc.experiment.", config.name)].value =
        IsExperimentActive(config.id) ? 1 : 0;
  }
}

absl::optional<Experiment> FindExperimentByName(absl::string_view name) {
  for (const auto& config : experiments) {
    if (name == config.name) {
      return config.id;
    }
  }

  return absl::nullopt;
}

void PrintExperiments(TCMalloc_Printer* printer) {
  // Index experiments by their positions in the experiments array, rather than
  // by experiment ID.
  static bool active[ABSL_ARRAYSIZE(experiments)];
  static const bool* status = []() {
    memset(active, 0, sizeof(active));
    const bool* by_id = GetSelectedExperiments();

    for (int i = 0; i < ABSL_ARRAYSIZE(experiments); i++) {
      const auto& config = experiments[i];
      active[i] = by_id[static_cast<int>(config.id)];
    }

    return active;
  }();

  printer->printf("MALLOC EXPERIMENTS:");
  for (int i = 0; i < ABSL_ARRAYSIZE(experiments); i++) {
    const char* value = status[i] ? "1" : "0";
    printer->printf(" %s=%s", experiments[i].name, value);
  }

  printer->printf("\n");
}

}  // namespace tcmalloc
<|endoftext|>


<commit_before>// Copyright 2019 The TCMalloc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tcmalloc/experiment.h"

#include <string.h>

#include <algorithm>
#include <string>

#include "absl/base/macros.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "tcmalloc/internal/environment.h"
#include "tcmalloc/internal/logging.h"

GOOGLE_MALLOC_SECTION_BEGIN
namespace tcmalloc {
namespace tcmalloc_internal {
namespace {

const char kDelimiter = ',';
const char kExperiments[] = "BORG_EXPERIMENTS";
const char kDisableExperiments[] = "BORG_DISABLE_EXPERIMENTS";
constexpr absl::string_view kEnableAll = "enable-all-known-experiments";
constexpr absl::string_view kDisableAll = "all";

bool LookupExperimentID(absl::string_view label, Experiment* exp) {
  for (auto config : experiments) {
    if (config.name == label) {
      *exp = config.id;
      return true;
    }
  }

  return false;
}

const bool* GetSelectedExperiments() {
  static bool by_id[kNumExperiments];

  static const bool* status = [&]() {
    const char* active_experiments = thread_safe_getenv(kExperiments);
    const char* disabled_experiments = thread_safe_getenv(kDisableExperiments);
    return SelectExperiments(by_id,
                             active_experiments ? active_experiments : "",
                             disabled_experiments ? disabled_experiments : "");
  }();
  return status;
}

template <typename F>
void ParseExperiments(absl::string_view labels, F f) {
  absl::string_view::size_type pos = 0;
  do {
    absl::string_view token;
    auto end = labels.find(kDelimiter, pos);
    if (end == absl::string_view::npos) {
      token = labels.substr(pos);
      pos = end;
    } else {
      token = labels.substr(pos, end - pos);
      pos = end + 1;
    }

    f(token);
  } while (pos != absl::string_view::npos);
}

}  // namespace

const bool* SelectExperiments(bool* buffer, absl::string_view active,
                              absl::string_view disabled) {
  memset(buffer, 0, sizeof(*buffer) * kNumExperiments);

  if (active == kEnableAll) {
    std::fill(buffer, buffer + kNumExperiments, true);
  }

  ParseExperiments(active, [buffer](absl::string_view token) {
    Experiment id;
    if (LookupExperimentID(token, &id)) {
      buffer[static_cast<int>(id)] = true;
    }
  });

  if (disabled == kDisableAll) {
    memset(buffer, 0, sizeof(*buffer) * kNumExperiments);
  }

  ParseExperiments(disabled, [buffer](absl::string_view token) {
    Experiment id;
    if (LookupExperimentID(token, &id)) {
      buffer[static_cast<int>(id)] = false;
    }
  });

  return buffer;
}

}  // namespace tcmalloc_internal

bool IsExperimentActive(Experiment exp) {
  ASSERT(static_cast<int>(exp) >= 0);
  ASSERT(exp < Experiment::kMaxExperimentID);

  return tcmalloc_internal::GetSelectedExperiments()[static_cast<int>(exp)];
}

absl::optional<Experiment> FindExperimentByName(absl::string_view name) {
  for (const auto& config : experiments) {
    if (name == config.name) {
      return config.id;
    }
  }

  return absl::nullopt;
}

void WalkExperiments(
    absl::FunctionRef<void(absl::string_view name, bool active)> callback) {
  for (const auto& config : experiments) {
    callback(config.name, IsExperimentActive(config.id));
  }
}

}  // namespace tcmalloc
GOOGLE_MALLOC_SECTION_END
<commit_msg>Internal change<commit_after>// Copyright 2019 The TCMalloc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tcmalloc/experiment.h"

#include <string.h>

#include <algorithm>
#include <string>

#include "absl/base/macros.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "tcmalloc/internal/environment.h"
#include "tcmalloc/internal/logging.h"

GOOGLE_MALLOC_SECTION_BEGIN
namespace tcmalloc {
namespace tcmalloc_internal {
namespace {

const char kDelimiter = ',';
const char kExperiments[] = "BORG_EXPERIMENTS";
const char kDisableExperiments[] = "BORG_DISABLE_EXPERIMENTS";
constexpr absl::string_view kEnableAll = "enable-all-known-experiments";
constexpr absl::string_view kDisableAll = "all";

bool LookupExperimentID(absl::string_view label, Experiment* exp) {
  for (auto config : experiments) {
    if (config.name == label) {
      *exp = config.id;
      return true;
    }
  }

  return false;
}

const bool* GetSelectedExperiments() {
  static bool by_id[kNumExperiments];

  static const bool* status = [&]() {
    const char* active_experiments = thread_safe_getenv(kExperiments);
    const char* disabled_experiments = thread_safe_getenv(kDisableExperiments);
    return SelectExperiments(by_id,
                             active_experiments ? active_experiments : "",
                             disabled_experiments ? disabled_experiments : "");
  }();
  return status;
}

template <typename F>
void ParseExperiments(absl::string_view labels, F f) {
  absl::string_view::size_type pos = 0;
  do {
    absl::string_view token;
    auto end = labels.find(kDelimiter, pos);
    if (end == absl::string_view::npos) {
      token = labels.substr(pos);
      pos = end;
    } else {
      token = labels.substr(pos, end - pos);
      pos = end + 1;
    }

    f(token);
  } while (pos != absl::string_view::npos);
}

}  // namespace

const bool* SelectExperiments(bool* buffer, absl::string_view active,
                              absl::string_view disabled) {
  memset(buffer, 0, sizeof(*buffer) * kNumExperiments);

  if (active == kEnableAll) {
    std::fill(buffer, buffer + kNumExperiments, true);
  }

  ParseExperiments(active, [buffer](absl::string_view token) {
    Experiment id;
    if (LookupExperimentID(token, &id)) {
      buffer[static_cast<int>(id)] = true;
    }
  });

  if (disabled == kDisableAll) {
    memset(buffer, 0, sizeof(*buffer) * kNumExperiments);
  }

  ParseExperiments(disabled, [buffer](absl::string_view token) {
    Experiment id;
    if (LookupExperimentID(token, &id)) {
      buffer[static_cast<int>(id)] = false;
    }
  });

  return buffer;
}

}  // namespace tcmalloc_internal

bool IsExperimentActive(Experiment exp) {
  ASSERT(static_cast<int>(exp) >= 0);
  ASSERT(exp < Experiment::kMaxExperimentID);

  return tcmalloc_internal::GetSelectedExperiments()[static_cast<int>(exp)];
}

absl::optional<Experiment> FindExperimentByName(absl::string_view name) {
  for (const auto& config : experiments) {
    if (name == config.name) {
      return config.id;
    }
  }

  return absl::nullopt;
}

void WalkExperiments(
    absl::FunctionRef<void(absl::string_view name, bool active)> callback) {
  for (const auto& config : experiments) {
    callback(config.name, IsExperimentActive(config.id));
  }
}

}  // namespace tcmalloc
GOOGLE_MALLOC_SECTION_END
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: propertyanimationnode.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-13 15:34:26 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

// must be first
#include "canvas/debug.hxx"
#include "canvas/verbosetrace.hxx"
#include "propertyanimationnode.hxx"
#include "animationfactory.hxx"

using namespace com::sun::star;

namespace slideshow {
namespace internal {

AnimationActivitySharedPtr PropertyAnimationNode::createActivity() const
{
    // Create AnimationActivity from common XAnimate parameters:
    ActivitiesFactory::CommonParameters aParms( fillCommonParameters() );
    uno::Reference<animations::XAnimate> const& xAnimateNode =getXAnimateNode();
    rtl::OUString const attrName( xAnimateNode->getAttributeName() );
    AttributableShapeSharedPtr const pShape( getShape() );

    switch (AnimationFactory::classifyAttributeName( attrName )) {
    default:
    case AnimationFactory::CLASS_UNKNOWN_PROPERTY:
        ENSURE_AND_THROW(
            false,
            "Unexpected attribute class (unknown or empty attribute name)" );
        break;

    case AnimationFactory::CLASS_NUMBER_PROPERTY:
        return ActivitiesFactory::createAnimateActivity(
            aParms,
            AnimationFactory::createNumberPropertyAnimation(
                attrName,
                pShape,
                getContext().mpLayerManager ),
            xAnimateNode );

    case AnimationFactory::CLASS_ENUM_PROPERTY:
        return ActivitiesFactory::createAnimateActivity(
            aParms,
            AnimationFactory::createEnumPropertyAnimation(
                attrName,
                pShape,
                getContext().mpLayerManager ),
            xAnimateNode );

    case AnimationFactory::CLASS_COLOR_PROPERTY:
        return ActivitiesFactory::createAnimateActivity(
            aParms,
            AnimationFactory::createColorPropertyAnimation(
                attrName,
                pShape,
                getContext().mpLayerManager ),
            xAnimateNode );

    case AnimationFactory::CLASS_STRING_PROPERTY:
        return ActivitiesFactory::createAnimateActivity(
            aParms,
            AnimationFactory::createStringPropertyAnimation(
                attrName,
                pShape,
                getContext().mpLayerManager ),
            xAnimateNode );

    case AnimationFactory::CLASS_BOOL_PROPERTY:
        return ActivitiesFactory::createAnimateActivity(
            aParms,
            AnimationFactory::createBoolPropertyAnimation(
                attrName,
                pShape,
                getContext().mpLayerManager ),
            xAnimateNode );
    }

    return AnimationActivitySharedPtr();
}

} // namespace internal
} // namespace slideshow

<commit_msg>INTEGRATION: CWS presfixes12 (1.6.12); FILE MERGED 2007/02/06 17:18:08 thb 1.6.12.2: #i37778# Moved clear() method from View to ViewLayer (also sprites need to be cleared); fixed a few more cases of local code style violations; removed redundant inline keywords; finished Layer/LayerManager rework (Layer now represents ViewLayers, shapes and rendering are fully under LayerManager control); made shape comparator reusable 2007/01/29 14:02:02 thb 1.6.12.1: Issue number: #i37778#<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: propertyanimationnode.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2007-07-17 14:50:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_slideshow.hxx"

// must be first
#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>

#include "propertyanimationnode.hxx"
#include "animationfactory.hxx"

using namespace com::sun::star;

namespace slideshow {
namespace internal {

AnimationActivitySharedPtr PropertyAnimationNode::createActivity() const
{
    // Create AnimationActivity from common XAnimate parameters:
    ActivitiesFactory::CommonParameters aParms( fillCommonParameters() );
    uno::Reference<animations::XAnimate> const& xAnimateNode =getXAnimateNode();
    rtl::OUString const attrName( xAnimateNode->getAttributeName() );
    AttributableShapeSharedPtr const pShape( getShape() );

    switch (AnimationFactory::classifyAttributeName( attrName )) {
    default:
    case AnimationFactory::CLASS_UNKNOWN_PROPERTY:
        ENSURE_AND_THROW(
            false,
            "Unexpected attribute class (unknown or empty attribute name)" );
        break;

    case AnimationFactory::CLASS_NUMBER_PROPERTY:
        return ActivitiesFactory::createAnimateActivity(
            aParms,
            AnimationFactory::createNumberPropertyAnimation(
                attrName,
                pShape,
                getContext().mpSubsettableShapeManager,
                getSlideSize() ),
            xAnimateNode );

    case AnimationFactory::CLASS_ENUM_PROPERTY:
        return ActivitiesFactory::createAnimateActivity(
            aParms,
            AnimationFactory::createEnumPropertyAnimation(
                attrName,
                pShape,
                getContext().mpSubsettableShapeManager,
                getSlideSize() ),
            xAnimateNode );

    case AnimationFactory::CLASS_COLOR_PROPERTY:
        return ActivitiesFactory::createAnimateActivity(
            aParms,
            AnimationFactory::createColorPropertyAnimation(
                attrName,
                pShape,
                getContext().mpSubsettableShapeManager,
                getSlideSize() ),
            xAnimateNode );

    case AnimationFactory::CLASS_STRING_PROPERTY:
        return ActivitiesFactory::createAnimateActivity(
            aParms,
            AnimationFactory::createStringPropertyAnimation(
                attrName,
                pShape,
                getContext().mpSubsettableShapeManager,
                getSlideSize() ),
            xAnimateNode );

    case AnimationFactory::CLASS_BOOL_PROPERTY:
        return ActivitiesFactory::createAnimateActivity(
            aParms,
            AnimationFactory::createBoolPropertyAnimation(
                attrName,
                pShape,
                getContext().mpSubsettableShapeManager,
                getSlideSize() ),
            xAnimateNode );
    }

    return AnimationActivitySharedPtr();
}

} // namespace internal
} // namespace slideshow

<|endoftext|>


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

#include <iostream>
#include <memory>
#include <string>
#include <utility>

#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_system_event_loop.h"
#include "net/quic/platform/impl/quic_epoll_clock.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h"
#include "net/third_party/quiche/src/quic/tools/fake_proof_verifier.h"
#include "net/third_party/quiche/src/quic/tools/quic_client.h"
#include "net/third_party/quiche/src/quic/tools/quic_url.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"

DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
                              host,
                              "",
                              "The IP or hostname to connect to.");

DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");

namespace quic {

enum class Feature {
  // First row of features ("table stakes")
  // A version negotiation response is elicited and acted on.
  kVersionNegotiation,
  // The handshake completes successfully.
  kHandshake,
  // Stream data is being exchanged and ACK'ed.
  kStreamData,
  // The connection close procedcure completes with a zero error code.
  kConnectionClose,
  // The connection was established using TLS resumption.
  kResumption,
  // A RETRY packet was successfully processed.
  kRetry,

  // Second row of features (anything else protocol-related)
  // We switched to a different port and the server migrated to it.
  kRebinding,

  // Third row of features (H3 tests)
  // An H3 transaction succeeded.
  kHttp3,
  // One or both endpoints insert entries into dynamic table and subsequenly
  // reference them from header blocks.
  kDynamicEntryReferenced,
};

char MatrixLetter(Feature f) {
  switch (f) {
    case Feature::kVersionNegotiation:
      return 'V';
    case Feature::kHandshake:
      return 'H';
    case Feature::kStreamData:
      return 'D';
    case Feature::kConnectionClose:
      return 'C';
    case Feature::kResumption:
      return 'R';
    case Feature::kRetry:
      return 'S';
    case Feature::kRebinding:
      return 'B';
    case Feature::kHttp3:
      return '3';
    case Feature::kDynamicEntryReferenced:
      return 'd';
  }
}

class QuicClientInteropRunner : QuicConnectionDebugVisitor {
 public:
  QuicClientInteropRunner() {}

  void InsertFeature(Feature feature) { features_.insert(feature); }

  std::set<Feature> features() const { return features_; }

  // Attempts a resumption using |client| by disconnecting and reconnecting. If
  // resumption is successful, |features_| is modified to add
  // Feature::kResumption to it, otherwise it is left unmodified.
  void AttemptResumption(QuicClient* client);

  void AttemptRequest(QuicSocketAddress addr,
                      std::string authority,
                      QuicServerId server_id,
                      ParsedQuicVersion version,
                      bool test_version_negotiation,
                      bool attempt_rebind);

  void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
    switch (frame.close_type) {
      case GOOGLE_QUIC_CONNECTION_CLOSE:
        QUIC_LOG(ERROR) << "Received unexpected GoogleQUIC connection close";
        break;
      case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
        if (frame.wire_error_code == NO_IETF_QUIC_ERROR) {
          InsertFeature(Feature::kConnectionClose);
        } else {
          QUIC_LOG(ERROR) << "Received transport connection close "
                          << QuicIetfTransportErrorCodeString(
                                 static_cast<QuicIetfTransportErrorCodes>(
                                     frame.wire_error_code));
        }
        break;
      case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
        if (frame.wire_error_code == 0) {
          InsertFeature(Feature::kConnectionClose);
        } else {
          QUIC_LOG(ERROR) << "Received application connection close "
                          << frame.wire_error_code;
        }
        break;
    }
  }

  void OnVersionNegotiationPacket(
      const QuicVersionNegotiationPacket& /*packet*/) override {
    InsertFeature(Feature::kVersionNegotiation);
  }

 private:
  std::set<Feature> features_;
};

void QuicClientInteropRunner::AttemptResumption(QuicClient* client) {
  client->Disconnect();
  if (!client->Initialize()) {
    QUIC_LOG(ERROR) << "Failed to reinitialize client";
    return;
  }
  if (!client->Connect() || !client->session()->OneRttKeysAvailable()) {
    return;
  }
  if (static_cast<QuicCryptoClientStream*>(
          test::QuicSessionPeer::GetMutableCryptoStream(client->session()))
          ->IsResumption()) {
    InsertFeature(Feature::kResumption);
  }
}

void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr,
                                             std::string authority,
                                             QuicServerId server_id,
                                             ParsedQuicVersion version,
                                             bool test_version_negotiation,
                                             bool attempt_rebind) {
  ParsedQuicVersionVector versions = {version};
  if (test_version_negotiation) {
    versions.insert(versions.begin(), QuicVersionReservedForNegotiation());
  }

  auto proof_verifier = std::make_unique<FakeProofVerifier>();
  auto session_cache = std::make_unique<test::SimpleSessionCache>();
  QuicEpollServer epoll_server;
  QuicEpollClock epoll_clock(&epoll_server);
  QuicConfig config;
  QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(20);
  config.SetIdleNetworkTimeout(timeout);
  auto client = std::make_unique<QuicClient>(
      addr, server_id, versions, config, &epoll_server,
      std::move(proof_verifier), std::move(session_cache));
  client->set_connection_debug_visitor(this);
  if (!client->Initialize()) {
    QUIC_LOG(ERROR) << "Failed to initialize client";
    return;
  }
  const bool connect_result = client->Connect();
  QuicConnection* connection = client->session()->connection();
  if (connection == nullptr) {
    QUIC_LOG(ERROR) << "No QuicConnection object";
    return;
  }
  QuicConnectionStats client_stats = connection->GetStats();
  if (client_stats.retry_packet_processed) {
    InsertFeature(Feature::kRetry);
  }
  if (test_version_negotiation && connection->version() == version) {
    InsertFeature(Feature::kVersionNegotiation);
  }
  if (test_version_negotiation && !connect_result) {
    // Failed to negotiate version, retry without version negotiation.
    AttemptRequest(addr, authority, server_id, version,
                   /*test_version_negotiation=*/false, attempt_rebind);
    return;
  }
  if (!client->session()->OneRttKeysAvailable()) {
    return;
  }
  InsertFeature(Feature::kHandshake);

  // Construct and send a request.
  spdy::SpdyHeaderBlock header_block;
  header_block[":method"] = "GET";
  header_block[":scheme"] = "https";
  header_block[":authority"] = authority;
  header_block[":path"] = "/";
  client->set_store_response(true);
  client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);

  client_stats = connection->GetStats();
  QuicSentPacketManager* sent_packet_manager =
      test::QuicConnectionPeer::GetSentPacketManager(connection);
  const bool received_forward_secure_ack =
      sent_packet_manager != nullptr &&
      sent_packet_manager->GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE)
          .IsInitialized();
  if (client_stats.stream_bytes_received > 0 && received_forward_secure_ack) {
    InsertFeature(Feature::kStreamData);
  }

  if (!client->connected()) {
    return;
  }

  if (client->latest_response_code() != -1) {
    InsertFeature(Feature::kHttp3);

    if (client->client_session()->dynamic_table_entry_referenced()) {
      InsertFeature(Feature::kDynamicEntryReferenced);
    }

    if (attempt_rebind) {
      // Now make a second request after switching to a different client port.
      if (client->ChangeEphemeralPort()) {
        client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
        if (!client->connected()) {
          // Rebinding does not work, retry without attempting it.
          AttemptRequest(addr, authority, server_id, version,
                         test_version_negotiation, /*attempt_rebind=*/false);
          return;
        }
        InsertFeature(Feature::kRebinding);

        if (client->client_session()->dynamic_table_entry_referenced()) {
          InsertFeature(Feature::kDynamicEntryReferenced);
        }
      } else {
        QUIC_LOG(ERROR) << "Failed to change ephemeral port";
      }
    }
  }

  if (connection->connected()) {
    connection->CloseConnection(
        QUIC_NO_ERROR, "Graceful close",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    InsertFeature(Feature::kConnectionClose);
  }

  AttemptResumption(client.get());
}

std::set<Feature> ServerSupport(std::string host, int port) {
  // Enable IETF version support.
  QuicVersionInitializeSupportForIetfDraft();
  ParsedQuicVersion version = UnsupportedQuicVersion();
  for (const ParsedQuicVersion& vers : AllSupportedVersions()) {
    // Find the first version that supports IETF QUIC.
    if (vers.HasIetfQuicFrames() &&
        vers.handshake_protocol == quic::PROTOCOL_TLS1_3) {
      version = vers;
      break;
    }
  }
  CHECK_NE(version.transport_version, QUIC_VERSION_UNSUPPORTED);
  QuicEnableVersion(version);

  // Build the client, and try to connect.
  QuicSocketAddress addr =
      tools::LookupAddress(host, quiche::QuicheStrCat(port));
  if (!addr.IsInitialized()) {
    QUIC_LOG(ERROR) << "Failed to resolve " << host;
    return std::set<Feature>();
  }
  QuicServerId server_id(host, port, false);
  std::string authority = quiche::QuicheStrCat(host, ":", port);

  QuicClientInteropRunner runner;

  runner.AttemptRequest(addr, authority, server_id, version,
                        /*test_version_negotiation=*/true,
                        /*attempt_rebind=*/true);

  return runner.features();
}

}  // namespace quic

int main(int argc, char* argv[]) {
  QuicSystemEventLoop event_loop("quic_client");
  const char* usage = "Usage: quic_client_interop_test [options] [url]";

  std::vector<std::string> args =
      quic::QuicParseCommandLineFlags(usage, argc, argv);
  if (args.size() > 1) {
    quic::QuicPrintCommandLineFlagHelp(usage);
    exit(1);
  }
  std::string host = GetQuicFlag(FLAGS_host);
  int port = GetQuicFlag(FLAGS_port);

  if (!args.empty()) {
    quic::QuicUrl url(args[0], "https");
    if (host.empty()) {
      host = url.host();
    }
    if (port == 0) {
      port = url.port();
    }
  }
  if (port == 0) {
    port = 443;
  }
  if (host.empty()) {
    quic::QuicPrintCommandLineFlagHelp(usage);
    exit(1);
  }

  auto supported_features = quic::ServerSupport(host, port);
  std::cout << "Results for " << host << ":" << port << std::endl;
  int current_row = 1;
  for (auto feature : supported_features) {
    if (current_row < 2 && feature >= quic::Feature::kRebinding) {
      std::cout << std::endl;
      current_row = 2;
    }
    if (current_row < 3 && feature >= quic::Feature::kHttp3) {
      std::cout << std::endl;
      current_row = 3;
    }
    std::cout << MatrixLetter(feature);
  }
  std::cout << std::endl;
}
<commit_msg>Allow --host and url to refer to different hosts in quic_client_interop_test_bin<commit_after>// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <iostream>
#include <memory>
#include <string>
#include <utility>

#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_system_event_loop.h"
#include "net/quic/platform/impl/quic_epoll_clock.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h"
#include "net/third_party/quiche/src/quic/tools/fake_proof_verifier.h"
#include "net/third_party/quiche/src/quic/tools/quic_client.h"
#include "net/third_party/quiche/src/quic/tools/quic_url.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_str_cat.h"

DEFINE_QUIC_COMMAND_LINE_FLAG(std::string,
                              host,
                              "",
                              "The IP or hostname to connect to.");

DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t, port, 0, "The port to connect to.");

namespace quic {

enum class Feature {
  // First row of features ("table stakes")
  // A version negotiation response is elicited and acted on.
  kVersionNegotiation,
  // The handshake completes successfully.
  kHandshake,
  // Stream data is being exchanged and ACK'ed.
  kStreamData,
  // The connection close procedcure completes with a zero error code.
  kConnectionClose,
  // The connection was established using TLS resumption.
  kResumption,
  // A RETRY packet was successfully processed.
  kRetry,

  // Second row of features (anything else protocol-related)
  // We switched to a different port and the server migrated to it.
  kRebinding,

  // Third row of features (H3 tests)
  // An H3 transaction succeeded.
  kHttp3,
  // One or both endpoints insert entries into dynamic table and subsequenly
  // reference them from header blocks.
  kDynamicEntryReferenced,
};

char MatrixLetter(Feature f) {
  switch (f) {
    case Feature::kVersionNegotiation:
      return 'V';
    case Feature::kHandshake:
      return 'H';
    case Feature::kStreamData:
      return 'D';
    case Feature::kConnectionClose:
      return 'C';
    case Feature::kResumption:
      return 'R';
    case Feature::kRetry:
      return 'S';
    case Feature::kRebinding:
      return 'B';
    case Feature::kHttp3:
      return '3';
    case Feature::kDynamicEntryReferenced:
      return 'd';
  }
}

class QuicClientInteropRunner : QuicConnectionDebugVisitor {
 public:
  QuicClientInteropRunner() {}

  void InsertFeature(Feature feature) { features_.insert(feature); }

  std::set<Feature> features() const { return features_; }

  // Attempts a resumption using |client| by disconnecting and reconnecting. If
  // resumption is successful, |features_| is modified to add
  // Feature::kResumption to it, otherwise it is left unmodified.
  void AttemptResumption(QuicClient* client);

  void AttemptRequest(QuicSocketAddress addr,
                      std::string authority,
                      QuicServerId server_id,
                      ParsedQuicVersion version,
                      bool test_version_negotiation,
                      bool attempt_rebind);

  void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
    switch (frame.close_type) {
      case GOOGLE_QUIC_CONNECTION_CLOSE:
        QUIC_LOG(ERROR) << "Received unexpected GoogleQUIC connection close";
        break;
      case IETF_QUIC_TRANSPORT_CONNECTION_CLOSE:
        if (frame.wire_error_code == NO_IETF_QUIC_ERROR) {
          InsertFeature(Feature::kConnectionClose);
        } else {
          QUIC_LOG(ERROR) << "Received transport connection close "
                          << QuicIetfTransportErrorCodeString(
                                 static_cast<QuicIetfTransportErrorCodes>(
                                     frame.wire_error_code));
        }
        break;
      case IETF_QUIC_APPLICATION_CONNECTION_CLOSE:
        if (frame.wire_error_code == 0) {
          InsertFeature(Feature::kConnectionClose);
        } else {
          QUIC_LOG(ERROR) << "Received application connection close "
                          << frame.wire_error_code;
        }
        break;
    }
  }

  void OnVersionNegotiationPacket(
      const QuicVersionNegotiationPacket& /*packet*/) override {
    InsertFeature(Feature::kVersionNegotiation);
  }

 private:
  std::set<Feature> features_;
};

void QuicClientInteropRunner::AttemptResumption(QuicClient* client) {
  client->Disconnect();
  if (!client->Initialize()) {
    QUIC_LOG(ERROR) << "Failed to reinitialize client";
    return;
  }
  if (!client->Connect() || !client->session()->OneRttKeysAvailable()) {
    return;
  }
  if (static_cast<QuicCryptoClientStream*>(
          test::QuicSessionPeer::GetMutableCryptoStream(client->session()))
          ->IsResumption()) {
    InsertFeature(Feature::kResumption);
  }
}

void QuicClientInteropRunner::AttemptRequest(QuicSocketAddress addr,
                                             std::string authority,
                                             QuicServerId server_id,
                                             ParsedQuicVersion version,
                                             bool test_version_negotiation,
                                             bool attempt_rebind) {
  ParsedQuicVersionVector versions = {version};
  if (test_version_negotiation) {
    versions.insert(versions.begin(), QuicVersionReservedForNegotiation());
  }

  auto proof_verifier = std::make_unique<FakeProofVerifier>();
  auto session_cache = std::make_unique<test::SimpleSessionCache>();
  QuicEpollServer epoll_server;
  QuicEpollClock epoll_clock(&epoll_server);
  QuicConfig config;
  QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(20);
  config.SetIdleNetworkTimeout(timeout);
  auto client = std::make_unique<QuicClient>(
      addr, server_id, versions, config, &epoll_server,
      std::move(proof_verifier), std::move(session_cache));
  client->set_connection_debug_visitor(this);
  if (!client->Initialize()) {
    QUIC_LOG(ERROR) << "Failed to initialize client";
    return;
  }
  const bool connect_result = client->Connect();
  QuicConnection* connection = client->session()->connection();
  if (connection == nullptr) {
    QUIC_LOG(ERROR) << "No QuicConnection object";
    return;
  }
  QuicConnectionStats client_stats = connection->GetStats();
  if (client_stats.retry_packet_processed) {
    InsertFeature(Feature::kRetry);
  }
  if (test_version_negotiation && connection->version() == version) {
    InsertFeature(Feature::kVersionNegotiation);
  }
  if (test_version_negotiation && !connect_result) {
    // Failed to negotiate version, retry without version negotiation.
    AttemptRequest(addr, authority, server_id, version,
                   /*test_version_negotiation=*/false, attempt_rebind);
    return;
  }
  if (!client->session()->OneRttKeysAvailable()) {
    return;
  }
  InsertFeature(Feature::kHandshake);

  // Construct and send a request.
  spdy::SpdyHeaderBlock header_block;
  header_block[":method"] = "GET";
  header_block[":scheme"] = "https";
  header_block[":authority"] = authority;
  header_block[":path"] = "/";
  client->set_store_response(true);
  client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);

  client_stats = connection->GetStats();
  QuicSentPacketManager* sent_packet_manager =
      test::QuicConnectionPeer::GetSentPacketManager(connection);
  const bool received_forward_secure_ack =
      sent_packet_manager != nullptr &&
      sent_packet_manager->GetLargestAckedPacket(ENCRYPTION_FORWARD_SECURE)
          .IsInitialized();
  if (client_stats.stream_bytes_received > 0 && received_forward_secure_ack) {
    InsertFeature(Feature::kStreamData);
  }

  if (!client->connected()) {
    return;
  }

  if (client->latest_response_code() != -1) {
    InsertFeature(Feature::kHttp3);

    if (client->client_session()->dynamic_table_entry_referenced()) {
      InsertFeature(Feature::kDynamicEntryReferenced);
    }

    if (attempt_rebind) {
      // Now make a second request after switching to a different client port.
      if (client->ChangeEphemeralPort()) {
        client->SendRequestAndWaitForResponse(header_block, "", /*fin=*/true);
        if (!client->connected()) {
          // Rebinding does not work, retry without attempting it.
          AttemptRequest(addr, authority, server_id, version,
                         test_version_negotiation, /*attempt_rebind=*/false);
          return;
        }
        InsertFeature(Feature::kRebinding);

        if (client->client_session()->dynamic_table_entry_referenced()) {
          InsertFeature(Feature::kDynamicEntryReferenced);
        }
      } else {
        QUIC_LOG(ERROR) << "Failed to change ephemeral port";
      }
    }
  }

  if (connection->connected()) {
    connection->CloseConnection(
        QUIC_NO_ERROR, "Graceful close",
        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
    InsertFeature(Feature::kConnectionClose);
  }

  AttemptResumption(client.get());
}

std::set<Feature> ServerSupport(std::string dns_host,
                                std::string url_host,
                                int port) {
  // Enable IETF version support.
  QuicVersionInitializeSupportForIetfDraft();
  ParsedQuicVersion version = UnsupportedQuicVersion();
  for (const ParsedQuicVersion& vers : AllSupportedVersions()) {
    // Find the first version that supports IETF QUIC.
    if (vers.HasIetfQuicFrames() &&
        vers.handshake_protocol == quic::PROTOCOL_TLS1_3) {
      version = vers;
      break;
    }
  }
  CHECK_NE(version.transport_version, QUIC_VERSION_UNSUPPORTED);
  QuicEnableVersion(version);

  // Build the client, and try to connect.
  QuicSocketAddress addr =
      tools::LookupAddress(dns_host, quiche::QuicheStrCat(port));
  if (!addr.IsInitialized()) {
    QUIC_LOG(ERROR) << "Failed to resolve " << dns_host;
    return std::set<Feature>();
  }
  QuicServerId server_id(url_host, port, false);
  std::string authority = quiche::QuicheStrCat(url_host, ":", port);

  QuicClientInteropRunner runner;

  runner.AttemptRequest(addr, authority, server_id, version,
                        /*test_version_negotiation=*/true,
                        /*attempt_rebind=*/true);

  return runner.features();
}

}  // namespace quic

int main(int argc, char* argv[]) {
  QuicSystemEventLoop event_loop("quic_client");
  const char* usage = "Usage: quic_client_interop_test [options] [url]";

  std::vector<std::string> args =
      quic::QuicParseCommandLineFlags(usage, argc, argv);
  if (args.size() > 1) {
    quic::QuicPrintCommandLineFlagHelp(usage);
    exit(1);
  }
  std::string dns_host = GetQuicFlag(FLAGS_host);
  std::string url_host = "";
  int port = GetQuicFlag(FLAGS_port);

  if (!args.empty()) {
    quic::QuicUrl url(args[0], "https");
    url_host = url.host();
    if (dns_host.empty()) {
      dns_host = url_host;
    }
    if (port == 0) {
      port = url.port();
    }
  }
  if (port == 0) {
    port = 443;
  }
  if (dns_host.empty()) {
    quic::QuicPrintCommandLineFlagHelp(usage);
    exit(1);
  }
  if (url_host.empty()) {
    url_host = dns_host;
  }

  auto supported_features = quic::ServerSupport(dns_host, url_host, port);
  std::cout << "Results for " << url_host << ":" << port << std::endl;
  int current_row = 1;
  for (auto feature : supported_features) {
    if (current_row < 2 && feature >= quic::Feature::kRebinding) {
      std::cout << std::endl;
      current_row = 2;
    }
    if (current_row < 3 && feature >= quic::Feature::kHttp3) {
      std::cout << std::endl;
      current_row = 3;
    }
    std::cout << MatrixLetter(feature);
  }
  std::cout << std::endl;
}
<|endoftext|>


<commit_before>#define _IRR_STATIC_LIB_
#include <irrlicht.h>
#include <iostream>
#include <cstdio>
#include "../source/Irrlicht/COpenGLExtensionHandler.h"

using namespace irr;
using namespace core;

/**
We do cool stuff here, like make an event receiver to process input
**/
class MyEventReceiver : public IEventReceiver
{
public:

	MyEventReceiver()
	{
	}

	bool OnEvent(const SEvent& event)
	{
        if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
        {
            switch (event.KeyInput.Key)
            {
            case irr::KEY_KEY_Q: // switch wire frame mode
                exit(0);
                return true;
            default:
                break;
            }
        }

		return false;
	}

private:
};

class SimpleCallBack : public video::IShaderConstantSetCallBack
{
    int32_t mvpUniformLocation;
    video::E_SHADER_CONSTANT_TYPE mvpUniformType;
public:
    SimpleCallBack() : mvpUniformLocation(-1), mvpUniformType(video::ESCT_FLOAT_VEC3) {}

    virtual void PostLink(video::IMaterialRendererServices* services, const video::E_MATERIAL_TYPE& materialType, const core::vector<video::SConstantLocationNamePair>& constants)
    {
        //! Normally we'd iterate through the array and check our actual constant names before mapping them to locations but oh well
        mvpUniformLocation = constants[0].location;
        mvpUniformType = constants[0].type;
    }

    virtual void OnSetConstants(video::IMaterialRendererServices* services, int32_t userData)
    {
        services->setShaderConstant(services->getVideoDriver()->getTransform(video::EPTS_PROJ_VIEW_WORLD).pointer(),mvpUniformLocation,mvpUniformType,1);
    }

    virtual void OnUnsetMaterial() {}
};

#include "irr/irrpack.h"
struct VertexStruct
{
    /// every member needs to be at location aligned to its type size for GLSL
    float Pos[3]; /// uses float hence need 4 byte alignment
    uint8_t Col[2]; /// same logic needs 1 byte alignment
    uint8_t uselessPadding[2]; /// so if there is a member with 4 byte alignment then whole struct needs 4 byte align, so pad it
} PACK_STRUCT;
#include "irr/irrunpack.h"

int main()
{
	printf("Please select the background:\n");
	printf(" (0 : default) Use SkyDome\n");
	printf(" (1) Use SkyBox\n");

	uint8_t c = 0;
	std::cin >> c;

	// create device with full flexibility over creation parameters
	// you can add more parameters if desired, check irr::SIrrlichtCreationParameters
	irr::SIrrlichtCreationParameters params;
	params.Bits = 24; //may have to set to 32bit for some platforms
	params.ZBufferBits = 24; //we'd like 32bit here
	params.DriverType = video::EDT_OPENGL; //! Only Well functioning driver, software renderer left for sake of 2D image drawing
	params.WindowSize = dimension2d<uint32_t>(1280, 720);
	params.Fullscreen = false;
	params.Vsync = true; //! If supported by target platform
	params.Doublebuffer = true;
	params.Stencilbuffer = false; //! This will not even be a choice soon
	IrrlichtDevice* device = createDeviceEx(params);

	if (device == 0)
		return 1; // could not create selected driver.

	video::IVideoDriver* driver = device->getVideoDriver();
    SimpleCallBack* callBack = new SimpleCallBack();

    //! First need to make a material other than default to be able to draw with custom shader
    video::SMaterial material;
    material.BackfaceCulling = false; //! Triangles will be visible from both sides
    material.MaterialType = (video::E_MATERIAL_TYPE)driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles("../mesh.vert",
                                                        "","","", //! No Geometry or Tessellation Shaders
                                                        "../mesh.frag",
                                                        3,video::EMT_SOLID, //! 3 vertices per primitive (this is tessellation shader relevant only
                                                        callBack,
                                                        0); //! No custom user data
    callBack->drop();

	scene::ISceneManager* smgr = device->getSceneManager();

	driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);

	// create skybox and skydome
	switch (c)
	{
        case '1':
            smgr->addSkyBoxSceneNode(
                driver->getTexture("../../media/irrlicht2_up.jpg"),
                driver->getTexture("../../media/irrlicht2_dn.jpg"),
                driver->getTexture("../../media/irrlicht2_lf.jpg"),
                driver->getTexture("../../media/irrlicht2_rt.jpg"),
                driver->getTexture("../../media/irrlicht2_ft.jpg"),
                driver->getTexture("../../media/irrlicht2_bk.jpg"));
            break;
        default:
            smgr->addSkyDomeSceneNode(driver->getTexture("../../media/skydome.jpg"),16,8,0.95f,2.0f,10.f);
            break;
	}

	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);

	//! we want to move around the scene and view it from different angles
	scene::ICameraSceneNode* camera =
		smgr->addCameraSceneNodeFPS(0,100.0f,0.001f);

	camera->setPosition(core::vector3df(-4,0,0));
	camera->setTarget(core::vector3df(0,0,0));
	camera->setNearValue(0.01f);
	camera->setFarValue(10.0f);

    smgr->setActiveCamera(camera);

	//! disable mouse cursor, since camera will force it to the middle
	//! and we don't want a jittery cursor in the middle distracting us
	device->getCursorControl()->setVisible(false);

	//! Since our cursor will be enslaved, there will be no way to close the window
	//! So we listen for the "Q" key being pressed and exit the application
	MyEventReceiver receiver;
	device->setEventReceiver(&receiver);

	uint64_t lastFPSTime = 0;

	while(device->run())
	//if (device->isWindowActive())
	{
		driver->beginScene(true, true, video::SColor(255,255,255,255) );

        //! This animates (moves) the camera and sets the transforms
        //! Also draws the meshbuffer
        smgr->drawAll();

        //! Stress test for memleaks aside from demo how to create meshes that live on the GPU RAM
        {
            VertexStruct vertices[8];
            vertices[0] = VertexStruct{{-1.f,-1.f,-1.f},{  0,  0}};
            vertices[1] = VertexStruct{{ 1.f,-1.f,-1.f},{127,  0}};
            vertices[2] = VertexStruct{{-1.f, 1.f,-1.f},{255,  0}};
            vertices[3] = VertexStruct{{ 1.f, 1.f,-1.f},{  0,127}};
            vertices[4] = VertexStruct{{-1.f,-1.f, 1.f},{127,127}};
            vertices[5] = VertexStruct{{ 1.f,-1.f, 1.f},{255,127}};
            vertices[6] = VertexStruct{{-1.f, 1.f, 1.f},{  0,255}};
            vertices[7] = VertexStruct{{ 1.f, 1.f, 1.f},{127,255}};

            uint16_t indices_indexed16[] =
            {
                0,1,2,1,2,3,
                4,5,6,5,6,7,
                0,1,4,1,4,5,
                2,3,6,3,6,7,
                0,2,4,2,4,6,
                1,3,5,3,5,7
            };

            auto upStreamBuff = driver->getDefaultUpStreamingBuffer();
            const void* dataToPlace[2]  = {vertices,indices_indexed16};
            uint32_t offsets[2]         = {video::StreamingTransientDataBufferMT<>::invalid_address,video::StreamingTransientDataBufferMT<>::invalid_address};
            uint32_t alignments[2]      = {sizeof(decltype(vertices[0u])),sizeof(decltype(indices_indexed16[0u]))};
            uint32_t sizes[2]           = {sizeof(vertices),sizeof(indices_indexed16)};
            upStreamBuff->multi_place(2u,(const void* const*)dataToPlace,(uint32_t*)&offsets,(uint32_t*)&sizes,(uint32_t*)&alignments);
            if (upStreamBuff->needsManualFlushOrInvalidate())
            {
                auto upStreamMem = upStreamBuff->getBuffer()->getBoundMemory();
                driver->flushMappedMemoryRanges({video::IDriverMemoryAllocation::MappedMemoryRange(upStreamMem,offsets[0],sizes[0]),video::IDriverMemoryAllocation::MappedMemoryRange(upStreamMem,offsets[1],sizes[1])});
            }

            auto buff = upStreamBuff->getBuffer();
            scene::IGPUMeshDataFormatDesc* desc = driver->createGPUMeshDataFormatDesc();
            desc->mapVertexAttrBuffer(buff,scene::EVAI_ATTR0,scene::ECPA_THREE,scene::ECT_FLOAT,sizeof(VertexStruct),offsetof(VertexStruct,Pos[0])+offsets[0]);
            desc->mapVertexAttrBuffer(buff,scene::EVAI_ATTR1,scene::ECPA_TWO,scene::ECT_NORMALIZED_UNSIGNED_BYTE,sizeof(VertexStruct),offsetof(VertexStruct,Col[0])+offsets[0]);
            desc->mapIndexBuffer(buff);

            scene::IGPUMeshBuffer* mb = new scene::IGPUMeshBuffer();
            mb->setMeshDataAndFormat(desc);
            mb->setIndexBufferOffset(offsets[1]);
            mb->setIndexType(scene::EIT_16BIT);
            mb->setIndexCount(2*3*6);
            desc->drop();

            driver->setTransform(video::E4X3TS_WORLD,core::matrix4x3());
            driver->setMaterial(material);
            driver->drawMeshBuffer(mb);
            mb->drop();

            upStreamBuff->multi_free(1u,(uint32_t*)&offsets,(uint32_t*)&sizes,driver->placeFence());
        }

		driver->endScene();

		// display frames per second in window title
		uint64_t time = device->getTimer()->getRealTime();
		if (time-lastFPSTime > 1000)
		{
			std::wostringstream str;
			str << L"GPU Mesh Demo - Irrlicht Engine [" << driver->getName() << "] FPS:" << driver->getFPS() << " PrimitvesDrawn:" << driver->getPrimitiveCountDrawn();

			device->setWindowCaption(str.str().c_str());
			lastFPSTime = time;
		}
	}

    //create a screenshot
	video::IImage* screenshot = driver->createImage(video::ECF_A8R8G8B8,params.WindowSize);
    glReadPixels(0,0, params.WindowSize.Width,params.WindowSize.Height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, screenshot->getData());
    {
        // images are horizontally flipped, so we have to fix that here.
        uint8_t* pixels = (uint8_t*)screenshot->getData();

        const int32_t pitch=screenshot->getPitch();
        uint8_t* p2 = pixels + (params.WindowSize.Height - 1) * pitch;
        uint8_t* tmpBuffer = new uint8_t[pitch];
        for (uint32_t i=0; i < params.WindowSize.Height; i += 2)
        {
            memcpy(tmpBuffer, pixels, pitch);
            memcpy(pixels, p2, pitch);
            memcpy(p2, tmpBuffer, pitch);
            pixels += pitch;
            p2 -= pitch;
        }
        delete [] tmpBuffer;
    }
	driver->writeImageToFile(screenshot,"./screenshot.png");
	screenshot->drop();
	device->sleep(3000);

	device->drop();

	return 0;
}
<commit_msg>Fix #170<commit_after>#define _IRR_STATIC_LIB_
#include <irrlicht.h>
#include <iostream>
#include <cstdio>
#include "../source/Irrlicht/COpenGLExtensionHandler.h"

using namespace irr;
using namespace core;

/**
We do cool stuff here, like make an event receiver to process input
**/
class MyEventReceiver : public IEventReceiver
{
public:

	MyEventReceiver()
	{
	}

	bool OnEvent(const SEvent& event)
	{
        if (event.EventType == irr::EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
        {
            switch (event.KeyInput.Key)
            {
            case irr::KEY_KEY_Q: // switch wire frame mode
                exit(0);
                return true;
            default:
                break;
            }
        }

		return false;
	}

private:
};

class SimpleCallBack : public video::IShaderConstantSetCallBack
{
    int32_t mvpUniformLocation;
    video::E_SHADER_CONSTANT_TYPE mvpUniformType;
public:
    SimpleCallBack() : mvpUniformLocation(-1), mvpUniformType(video::ESCT_FLOAT_VEC3) {}

    virtual void PostLink(video::IMaterialRendererServices* services, const video::E_MATERIAL_TYPE& materialType, const core::vector<video::SConstantLocationNamePair>& constants)
    {
        //! Normally we'd iterate through the array and check our actual constant names before mapping them to locations but oh well
        mvpUniformLocation = constants[0].location;
        mvpUniformType = constants[0].type;
    }

    virtual void OnSetConstants(video::IMaterialRendererServices* services, int32_t userData)
    {
        services->setShaderConstant(services->getVideoDriver()->getTransform(video::EPTS_PROJ_VIEW_WORLD).pointer(),mvpUniformLocation,mvpUniformType,1);
    }

    virtual void OnUnsetMaterial() {}
};

#include "irr/irrpack.h"
struct VertexStruct
{
    /// every member needs to be at location aligned to its type size for GLSL
    float Pos[3]; /// uses float hence need 4 byte alignment
    uint8_t Col[2]; /// same logic needs 1 byte alignment
    uint8_t uselessPadding[2]; /// so if there is a member with 4 byte alignment then whole struct needs 4 byte align, so pad it
} PACK_STRUCT;
#include "irr/irrunpack.h"

int main()
{
	printf("Please select the background:\n");
	printf(" (0 : default) Use SkyDome\n");
	printf(" (1) Use SkyBox\n");

	uint8_t c = 0;
	std::cin >> c;

	// create device with full flexibility over creation parameters
	// you can add more parameters if desired, check irr::SIrrlichtCreationParameters
	irr::SIrrlichtCreationParameters params;
	params.Bits = 24; //may have to set to 32bit for some platforms
	params.ZBufferBits = 24; //we'd like 32bit here
	params.DriverType = video::EDT_OPENGL; //! Only Well functioning driver, software renderer left for sake of 2D image drawing
	params.WindowSize = dimension2d<uint32_t>(1280, 720);
	params.Fullscreen = false;
	params.Vsync = true; //! If supported by target platform
	params.Doublebuffer = true;
	params.Stencilbuffer = false; //! This will not even be a choice soon
	IrrlichtDevice* device = createDeviceEx(params);

	if (device == 0)
		return 1; // could not create selected driver.

	video::IVideoDriver* driver = device->getVideoDriver();
    SimpleCallBack* callBack = new SimpleCallBack();

    //! First need to make a material other than default to be able to draw with custom shader
    video::SMaterial material;
    material.BackfaceCulling = false; //! Triangles will be visible from both sides
    material.MaterialType = (video::E_MATERIAL_TYPE)driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles("../mesh.vert",
                                                        "","","", //! No Geometry or Tessellation Shaders
                                                        "../mesh.frag",
                                                        3,video::EMT_SOLID, //! 3 vertices per primitive (this is tessellation shader relevant only
                                                        callBack,
                                                        0); //! No custom user data
    callBack->drop();

	scene::ISceneManager* smgr = device->getSceneManager();

	driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);

	// create skybox and skydome
	switch (c)
	{
        case '1':
            smgr->addSkyBoxSceneNode(
                driver->getTexture("../../media/irrlicht2_up.jpg"),
                driver->getTexture("../../media/irrlicht2_dn.jpg"),
                driver->getTexture("../../media/irrlicht2_lf.jpg"),
                driver->getTexture("../../media/irrlicht2_rt.jpg"),
                driver->getTexture("../../media/irrlicht2_ft.jpg"),
                driver->getTexture("../../media/irrlicht2_bk.jpg"));
            break;
        default:
            smgr->addSkyDomeSceneNode(driver->getTexture("../../media/skydome.jpg"),16,8,0.95f,2.0f,10.f);
            break;
	}

	driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);

	//! we want to move around the scene and view it from different angles
	scene::ICameraSceneNode* camera =
		smgr->addCameraSceneNodeFPS(0,100.0f,0.001f);

	camera->setPosition(core::vector3df(-4,0,0));
	camera->setTarget(core::vector3df(0,0,0));
	camera->setNearValue(0.01f);
	camera->setFarValue(10.0f);

    smgr->setActiveCamera(camera);

	//! disable mouse cursor, since camera will force it to the middle
	//! and we don't want a jittery cursor in the middle distracting us
	device->getCursorControl()->setVisible(false);

	//! Since our cursor will be enslaved, there will be no way to close the window
	//! So we listen for the "Q" key being pressed and exit the application
	MyEventReceiver receiver;
	device->setEventReceiver(&receiver);

	uint64_t lastFPSTime = 0;

	while(device->run())
	//if (device->isWindowActive())
	{
		driver->beginScene(true, true, video::SColor(255,255,255,255) );

        //! This animates (moves) the camera and sets the transforms
        //! Also draws the meshbuffer
        smgr->drawAll();

        //! Stress test for memleaks aside from demo how to create meshes that live on the GPU RAM
        {
            VertexStruct vertices[8];
            vertices[0] = VertexStruct{{-1.f,-1.f,-1.f},{  0,  0}};
            vertices[1] = VertexStruct{{ 1.f,-1.f,-1.f},{127,  0}};
            vertices[2] = VertexStruct{{-1.f, 1.f,-1.f},{255,  0}};
            vertices[3] = VertexStruct{{ 1.f, 1.f,-1.f},{  0,127}};
            vertices[4] = VertexStruct{{-1.f,-1.f, 1.f},{127,127}};
            vertices[5] = VertexStruct{{ 1.f,-1.f, 1.f},{255,127}};
            vertices[6] = VertexStruct{{-1.f, 1.f, 1.f},{  0,255}};
            vertices[7] = VertexStruct{{ 1.f, 1.f, 1.f},{127,255}};

            uint16_t indices_indexed16[] =
            {
                0,1,2,1,2,3,
                4,5,6,5,6,7,
                0,1,4,1,4,5,
                2,3,6,3,6,7,
                0,2,4,2,4,6,
                1,3,5,3,5,7
            };

            auto upStreamBuff = driver->getDefaultUpStreamingBuffer();
            const void* dataToPlace[2]  = {vertices,indices_indexed16};
            uint32_t offsets[2]         = {video::StreamingTransientDataBufferMT<>::invalid_address,video::StreamingTransientDataBufferMT<>::invalid_address};
            uint32_t alignments[2]      = {sizeof(decltype(vertices[0u])),sizeof(decltype(indices_indexed16[0u]))};
            uint32_t sizes[2]           = {sizeof(vertices),sizeof(indices_indexed16)};
            upStreamBuff->multi_place(2u,(const void* const*)dataToPlace,(uint32_t*)&offsets,(uint32_t*)&sizes,(uint32_t*)&alignments);
            if (upStreamBuff->needsManualFlushOrInvalidate())
            {
                auto upStreamMem = upStreamBuff->getBuffer()->getBoundMemory();
                driver->flushMappedMemoryRanges({video::IDriverMemoryAllocation::MappedMemoryRange(upStreamMem,offsets[0],sizes[0]),video::IDriverMemoryAllocation::MappedMemoryRange(upStreamMem,offsets[1],sizes[1])});
            }

            auto buff = upStreamBuff->getBuffer();
            scene::IGPUMeshDataFormatDesc* desc = driver->createGPUMeshDataFormatDesc();
            desc->mapVertexAttrBuffer(buff,scene::EVAI_ATTR0,scene::ECPA_THREE,scene::ECT_FLOAT,sizeof(VertexStruct),offsetof(VertexStruct,Pos[0])+offsets[0]);
            desc->mapVertexAttrBuffer(buff,scene::EVAI_ATTR1,scene::ECPA_TWO,scene::ECT_NORMALIZED_UNSIGNED_BYTE,sizeof(VertexStruct),offsetof(VertexStruct,Col[0])+offsets[0]);
            desc->mapIndexBuffer(buff);

            scene::IGPUMeshBuffer* mb = new scene::IGPUMeshBuffer();
            mb->setMeshDataAndFormat(desc);
            mb->setIndexBufferOffset(offsets[1]);
            mb->setIndexType(scene::EIT_16BIT);
            mb->setIndexCount(2*3*6);
            desc->drop();

            driver->setTransform(video::E4X3TS_WORLD,core::matrix4x3());
            driver->setMaterial(material);
            driver->drawMeshBuffer(mb);
            mb->drop();

            upStreamBuff->multi_free(2u,(uint32_t*)&offsets,(uint32_t*)&sizes,driver->placeFence());
        }

		driver->endScene();

		// display frames per second in window title
		uint64_t time = device->getTimer()->getRealTime();
		if (time-lastFPSTime > 1000)
		{
			std::wostringstream str;
			str << L"GPU Mesh Demo - Irrlicht Engine [" << driver->getName() << "] FPS:" << driver->getFPS() << " PrimitvesDrawn:" << driver->getPrimitiveCountDrawn();

			device->setWindowCaption(str.str().c_str());
			lastFPSTime = time;
		}
	}

    //create a screenshot
	video::IImage* screenshot = driver->createImage(video::ECF_A8R8G8B8,params.WindowSize);
    glReadPixels(0,0, params.WindowSize.Width,params.WindowSize.Height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, screenshot->getData());
    {
        // images are horizontally flipped, so we have to fix that here.
        uint8_t* pixels = (uint8_t*)screenshot->getData();

        const int32_t pitch=screenshot->getPitch();
        uint8_t* p2 = pixels + (params.WindowSize.Height - 1) * pitch;
        uint8_t* tmpBuffer = new uint8_t[pitch];
        for (uint32_t i=0; i < params.WindowSize.Height; i += 2)
        {
            memcpy(tmpBuffer, pixels, pitch);
            memcpy(pixels, p2, pitch);
            memcpy(p2, tmpBuffer, pitch);
            pixels += pitch;
            p2 -= pitch;
        }
        delete [] tmpBuffer;
    }
	driver->writeImageToFile(screenshot,"./screenshot.png");
	screenshot->drop();
	device->sleep(3000);

	device->drop();

	return 0;
}
<|endoftext|>