text:
/*
 * okvis_library.cpp
 *
 *  Created on: 10 Mar 2017
 *      Author: toky
 */

#include<SLAMBenchAPI.h>

#include <stdint.h>
#include <vector>
#include <sstream>
#include <string>
#include <cstring>
#include <time.h>
#include <csignal>
#include <io/sensor/CameraSensor.h>
#include <io/sensor/CameraSensorFinder.h>
#include <io/sensor/IMUSensor.h>
#include <io/sensor/AccelerometerSensor.h>
#include <io/sensor/GyroSensor.h>
#include "io/SLAMFrame.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sstream>
#include <iomanip>

#include <okvis/VioParametersReader.hpp>
#include <timings.h>

#include <Eigen/Dense>
#include <Eigen/Geometry>

#include <okvis/ThreadedKFVio.hpp>
#include <okvis/cameras/PinholeCamera.hpp>
#include <okvis/cameras/RadialTangentialDistortion.hpp>
#include <okvis/VioVisualizer.hpp>
#include <vector>

//=========================================================================
// SLAMBENCH SENSORS
//=========================================================================

static slambench::io::CameraSensor *grey_sensor_one = nullptr;
static slambench::io::CameraSensor *grey_sensor_two = nullptr;
static slambench::io::IMUSensor *IMU_sensor = nullptr;
static slambench::io::AccelerometerSensor *Acc_sensor = nullptr;
static slambench::io::GyroSensor *Gyro_sensor = nullptr;

//=========================================================================
// OKVIS INPUTS AND ESTIMATOR
//=========================================================================

okvis::Time t_one;
okvis::Time t_two;

cv::Mat* img_one;
cv::Mat* img_two;

static std::vector<okvis::Time>   tim_data;
static std::vector<Eigen::Vector3d>      gyr_data;
static std::vector<Eigen::Vector3d>      acc_data;

static bool one_ok = false;
static bool two_ok = false;

okvis::VioParameters parameters;
okvis::ThreadedKFVio* okvis_estimator;

//=========================================================================
// Object used to collect current pose via callbacks
//=========================================================================

class PoseViewer
{
public:

	Eigen::Matrix4d callback_position;

	EIGEN_MAKE_ALIGNED_OPERATOR_NEW
	constexpr static const double imageSize = 500.0;
	PoseViewer()
	{
	}
	// this we can register as a callback
	void publishFullStateAsCallback(
			const okvis::Time & /*t*/, const okvis::kinematics::Transformation & T_WS,
			const Eigen::Matrix<double, 9, 1> & speedAndBiases,
			const Eigen::Matrix<double, 3, 1> & /*omega_S*/)
	{

		callback_position = T_WS.T();
	}
} poseViewer;

//=========================================================================
// SLAMBench output values
//=========================================================================

slambench::outputs::Output *pose_output;

slambench::outputs::Output *left_frame_output = nullptr;
slambench::outputs::Output *right_frame_output = nullptr;

//=========================================================================
// Algorithmic parameters and default_values
//=========================================================================

bool blockingEstimator;
int numKeyframes;
int numImuFrames;

double detectionThreshold;  ///< Keypoint detection threshold.
int detectionOctaves;     ///< Number of keypoint detection octaves.
int maxNoKeypoints;       ///< Restrict to a maximum of this many keypoints per image (strongest ones).
int max_iterations; ///< Maximum iterations the optimization should perform.
int min_iterations; ///< Minimum iterations the optimization should perform.
double timeLimitForMatchingAndOptimization; ///< The time limit for both matching and optimization. [s]
double frameTimestampTolerance; ///< Time tolerance between frames to accept them as stereo frames. [s]

bool default_blockingEstimator = true;
int default_max_iterations = 10; ///< Maximum iterations the optimization should perform.
int default_min_iterations = 3; ///< Minimum iterations the optimization should perform.
double default_timeLimitForMatchingAndOptimization = 0.035; ///< The time limit for both matching and optimization. [s]
double default_detectionThreshold = 40.0;  ///< Keypoint detection threshold.
int default_detectionOctaves = 0;     ///< Number of keypoint detection octaves.
int default_maxNoKeypoints = 400;       ///< Restrict to a maximum of this many keypoints per image (strongest ones).
int default_numKeyframes = 5; ///< Number of keyframes.
int default_numImuFrames = 3; ///< Number of IMU frames.
double default_frameTimestampTolerance = 0.005; ///< Time tolerance between frames to accept them as stereo frames. [s]

//=========================================================================
// IMU parameters are hard-coded TODO !!
//=========================================================================

/// Those values are NOT available in the dataset
//------------------------------------------------------

double tau= 3600.0 ; // # reversion time constant, currently not in use [s]
double g= 9.81007 ; // # Earth's acceleration due to gravity [m/s^2]
Eigen::Vector3d a0 = {0.0, 0.0, 0.0};// # Accelerometer bias [m/s^2]

//=========================================================================
// What are those ? TODO
//=========================================================================

int publishRate = 200;  ///< Maximum publishing rate. [Hz] # rate at which odometry updates are published only works properly if imu_rate/publish_rate is an integer!!
bool publishLandmarks = true; ///< Select, if you want to publish landmarks at all.
float landmarkQualityThreshold = 1.0e-2; ///< Quality threshold under which landmarks are not published. Between 0 and 1.
float maxLandmarkQuality = 0.05; ///< Quality above which landmarks are assumed to be of the best quality. Between 0 and 1.
size_t maxPathLength = 20 ; ///< Maximum length of ros::nav_mgsgs::Path to be published.
bool publishImuPropagatedState = true; ///< Should the state that is propagated with IMU messages be published? Or just the optimized ones?
okvis::kinematics::Transformation T_Wc_W = okvis::kinematics::Transformation::Identity(); ///< Provide custom World frame Wc
okvis::FrameName trackedBodyFrame = okvis::FrameName::B; ///< B or S, the frame of reference that will be expressed relative to the selected worldFrame Wc
okvis::FrameName velocitiesFrame = okvis::FrameName::Wc; ///< B or S,  the frames in which the velocities of the selected trackedBodyFrame will be expressed in

//=========================================================================
// QUICK FIX TODO
//=========================================================================

bool visualization_fixed = false;

//=========================================================================
// SLAMBENCH API FUNCTIONS
//=========================================================================

bool sb_new_slam_configuration(SLAMBenchLibraryHelper * slam_settings) {

	slam_settings->addParameter(DiscretParameter<int>({1, 2, 3, 5, 10}, "nkf", "numKeyframes", "Number of key Frames", &numKeyframes, &default_numKeyframes));
	slam_settings->addParameter(DiscretParameter<int>({1, 2, 3, 5, 10}, "nif", "numImuframes", "Number of IMU Frames", &numImuFrames, &default_numImuFrames));

	slam_settings->addParameter(TypedParameter<int>("do", "detectionOctaves", "Number of keypoint detection octaves", &detectionOctaves, &default_detectionOctaves));
	slam_settings->addParameter(TypedParameter<int>("mnk", "maxNoKeypoints", "Restrict to a maximum of this many keypoints per image (strongest ones)", &maxNoKeypoints, &default_maxNoKeypoints));

	slam_settings->addParameter(TypedParameter<double>("dt", "detectionThreshold", "Keypoint detection threshold", &detectionThreshold, &default_detectionThreshold));
	slam_settings->addParameter(TypedParameter<double>("tm", "timeLimitForMatchingAndOptimization", "The time limit for both matching and optimization. [s]", &timeLimitForMatchingAndOptimization, &default_timeLimitForMatchingAndOptimization));

	slam_settings->addParameter(TypedParameter<int>("maxi", "max-iterations", "Maximum iterations the optimization should perform.", &max_iterations, &default_max_iterations));
	slam_settings->addParameter(TypedParameter<int>("mini", "min-iterations", "Minimum iterations the optimization should perform.", &min_iterations, &default_min_iterations));

	slam_settings->addParameter(TypedParameter<double>("tst", "frameTimestampTolerance", "Time tolerance between frames to accept them as stereo frames. [s]", &frameTimestampTolerance, &default_frameTimestampTolerance));

	slam_settings->addParameter(TypedParameter<bool>("be", "blockingEstimator", "The estimator has a blocking feature.", &blockingEstimator, &default_blockingEstimator));

	return true;
}

bool sb_init_slam_system(SLAMBenchLibraryHelper * slam_settings) {

	//=========================================================================
	//OKVIS uses glog
	//=========================================================================
	google::InitGoogleLogging("");
	FLAGS_stderrthreshold = 0;  // INFO: 0, WARNING: 1, ERROR: 2, FATAL: 3
	FLAGS_colorlogtostderr = 1;
	//=========================================================================

	//=========================================================================
	// We retrieve two grey sensors + IMU
	//=========================================================================

	slambench::io::CameraSensorFinder sensor_finder;
	auto grey_sensors = sensor_finder.Find(slam_settings->get_sensors(), {{"camera_type", "grey"}});
	if(grey_sensors.size() < 2) {
		std::cout << "Init failed, did not found enough cameras." << std::endl;
		return false;
	}

	grey_sensor_one = grey_sensors.at(0);
	grey_sensor_two = grey_sensors.at(1);
	img_one = new cv::Mat ( grey_sensor_one->Height ,  grey_sensor_one->Width, CV_8UC1);
	img_two = new cv::Mat ( grey_sensor_two->Height ,  grey_sensor_two->Width, CV_8UC1);

	// IMU_sensor = (slambench::io::IMUSensor*)slam_settings->get_sensors().GetSensor(slambench::io::IMUSensor::kIMUType);
	// if(IMU_sensor == nullptr) {
	// 	std::cout << "Init failed, did not found IMU." << std::endl;
	// 	return false;
	// }
	Acc_sensor = (slambench::io::AccelerometerSensor*)slam_settings->get_sensors().GetSensor(slambench::io::AccelerometerSensor::kAccType);
	if(Acc_sensor == nullptr) {
		std::cout << "Init failed, did not found Accelerometer." << std::endl;
		return false;
	}
	Gyro_sensor = (slambench::io::GyroSensor*)slam_settings->get_sensors().GetSensor(slambench::io::GyroSensor::kGyroType);
	if(Gyro_sensor == nullptr) {
		std::cout << "Init failed, did not found Gyroscope." << std::endl;
		return false;
	}

	if (grey_sensor_one->Rate != grey_sensor_two->Rate) {
		std::cout << "Camera sensors have a different rate, this is not supported." << std::endl;
		return false;
	}

	//=========================================================================
	// Prepare okvis parameters
	//=========================================================================

	parameters.optimization.numKeyframes = numKeyframes;
	parameters.optimization.numImuFrames = numImuFrames;

	parameters.optimization.max_iterations = max_iterations;
	parameters.optimization.min_iterations = min_iterations;
	parameters.optimization.timeLimitForMatchingAndOptimization = timeLimitForMatchingAndOptimization;

	parameters.optimization.detectionThreshold = detectionThreshold;
	parameters.optimization.detectionOctaves = detectionOctaves;
	parameters.optimization.maxNoKeypoints = maxNoKeypoints;

	parameters.sensors_information.cameraRate = grey_sensor_one->Rate;     ///< Camera rate in Hz.
	parameters.sensors_information.frameTimestampTolerance = frameTimestampTolerance; ///< Time tolerance between frames to accept them as stereo frames. [s]

	parameters.sensors_information.imageDelay = 0.0;  ///< Camera image delay. [s]
	parameters.sensors_information.imuIdx = 0;         ///< IMU index. Anything other than 0 will probably not work.

	// okvis::kinematics::Transformation T_BS = okvis::kinematics::Transformation(IMU_sensor->Pose.cast<double>()); //  # tranform Body-Sensor (IMU)
	okvis::kinematics::Transformation T_BS = okvis::kinematics::Transformation(Acc_sensor->Pose.cast<double>());

	/// Those values are available in the dataset
	//------------------------------------------------------

        parameters.imu.sigma_g_c  = 0.000227;//1.6968e-04     # [ rad / s / sqrt(Hz) ]
        parameters.imu.sigma_gw_c = 4.0e-6;//4.0e-6
        parameters.imu.sigma_bg  = 2e-4;//1.9393e-05       # [ rad / s^2 / sqrt(Hz) ]
        parameters.imu.g_max  = 7.8;//7.8

        parameters.imu.sigma_a_c  = 0.00146;//2.0000e-3  # [ m / s^2 / sqrt(Hz) ]
        parameters.imu.sigma_aw_c  = 4.0e-5;//4.0e-5
        parameters.imu.sigma_ba  = 3.0e-3;//3.0000e-3    # [ m / s^3 / sqrt(Hz) ]
        parameters.imu.a_max  = 176.0;//176.0

	parameters.imu.tau  = tau;
	parameters.imu.g  = g;
	parameters.imu.a0  = a0;

	// parameters.imu.rate = IMU_sensor->Rate;
	parameters.imu.rate = Gyro_sensor->Rate < Acc_sensor->Rate ? Gyro_sensor->Rate : Acc_sensor->Rate;
	parameters.imu.T_BS = T_BS;

	///< ************** Wind parameters.

	//// double priorStdev;  ///< Prior of wind. [m/s]
	//// double sigma_c;     ///< Drift noise density. [m/s/sqrt(s)]
	//// double tau;         ///< Reversion time constant. [s];
	//// double updateFrequency; ///< Related state estimates are inserted at this frequency. [Hz]
	////
	//// parameters.wind.priorStdev = priorStdev;
	//// parameters.wind.sigma_c = sigma_c;
	//// parameters.wind.tau = tau;
	//// parameters.wind.updateFrequency = updateFrequency;

	///< ****************** Camera extrinsic estimation parameters.

	// absolute (prior) w.r.t frame S
	double sigma_absolute_translation = 0.0; ///< Absolute translation stdev. [m]
	double sigma_absolute_orientation= 0.0; ///< Absolute orientation stdev. [rad]

	// relative (temporal)
	double sigma_c_relative_translation= 0.0; ///< Relative translation noise density. [m/sqrt(Hz)]
	double sigma_c_relative_orientation= 0.0; ///< Relative orientation noise density. [rad/sqrt(Hz)]

	parameters.camera_extrinsics.sigma_absolute_translation = sigma_absolute_translation;
	parameters.camera_extrinsics.sigma_absolute_orientation = sigma_absolute_orientation;
	parameters.camera_extrinsics.sigma_c_relative_translation = sigma_c_relative_translation;
	parameters.camera_extrinsics.sigma_c_relative_orientation = sigma_c_relative_orientation;

	///< ********** Publishing parameters.

	parameters.publishing.publishRate = publishRate ;
	parameters.publishing.publishLandmarks = publishLandmarks ;
	parameters.publishing.landmarkQualityThreshold = landmarkQualityThreshold ;
	parameters.publishing.maxLandmarkQuality = maxLandmarkQuality ;
	parameters.publishing.maxPathLength = maxPathLength ;
	parameters.publishing.publishImuPropagatedState = publishImuPropagatedState ;
	parameters.publishing.T_Wc_W = T_Wc_W ;
	parameters.publishing.trackedBodyFrame = trackedBodyFrame ;
	parameters.publishing.velocitiesFrame = velocitiesFrame ;

	///< Camera configuration.

	if (parameters.nCameraSystem.numCameras() != 0) {
		std::cout << "Unsupported case of configuration" << std::endl;
		exit(1);
	}

	std::cout << "Add cameras, may take a wee while..." << std::endl;

	for (auto sensor : grey_sensors) {
		Eigen::Matrix4d CAM_TSC = sensor->Pose.cast<double>();
		Eigen::Vector2d CAM_dimension = {sensor->Width,sensor->Height};
		Eigen::Vector2f CAM_focalLength    = {sensor->Intrinsics[0] * sensor->Width, sensor->Intrinsics[1] * sensor->Height};
		Eigen::Vector2f CAM_principalPoint = {sensor->Intrinsics[2] * sensor->Width, sensor->Intrinsics[3] * sensor->Height};

		if (sensor->DistortionType != slambench::io::CameraSensor::distortion_type_t::RadialTangential) {
			std::cerr << "Unsupported sensor with no distortion" << std::endl;
			// exit(1);
		}

		Eigen::Vector4f CAM_distortionCoefficients = { sensor->RadialTangentialDistortion[0],
				sensor->RadialTangentialDistortion[1],
				sensor->RadialTangentialDistortion[2],
				sensor->RadialTangentialDistortion[3]};
		okvis::cameras::NCameraSystem::DistortionType CAM_distortion_type =  okvis::cameras::NCameraSystem::RadialTangential;

		parameters.nCameraSystem.addCamera(
				std::shared_ptr<const okvis::kinematics::Transformation>(new okvis::kinematics::Transformation (CAM_TSC)),
				std::shared_ptr<const okvis::cameras::CameraBase>(
						new okvis::cameras::PinholeCamera<
						okvis::cameras::RadialTangentialDistortion>(
								CAM_dimension[0],
								CAM_dimension[1],
								CAM_focalLength[0],
								CAM_focalLength[1],
								CAM_principalPoint[0],
								CAM_principalPoint[1],
								okvis::cameras::RadialTangentialDistortion(
										CAM_distortionCoefficients[0],
										CAM_distortionCoefficients[1],
										CAM_distortionCoefficients[2],
										CAM_distortionCoefficients[3])/*, id ?*/)),
										CAM_distortion_type/*, computeOverlaps ?*/);

	}
	std::cout << "Done !" << std::endl;

	/// Those parameters are not supported yet....

	///  parameters.magnetometer;  ///< Magnetometer parameters.
	///  parameters.position;  ///< Position sensor parameters.
	///  parameters.gps; ///< GPS parameters
	///  parameters.magnetic_enu_z;  ///< Dynamics of magnetic ENU z component variation.
	///  parameters.barometer;  ///< Barometer parameters.
	///  parameters.qff;  ///< QFF parameters.
	///  parameters.differential; ///< Differential pressure sensor parameters.
	///

	//=========================================================================
	// Start the visualization (only if rendering will happen)
	//=========================================================================

	parameters.visualization.displayImages = true;
	if (visualization_fixed) parameters.visualization.displayImages = false;

	//=========================================================================
	// START ESTIMATOR
	//=========================================================================

	okvis_estimator = new okvis::ThreadedKFVio(parameters);

	okvis_estimator->setFullStateCallback(
			std::bind(&PoseViewer::publishFullStateAsCallback, &poseViewer,
					std::placeholders::_1, std::placeholders::_2,
					std::placeholders::_3, std::placeholders::_4));

	okvis_estimator->setBlocking(blockingEstimator);

	//=========================================================================
	// DECLARE OUTPTUS
	//=========================================================================

	pose_output = new slambench::outputs::Output("Pose", slambench::values::VT_POSE, true);
	slam_settings->GetOutputManager().RegisterOutput(pose_output);

	left_frame_output = new slambench::outputs::Output("Left Frame", slambench::values::VT_FRAME);
	right_frame_output = new slambench::outputs::Output("Right Frame", slambench::values::VT_FRAME);
	left_frame_output->SetKeepOnlyMostRecent(true);
	right_frame_output->SetKeepOnlyMostRecent(true);

	slam_settings->GetOutputManager().RegisterOutput(left_frame_output);
	slam_settings->GetOutputManager().RegisterOutput(right_frame_output);

	pose_output->SetActive(true);
	left_frame_output->SetActive(true);
	right_frame_output->SetActive(true);

	//=========================================================================
	// END OF CONFIGURATION
	//=========================================================================

	// return (grey_sensor_one && grey_sensor_two && IMU_sensor);
	return (grey_sensor_one && grey_sensor_two && Acc_sensor && Gyro_sensor);
}

bool acc_ready = false;

bool sb_update_frame (SLAMBenchLibraryHelper * slam_settings, slambench::io::SLAMFrame* s) {

	//=====================
	// SKIP UNKNOWNS
	//=====================

	if (s->FrameSensor->GetType() != slambench::io::CameraSensor::kCameraType and s->FrameSensor->GetType() != slambench::io::AccelerometerSensor::kAccType and s->FrameSensor->GetType() != slambench::io::GyroSensor::kGyroType) {
		// Skip Unsupported Frames
		return false;
	}

	//=====================
	// CRY BAD DATA MANAGEMENT
	//=====================

	if (one_ok && two_ok) {
		std::cout << "ALREADY HAVE REQURIED SENSORS, SHOULD PROCESS !" << std::endl;
		exit(1);
	}

	assert(s != nullptr);

	//=====================
	// GET S1
	//=====================

	if(s->FrameSensor == grey_sensor_one) {

		if (one_ok) {
			std::cout << "BUG: SENSOR ONE SEEN TWICE" << std::endl;
			exit(1);
		}

		one_ok = true;
		t_one = okvis::Time(s->Timestamp.S, s->Timestamp.Ns);
		memcpy(img_one->data, s->GetData(), s->GetSize());

	}

	//=====================
	// GET S2
	//=====================

	if(s->FrameSensor == grey_sensor_two) {

		if (two_ok) {
			std::cout << "BUG: SENSOR TWO SEEn TWICE" << std::endl;
			exit(1);
		}

		two_ok = true;
		t_two = okvis::Time(s->Timestamp.S, s->Timestamp.Ns);
		memcpy(img_two->data, s->GetData(), s->GetSize());

	}

	//=====================
	// GET IMU
	//=====================

	// if(s->FrameSensor == IMU_sensor) {

	// 	float* frame_data = (float*)s->GetData();
	// 	gyr_data.push_back(Eigen::Vector3d(frame_data[0],frame_data[1],frame_data[2]));
	// 	acc_data.push_back(Eigen::Vector3d(frame_data[3],frame_data[4],frame_data[5]));
	// 	tim_data.push_back (okvis::Time(s->Timestamp.S, s->Timestamp.Ns));

	// }
	if(!acc_ready && s->FrameSensor == Acc_sensor) {

		float* frame_data = (float*)s->GetData();
		acc_data.push_back(Eigen::Vector3d(frame_data[0],frame_data[1],frame_data[2]));
		// std::cout<<"acc_data:"<<frame_data[0]<<","<<frame_data[1]<<","<<frame_data[2]<<std::endl;
		tim_data.push_back (okvis::Time(s->Timestamp.S, s->Timestamp.Ns));
		acc_ready = true;
		// std::cout<<"acc sensor:"<<s->Timestamp<<" "<<acc_ready<<std::endl;
	}

	if(acc_ready && s->FrameSensor == Gyro_sensor) {

		float* frame_data = (float*)s->GetData();
		gyr_data.push_back(Eigen::Vector3d(frame_data[0],frame_data[1],frame_data[2]));
		// std::cout<<"gyr_data:"<<frame_data[0]<<","<<frame_data[1]<<","<<frame_data[2]<<std::endl;
		acc_ready = false;
		// std::cout<<"gyro sensor:"<<s->Timestamp<<" "<<acc_ready<<std::endl;
	}

	return two_ok && one_ok;

}

bool sb_process_once (SLAMBenchLibraryHelper * slam_settings) {

	// First Trail of IMU before Image One
	if(gyr_data.size() > acc_data.size()) {
		gyr_data.pop_back();
	} else if (gyr_data.size() < acc_data.size()) {
		acc_data.pop_back();
		tim_data.pop_back();
	}

	for (int i =0;i<tim_data.size();i++) {

		// std::cout << "addImuMeasurement:" << tim_data[i] << std::endl << acc_data[i] << std::endl  << gyr_data[i]<< std::endl;
		okvis_estimator->addImuMeasurement(tim_data[i], acc_data[i], gyr_data[i]);

	}

	// Image One
	//std::cout << "addImageOne:" << t_two << std::endl;
	okvis_estimator->addImage(t_one, 0, *img_one);

	// Image Two
	//std::cout << "addImageTwo:" << t_two << std::endl;
	okvis_estimator->addImage(t_two, 1, *img_two);

	if (one_ok && two_ok) {
		one_ok = false;
		two_ok = false;
		tim_data.clear();
		acc_data.clear();
		gyr_data.clear();
	} else {
		std::cerr << "Processed while not having right sensor data." << std::endl;
		exit(1);
	}

	return true;
}

bool       sb_get_tracked  (bool * tracked) {
	*tracked = (poseViewer.callback_position(3,3) != 1);
	return true;
}

bool sb_clean_slam_system(){
	return true;
}

bool sb_update_outputs(SLAMBenchLibraryHelper *lib, const slambench::TimeStamp *latest_output) {
	(void)lib;

	slambench::TimeStamp ts = *latest_output;

	if(pose_output->IsActive()) {

		Eigen::Matrix4f mat = poseViewer.callback_position.cast<float>();
		if (poseViewer.callback_position(3,3) != 1)  {
			mat = Eigen::Matrix4f::Identity();
		}

		std::lock_guard<FastLock> lock (lib->GetOutputManager().GetLock());
		pose_output->AddPoint(ts, new slambench::values::PoseValue(mat));
	}

	if(left_frame_output->IsActive() or right_frame_output->IsActive()) {

		std::vector<cv::Mat> out_images;
		okvis_estimator->get_cameras(out_images);

		if (out_images.size() == 0) {
			std::cout << "vizualizer failed" << std::endl;
		}

		if(left_frame_output->IsActive() and out_images.size() > 0) {
			cv::Mat& image = out_images[0];

			left_frame_output->AddPoint(*latest_output,
					new slambench::values::FrameValue(image.size().width, image.size().height,
							slambench::io::pixelformat::EPixelFormat::RGB_III_888 , image.data));
		}

		if(right_frame_output->IsActive() and out_images.size() > 1) {
			cv::Mat& image = out_images[0];

			right_frame_output->AddPoint(*latest_output,
					new slambench::values::FrameValue(image.size().width, image.size().height,
							slambench::io::pixelformat::EPixelFormat::RGB_III_888 , image.data));
		}

	}

	return true;
}


text:
#include "InputManager.h"
#include "InputConfig.h"
#include "Window.h"
#include "Log.h"
#include "pugiXML/pugixml.hpp"
#include <boost/filesystem.hpp>
#include "platform.h"

#if defined(WIN32) || defined(_WIN32)
	#include <Windows.h>
#endif

namespace fs = boost::filesystem;

//----- InputDevice ----------------------------------------------------------------------------

InputDevice::InputDevice(const std::string & deviceName, unsigned long vendorId, unsigned long productId)
	: name(deviceName), vendor(vendorId), product(productId)
{
}

bool InputDevice::operator==(const InputDevice & b) const
{
	return (name == b.name && vendor == b.vendor && product == b.product);
}

//----- InputManager ---------------------------------------------------------------------------

InputManager::InputManager(Window* window) : mWindow(window),
	mJoysticks(NULL), mInputConfigs(NULL), mKeyboardInputConfig(NULL), mPrevAxisValues(NULL),
	mNumJoysticks(0), mNumPlayers(0), devicePollingTimer(NULL)
{
}

InputManager::~InputManager()
{
	deinit();
}

std::vector<InputDevice> InputManager::getInputDevices() const
{
	std::vector<InputDevice> currentDevices;

	//retrieve all input devices from system
#if defined (__APPLE__)
    #error TODO: Not implemented for MacOS yet!!!
#elif defined(__linux__)
	//open linux input devices file system
	const std::string inputPath("/dev/input");
	fs::directory_iterator dirIt(inputPath);
	while (dirIt != fs::directory_iterator()) {
		//get directory entry
		std::string deviceName = (*dirIt).path().string();
		//remove parent path
		deviceName.erase(0, inputPath.length() + 1);
		//check if it start with "js"
		if (deviceName.length() >= 3 && deviceName.find("js") == 0) {
			//looks like a joystick. add to devices.
			currentDevices.push_back(InputDevice(deviceName, 0, 0));
		}
		++dirIt;
	}
	//or dump /proc/bus/input/devices anbd search for a Handler=..."js"... entry
#elif defined(WIN32) || defined(_WIN32)
	RAWINPUTDEVICELIST * deviceList = nullptr;
	UINT nrOfDevices = 0;
	//get number of input devices
	if (GetRawInputDeviceList(deviceList, &nrOfDevices, sizeof(RAWINPUTDEVICELIST)) != -1 && nrOfDevices > 0)
	{
		//get list of input devices
		deviceList = new RAWINPUTDEVICELIST[nrOfDevices];
		if (GetRawInputDeviceList(deviceList, &nrOfDevices, sizeof(RAWINPUTDEVICELIST)) != -1)
		{
			//loop through input devices
			for (unsigned int i = 0; i < nrOfDevices; i++)
			{
				//get device name
				char * rawName = new char[2048];
				UINT rawNameSize = 2047;
				GetRawInputDeviceInfo(deviceList[i].hDevice, RIDI_DEVICENAME, (void *)rawName, &rawNameSize);
				//null-terminate string
				rawName[rawNameSize] = '\0';
				//convert to string
				std::string deviceName = rawName;
				delete [] rawName;
				//get deviceType
				RID_DEVICE_INFO deviceInfo;
				UINT deviceInfoSize = sizeof(RID_DEVICE_INFO);
				GetRawInputDeviceInfo(deviceList[i].hDevice, RIDI_DEVICEINFO, (void *)&deviceInfo, &deviceInfoSize);
				//check if it is a HID. we ignore keyboards and mice...
				if (deviceInfo.dwType == RIM_TYPEHID)
				{
					//check if the vendor/product already exists in list. yes. could be more elegant...
					std::vector<InputDevice>::const_iterator cdIt = currentDevices.cbegin();
					while (cdIt != currentDevices.cend())
					{
						if (cdIt->name == deviceName && cdIt->product == deviceInfo.hid.dwProductId && cdIt->vendor == deviceInfo.hid.dwVendorId)
						{
							//device already there
							break;
						}
						++cdIt;
					}
					//was the device found?
					if (cdIt == currentDevices.cend())
					{
						//no. add it.
						currentDevices.push_back(InputDevice(deviceName, deviceInfo.hid.dwProductId, deviceInfo.hid.dwVendorId));
					}
				}
			}
		}
		delete [] deviceList;
	}
#endif

	return currentDevices;
}

Uint32 InputManager::devicePollingCallback(Uint32 interval, void* param)
{
	//this thing my be running in a different thread, so we're not allowed to call
	//any functions or change/allocate/delete stuff, but can send a user event
	SDL_Event event;
	event.user.type = SDL_USEREVENT;
	event.user.code = SDL_USEREVENT_POLLDEVICES;
	event.user.data1 = nullptr;
	event.user.data2 = nullptr;
	if (SDL_PushEvent(&event) != 0) {
		LOG(LogError) << "InputManager::devicePollingCallback - SDL event queue is full!";
	}

	return interval;
}

void InputManager::init()
{
	if(mJoysticks != NULL)
		deinit();

	//get current input devices from system
	inputDevices = getInputDevices();

	SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_TIMER);

	mNumJoysticks = SDL_NumJoysticks();
	mJoysticks = new SDL_Joystick*[mNumJoysticks];
	mInputConfigs = new InputConfig*[mNumJoysticks];
	mPrevAxisValues = new std::map<int, int>[mNumJoysticks];

	for(int i = 0; i < mNumJoysticks; i++)
	{
		mJoysticks[i] = SDL_JoystickOpen(i);
		mInputConfigs[i] = new InputConfig(i);

		for(int k = 0; k < SDL_JoystickNumAxes(mJoysticks[i]); k++)
		{
			mPrevAxisValues[i][k] = 0;
		}
	}

	mKeyboardInputConfig = new InputConfig(DEVICE_KEYBOARD);

	SDL_JoystickEventState(SDL_ENABLE);

	//start timer for input device polling
	startPolling();

	loadConfig();
}

void InputManager::startPolling()
{
	if(devicePollingTimer != NULL)
		return;

	devicePollingTimer = SDL_AddTimer(POLLING_INTERVAL, devicePollingCallback, (void *)this);
}

void InputManager::stopPolling()
{
	if(devicePollingTimer == NULL)
		return;

	SDL_RemoveTimer(devicePollingTimer);
	devicePollingTimer = NULL;
}

void InputManager::deinit()
{
	stopPolling();

	SDL_JoystickEventState(SDL_DISABLE);

	if(!SDL_WasInit(SDL_INIT_JOYSTICK))
		return;

	if(mJoysticks != NULL)
	{
		for(int i = 0; i < mNumJoysticks; i++)
		{
			SDL_JoystickClose(mJoysticks[i]);
			delete mInputConfigs[i];
		}

		delete[] mInputConfigs;
		mInputConfigs = NULL;

		delete[] mJoysticks;
		mJoysticks = NULL;

		delete mKeyboardInputConfig;
		mKeyboardInputConfig = NULL;

		delete[] mPrevAxisValues;
		mPrevAxisValues = NULL;
	}

	SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_TIMER);

	inputDevices.clear();
}

int InputManager::getNumJoysticks() { return mNumJoysticks; }
int InputManager::getButtonCountByDevice(int id)
{
	if(id == DEVICE_KEYBOARD)
		return 120; //it's a lot, okay.
	else
		return SDL_JoystickNumButtons(mJoysticks[id]);
}

int InputManager::getNumPlayers() { return mNumPlayers; }
void InputManager::setNumPlayers(int num) { mNumPlayers = num; }

InputConfig* InputManager::getInputConfigByDevice(int device)
{
	if(device == DEVICE_KEYBOARD)
		return mKeyboardInputConfig;
	else
		return mInputConfigs[device];
}

InputConfig* InputManager::getInputConfigByPlayer(int player)
{
	if(mKeyboardInputConfig->getPlayerNum() == player)
		return mKeyboardInputConfig;

	for(int i = 0; i < mNumJoysticks; i++)
	{
		if(mInputConfigs[i]->getPlayerNum() == player)
			return mInputConfigs[i];
	}

	LOG(LogError) << "Could not find input config for player number " << player << "!";
	return NULL;
}

bool InputManager::parseEvent(const SDL_Event& ev)
{
	bool causedEvent = false;
	switch(ev.type)
	{
	case SDL_JOYAXISMOTION:
		//if it switched boundaries
		if((abs(ev.jaxis.value) > DEADZONE) != (abs(mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis]) > DEADZONE))
		{
			int normValue;
			if(abs(ev.jaxis.value) <= DEADZONE)
				normValue = 0;
			else
				if(ev.jaxis.value > 0)
					normValue = 1;
				else
					normValue = -1;

			mWindow->input(getInputConfigByDevice(ev.jaxis.which), Input(ev.jaxis.which, TYPE_AXIS, ev.jaxis.axis, normValue, false));
			causedEvent = true;
		}

		mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis] = ev.jaxis.value;
		return causedEvent;

	case SDL_JOYBUTTONDOWN:
	case SDL_JOYBUTTONUP:
		mWindow->input(getInputConfigByDevice(ev.jbutton.which), Input(ev.jbutton.which, TYPE_BUTTON, ev.jbutton.button, ev.jbutton.state == SDL_PRESSED, false));
		return true;

	case SDL_JOYHATMOTION:
		mWindow->input(getInputConfigByDevice(ev.jhat.which), Input(ev.jhat.which, TYPE_HAT, ev.jhat.hat, ev.jhat.value, false));
		return true;

	case SDL_KEYDOWN:
		if(ev.key.keysym.sym == SDLK_F4)
		{
			SDL_Event* quit = new SDL_Event();
			quit->type = SDL_QUIT;
			SDL_PushEvent(quit);
			return false;
		}

		mWindow->input(getInputConfigByDevice(DEVICE_KEYBOARD), Input(DEVICE_KEYBOARD, TYPE_KEY, ev.key.keysym.sym, 1, false));
		return true;

	case SDL_KEYUP:
		mWindow->input(getInputConfigByDevice(DEVICE_KEYBOARD), Input(DEVICE_KEYBOARD, TYPE_KEY, ev.key.keysym.sym, 0, false));
		return true;

	case SDL_USEREVENT:
		if (ev.user.code == SDL_USEREVENT_POLLDEVICES) {
			//poll joystick / HID again
			std::vector<InputDevice> currentDevices = getInputDevices();
			//compare device lists to see if devices were added/deleted
			if (currentDevices != inputDevices) {
				LOG(LogInfo) << "Device configuration changed!";
				inputDevices = currentDevices;
				//deinit and reinit InputManager
				deinit();
				init();
			}
			return true;
		}
	}

	return false;
}

void InputManager::loadConfig()
{
	if(!mJoysticks)
	{
		LOG(LogError) << "ERROR - cannot load InputManager config without being initialized!";
	}

	std::string path = getConfigPath();
	if(!fs::exists(path))
		return;

	pugi::xml_document doc;
	pugi::xml_parse_result res = doc.load_file(path.c_str());

	if(!res)
	{
		LOG(LogError) << "Error loading input config: " << res.description();
		return;
	}

	mNumPlayers = 0;

	bool* configuredDevice = new bool[mNumJoysticks];
	for(int i = 0; i < mNumJoysticks; i++)
	{
		mInputConfigs[i]->setPlayerNum(-1);
		configuredDevice[i] = false;
	}

	pugi::xml_node root = doc.child("inputList");

	for(pugi::xml_node node = root.child("inputConfig"); node; node = node.next_sibling("inputConfig"))
	{
		std::string type = node.attribute("type").as_string();

		if(type == "keyboard")
		{
			getInputConfigByDevice(DEVICE_KEYBOARD)->loadFromXML(node, mNumPlayers);
			mNumPlayers++;
		}else if(type == "joystick")
		{
			bool found = false;
			std::string devName = node.attribute("deviceName").as_string();
			for(int i = 0; i < mNumJoysticks; i++)
			{
				if(!configuredDevice[i] && SDL_JoystickName(i) == devName)
				{
					mInputConfigs[i]->loadFromXML(node, mNumPlayers);
					mNumPlayers++;
					found = true;
					configuredDevice[i] = true;
					break;
				}
			}

			if(!found)
			{
				LOG(LogWarning) << "Could not find unconfigured joystick named \"" << devName << "\"! Skipping it.\n";
				continue;
			}
		}else{
			LOG(LogWarning) << "Device type \"" << type << "\" unknown!\n";
		}
	}

	delete[] configuredDevice;

	if(mNumPlayers == 0)
	{
		LOG(LogInfo) << "No input configs loaded. Loading default keyboard config.";
		loadDefaultConfig();
	}

	LOG(LogInfo) << "Loaded InputConfig data for " << getNumPlayers() << " devices.";
}

//used in an "emergency" where no configs could be loaded from the inputmanager config file
//allows the user to select to reconfigure in menus if this happens without having to delete es_input.cfg manually
void InputManager::loadDefaultConfig()
{
	InputConfig* cfg = getInputConfigByDevice(DEVICE_KEYBOARD);

	mNumPlayers++;
	cfg->setPlayerNum(0);
	cfg->mapInput("up", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_UP, 1, true));
	cfg->mapInput("down", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_DOWN, 1, true));
	cfg->mapInput("left", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_LEFT, 1, true));
	cfg->mapInput("right", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RIGHT, 1, true));

	cfg->mapInput("a", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RETURN, 1, true));
	cfg->mapInput("b", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_ESCAPE, 1, true));
	cfg->mapInput("menu", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F1, 1, true));
	cfg->mapInput("select", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F2, 1, true));
	cfg->mapInput("pageup", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_RIGHTBRACKET, 1, true));
	cfg->mapInput("pagedown", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_LEFTBRACKET, 1, true));

	cfg->mapInput("mastervolup", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_PLUS, 1, true));
	cfg->mapInput("mastervoldown", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_MINUS, 1, true));

	cfg->mapInput("sortordernext", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F7, 1, true));
	cfg->mapInput("sortorderprevious", Input(DEVICE_KEYBOARD, TYPE_KEY, SDLK_F8, 1, true));
}

void InputManager::writeConfig()
{
	if(!mJoysticks)
	{
		LOG(LogError) << "ERROR - cannot write config without being initialized!";
		return;
	}

	std::string path = getConfigPath();

	pugi::xml_document doc;

	pugi::xml_node root = doc.append_child("inputList");

	mKeyboardInputConfig->writeToXML(root);
	for(int i = 0; i < mNumJoysticks; i++)
	{
		mInputConfigs[i]->writeToXML(root);
	}

	doc.save_file(path.c_str());
}

std::string InputManager::getConfigPath()
{
	std::string path = getHomePath();
	path += "/.emulationstation/es_input.cfg";
	return path;
}

ext: cpp


text:
#ifndef BOOST_CONTRACT_DETAIL_DEBUG_HPP_
#define BOOST_CONTRACT_DETAIL_DEBUG_HPP_

// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html

// Usually, never #defined (so "debug" assertions always in code).
#ifdef BOOST_CONTRACT_DETAIL_NDEBUG
    #define BOOST_CONTRACT_DETAIL_DEBUG(cond) /* nothing */
#else
    #include <boost/assert.hpp>
    // Extra parenthesis around BOOST_ASSERT to be safe because its is a macro.
    #define BOOST_CONTRACT_DETAIL_DEBUG(cond) (BOOST_ASSERT(cond))
#endif

#endif // #include guard

ext: hpp


text:
/**
 * Canary - A free and open-source MMORPG server emulator
 * Copyright (C) 2021 OpenTibiaBR <opentibiabr@outlook.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "otpch.h"

#include <boost/range/adaptor/reversed.hpp>

#include "creatures/players/player.h"
#include "lua/functions/core/game/modal_window_functions.hpp"

// ModalWindow
int ModalWindowFunctions::luaModalWindowCreate(lua_State* L) {
    // ModalWindow(id, title, message)
    const std::string& message = getString(L, 4);
    const std::string& title = getString(L, 3);
    uint32_t id = getNumber<uint32_t>(L, 2);

    pushUserdata<ModalWindow>(L, new ModalWindow(id, title, message));
    setMetatable(L, -1, "ModalWindow");
    return 1;
}

int ModalWindowFunctions::luaModalWindowDelete(lua_State* L) {
    ModalWindow** windowPtr = getRawUserdata<ModalWindow>(L, 1);
    if (windowPtr && *windowPtr) {
        delete *windowPtr;
        *windowPtr = nullptr;
    }
    return 0;
}

int ModalWindowFunctions::luaModalWindowGetId(lua_State* L) {
    // modalWindow:getId()
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        lua_pushnumber(L, window->id);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowGetTitle(lua_State* L) {
    // modalWindow:getTitle()
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        pushString(L, window->title);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowGetMessage(lua_State* L) {
    // modalWindow:getMessage()
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        pushString(L, window->message);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowSetTitle(lua_State* L) {
    // modalWindow:setTitle(text)
    const std::string& text = getString(L, 2);
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        window->title = text;
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowSetMessage(lua_State* L) {
    // modalWindow:setMessage(text)
    const std::string& text = getString(L, 2);
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        window->message = text;
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowGetButtonCount(lua_State* L) {
    // modalWindow:getButtonCount()
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        lua_pushnumber(L, window->buttons.size());
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowGetChoiceCount(lua_State* L) {
    // modalWindow:getChoiceCount()
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        lua_pushnumber(L, window->choices.size());
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowAddButton(lua_State* L) {
    // modalWindow:addButton(id, text)
    const std::string& text = getString(L, 3);
    uint8_t id = getNumber<uint8_t>(L, 2);
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        window->buttons.emplace_back(text, id);
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowAddChoice(lua_State* L) {
    // modalWindow:addChoice(id, text)
    const std::string& text = getString(L, 3);
    uint8_t id = getNumber<uint8_t>(L, 2);
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        window->choices.emplace_back(text, id);
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowGetDefaultEnterButton(lua_State* L) {
    // modalWindow:getDefaultEnterButton()
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        lua_pushnumber(L, window->defaultEnterButton);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowSetDefaultEnterButton(lua_State* L) {
    // modalWindow:setDefaultEnterButton(buttonId)
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        window->defaultEnterButton = getNumber<uint8_t>(L, 2);
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowGetDefaultEscapeButton(lua_State* L) {
    // modalWindow:getDefaultEscapeButton()
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        lua_pushnumber(L, window->defaultEscapeButton);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowSetDefaultEscapeButton(lua_State* L) {
    // modalWindow:setDefaultEscapeButton(buttonId)
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        window->defaultEscapeButton = getNumber<uint8_t>(L, 2);
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowHasPriority(lua_State* L) {
    // modalWindow:hasPriority()
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        pushBoolean(L, window->priority);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowSetPriority(lua_State* L) {
    // modalWindow:setPriority(priority)
    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        window->priority = getBoolean(L, 2);
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

int ModalWindowFunctions::luaModalWindowSendToPlayer(lua_State* L) {
    // modalWindow:sendToPlayer(player)
    Player* player = getPlayer(L, 2);
    if (!player) {
        lua_pushnil(L);
        return 1;
    }

    ModalWindow* window = getUserdata<ModalWindow>(L, 1);
    if (window) {
        if (!player->hasModalWindowOpen(window->id)) {
            player->sendModalWindow(*window);
        }
        pushBoolean(L, true);
    } else {
        lua_pushnil(L);
    }
    return 1;
}

max_stars_repo_name: Waclaw-I/BagnoOTS

max_issues_repo_name: Waclaw-I/BagnoOTS

max_forks_repo_name: Waclaw-I/BagnoOTS


text:
// Copyright 2017 Battelle Energy Alliance, LLC
//
// 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
//
//     http://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.

// --- LEAF Includes --- //
#include <leaf/wrapper/weru/soil/NASIS.h>

#include <leaf/wrapper/weru/util/ConfigData.h>

#include <leaf/wrapper/java/lang/Double.h>

#include <leaf/wrapper/java/util/Array.h>

using namespace leaf::open;
using namespace leaf::util;
using namespace leaf::wrapper::java::lang;
using namespace leaf::wrapper::java::util;

// --- POCO Includes --- //
using namespace Poco;
using namespace Poco::Dynamic;
using namespace Poco::Data;
using namespace Poco::Data::Keywords;

// --- Boost Includes --- //
#include <boost/regex.hpp>

#include <boost/algorithm/string.hpp>

namespace leaf
{
namespace wrapper
{
namespace weru
{
namespace soil
{

////////////////////////////////////////////////////////////////////////////////
std::set< std::string > const NASIS::ORGANIC_TEXTURES = boost::assign::list_of
    ( "mpm" ) ( "mpt" ) ( "muck" ) ( "peat" )
    ( "spm" ) ( "udom" ) ( "pdom" ) ( "hpm" );
////////////////////////////////////////////////////////////////////////////////
NASIS::NASIS(
    jobject const& o )
    :
    java::lang::Object( o )
{
    ;
}
////////////////////////////////////////////////////////////////////////////////
NASIS::NASIS(
    std::size_t const& inpnumlay )
    :
    java::lang::Object(
        java::NewObject( GetJclass(), GetJmid( "<init>" ), inpnumlay ) )
{
    ;
}
////////////////////////////////////////////////////////////////////////////////
NASIS::~NASIS()
{
    ;
}
////////////////////////////////////////////////////////////////////////////////
SoilError NASIS::LoadSQL(
    soi::ComponentPtr const& component )
{
    std::string cokey = Convert< std::string >( component->GetCokey() );
    Nullable< Var > taxorder = CopyComponent( component );

    //Can test taxorder now to see if organic
    if( util::ConfigData::GetSoilTestOrganic() )
    {
        if( boost::algorithm::to_lower_copy(
                Convert< std::string >( taxorder ) ) == "histosols" )
        {
            return SOIERR_ORGANICTEST;
        }
    }

    //Get a reference to this component's parent
    soi::MapUnit const& mapunit = component->GetMapUnit();

    CopyMapUnit( mapunit );

    CopyMuAggatt( mapunit );

    CopyCoRestrictions( component );

    CopyLegend( mapunit );

    int layerNum( 0 );
    int i( 0 );

    bool foundAMineralLayer( false );

    //Up to this amount is allowed to be ignored
    double maxOrganicDepth( util::ConfigData::GetSoilMaxOrganicDepth() );

    //As we loop over the layers, add up how much organic layer has been ignored
    double usedOrganicDepth( 0 );
    bool isSkpOrgSurLays = util::ConfigData::IsSkipOrganicSoilSurfaceLayers();
    //Order by depth to make sure layers are in the correct order
    soi::CHorizons const& horizons = component->GetHorizons();
    soi::CHorizonsByHzdept::const_iterator chItr =
        horizons.get< HZDEPT >().begin();
    for( ; chItr != horizons.get< HZDEPT >().end(); ++chItr )
    {
        soi::CHorizon const& horizon = **chItr;
        soi::ChTextureGrps const& chtgrps = horizon.GetTextureGrps();
        soi::ChTextureGrpPtr chtgrp = horizon.HasTextureGrps() ?
            *( chtgrps.get< CHTGKEY >().begin() ) : soi::ChTextureGrpPtr();
        if( isSkpOrgSurLays && !foundAMineralLayer &&
            usedOrganicDepth <= maxOrganicDepth )
        {
            std::string hzname = Convert< std::string >( horizon.GetHzname() );
            std::string desgnmaster =
                Convert< std::string >( horizon.GetDesgnmaster() );
            double om = Convert< double >( horizon.GetOm(), Double::NaN() );
            //Convert from percent to fraction
            om /= 100.0;
            std::string text = ( chtgrp != soi::ChTextureGrpPtr() ) ?
                Convert< std::string >( chtgrp->GetTexture() ) : "";
            bool organic = IsLayerOrganic( hzname, desgnmaster, text, om );
            if( organic )
            {
                //Data mart is in cm not mm
                double thicknessMiliMeter = Convert< double >(
                    horizon.GetHzthk(),
                    Convert< double >(
                        horizon.GetHzdepb(), Double::NaN() ) ) * 10.0;
                usedOrganicDepth += thicknessMiliMeter;
                if( usedOrganicDepth <= maxOrganicDepth )
                {
                    //Still allowed to ignore
                    continue;
                }
                else
                {
                    if( i == 0 )
                    {
                        return SOIERR_ORGLAYEXCIGNDEP;
                    }
                    else
                    {
                        return SOIERR_SOILAYBELIGNORGLAYISORG;
                    }
                }
            }
            else
            {
                //Not organic, so we're good to go
                foundAMineralLayer = true;
            }
        }

        CopyHorizon( horizon, layerNum );

        soi::ChFrags const& frags = horizon.GetFrags();
        CopyFrags( frags, layerNum );

        CopyTexture( chtgrp, layerNum );

        ++layerNum;
        ++i;
    }

    if( layerNum <= 0 )
    {
        return SOIERR_HORIZON;
    }

    java::SetField< jint >( m_jobject, GetJfid( "numlay" ), layerNum );

    if( util::ConfigData::IsAverageStratifiedSoilLayers() )
    {
        java::CallMethod< void >(
            m_jobject, GetJmid( "averageStratifiedLayers" ) );
    }

    java::CallMethod< void >( m_jobject, GetJmid( "fixUpData" ) );

    try
    {
        java::CallMethod< void >( m_jobject, GetJmid( "testData" ) );
    }
    catch( std::exception const& e )
    {
        //This exception will occur when estimating a value for lep,
        //but either clay or sand values are NaN
        static boost::regex const rgx(
            "java\\.lang\\.ArrayIndexOutOfBoundsException: \\d+\n"
            "\\s+usda\\.weru\\.soil\\.SoilUtil\\.estimateMineralBulkDensity\\(SoilUtil\\.java:\\d+\\)\n"
            "\\s+usda\\.weru\\.soil\\.SoilUtil\\.estimateSettledBulkDensity\\(SoilUtil\\.java:\\d+\\)\n"
            "\\s+usda\\.weru\\.soil\\.NASIS\\.testData\\(NASIS\\.java:\\d+\\)",
            boost::regex::perl );
        if( boost::regex_search( e.what(), rgx ) ) return SOIERR_NAN;

        throw;
    }

    return SOIERR_NONE;
}
////////////////////////////////////////////////////////////////////////////////
Nullable< Var > NASIS::CopyComponent(
    soi::ComponentPtr const& component )
{
    //compname
    Nullable< Var > const& compname = component->GetCompname();
    java::SetField< jobject >(
        m_jobject, GetJfid( "compname" ), String( compname ).Jobj() );

    //comppct
    Nullable< Var > const& comppct = component->GetComppct_r();
    java::SetField< jobject >(
        m_jobject, GetJfid( "comppct" ), String( comppct ).Jobj() );

    //taxorder
    Nullable< Var > const& taxorder = component->GetTaxorder();
    java::SetField< jobject >(
        m_jobject, GetJfid( "taxorder" ), String( taxorder ).Jobj() );

    //localphase
    std::string localphase =
        Convert< std::string >( component->GetLocalphase(), "" );
    java::SetField< jobject >(
        m_jobject, GetJfid( "localphase" ), String( localphase ).Jobj() );

    //tfact - losstolerance
    std::string temp = Convert< std::string >( component->GetTfact(), "0" );
    boost::trim( temp );
    if( temp.length() == 0 ) temp = "0";
    double tfact = boost::lexical_cast< int >( temp );
    java::SetField< jdouble >( m_jobject, GetJfid( "tfact" ), tfact );

    //slope
    double slope = Convert< double >( component->GetSlope(), Double::NaN() );
    java::SetField< jdouble >( m_jobject, GetJfid( "slope" ), slope );

    //albedodry
    double albedodry =
        Convert< double >( component->GetAlbedodry(), Double::NaN() );
    java::SetField< jdouble >( m_jobject, GetJfid( "albedodry" ), albedodry );

    return taxorder;
}
////////////////////////////////////////////////////////////////////////////////
void NASIS::CopyMapUnit(
    soi::MapUnit const& mapunit )
{
    //musym
    Var const& musym = mapunit.GetMusym();
    java::SetField< jobject >( m_jobject, GetJfid( "musym" ),
        String( musym ).Jobj() );
}
////////////////////////////////////////////////////////////////////////////////
void NASIS::CopyMuAggatt(
    soi::MapUnit const& mapunit )
{
    //brockdepmin
    double brockdepmin =
        Convert< double >( mapunit.GetBrockdepmin(), Double::NaN() );
    java::SetField< jdouble >(
        m_jobject, GetJfid( "brockdepmin" ), brockdepmin );
}
////////////////////////////////////////////////////////////////////////////////
void NASIS::CopyCoRestrictions(
    soi::ComponentPtr const& component )
{
    //resdeptmin
    double resdeptmin =
        Convert< double >( component->GetMinResDept(), Double::NaN() );
    java::SetField< jdouble >( m_jobject, GetJfid( "resdeptmin" ), resdeptmin );
}
////////////////////////////////////////////////////////////////////////////////
void NASIS::CopyLegend(
    soi::MapUnit const& mapunit )
{
    //areaname - ssaname
    Nullable< Var > const& ssaname = mapunit.GetAreanameLegend();
    java::SetField< jobject >(
        m_jobject, GetJfid( "areaname" ), String( ssaname ).Jobj() );

    //areasymbol - ssaid
    Nullable< Var > const& ssaid = mapunit.GetAreasymbolLegend();
    java::SetField< jobject >(
        m_jobject, GetJfid( "areasymbol" ), String( ssaid ).Jobj() );

    // --- Skip cordate, ssurgoarchived, tabularversion logging --- //

    Nullable< Var > state, county;
    std::vector< std::string > parts;
    std::string str = Convert< std::string >( ssaname );
    boost::split( parts, str, boost::is_any_of( "," ) );
    if( parts.size() == 0 )
    {
        county = "";
    }
    else if( parts.size() == 1 )
    {
        boost::trim( parts[ 0 ] );
        state = parts[ 0 ];
        county = "";
    }
    else
    {
        boost::trim( parts[ 0 ] );
        county = parts[ 0 ];
        boost::trim( parts[ 1 ] );
        state = parts[ 1 ];
    }

    //state
    java::SetField< jobject >(
        m_jobject, GetJfid( "state" ), String( state ).Jobj() );

    //county
    java::SetField< jobject >(
        m_jobject, GetJfid( "county" ), String( county ).Jobj() );
}
////////////////////////////////////////////////////////////////////////////////
void NASIS::CopyHorizon(
    soi::CHorizon const& horizon,
    unsigned int const& idx )
{
    //hzdept
    double hzdept = Convert< double >( horizon.GetHzdept(), Double::NaN() );
    Array< double > hzdept_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "hzdept" ) ) );
    hzdept_arr.SetElement( idx, hzdept );

    //hzdepb
    double hzdepb = Convert< double >( horizon.GetHzdepb(), Double::NaN() );
    Array< double > hzdepb_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "hzdepb" ) ) );
    hzdepb_arr.SetElement( idx, hzdepb );

    //claytotal
    double claytotal =
        Convert< double >( horizon.GetClaytotal(), Double::NaN() );
    Array< double > claytotal_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "claytotal" ) ) );
    claytotal_arr.SetElement( idx, claytotal );

    //sandtotal
    double sandtotal =
        Convert< double >( horizon.GetSandtotal(), Double::NaN() );
    Array< double > sandtotal_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "sandtotal" ) ) );
    sandtotal_arr.SetElement( idx, sandtotal );

    //silttotal
    double silttotal =
        Convert< double >( horizon.GetSilttotal(), Double::NaN() );
    Array< double > silttotal_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "silttotal" ) ) );
    silttotal_arr.SetElement( idx, silttotal );

    //sandvc
    double sandvc = Convert< double >( horizon.GetSandvc(), 0 );
    Array< double > sandvc_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "sandvc" ) ) );
    sandvc_arr.SetElement( idx, sandvc );

    //sandco
    double sandco = Convert< double >( horizon.GetSandco(), 0 );
    Array< double > sandco_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "sandco" ) ) );
    sandco_arr.SetElement( idx, sandco );

    //sandmed
    double sandmed = Convert< double >( horizon.GetSandmed(), 0 );
    Array< double > sandmed_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "sandmed" ) ) );
    sandmed_arr.SetElement( idx, sandmed );

    //sandfine
    double sandfine = Convert< double >( horizon.GetSandfine(), 0 );
    Array< double > sandfine_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "sandfine" ) ) );
    sandfine_arr.SetElement( idx, sandfine );

    //sandvf
    double sandvf = Convert< double >( horizon.GetSandvf(), Double::NaN() );
    Array< double > sandvf_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "sandvf" ) ) );
    sandvf_arr.SetElement( idx, sandvf );

    //dbthirdbar
    double dbthirdbar =
        Convert< double >( horizon.GetDbthirdbar(), Double::NaN() );
    Array< double > dbthirdbar_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "dbthirdbar" ) ) );
    dbthirdbar_arr.SetElement( idx, dbthirdbar );

    //dbovendry
    //double dbovendry =
        //Convert< double >( horizon.Dbovendry(), Double::NaN() );
    //Array< double > dbovendry_arr(
        //java::GetField< jobject >( m_jobject, GetJfid( "dbovendry" ) ) );
    //dbovendry_arr.SetElement( idx, dbovendry );

    //wtenthbar
    //double wtenthbar =
        //Convert< double >( horizon.GetWtenthbar(), Double::NaN() );
    double wtenthbar = -9.9;
    Array< double > wtenthbar_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "wtenthbar" ) ) );
    wtenthbar_arr.SetElement( idx, wtenthbar );

    //wthirdbar
    double wthirdbar =
        Convert< double >( horizon.GetWthirdbar(), Double::NaN() );
    Array< double > wthirdbar_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "wthirdbar" ) ) );
    wthirdbar_arr.SetElement( idx, wthirdbar );

    //wfifteenbar
    double wfifteenbar =
        Convert< double >( horizon.GetWfifteenbar(), Double::NaN() );
    Array< double > wfifteenbar_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "wfifteenbar" ) ) );
    wfifteenbar_arr.SetElement( idx, wfifteenbar );

    //ksat
    double ksat = Convert< double >( horizon.GetKsat(), Double::NaN() );
    Array< double > ksat_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "ksat" ) ) );
    ksat_arr.SetElement( idx, ksat );

    //cec7
    double cec7 = Convert< double >( horizon.GetCec7(), Double::NaN() );
    Array< double > cec7_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "cec7" ) ) );
    cec7_arr.SetElement( idx, cec7 );

    //ecec
    double ecec = Convert< double >( horizon.GetEcec(), Double::NaN() );
    Array< double > ecec_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "ecec" ) ) );
    ecec_arr.SetElement( idx, ecec );

    //I think my error checking will work - it compiles :-)
    //However, my test case error is not because both fields are null,
    //but that one is null for one layer and the other is null for another
    //and the NASIS(SSURGO) to IFC code can't handle that correctly (yet) - LEW
    //if( ( cec7[ idx ] < 0.0 ) && ( ecec[ idx ] < 0.0 ) )
        //System.err.println(
            //"NASIS_copyHorizon: cec7 or ecec fields not populated " );
    //if( ( cec7[ idx ] < 0.0 ) && ( ecec[ idx ] < 0.0 ) )
        //throw new FieldNotPopulated( "cec7 and ecec" );

    //om
    double om = Convert< double >( horizon.GetOm(), Double::NaN() );
    Array< double > om_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "om" ) ) );
    om_arr.SetElement( idx, om );

    //caco3
    double caco3 = Convert< double >( horizon.GetCaco3(), Double::NaN() );
    Array< double > caco3_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "caco3" ) ) );
    caco3_arr.SetElement( idx, caco3 );

    //ph1to1h2o
    double ph1to1h2o =
        Convert< double >( horizon.GetPh1to1h2o(), Double::NaN() );
    Array< double > ph1to1h2o_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "ph1to1h2o" ) ) );
    ph1to1h2o_arr.SetElement( idx, ph1to1h2o );

    //ph01mcacl2
    double ph01mcacl2 =
        Convert< double >( horizon.GetPh01mcacl2(), Double::NaN() );
    Array< double > ph01mcacl2_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "ph01mcacl2" ) ) );
    ph01mcacl2_arr.SetElement( idx, ph01mcacl2 );

    //lep
    double lep = Convert< double >( horizon.GetLep(), Double::NaN() );
    Array< double > lep_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "lep" ) ) );
    lep_arr.SetElement( idx, lep );
}
////////////////////////////////////////////////////////////////////////////////
void NASIS::CopyFrags(
    soi::ChFrags const& frags,
    unsigned int const& idx )
{
    double fragvol( 0.0 );

    soi::ChFragsByChfragskey::const_iterator chfItr =
        frags.get< CHFRAGSKEY >().begin();
    for( ; chfItr != frags.get< CHFRAGSKEY >().end(); ++chfItr )
    {
        soi::ChFrag const& frag = **chfItr;
        double tempFragVol =
            Convert< double >( frag.GetFragvol(), Double::NaN() );
        if( tempFragVol != Double::NaN() ) fragvol += tempFragVol;
    }

    //fragvol
    Array< double > fragvol_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "fragvol" ) ) );
    fragvol_arr.SetElement( idx, fragvol );
}
////////////////////////////////////////////////////////////////////////////////
void NASIS::CopyTexture(
    soi::ChTextureGrpPtr const& chtgrp,
    unsigned int const& idx )
{
    bool exists = ( chtgrp != soi::ChTextureGrpPtr() );

    //texture
    std::string temp = exists ?
        Convert< std::string >( chtgrp->GetTexture() ) : "";
    boost::algorithm::replace_all( temp, "-", "_" );
    Array< String > texture_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "texture" ) ) );
    texture_arr.SetElement( idx, temp );

    bool bVal( false );

    std::string stratifiedString = exists ?
        Convert< std::string >( chtgrp->GetStratextsflag() ) : "";
    boost::trim( stratifiedString );
    boost::algorithm::to_lower( stratifiedString );
    if( stratifiedString == "yes" )
    {
        bVal = true;
    }
    else
    {
        bVal = false;
    }

    //stratextsflag
    Array< bool > stratextsflag_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "stratextsflag" ) ) );
    stratextsflag_arr.SetElement( idx, bVal );

    std::string rvString = exists ?
        Convert< std::string >( chtgrp->GetRvindicator() ) : "";
    boost::trim( rvString );
    boost::algorithm::to_lower( rvString );
    if( rvString == "yes" )
    {
        bVal = true;
    }
    else
    {
        bVal = false;
    }

    //rvindicator
    Array< bool > rvindicator_arr(
        java::GetField< jobject >( m_jobject, GetJfid( "rvindicator" ) ) );
    rvindicator_arr.SetElement( idx, bVal );
}
////////////////////////////////////////////////////////////////////////////////
jclass const& NASIS::GetJclass()
{
    static jclass const clazz = java::FindClass( "usda/weru/soil/NASIS" );
    return clazz;
}
////////////////////////////////////////////////////////////////////////////////
jmethodID const& NASIS::GetJmid(
    std::string const& name )
{
    static java::JMIDMAP const jmidMap = boost::assign::map_list_of
        ( "<init>",
          java::GetMethodID(
              GetJclass(), "<init>",
              "(I)V" ) )
        ( "averageStratifiedLayers",
          java::GetMethodID(
              GetJclass(), "averageStratifiedLayers",
              "()V" ) )
        ( "fixUpData",
          java::GetMethodID(
              GetJclass(), "fixUpData",
              "()V" ) )
        ( "testData",
          java::GetMethodID(
              GetJclass(), "testData",
              "()V" ) );

    java::JMIDMAP::const_iterator itr = jmidMap.find( name );
    return itr->second;
}
////////////////////////////////////////////////////////////////////////////////
jfieldID const& NASIS::GetJfid(
    std::string const& name )
{
    static java::JFIDMAP const jfidMap = boost::assign::map_list_of
        //spatial
        ( "state",
          java::GetFieldID(
              GetJclass(), "state",
              "Ljava/lang/String;" ) )
        ( "county",
          java::GetFieldID(
              GetJclass(), "county",
              "Ljava/lang/String;" ) )
        //legend
        ( "areaname",
          java::GetFieldID(
              GetJclass(), "ssaname",
              "Ljava/lang/String;" ) )
        ( "areasymbol",
          java::GetFieldID(
              GetJclass(), "ssaid",
              "Ljava/lang/String;" ) )
        //mapunit
        ( "musym",
          java::GetFieldID(
              GetJclass(), "musym",
              "Ljava/lang/String;" ) )
        //muaggatt
        ( "brockdepmin",
          java::GetFieldID(
              GetJclass(), "bedrockDepth",
              "D" ) )
        //component
        ( "compname",
          java::GetFieldID(
              GetJclass(), "compname",
              "Ljava/lang/String;" ) )
        ( "comppct",
          java::GetFieldID(
              GetJclass(), "comppct",
              "Ljava/lang/String;" ) )
        ( "taxorder",
          java::GetFieldID(
              GetJclass(), "taxorder",
              "Ljava/lang/String;" ) )
        ( "localphase",
          java::GetFieldID(
              GetJclass(), "localphase",
              "Ljava/lang/String;" ) )
        ( "tfact",
          java::GetFieldID(
              GetJclass(), "losstolerance",
              "D" ) )
        ( "slope",
          java::GetFieldID(
              GetJclass(), "slope",
              "D" ) )
        ( "albedodry",
          java::GetFieldID(
              GetJclass(), "albedodry",
              "D" ) )
        //corestrictions
        ( "resdeptmin",
          java::GetFieldID(
              GetJclass(), "impermiableDepth",
              "D" ) )
        //horizon
        ( "hzdept",
          java::GetFieldID(
              GetJclass(), "hzdept",
              "[D" ) )
        ( "hzdepb",
          java::GetFieldID(
              GetJclass(), "hzdepb",
              "[D" ) )
        //( "hzthk",
          //java::GetFieldID(
              //GetJclass(), "hzthk",
              //"[D" ) )
        ( "claytotal",
          java::GetFieldID(
              GetJclass(), "claytotal",
              "[D" ) )
        ( "sandtotal",
          java::GetFieldID(
              GetJclass(), "sandtotal",
              "[D" ) )
        ( "silttotal",
          java::GetFieldID(
              GetJclass(), "silttotal",
              "[D" ) )
        ( "sandvc",
          java::GetFieldID(
              GetJclass(), "sandvco",
              "[D" ) )
        ( "sandco",
          java::GetFieldID(
              GetJclass(), "sandco",
              "[D" ) )
        ( "sandmed",
          java::GetFieldID(
              GetJclass(), "sandmed",
              "[D" ) )
        ( "sandfine",
          java::GetFieldID(
              GetJclass(), "sandfine",
              "[D" ) )
        ( "sandvf",
          java::GetFieldID(
              GetJclass(), "sandvf",
              "[D" ) )
        ( "dbthirdbar",
          java::GetFieldID(
              GetJclass(), "dbthirdbar",
              "[D" ) )
        ( "wtenthbar",
          java::GetFieldID(
              GetJclass(), "wtenthbar",
              "[D" ) )
        ( "wthirdbar",
          java::GetFieldID(
              GetJclass(), "wthirdbar",
              "[D" ) )
        ( "wfifteenbar",
          java::GetFieldID(
              GetJclass(), "w15thbar",
              "[D" ) )
        ( "ksat",
          java::GetFieldID(
              GetJclass(), "ksat",
              "[D" ) )
        ( "cec7",
          java::GetFieldID(
              GetJclass(), "cec7",
              "[D" ) )
        ( "ecec",
          java::GetFieldID(
              GetJclass(), "ecec",
              "[D" ) )
        ( "om",
          java::GetFieldID(
              GetJclass(), "om",
              "[D" ) )
        ( "caco3",
          java::GetFieldID(
              GetJclass(), "caco3",
              "[D" ) )
        ( "ph1to1h2o",
          java::GetFieldID(
              GetJclass(), "ph1to1h2o",
              "[D" ) )
        ( "ph01mcacl2",
          java::GetFieldID(
              GetJclass(), "ph01mcacl2",
              "[D" ) )
        ( "lep",
          java::GetFieldID(
              GetJclass(), "lep",
              "[D" ) )
        //chfrags
        ( "fragvol",
          java::GetFieldID(
              GetJclass(), "fragvol",
              "[D" ) )
        //chtexturegrp
        ( "texture",
          java::GetFieldID(
              GetJclass(), "texture",
              "[Ljava/lang/String;" ) )
        ( "stratextsflag",
          java::GetFieldID(
              GetJclass(), "stratified",
              "[Z" ) )
        ( "rvindicator",
          java::GetFieldID(
              GetJclass(), "rv",
              "[Z" ) )
        //misc
        ( "numlay",
          java::GetFieldID(
              GetJclass(), "numlay",
              "I" ) );

    java::JFIDMAP::const_iterator itr = jfidMap.find( name );
    return itr->second;
}
////////////////////////////////////////////////////////////////////////////////
bool NASIS::IsLayerOrganic(
    std::string const& hzname,
    std::string const& desgnmaster,
    std::string const& texture,
    double const& organicMatter )
{
    //Horizon name
    if( boost::algorithm::starts_with( hzname, "O" ) )
    {
        return true;
    }

    if( boost::algorithm::starts_with( desgnmaster, "O" ) )
    {
        return true;
    }

    if( ORGANIC_TEXTURES.find( boost::algorithm::to_lower_copy( texture ) ) !=
        ORGANIC_TEXTURES.end() )
    {
        return true;
    }

    if( organicMatter > util::ConfigData::GetOmFractionThreshold() )
    {
        return true;
    }

    //Aka, a mineral layer
    return false;
}
////////////////////////////////////////////////////////////////////////////////

} //end soil
} //end weru
} //end wrapper
} //end leaf

ext: cxx

max_stars_repo_name: IdahoLabCuttingBoard/LEAF

max_issues_repo_name: IdahoLabCuttingBoard/LEAF

max_forks_repo_name: IdahoLabCuttingBoard/LEAF


text:
#include "OsqpEigen/OsqpEigen.h"
#include <Eigen/Dense>
#include <iostream>

int main()
{

    OsqpEigen::Solver solver;

    solver.settings()->setVerbosity(true);
    solver.settings()->setWarmStart(true);

    solver.data()->setNumberOfVariables(7);
    solver.data()->setNumberOfConstraints(7);

    std::cout << std::endl;
}


text:
//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/vinniefalco/json
//

#ifndef BOOST_JSON_SERIALIZER_HPP
#define BOOST_JSON_SERIALIZER_HPP

#include <boost/json/config.hpp>
#include <boost/json/value.hpp>
#include <boost/json/detail/format.hpp>
#include <boost/json/detail/static_stack.hpp>
#include <iosfwd>

namespace boost {
namespace json {

/** A serializer for JSON.

    This class traverses a @ref value and emits
    a serialized JSON object. It can work
    incrementally, by filling successive
    caller-provided buffers.
*/
class serializer
{
    enum class state : char;

#ifndef GENERATING_DOCUMENTATION
    // The xsl has problems with anonymous unions
    struct nobj
    {
        object const* po;
        object::const_iterator it;
    };

    struct narr
    {
        array const* pa;
        array::const_iterator it;
    };

    struct node
    {
        union
        {
            value const* pjv;
            nobj obj;
            narr arr;
        };
        state st;

        inline
        explicit
        node(state st_) noexcept;

        inline
        explicit
        node(value const& jv) noexcept;

        inline
        explicit
        node(object const& o) noexcept;

        inline
        explicit
        node(array const& a) noexcept;
    };
#endif

    detail::static_stack<node, 16> stack_;

    string_view str_;
    unsigned char nbuf_;
    char buf_[detail::max_number_chars + 1];

public:
    /** Default constructor.

        This constructs a serializer without
        a current @ref value to serialize. Before
        any serialization can take place, @ref reset
        must be called.

        @par Exception Safety

        No-throw guarantee.
    */
    BOOST_JSON_DECL
    serializer() noexcept;

    /** Constructor.

        This constructs the serializer and
        calls @ref reset with `jv`.

        @par Exception Safety

        No-throw guarantee.

        @param jv The value to serialize.
    */
    explicit
    serializer(value const& jv) noexcept
    {
        reset(jv);
    }

    /** Returns `true` if the serialization is complete.

        This function returns `true` when all of the
        characters in the serialized representation of
        the value have been read.
    */
    BOOST_JSON_DECL
    bool
    is_done() const noexcept;

    /** Reset the serializer for a new JSON value.

        This function prepares the serializer to emit
        a new serialized JSON based on the specified
        value. Any internally allocated memory is
        preserved and re-used for the new output.

        @param jv The value to serialize.
    */
    BOOST_JSON_DECL
    void
    reset(value const& jv) noexcept;

    /** Read the next buffer of serialized JSON.

        This function attempts to fill the caller
        provided buffer starting at `dest` with
        up to `size` characters of the serialized
        JSON that represents the value. If the
        buffer is not large enough, multiple calls
        may be required.

        @par Example

        This demonstrates how the serializer may
        be used to print a JSON value to an output
        stream.

        @code

        void print( std::ostream& os, value const& jv)
        {
            serializer sr( jv );
            while( ! sr.done() )
            {
                char buf[1024];
                auto const n = sr.read( buf, sizeof(buf) );
                os << string_view( buf, n );
            }
        }

        @endcode

        @par Exception Safety

        Strong guarantee.
        Calls to @ref storage::allocate may throw.

        @throw std::logic_error if no value is set.

        @return The number of characters written
        to `dest`.
    */
    BOOST_JSON_DECL
    std::size_t
    read(char* dest, std::size_t size);
};

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

/** Return a string representing a serialized @ref value.

    This function serializes the specified value
    and returns it as a @ref string.

    @par Exception Safety

    Strong guarantee.
    Calls to @ref storage::allocate may throw.

    @param jv The value to serialize.
*/
BOOST_JSON_DECL
string
to_string(
    value const& jv);

/** Serialize a @ref value to an output stream.

    This function serializes the specified value
    into the output stream.

    @par Exception Safety

    Strong guarantee.
    Calls to @ref storage::allocate may throw.

    @param os The output stream to serialize to.

    @param jv The value to serialize.

    @return `os`.
*/
BOOST_JSON_DECL
std::ostream&
operator<<(
    std::ostream& os,
    value const& jv);

} // json
} // boost

#ifdef BOOST_JSON_HEADER_ONLY
#include <boost/json/impl/serializer.ipp>
#endif

#endif

max_stars_repo_name: ayounes-synaptics/json

max_issues_repo_name: ayounes-synaptics/json

max_forks_repo_name: ayounes-synaptics/json


text:
// Copyright (C) 2020 T. Zachary Laine
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/text/unencoded_rope.hpp>

#include <atomic>
#include <thread>

std::atomic<bool> done(false);

void thread_function(boost::text::unencoded_rope r)
{
    boost::text::unencoded_rope local_r = r;

    while (!done)
        ;
}

int main()
{
    boost::text::unencoded_rope r("some text");

    std::thread thread_0(thread_function, r);
    std::thread thread_1(thread_function, r);
    std::thread thread_2(thread_function, r);
    std::thread thread_3(thread_function, r);

    std::thread thread_4(thread_function, r);
    std::thread thread_5(thread_function, r);
    std::thread thread_6(thread_function, r);
    std::thread thread_7(thread_function, r);

    done = true;

    thread_0.join();
    thread_1.join();
    thread_2.join();
    thread_3.join();

    thread_4.join();
    thread_5.join();
    thread_6.join();
    thread_7.join();
}

max_stars_repo_name: Ryan-rsm-McKenzie/text

max_issues_repo_name: Ryan-rsm-McKenzie/text

max_forks_repo_name: Ryan-rsm-McKenzie/text


text:
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/cstdint.hpp>

using boost::unit_test::test_suite;

#include <protean/variant.hpp>
using namespace protean;

BOOST_AUTO_TEST_SUITE( types );

BOOST_AUTO_TEST_CASE( pod_types )
{
    {
        variant v( bool(true) );
        BOOST_CHECK(v.is<variant::Boolean>());
        BOOST_CHECK(v.is<bool>());
        BOOST_CHECK_EQUAL(v.as<bool>(), true);
    }

    {
        variant v( long(0) );
        BOOST_CHECK(v.is<sizeof(long)==4?variant::Int32:variant::Int64>());
        BOOST_CHECK(v.is<long>());
        BOOST_CHECK_EQUAL(v.as<long>(), 0);
    }

    {
        variant v( 0ul );
        BOOST_CHECK(v.is<sizeof(long)==4?variant::UInt32:variant::UInt64>());
        BOOST_CHECK(v.is<unsigned long>());
        BOOST_CHECK_EQUAL(v.as<unsigned long>(), 0u);
    }

    {
        variant v( int(0) );
        BOOST_CHECK(v.is<variant::Int32>());
        BOOST_CHECK(v.is<int>());
        BOOST_CHECK_EQUAL(v.as<int>(), 0);
    }

    {
        variant v( 0u );
        BOOST_CHECK(v.is<variant::UInt32>());
        BOOST_CHECK(v.is<unsigned int>());
        BOOST_CHECK_EQUAL(v.as<unsigned int>(), 0u);
    }

    {
        variant v( 0ll );
        BOOST_CHECK(v.is<variant::Int64>());
        BOOST_CHECK(v.is<long long>());
        BOOST_CHECK_EQUAL(v.as<long long>(), 0);
    }

    {
        variant v( 0ull );
        BOOST_CHECK(v.is<variant::UInt64>());
        BOOST_CHECK(v.is<unsigned long long>());
        BOOST_CHECK_EQUAL(v.as<unsigned long long>(), 0u);
    }

    {
        variant v( float(0) );
        BOOST_CHECK(v.is<variant::Float>());
        BOOST_CHECK(v.is<float>());
        BOOST_CHECK_EQUAL(v.as<float>(), 0);
    }

    {
        variant v( double(0) );
        BOOST_CHECK(v.is<variant::Double>());
        BOOST_CHECK(v.is<double>());
        BOOST_CHECK_EQUAL(v.as<double>(), 0);
    }
#   ifdef _MSC_VER
    {
        variant v( static_cast<long double>(0) );
        BOOST_CHECK(v.is<variant::Double>());
        BOOST_CHECK(v.is<long double>());
        BOOST_CHECK_EQUAL(v.as<long double>(), 0);
    }
#   endif
}

BOOST_AUTO_TEST_CASE( stl_types )
{
    {
        variant v( size_t(0) );
        BOOST_CHECK(v.is<sizeof(size_t)==4?variant::UInt32:variant::UInt64>());
        BOOST_CHECK(v.is<size_t>());
        BOOST_CHECK_EQUAL(v.as<size_t>(), 0u);
    }
}

BOOST_AUTO_TEST_CASE( boost_types )
{
    {
        variant v( boost::int32_t(0) );
        BOOST_CHECK(v.is<variant::Int32>());
        BOOST_CHECK(v.is<boost::int32_t>());
        BOOST_CHECK_EQUAL(v.as<boost::int32_t>(), 0);
    }

    {
        variant v( boost::uint32_t(0) );
        BOOST_CHECK(v.is<variant::UInt32>());
        BOOST_CHECK(v.is<boost::uint32_t>());
        BOOST_CHECK_EQUAL(v.as<boost::uint32_t>(), 0u);
    }

    {
        variant v( boost::int64_t(0) );
        BOOST_CHECK(v.is<variant::Int64>());
        BOOST_CHECK(v.is<boost::int64_t>());
        BOOST_CHECK_EQUAL(v.as<boost::int64_t>(), 0);
    }

    {
        variant v( boost::uint64_t(0) );
        BOOST_CHECK(v.is<variant::UInt64>());
        BOOST_CHECK(v.is<boost::uint64_t>());
        BOOST_CHECK_EQUAL(v.as<boost::uint64_t>(), 0u);
    }

}

BOOST_AUTO_TEST_CASE( ms_specific_types )
{
#   ifdef _MSC_VER
    {
        variant v( __int32(0) );
        BOOST_CHECK(v.is<variant::Int32>());
        BOOST_CHECK(v.is<__int32>());
        BOOST_CHECK_EQUAL(v.as<__int32>(), 0);
    }

    {
        variant v( unsigned __int32(0) );
        BOOST_CHECK(v.is<variant::UInt32>());
        BOOST_CHECK(v.is<unsigned __int32>());
        BOOST_CHECK_EQUAL(v.as<unsigned __int32>(), 0u);
    }

    {
        variant v( __int64(0) );
        BOOST_CHECK(v.is<variant::Int64>());
        BOOST_CHECK(v.is<__int64>());
        BOOST_CHECK_EQUAL(v.as<__int64>(), 0);
    }

    {
        variant v( unsigned __int64(0) );
        BOOST_CHECK(v.is<variant::UInt64>());
        BOOST_CHECK(v.is<unsigned __int64>());
        BOOST_CHECK_EQUAL(v.as<unsigned __int64>(), 0u);
    }

	{
        variant i(3);
        variant j(4);
		i<j;
		BOOST_CHECK(i<j);
	}

#   endif
}

BOOST_AUTO_TEST_CASE(lexical_cast)
{
    BOOST_CHECK_EQUAL(variant(variant::Boolean, "true").as<bool>(),             true);
    BOOST_CHECK_EQUAL(variant(variant::Boolean, "false").as<bool>(),            false);
    BOOST_CHECK_EQUAL(variant(variant::Boolean, "1").as<bool>(),                true);
    BOOST_CHECK_EQUAL(variant(variant::Boolean, "0").as<bool>(),                false);
    BOOST_CHECK_EQUAL(variant(variant::Int32,   "10").as<boost::int32_t>(),     10);
    BOOST_CHECK_EQUAL(variant(variant::UInt32,  "10").as<boost::uint32_t>(),    10u);
    BOOST_CHECK_EQUAL(variant(variant::Int64,   "10").as<boost::int64_t>(),     10);
    BOOST_CHECK_EQUAL(variant(variant::UInt64,  "10").as<boost::uint64_t>(),    10u);
    BOOST_CHECK_EQUAL(variant(variant::Float,   "10").as<float>(),              10.);
    BOOST_CHECK_EQUAL(variant(variant::Double,  "10").as<double>(),             10.);
	BOOST_CHECK_EQUAL(variant(variant::DateTime, "2014-03-21T15:50:31").as<variant::date_time_t>(), variant::date_time_t(variant::date_t(2014, 3, 21), variant::time_t(15, 50, 31)));

    BOOST_CHECK_THROW(variant(variant::Boolean, "###"),   variant_error);
    BOOST_CHECK_THROW(variant(variant::Boolean, "###"),   variant_error);
    BOOST_CHECK_THROW(variant(variant::Boolean, "###"),   variant_error);
    BOOST_CHECK_THROW(variant(variant::Boolean, "###"),   variant_error);
    BOOST_CHECK_THROW(variant(variant::Int32,   "###"),   variant_error);
    BOOST_CHECK_THROW(variant(variant::UInt32,  "###"),   variant_error);
    BOOST_CHECK_THROW(variant(variant::Int64,   "###"),   variant_error);
    BOOST_CHECK_THROW(variant(variant::UInt64,  "###"),   variant_error);
    BOOST_CHECK_THROW(variant(variant::Float,   "###"),   variant_error);
    BOOST_CHECK_THROW(variant(variant::Double,  "###"),   variant_error);
	BOOST_CHECK_THROW(variant(variant::DateTime, "###"),  variant_error);
}

BOOST_AUTO_TEST_CASE(numerical_cast)
{
    BOOST_CHECK_EQUAL(variant(boost::int32_t(1)).numerical_cast<double>(), 1.);
    BOOST_CHECK_EQUAL(variant(boost::int32_t(1)).numerical_cast<bool>(), true);
    BOOST_CHECK_EQUAL(variant(boost::int32_t(0)).numerical_cast<double>(), 0.);
    BOOST_CHECK_EQUAL(variant(boost::int32_t(0)).numerical_cast<bool>(), false);
    BOOST_CHECK_EQUAL(variant(1.).numerical_cast<boost::int32_t>(), 1);
    BOOST_CHECK_EQUAL(variant(1.).numerical_cast<bool>(), true);
    BOOST_CHECK_EQUAL(variant(0.).numerical_cast<boost::int32_t>(), 0);
    BOOST_CHECK_EQUAL(variant(0.).numerical_cast<bool>(), false);

    BOOST_CHECK_THROW(variant("1.").numerical_cast<double>(), variant_error);
}

BOOST_AUTO_TEST_SUITE_END()

max_stars_repo_name: proteanic/protean

max_issues_repo_name: roederja/protean

max_forks_repo_name: roederja/protean


text:
/**
 * \file dcs/iterator/any_forward_iterator.hpp
 *
 * \brief Generic (type-erased) forward iterator.
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 *
 * <hr/>
 *
 * Copyright 2009 Marco Guazzone (marco.guazzone@gmail.com)
 *
 * 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
 *
 *     http://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.
 */

#ifndef DCS_ITERATOR_ANY_FORWARD_ITERATOR_HPP
#define DCS_ITERATOR_ANY_FORWARD_ITERATOR_HPP

#include <dcs/detail/config/boost.hpp>

#if !DCS_DETAIL_CONFIG_BOOST_CHECK_VERSION(103100) // 1.31
#	error "Required Boost libraries version >= 1.31"
#endif // DCS_DETAIL_CONFIG_BOOST_CHECK_VERSION

#include <boost/utility/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
#include <boost/static_assert.hpp>
#include <cstddef>
#include <dcs/iterator/any_iterator.hpp>
#include <dcs/type_traits/remove_const.hpp>
#include <iterator>

namespace dcs { namespace iterator {

/**
 * \brief Generic (type-erased) forward iterator.
 *
 * \author Marco Guazzone (marco.guazzone@gmail.com)
 */
template<typename ValueT, typename ReferenceT, typename DifferenceT>
class any_forward_iterator;

namespace detail {

template<class SomeIterator>
struct is_any_forward_iterator : public ::boost::mpl::bool_<false>
{
	// empty
};

template<
	typename ValueT,
	typename ReferenceT,
	typename DifferenceT
>
struct is_any_forward_iterator< any_forward_iterator<ValueT,ReferenceT,DifferenceT> >: public ::boost::mpl::bool_<true>
{
	// empty
};

} // Namespace detail

template<
	typename ValueT,
	typename ReferenceT = ValueT&,
	typename DifferenceT = std::ptrdiff_t
>
class any_forward_iterator: public any_iterator<ValueT, ::std::forward_iterator_tag, ReferenceT, DifferenceT>
{

	// We make every other any_iterator our friend. This is needed only for
	// the conversion from non-const to const, but there should be no harm
	// in being overly friendly here.
	template<
		typename OtherValueT,
		typename OtherReferenceT,
		typename OtherDifferenceT
	>
	friend class any_forward_iterator;

	private: typedef any_iterator<ValueT,::std::forward_iterator_tag,ReferenceT,DifferenceT> base_type;
	public: typedef typename base_type::traversal_type traversal_type;

	private: struct enabler{};  // a private type avoids misuse
	private: struct disabler{};  // a private type avoids misuse

	public: any_forward_iterator()
		: base_type()
	{
		// empty
	}

	public: any_forward_iterator(any_forward_iterator const& rhs)
		: base_type(*static_cast<base_type const*>(&rhs))
	{
		// empty
	}

	public: any_forward_iterator& operator=(any_forward_iterator const& rhs)
	{
		if (this != &rhs)
		{
			base_type::operator=(*static_cast<base_type const*>(&rhs));
		}

		return *this;
	}

	public: template<class WrappedIteratorT>
		explicit any_forward_iterator(WrappedIteratorT const& wrapped_iterator, typename boost::disable_if<detail::is_any_forward_iterator<WrappedIteratorT>, disabler>::type = disabler())
		: base_type(wrapped_iterator)
	{
		// empty
	}

	public: template<class WrappedIteratorT>
		typename boost::enable_if<
			boost::mpl::and_<
				detail::is_iterator_type_erasure_compatible<
					WrappedIteratorT,
					any_forward_iterator
				>,
				boost::mpl::not_< detail::is_any_forward_iterator<WrappedIteratorT> >
			>,
			any_forward_iterator
		>::type&
		operator=(WrappedIteratorT const& wrapped_iterator)
		{
			//any_forward_iterator tmp(wrapped_iterator);
			//swap(tmp);
			//return *this;

			//base_type base;
			base_type::operator=(wrapped_iterator);
			return *this;
		}
};

// Metafunction that takes an iterator and returns an any_iterator with the same
// traits.
template<class IteratorT>
struct make_any_forward_iterator_type
{
	typedef any_forward_iterator<
		//typename ::boost::iterator_value<IteratorT>::type,
		typename ::std::iterator_traits<IteratorT>::value_type,
		////typename ::boost::iterator_category<IteratorT>::type,
		//typename ::boost::iterator_reference<IteratorT>::type,
		typename ::std::iterator_traits<IteratorT>::reference,
		//typename ::boost::iterator_difference<IteratorT>::type
		typename ::std::iterator_traits<IteratorT>::difference_type
	> type;
};

/*
  namespace detail {
  template <typename IteratorT>
  struct iterator_traits
  {
      typedef typename boost::iterator_value<IteratorT>::type value_type;
      typedef typename boost::iterator_category<IteratorT>::type category_type;
      typedef typename boost::iterator_reference<IteratorT>::type reference;
      typedef typename boost::iterator_difference<IteratorT>::type difference_type;
      typedef typename boost::iterator_pointer<IteratorT>::type pointer;
  };
  }
  template<class IteratorT, class IteratorTraitsT=detail::iterator_traits<IteratorT> >
  struct make_any_iterator_type
  {
    typedef
    any_iterator<
      typename IteratorTraitsT::value_type,
      typename IteratorTraitsT::iterator_category,
      typename IteratorTraitsT::reference,
      typename IteratorTraitsT::difference_type
    > type;
  };
//@}[sguazt]
*/

// Function that takes an iterator and returns an any_iterator with the same
// traits.
template<class IteratorT>
typename make_any_forward_iterator_type<IteratorT>::type make_any_forward_iterator(IteratorT it)
{
	typedef typename make_any_forward_iterator_type<IteratorT>::type any_iterator_type;
	return any_iterator_type(it);
}

/*
//@{[sguazt]
  template<class IteratorT, class IteratorTraitsT>
  typename make_any_iterator_type<IteratorT,IteratorTraitsT>::type make_any_iterator(IteratorT it)
  {
	typedef typename make_any_iterator_type<IteratorT,IteratorTraitsT>::type any_iterator_type;
	return any_iterator_type(it);
  }
//@}[sguazt]
*/

}} // Namespace dcs::iterator

#endif // DCS_ITERATOR_ANY_FORWARD_ITERATOR_HPP

max_stars_repo_name: sguazt/dcsxx-commons

max_issues_repo_name: sguazt/dcsxx-commons

max_forks_repo_name: sguazt/dcsxx-commons


text:
#include "io/FileWriter.hpp"

#if HAVE_PARALLEL_DOMAIN_AMDIS
#include <mpi.h>
#endif

#include <boost/filesystem.hpp>

#include "Initfile.hpp"
#include "io/ValueWriter.hpp"
#include "io/MacroWriter.hpp"
#include "io/VtkWriter.hpp"
#include "io/VtkVectorWriter.hpp"
#include "io/PngWriter.hpp"
#include "io/PovrayWriter.hpp"
#include "io/DofWriter.hpp"
#include "io/Arh3Writer.hpp"
#include "FiniteElemSpace.hpp"
#include "AdaptInfo.hpp"
#include "Flag.hpp"
#include "ElInfo.hpp"
#include "Mesh.hpp"
#include "io/DataCollector.hpp"

using namespace std;

namespace AMDiS
{
  namespace detail
  {
    template<>
    FileWriter<double>::FileWriter(std::string name_,
                                   Mesh* mesh_,
                                   SystemVector* vecs)
      : name(name_),
        mesh(mesh_)
    {
      initialize();

      /*
      * Removed by Siqi. not sure.
      * for (int i = 0; i < static_cast<int>(vecs->getSize()); i++)
      * TEST_EXIT(vecs->getDOFVector(0)->getFeSpace() == vecs->getDOFVector(i)->getFeSpace())
      * 	("All FeSpace have to be equal!\n");
      */
      feSpace = vecs->getDOFVector(0)->getFeSpace();
      solutionVecs.resize(vecs->getSize());
      for (int i = 0; i < static_cast<int>(vecs->getSize()); i++)
        solutionVecs[i] = vecs->getDOFVector(i);

      for (size_t i = 0; i < solutionVecs.size(); i++)
        solutionNames.push_back(solutionVecs[i]->getName());
    }

    template<>
    void FileWriter<double>::writeFiles(AdaptInfo& adaptInfo,
                                        bool force,
                                        int level,
                                        Flag flag,
                                        bool (*writeElem)(ElInfo*))
    {
      FUNCNAME("FileWriter<T>::writeFiles()");
      using namespace ::AMDiS::io;

      if (!super::doWriteTimestep(adaptInfo, force))
        return;

      //-----------------by Siqi---------------------//
      if (writeAMDiSFormat || writePeriodicFormat || writeParaViewFormat
          || writeParaViewVectorFormat || writeParaViewAnimation
          || writeDofFormat || writeArhFormat || writePovrayFormat)
      {
        for (int i = 0; i < static_cast<int>(solutionVecs.size()); i++)
          TEST_EXIT(solutionVecs[0]->getFeSpace() == solutionVecs[i]->getFeSpace())
          ("All FeSpaces have to be equal!\n");
      }

      // Containers, which store the data to be written;
      std::vector<DataCollector<>*> dataCollectors(solutionVecs.size());

      if (writeElem)
      {
        for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
          dataCollectors[i] = new DataCollector<>(feSpace, solutionVecs[i],
                                                  level, flag, writeElem);
      }
      else
      {
        for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
          dataCollectors[i] = new DataCollector<>(feSpace, solutionVecs[i],
                                                  traverseLevel,
                                                  flag | traverseFlag,
                                                  writeElement);
      }

      std::string fn, fn_;
#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
      std::string paraFilename, postfix;
      super::getFilename(adaptInfo, fn, paraFilename, postfix);
      postfix += paraviewFileExt;
      fn_ = paraFilename;
#else
      super::getFilename(adaptInfo, fn);
      fn_ = fn;
#endif

      if (writeAMDiSFormat)
      {
        MacroWriter::writeMacro(dataCollectors[0],
                                const_cast<char*>((fn +  amdisMeshExt).c_str()),
                                adaptInfo.getTime());
        MSG("macro file written to %s\n", (fn + amdisMeshExt).c_str());

        ValueWriter::writeValues(dataCollectors[0],
                                 (fn + amdisDataExt).c_str(),
                                 adaptInfo.getTime());
        MSG("value file written to %s\n", (fn + amdisDataExt).c_str());
      }

      if (writePeriodicFormat)
      {
        MacroWriter::writePeriodicFile(dataCollectors[0],
                                       (fn + periodicFileExt).c_str());
        MSG("periodic file written to %s\n", (fn + periodicFileExt).c_str());
      }

      if (writeParaViewFormat)
      {
        std::string vtu_file = fn + paraviewFileExt;
        VtkWriter::Aux vtkWriter(&dataCollectors,
                                 solutionNames,
                                 VtkWriter::Vtuformat(paraViewMode), (paraViewPrecision == 1), (writeParaViewVectorFormat == 1));
        vtkWriter.writeFile(vtu_file);

#if HAVE_PARALLEL_DOMAIN_AMDIS
        if (MPI::COMM_WORLD.Get_rank() == 0)
        {
          // 	  vector<string> componentNames;
          // 	  for (unsigned int i = 0; i < dataCollectors.size(); i++)
          // 	    componentNames.push_back(dataCollectors[i]->getValues()->getName());
          VtkWriter::detail::writeParallelFile(paraFilename + paraviewParallelFileExt,
                                               MPI::COMM_WORLD.Get_size(),
                                               filename,
                                               postfix,
                                               solutionNames,
                                               VtkWriter::Vtuformat(paraViewMode),
                                               (paraViewPrecision == 1),
                                               writeParaViewVectorFormat,
                                               createSubDir > 0);
        }
#endif

        MSG("ParaView file written to %s\n", (fn + paraviewFileExt).c_str());
      }

      // write vtu-vector files
      if (writeParaViewVectorFormat && !writeParaViewFormat)
      {
        VtkVectorWriter::writeFile(solutionVecs, fn_ + paraviewFileExt, true, writeAs3dVector);
        MSG("ParaView file written to %s\n", (fn_ + paraviewFileExt).c_str());
      }

      if (writeParaViewAnimation)
      {
        std::string pvd_file = fn_ + paraviewFileExt;
#if HAVE_PARALLEL_DOMAIN_AMDIS
        pvd_file = fn_ + paraviewParallelFileExt;
        if (MPI::COMM_WORLD.Get_rank() == 0)
#endif
        {
          VtkWriter::detail::updateAnimationFile(adaptInfo,
                                                 pvd_file,
                                                 &paraviewAnimationFrames,
                                                 filename + ".pvd");
        }
      }

      if (writeDofFormat)
      {
        DofWriter::writeFile(solutionVecs, fn + ".dof");
      }

      if (writeArhFormat)
      {
        // write Arh files
        Arh3Writer::writeFile(solutionVecs, fn_ + ".arh");
      }

#ifdef HAVE_PNG
      if (writePngFormat)
      {
        PngWriter pngWriter(dataCollectors[0]);
        pngWriter.writeFile(fn + ".png", pngType);

        MSG("PNG image file written to %s\n", (fn + ".png").c_str());
      }
#endif

      if (writePovrayFormat)
      {
        PovrayWriter povrayWriter(dataCollectors[0]);
        povrayWriter.writeFile(fn + ".pov");

        MSG("Povray script written to %s\n", (fn + ".pov").c_str());
      }

      for (int i = 0; i < static_cast<int>(dataCollectors.size()); i++)
        delete dataCollectors[i];
    }

    template<>
    string FileWriter<double>::getParaViewFilename(AdaptInfo& adaptInfo) const
    {
      string ret(filename);
      if (appendIndex)
      {
        TEST_EXIT(indexLength <= 99)("index lenght > 99\n");
        TEST_EXIT(indexDecimals <= 97)("index decimals > 97\n");
        TEST_EXIT(indexDecimals < indexLength)("index length <= index decimals\n");

        char formatStr[9];
        char timeStr[20];

        sprintf(formatStr, "%%0%d.%df", indexLength, indexDecimals);
        sprintf(timeStr, formatStr, adaptInfo.getTime());

        ret += timeStr;
      }
      return ret;
    }
  } // end namespace detail
} // end namespace AMDiS