<commit_before>#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>

/*****************************************************************************************************************************/
//Namespaces
using namespace cv;
using namespace cv::ml;
using std::cout;
using std::endl;

/*****************************************************************************************************************************/
//Global
const std::string IMAGETYPE = ".jpg";              //Image type for all images inside the program
const unsigned int NUMBEROFCLASSES = 2;			   //Number of classes used in the Training
const unsigned int NUMBEROFIMAGESPERCLASS =10;     //Number of Images in each class
const unsigned int IMAGERESOLUTION = 256;          //Y and X resolution for all images

/*****************************************************************************************************************************/
//Headers
Mat resizeTo1xN(Mat image);
Mat populateTrainingMat(const unsigned int numberOfImages, const unsigned int numberOfClasses);
Mat populateLabels(const unsigned int numberOfImages, const unsigned int numberOfClasses);
void printSupportVectors(const Ptr<SVM>& svm);
Mat edgeDetection(Mat image);
/*****************************************************************************************************************************/
//Main
auto main(int argc, char *argv[]) -> int {
	Mat testImage;
	if (argc>1){
		std::string image = argv[1];
		testImage = imread(image.c_str(),IMREAD_GRAYSCALE);
		if (!testImage.data){
			cout<<"Error opening the image!";
			return (0);
		}
		cout<<"Parameters: "<<"extension: "<<IMAGETYPE<<" Nclasses: "<<NUMBEROFCLASSES<<" Nimages: "<<NUMBEROFIMAGESPERCLASS<<" Resolution: "<<IMAGERESOLUTION<<endl;
	}
	else {
		cout<<"Please, specify the test image!";
		return(0);
	}

	Mat sampleImage = resizeTo1xN(edgeDetection(testImage));
	sampleImage.convertTo(sampleImage,CV_32F);
	Mat trainingMatrix = populateTrainingMat(NUMBEROFIMAGESPERCLASS,NUMBEROFCLASSES);
	Mat labels=populateLabels(NUMBEROFIMAGESPERCLASS,NUMBEROFCLASSES);
	cout<<"Train data"<<endl<<"rows: "<<trainingMatrix.rows<<" cols: "<<trainingMatrix.cols<<endl<<endl;
	cout<<"Labels"<<endl<<"rows: "<<labels.rows<<" cols: "<<labels.cols<<endl<<endl;
	cout<<"Prediction Image"<<endl<<"rows: "<<sampleImage.rows<<" cols: "<<sampleImage.cols<<endl<<endl;

    // Set up SVM's parameters
    cout<<"Setting up SVM's parameters.";
    Ptr<SVM> svm = SVM::create();
    svm->setType(SVM::C_SVC );
    svm->setKernel(SVM::LINEAR);
    svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 10000, 1e-6));
    cout<<"..Done!"<<endl;

    // Train the SVM with given parameters
    Ptr<TrainData> td = TrainData::create(trainingMatrix, ROW_SAMPLE, labels);
    cout<<"Training SVM.";
    svm->train(td);
    cout<<"..Done!"<<endl<<endl;

    // Train the SVM with optimal parameters
    //svm->trainAuto(td);

    float response = svm->predict(sampleImage);
    cout<<"The test image belongs to class: "<<response<<endl;

    printSupportVectors(svm);

    waitKey(0);
}

/******************************************************************************************************************************/
Mat resizeTo1xN(Mat image){
	/* This function resize the given image into a 1xN Mat
	 * @param Mat image - The image to be resized
	 */
	Size size(IMAGERESOLUTION,IMAGERESOLUTION);
	resize(image,image,size);
	Size size1xN(image.cols*image.rows,1);
	resize(image,image,size1xN);
	return image;

}
/*****************************************************************************************************************************/
Mat populateTrainingMat(const unsigned int numberOfImages, const unsigned int numberOfClasses){
	/*Build the trainig Matrix for the the SVM. Each line will be a image.
	 * @param  const unsigned int numberOfImages
	 * @param const unsigned int numberOfClasses
	 *
	 */
	Mat trainingMatrix = Mat::zeros(numberOfClasses*numberOfImages,IMAGERESOLUTION*IMAGERESOLUTION,CV_32F);
	for (unsigned int i=0; i<numberOfClasses;i++){
		for (unsigned int j=0 ; j<numberOfImages;j++){
			const unsigned int imageNumber = j+(numberOfImages*i);
			std::ostringstream ss;
			ss<<imageNumber;                                                       // Workaround for std::to_string MinGW bug
			cv::String imageName =  ss.str() + IMAGETYPE;
 			Mat input=imread(imageName ,IMREAD_GRAYSCALE);
 			input=edgeDetection(input);
 			Mat resizedInput=resizeTo1xN(input);
			resizedInput.copyTo(trainingMatrix(Rect(0,j+(numberOfImages*i),resizedInput.cols,resizedInput.rows)));
		}
	}
	return trainingMatrix;
}

/*****************************************************************************************************************************/
Mat edgeDetection(Mat image){
	/*Uses the SobelFeldman operator to extract the image edges
			 * @param  Mat image - The image to be processed
			 *
			 */
	 int scale = 1;
	 int delta = 0;
	 int ddepth = CV_32F;
	 Mat gradX, gradY;
	 Mat absGradX, absGradY;

	 // Gradient X
	 Sobel( image, gradX, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
	 convertScaleAbs( gradX, absGradX );

	 // Gradient Y
	 Sobel( image, gradY, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
	 convertScaleAbs( gradY, absGradY );

	 // Total Gradient (approximate)
	 addWeighted( absGradX, 0.5, absGradY, 0.5, 0, image );
	 return image;
}

/*****************************************************************************************************************************/
Mat populateLabels(const unsigned int numberOfImages, const unsigned int numberOfClasses){
	/*Build the trainig Matrix's Labels for the the SVM. Each line will be the label of the respective image in the TrainingMat.
		 * @param  const unsigned int numberOfImages
		 * @param const unsigned int numberOfClasses
		 *
		 */
	std::vector<int> labels;
	for (unsigned int i=0; i<numberOfClasses;i++){
			for (unsigned int j=0 ; j<numberOfImages;j++){
				labels.push_back(i);
			}
	}
	Mat labelsMat(numberOfImages*numberOfClasses, 1, CV_32SC1 , labels.data());
	return labelsMat;

}

/*****************************************************************************************************************************/
void printSupportVectors(const Ptr<SVM>& svm){
	/* Print the Support Vectors.
	 * @param Ptr<SVM> svm The svm containing the Support Vectors to show
	 */
	// Data for visual representation
	int width = 512, height = 512;
	Mat image = Mat::zeros(height, width, CV_8UC3);
	int thickness = -1;
	int lineType = 8;
	// Show support vectors
	thickness = 2;
	lineType  = 8;
	Mat sv = svm->getUncompressedSupportVectors();
	for (int i = 0; i < sv.rows; ++i){
		const float* v = sv.ptr<float>(i);
		circle( image,  Point( (int) v[0], (int) v[1]),   6,  Scalar(30, 128, 0), thickness, lineType);
	}
	imwrite("result.png", image);
	imshow("Uncompressed Support Vectors", image);

}
/*****************************************************************************************************************************/
<commit_msg>Improved grammar<commit_after>#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>

/*****************************************************************************************************************************/
//Namespaces
using namespace cv;
using namespace cv::ml;
using std::cout;
using std::endl;

/*****************************************************************************************************************************/
//Global
const std::string IMAGETYPE = ".jpg";              //Image type for all images inside the program
const unsigned int NUMBEROFCLASSES = 2;		   //Number of classes used in the Training
const unsigned int NUMBEROFIMAGESPERCLASS =10;     //Number of Images in each class
const unsigned int IMAGERESOLUTION = 256;          //Y and X resolution for all images

/*****************************************************************************************************************************/
//Headers
Mat resizeTo1xN(Mat image);
Mat populateTrainingMat(const unsigned int numberOfImages, const unsigned int numberOfClasses);
Mat populateLabels(const unsigned int numberOfImages, const unsigned int numberOfClasses);
void printSupportVectors(const Ptr<SVM>& svm);
Mat edgeDetection(Mat image);
/*****************************************************************************************************************************/
//Main
auto main(int argc, char *argv[]) -> int {
	Mat testImage;
	if (argc>1){
		std::string image = argv[1];
		testImage = imread(image.c_str(),IMREAD_GRAYSCALE);
		if (!testImage.data){
			cout<<"Error opening the image!";
			return (0);
		}
		cout<<"Parameters: "<<"extension: "<<IMAGETYPE<<" Nclasses: "<<NUMBEROFCLASSES<<" Nimages: "<<NUMBEROFIMAGESPERCLASS<<" Resolution: "<<IMAGERESOLUTION<<endl;
	}
	else {
		cout<<"Please, specify the test image!";
		return(0);
	}

	Mat sampleImage = resizeTo1xN(edgeDetection(testImage));
	sampleImage.convertTo(sampleImage,CV_32F);
	Mat trainingMatrix = populateTrainingMat(NUMBEROFIMAGESPERCLASS,NUMBEROFCLASSES);
	Mat labels=populateLabels(NUMBEROFIMAGESPERCLASS,NUMBEROFCLASSES);
	cout<<"Train data"<<endl<<"rows: "<<trainingMatrix.rows<<" cols: "<<trainingMatrix.cols<<endl<<endl;
	cout<<"Labels"<<endl<<"rows: "<<labels.rows<<" cols: "<<labels.cols<<endl<<endl;
	cout<<"Prediction Image"<<endl<<"rows: "<<sampleImage.rows<<" cols: "<<sampleImage.cols<<endl<<endl;

    // Set up SVM's parameters
    cout<<"Setting up SVM's parameters.";
    Ptr<SVM> svm = SVM::create();
    svm->setType(SVM::C_SVC );
    svm->setKernel(SVM::LINEAR);
    svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 10000, 1e-6));
    cout<<"..Done!"<<endl;

    // Train the SVM with given parameters
    Ptr<TrainData> td = TrainData::create(trainingMatrix, ROW_SAMPLE, labels);
    cout<<"Training SVM.";
    svm->train(td);
    cout<<"..Done!"<<endl<<endl;

    // Train the SVM with optimal parameters
    //svm->trainAuto(td);

    float response = svm->predict(sampleImage);
    cout<<"The test image belongs to class: "<<response<<endl;

    printSupportVectors(svm);

    waitKey(0);
}

/******************************************************************************************************************************/
Mat resizeTo1xN(Mat image){
	/* This function resize the given image into a 1xN Mat
	 * @param Mat image - The image to be resized
	 */
	Size size(IMAGERESOLUTION,IMAGERESOLUTION);
	resize(image,image,size);
	Size size1xN(image.cols*image.rows,1);
	resize(image,image,size1xN);
	return image;

}
/*****************************************************************************************************************************/
Mat populateTrainingMat(const unsigned int numberOfImages, const unsigned int numberOfClasses){
	/*Build the trainig Matrix for the the SVM. Each line will be an image.
	 * @param  const unsigned int numberOfImages
	 * @param const unsigned int numberOfClasses
	 *
	 */
	Mat trainingMatrix = Mat::zeros(numberOfClasses*numberOfImages,IMAGERESOLUTION*IMAGERESOLUTION,CV_32F);
	for (unsigned int i=0; i<numberOfClasses;i++){
		for (unsigned int j=0 ; j<numberOfImages;j++){
			const unsigned int imageNumber = j+(numberOfImages*i);
			std::ostringstream ss;
			ss<<imageNumber;                                                       // Workaround for std::to_string MinGW bug
			cv::String imageName =  ss.str() + IMAGETYPE;
 			Mat input=imread(imageName ,IMREAD_GRAYSCALE);
 			input=edgeDetection(input);
 			Mat resizedInput=resizeTo1xN(input);
			resizedInput.copyTo(trainingMatrix(Rect(0,j+(numberOfImages*i),resizedInput.cols,resizedInput.rows)));
		}
	}
	return trainingMatrix;
}

/*****************************************************************************************************************************/
Mat edgeDetection(Mat image){
	/*Uses the Sobel–Feldman operator to extract the image edges
			 * @param  Mat image - The image to be processed
			 *
			 */
	 int scale = 1;
	 int delta = 0;
	 int ddepth = CV_32F;
	 Mat gradX, gradY;
	 Mat absGradX, absGradY;

	 // Gradient X
	 Sobel( image, gradX, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT );
	 convertScaleAbs( gradX, absGradX );

	 // Gradient Y
	 Sobel( image, gradY, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT );
	 convertScaleAbs( gradY, absGradY );

	 // Total Gradient (approximate)
	 addWeighted( absGradX, 0.5, absGradY, 0.5, 0, image );
	 return image;
}

/*****************************************************************************************************************************/
Mat populateLabels(const unsigned int numberOfImages, const unsigned int numberOfClasses){
	/*Build the training Matrix's Labels for the SVM. Each line will be the label of the respective image in the TrainingMat.
		 * @param  const unsigned int numberOfImages
		 * @param const unsigned int numberOfClasses
		 *
		 */
	std::vector<int> labels;
	for (unsigned int i=0; i<numberOfClasses;i++){
			for (unsigned int j=0 ; j<numberOfImages;j++){
				labels.push_back(i);
			}
	}
	Mat labelsMat(numberOfImages*numberOfClasses, 1, CV_32SC1 , labels.data());
	return labelsMat;

}

/*****************************************************************************************************************************/
void printSupportVectors(const Ptr<SVM>& svm){
	/* Print the Support Vectors.
	 * @param Ptr<SVM> svm The SVM containing the Support Vectors to show
	 */
	// Data for visual representation
	int width = 512, height = 512;
	Mat image = Mat::zeros(height, width, CV_8UC3);
	int thickness = -1;
	int lineType = 8;
	// Show support vectors
	thickness = 2;
	lineType  = 8;
	Mat sv = svm->getUncompressedSupportVectors();
	for (int i = 0; i < sv.rows; ++i){
		const float* v = sv.ptr<float>(i);
		circle( image,  Point( (int) v[0], (int) v[1]),   6,  Scalar(30, 128, 0), thickness, lineType);
	}
	imwrite("result.png", image);
	imshow("Uncompressed Support Vectors", image);

}
/*****************************************************************************************************************************/
<|endoftext|>


<commit_before>#include "event_handler.h"

#include <CoreServices/CoreServices.h>
#include <cerrno>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <sys/stat.h>
#include <utility>

#include "../../log.h"
#include "../../message.h"
#include "flags.h"
#include "recent_file_cache.h"
#include "rename_buffer.h"

using std::dec;
using std::endl;
using std::hex;
using std::map;
using std::move;
using std::ostream;
using std::shared_ptr;
using std::string;

class EventFunctor
{
public:
  EventFunctor(EventHandler &handler, string &&event_path, FSEventStreamEventFlags flags) :
    message_buffer{handler.message_buffer},
    cache{handler.cache},
    rename_buffer{handler.rename_buffer},
    event_path{move(event_path)},
    flags{flags}
  {
    flag_created = (flags & CREATE_FLAGS) != 0;
    flag_deleted = (flags & DELETED_FLAGS) != 0;
    flag_modified = (flags & MODIFY_FLAGS) != 0;
    flag_renamed = (flags & RENAME_FLAGS) != 0;
    flag_file = (flags & IS_FILE) != 0;
    flag_directory = (flags & IS_DIRECTORY) != 0;
  }

  void operator()()
  {
    collect_info();
    report();

    if (emit_if_unambiguous()) return;
    if (emit_if_rename()) return;
    if (emit_if_absent()) return;
    emit_if_present();
  }

private:
  // Log the raw and interpreted flag information.
  void report()
  {
    ostream &logline = LOGGER;
    logline << "Event at [" << event_path << "] flags " << hex << flags << dec << " [";

    if ((flags & kFSEventStreamEventFlagMustScanSubDirs) != 0) logline << " MustScanSubDirs";
    if ((flags & kFSEventStreamEventFlagUserDropped) != 0) logline << " UserDropped";
    if ((flags & kFSEventStreamEventFlagKernelDropped) != 0) logline << " KernelDropped";
    if ((flags & kFSEventStreamEventFlagEventIdsWrapped) != 0) logline << " EventIdsWrapped";
    if ((flags & kFSEventStreamEventFlagMustScanSubDirs) != 0) logline << " MustScanSubDirs";
    if ((flags & kFSEventStreamEventFlagHistoryDone) != 0) logline << " HistoryDone";
    if ((flags & kFSEventStreamEventFlagRootChanged) != 0) logline << " RootChanged";
    if ((flags & kFSEventStreamEventFlagMount) != 0) logline << " Mount";
    if ((flags & kFSEventStreamEventFlagUnmount) != 0) logline << " Unmount";
    if ((flags & kFSEventStreamEventFlagMustScanSubDirs) != 0) logline << " MustScanSubDirs";
    if ((flags & kFSEventStreamEventFlagItemCreated) != 0) logline << " ItemCreated";
    if ((flags & kFSEventStreamEventFlagItemRemoved) != 0) logline << " ItemRemoved";
    if ((flags & kFSEventStreamEventFlagItemInodeMetaMod) != 0) logline << " ItemInodeMetaMod";
    if ((flags & kFSEventStreamEventFlagItemRenamed) != 0) logline << " ItemRenamed";
    if ((flags & kFSEventStreamEventFlagItemModified) != 0) logline << " ItemModified";
    if ((flags & kFSEventStreamEventFlagItemFinderInfoMod) != 0) logline << " ItemFinderInfoMod";
    if ((flags & kFSEventStreamEventFlagItemChangeOwner) != 0) logline << " ItemChangeOwner";
    if ((flags & kFSEventStreamEventFlagItemXattrMod) != 0) logline << " ItemXattrMod";
    if ((flags & kFSEventStreamEventFlagItemIsFile) != 0) logline << " ItemIsFile";
    if ((flags & kFSEventStreamEventFlagItemIsDir) != 0) logline << " ItemIsDir";
    if ((flags & kFSEventStreamEventFlagItemIsSymlink) != 0) logline << " ItemIsSymlink";
    if ((flags & kFSEventStreamEventFlagOwnEvent) != 0) logline << " OwnEvent";
    if ((flags & kFSEventStreamEventFlagItemIsHardlink) != 0) logline << " ItemIsHardlink";
    if ((flags & kFSEventStreamEventFlagItemIsLastHardlink) != 0) logline << " ItemIsLastHardlink";

    logline << "] former=" << former->to_string(false) << " current=" << current->to_string(false) << endl;
  }

  // Check and update the recently-seen entry cache for this entry.
  void collect_info()
  {
    former = cache.former_at_path(event_path, flag_file, flag_directory);
    current = cache.current_at_path(event_path, flag_file, flag_directory);
  }

  // Emit messages for events that have unambiguous flags.
  bool emit_if_unambiguous()
  {
    if (flag_created && !(flag_deleted || flag_modified || flag_renamed)) {
      message_buffer.created(move(event_path), current->get_entry_kind());
      return true;
    }

    if (flag_deleted && !(flag_created || flag_modified || flag_renamed)) {
      EntryKind former_kind = KIND_UNKNOWN;
      if (current->get_entry_kind() != KIND_UNKNOWN) {
        former_kind = current->get_entry_kind();
      } else if (former->get_entry_kind() != KIND_UNKNOWN) {
        former_kind = former->get_entry_kind();
      }

      message_buffer.deleted(move(event_path), former_kind);
      return true;
    }

    if (flag_modified && !(flag_created || flag_deleted || flag_renamed)) {
      message_buffer.modified(move(event_path), current->get_entry_kind());
      return true;
    }

    return false;
  }

  // Present the current and former entries to the RenameBuffer if the rename flag is set. This may
  // emit a rename event if a matching entry pair is discovered, or it will buffer the entries to find
  // matches when they arrive.
  bool emit_if_rename()
  {
    if (flag_renamed) {
      rename_buffer.observe_entry(message_buffer, former, current);
      return true;
    }

    return false;
  }

  // Emit messages based on the last observed state of this entry if it no longer exists.
  bool emit_if_absent()
  {
    if (current->is_present()) return false;

    if (former->is_present() && kinds_are_different(former->get_entry_kind(), current->get_entry_kind())) {
      // Entry was last seen as a directory, but the latest event has it flagged as a file (or vice versa).
      // The directory must have been deleted.
      message_buffer.deleted(string(former->get_path()), former->get_entry_kind());
      message_buffer.created(string(current->get_path()), current->get_entry_kind());
    } else {
      // Entry has not been seen before, so we must have missed its creation event.
      message_buffer.created(string(current->get_path()), current->get_entry_kind());
    }

    // It isn't there now, so it must have been deleted.
    message_buffer.deleted(string(current->get_path()), current->get_entry_kind());
    return true;
  }

  // Emit messages based on the event flags and the current lstat() output.
  bool emit_if_present()
  {
    if (current->is_absent()) return false;

    if (former->is_present()) {
      // This is *not* the first time an event at this path has been seen.
      if (flag_deleted) {
        // Rapid creation and deletion. There may be a lost modification event just before deletion or just after
        // recreation.
        message_buffer.deleted(string(former->get_path()), former->get_entry_kind());
        message_buffer.created(string(current->get_path()), current->get_entry_kind());
      } else {
        // Modification of an existing entry.
        message_buffer.modified(string(current->get_path()), current->get_entry_kind());
      }
    } else {
      // This *is* the first time an event has been seen at this path.
      if (flag_deleted) {
        // The only way for the deletion flag to be set on an entry we haven't seen before is for the entry to
        // be rapidly created, deleted, and created again.
        message_buffer.created(string(former->get_path()), former->get_entry_kind());
        message_buffer.deleted(string(former->get_path()), former->get_entry_kind());
        message_buffer.created(string(current->get_path()), current->get_entry_kind());
      } else {
        // Otherwise, it must have been created. This may conceal a separate modification event just after
        // the entry's creation.
        message_buffer.created(string(current->get_path()), current->get_entry_kind());
      }
    }

    return true;
  }

  ChannelMessageBuffer &message_buffer;
  RecentFileCache &cache;
  RenameBuffer &rename_buffer;

  string event_path;
  FSEventStreamEventFlags flags;

  bool flag_created;
  bool flag_deleted;
  bool flag_modified;
  bool flag_renamed;
  bool flag_file;
  bool flag_directory;

  shared_ptr<StatResult> former;
  shared_ptr<StatResult> current;
};

EventHandler::EventHandler(ChannelMessageBuffer &message_buffer, RecentFileCache &cache, RenameBuffer &rename_buffer) :
  cache{cache},
  message_buffer{message_buffer},
  rename_buffer{rename_buffer}
{
  //
}

void EventHandler::handle(string &&event_path, FSEventStreamEventFlags flags)
{
  EventFunctor callable(*this, move(event_path), flags);
  callable();
}
<commit_msg>:art: more log message tidiness<commit_after>#include "event_handler.h"

#include <CoreServices/CoreServices.h>
#include <cerrno>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <sys/stat.h>
#include <utility>

#include "../../log.h"
#include "../../message.h"
#include "flags.h"
#include "recent_file_cache.h"
#include "rename_buffer.h"

using std::dec;
using std::endl;
using std::hex;
using std::map;
using std::move;
using std::ostream;
using std::shared_ptr;
using std::string;

class EventFunctor
{
public:
  EventFunctor(EventHandler &handler, string &&event_path, FSEventStreamEventFlags flags) :
    message_buffer{handler.message_buffer},
    cache{handler.cache},
    rename_buffer{handler.rename_buffer},
    event_path{move(event_path)},
    flags{flags}
  {
    flag_created = (flags & CREATE_FLAGS) != 0;
    flag_deleted = (flags & DELETED_FLAGS) != 0;
    flag_modified = (flags & MODIFY_FLAGS) != 0;
    flag_renamed = (flags & RENAME_FLAGS) != 0;
    flag_file = (flags & IS_FILE) != 0;
    flag_directory = (flags & IS_DIRECTORY) != 0;
  }

  void operator()()
  {
    collect_info();
    report();

    if (emit_if_unambiguous()) return;
    if (emit_if_rename()) return;
    if (emit_if_absent()) return;
    emit_if_present();
  }

private:
  // Log the raw and interpreted flag information.
  void report()
  {
    ostream &logline = LOGGER;
    logline << "Event at [" << event_path << "] flags " << hex << flags << dec << " [";

    if ((flags & kFSEventStreamEventFlagMustScanSubDirs) != 0) logline << " MustScanSubDirs";
    if ((flags & kFSEventStreamEventFlagUserDropped) != 0) logline << " UserDropped";
    if ((flags & kFSEventStreamEventFlagKernelDropped) != 0) logline << " KernelDropped";
    if ((flags & kFSEventStreamEventFlagEventIdsWrapped) != 0) logline << " EventIdsWrapped";
    if ((flags & kFSEventStreamEventFlagMustScanSubDirs) != 0) logline << " MustScanSubDirs";
    if ((flags & kFSEventStreamEventFlagHistoryDone) != 0) logline << " HistoryDone";
    if ((flags & kFSEventStreamEventFlagRootChanged) != 0) logline << " RootChanged";
    if ((flags & kFSEventStreamEventFlagMount) != 0) logline << " Mount";
    if ((flags & kFSEventStreamEventFlagUnmount) != 0) logline << " Unmount";
    if ((flags & kFSEventStreamEventFlagMustScanSubDirs) != 0) logline << " MustScanSubDirs";
    if ((flags & kFSEventStreamEventFlagItemCreated) != 0) logline << " ItemCreated";
    if ((flags & kFSEventStreamEventFlagItemRemoved) != 0) logline << " ItemRemoved";
    if ((flags & kFSEventStreamEventFlagItemInodeMetaMod) != 0) logline << " ItemInodeMetaMod";
    if ((flags & kFSEventStreamEventFlagItemRenamed) != 0) logline << " ItemRenamed";
    if ((flags & kFSEventStreamEventFlagItemModified) != 0) logline << " ItemModified";
    if ((flags & kFSEventStreamEventFlagItemFinderInfoMod) != 0) logline << " ItemFinderInfoMod";
    if ((flags & kFSEventStreamEventFlagItemChangeOwner) != 0) logline << " ItemChangeOwner";
    if ((flags & kFSEventStreamEventFlagItemXattrMod) != 0) logline << " ItemXattrMod";
    if ((flags & kFSEventStreamEventFlagItemIsFile) != 0) logline << " ItemIsFile";
    if ((flags & kFSEventStreamEventFlagItemIsDir) != 0) logline << " ItemIsDir";
    if ((flags & kFSEventStreamEventFlagItemIsSymlink) != 0) logline << " ItemIsSymlink";
    if ((flags & kFSEventStreamEventFlagOwnEvent) != 0) logline << " OwnEvent";
    if ((flags & kFSEventStreamEventFlagItemIsHardlink) != 0) logline << " ItemIsHardlink";
    if ((flags & kFSEventStreamEventFlagItemIsLastHardlink) != 0) logline << " ItemIsLastHardlink";

    logline << " ] former=" << former->to_string(false) << " current=" << current->to_string(false) << endl;
  }

  // Check and update the recently-seen entry cache for this entry.
  void collect_info()
  {
    former = cache.former_at_path(event_path, flag_file, flag_directory);
    current = cache.current_at_path(event_path, flag_file, flag_directory);
  }

  // Emit messages for events that have unambiguous flags.
  bool emit_if_unambiguous()
  {
    if (flag_created && !(flag_deleted || flag_modified || flag_renamed)) {
      message_buffer.created(move(event_path), current->get_entry_kind());
      return true;
    }

    if (flag_deleted && !(flag_created || flag_modified || flag_renamed)) {
      EntryKind former_kind = KIND_UNKNOWN;
      if (current->get_entry_kind() != KIND_UNKNOWN) {
        former_kind = current->get_entry_kind();
      } else if (former->get_entry_kind() != KIND_UNKNOWN) {
        former_kind = former->get_entry_kind();
      }

      message_buffer.deleted(move(event_path), former_kind);
      return true;
    }

    if (flag_modified && !(flag_created || flag_deleted || flag_renamed)) {
      message_buffer.modified(move(event_path), current->get_entry_kind());
      return true;
    }

    return false;
  }

  // Present the current and former entries to the RenameBuffer if the rename flag is set. This may
  // emit a rename event if a matching entry pair is discovered, or it will buffer the entries to find
  // matches when they arrive.
  bool emit_if_rename()
  {
    if (flag_renamed) {
      rename_buffer.observe_entry(message_buffer, former, current);
      return true;
    }

    return false;
  }

  // Emit messages based on the last observed state of this entry if it no longer exists.
  bool emit_if_absent()
  {
    if (current->is_present()) return false;

    if (former->is_present() && kinds_are_different(former->get_entry_kind(), current->get_entry_kind())) {
      // Entry was last seen as a directory, but the latest event has it flagged as a file (or vice versa).
      // The directory must have been deleted.
      message_buffer.deleted(string(former->get_path()), former->get_entry_kind());
      message_buffer.created(string(current->get_path()), current->get_entry_kind());
    } else {
      // Entry has not been seen before, so we must have missed its creation event.
      message_buffer.created(string(current->get_path()), current->get_entry_kind());
    }

    // It isn't there now, so it must have been deleted.
    message_buffer.deleted(string(current->get_path()), current->get_entry_kind());
    return true;
  }

  // Emit messages based on the event flags and the current lstat() output.
  bool emit_if_present()
  {
    if (current->is_absent()) return false;

    if (former->is_present()) {
      // This is *not* the first time an event at this path has been seen.
      if (flag_deleted) {
        // Rapid creation and deletion. There may be a lost modification event just before deletion or just after
        // recreation.
        message_buffer.deleted(string(former->get_path()), former->get_entry_kind());
        message_buffer.created(string(current->get_path()), current->get_entry_kind());
      } else {
        // Modification of an existing entry.
        message_buffer.modified(string(current->get_path()), current->get_entry_kind());
      }
    } else {
      // This *is* the first time an event has been seen at this path.
      if (flag_deleted) {
        // The only way for the deletion flag to be set on an entry we haven't seen before is for the entry to
        // be rapidly created, deleted, and created again.
        message_buffer.created(string(former->get_path()), former->get_entry_kind());
        message_buffer.deleted(string(former->get_path()), former->get_entry_kind());
        message_buffer.created(string(current->get_path()), current->get_entry_kind());
      } else {
        // Otherwise, it must have been created. This may conceal a separate modification event just after
        // the entry's creation.
        message_buffer.created(string(current->get_path()), current->get_entry_kind());
      }
    }

    return true;
  }

  ChannelMessageBuffer &message_buffer;
  RecentFileCache &cache;
  RenameBuffer &rename_buffer;

  string event_path;
  FSEventStreamEventFlags flags;

  bool flag_created;
  bool flag_deleted;
  bool flag_modified;
  bool flag_renamed;
  bool flag_file;
  bool flag_directory;

  shared_ptr<StatResult> former;
  shared_ptr<StatResult> current;
};

EventHandler::EventHandler(ChannelMessageBuffer &message_buffer, RecentFileCache &cache, RenameBuffer &rename_buffer) :
  cache{cache},
  message_buffer{message_buffer},
  rename_buffer{rename_buffer}
{
  //
}

void EventHandler::handle(string &&event_path, FSEventStreamEventFlags flags)
{
  EventFunctor callable(*this, move(event_path), flags);
  callable();
}
<|endoftext|>


<commit_before>/****************************************************************************
 * Custom dialog - Pgn browser
 *  Author:  Bill Forster
 *  License: MIT license. Full text of license is in associated file LICENSE
 *  Copyright 2010-2014, Bill Forster <billforsternz at gmail dot com>
 ****************************************************************************/
#include "wx/wx.h"
#include "wx/valtext.h"
#include "wx/valgen.h"
#include "wx/listctrl.h"
#include "Portability.h"
#include "Appdefs.h"
#include "DebugPrintf.h"
#include "thc.h"
#include "GameDetailsDialog.h"
#include "GamePrefixDialog.h"
#include "GameLogic.h"
#include "Objects.h"
#include "CtrlChessBoard.h"
#include "PgnFiles.h"
#include "PgnDialog.h"
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;

void PgnDialog::GdvEnumerateGames()
{
}

wxSizer *PgnDialog::GdvAddExtraControls( bool WXUNUSED(big_display) )
{
    if( id == ID_PGN_DIALOG_FILE )
    {
        // Edit game details
        wxButton* edit_game_details = new wxButton ( this, ID_PGN_DIALOG_GAME_DETAILS, wxT("Edit Game Details"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( edit_game_details );
        vsiz_panel_buttons->Add(edit_game_details, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Edit game prefix
        //wxButton* edit_game_prefix = new wxButton ( this, ID_PGN_DIALOG_GAME_PREFIX, wxT("Edit Game Prefix"),
        //    wxDefaultPosition, wxDefaultSize, 0 );
        //vsiz_panel_buttons->Add(edit_game_prefix, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Paste game / Board->Game
        wxButton* board2game = new wxButton ( this, ID_BOARD2GAME, wxT("Paste current game"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( board2game );
        vsiz_panel_buttons->Add(board2game, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Delete
        wxButton* delete_ = new wxButton ( this, wxID_DELETE, wxT("Delete"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( delete_ );
        vsiz_panel_buttons->Add(delete_, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Cut
        wxButton* cut = new wxButton ( this, wxID_CUT, wxT("Cut"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( cut );
        vsiz_panel_buttons->Add(cut, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Add to clipboard
        wxButton* add = new wxButton ( this, ID_ADD_TO_CLIPBOARD, wxT("Add to clipboard"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( add );
        vsiz_panel_buttons->Add(add, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Copy
        wxButton* copy = new wxButton ( this, wxID_COPY, wxT("Copy"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( copy );
        vsiz_panel_buttons->Add(copy, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Paste
        wxButton* paste = new wxButton ( this, wxID_PASTE, wxT("Paste"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( paste );
        vsiz_panel_buttons->Add(paste, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Publish
        wxButton* publish = new wxButton ( this, ID_PGN_DIALOG_PUBLISH, wxT("Publish"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( publish );
        vsiz_panel_buttons->Add(publish, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // ECO codes
        wxButton* eco_codes = new wxButton ( this, ID_DIALOG_ECO, wxT("ECO codes"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( eco_codes );
        vsiz_panel_buttons->Add(eco_codes, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    }
    else if( id == ID_PGN_DIALOG_CLIPBOARD )
    {
        // Edit game details
        wxButton* edit_game_details = new wxButton ( this, ID_PGN_DIALOG_GAME_DETAILS, wxT("Edit Game Details"),
                                                    wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( edit_game_details );
        vsiz_panel_buttons->Add(edit_game_details, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Paste game / Board->Game
        wxButton* board2game = new wxButton ( this, ID_BOARD2GAME, wxT("Paste current game"),
                                             wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( board2game );
        vsiz_panel_buttons->Add(board2game, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Delete
        wxButton* delete_ = new wxButton ( this, wxID_DELETE, wxT("Delete"),
                                          wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( delete_ );
        vsiz_panel_buttons->Add(delete_, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    }
    else if( id == ID_PGN_DIALOG_SESSION )
    {
        // Add to clipboard
        wxButton* add = new wxButton ( this, ID_ADD_TO_CLIPBOARD, wxT("Add to clipboard"),
                                      wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( add );
        vsiz_panel_buttons->Add(add, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Copy
        wxButton* copy = new wxButton ( this, wxID_COPY, wxT("Copy"),
                                       wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( copy );
        vsiz_panel_buttons->Add(copy, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    }
    return vsiz_panel_buttons;
}

void PgnDialog::GetCachedDocumentRaw( int idx, GameDocument &gd )
{
    smart_ptr<ListableGame> &mb = gc->gds[idx];
    mb->ConvertToGameDocument(gd);
}

GameDocument * PgnDialog::GetCachedDocument( int idx )
{
    static GameDocument gd;
    CompactGame pact;
    smart_ptr<ListableGame> &mb = gc->gds[idx];
    mb->GetCompactGame(pact);
    pact.Upscale( gd );
    return &gd;
}

void PgnDialog::GdvReadItem( int item, CompactGame &info )
{
    if( 0<=item && static_cast<unsigned int>(item)<gc->gds.size() )
    {
        smart_ptr<ListableGame> &mb = gc->gds[item];
        mb->GetCompactGame( info );
    }
}

void PgnDialog::GdvHelpClick()
{
    wxString helpText;
    if( id == ID_PGN_DIALOG_FILE )
        helpText=
    "\nUse this panel to preview the games in a .pgn file."
    "\n\n"
    "You can sort on any column. The first column (column '#') is provided only to allow "
    "a sort on initial order (for restoring or reversing the initial order). To reverse "
	"sort click twice. The moves column sort is statistical (most popular lines first) "
	"rather than alphabetical. Sort history is respected in tie breaks. For example, if you "
	"sort on Moves, then on Black, then on White; The games will be sorted by White "
	"player, but all opponents will be grouped together (because of the earlier sort on Black), "
	"and if there are multiple games between the same players, the games will be sorted according "
	"to the most common opening sequences between those two players (because of the earlier sort on Moves)."
    "\n\n"
    "Two special features are provided at the moment. ECO calculates ECO codes for games "
    "which do not have them yet."
    "\n\n"
    "The Publish button is used to create interactive web content. This is still under "
    "development and should be treated as an extra-for-experts. There is a file "
    "named web.zip in your Tarrasch installation directory with supplementary files "
    "and instructions for the keen and well motivated.";

    else if( id == ID_PGN_DIALOG_CLIPBOARD )
        helpText=
    "\nUse this panel to look at games in the clipboard. Games can be copied to the clipboard "
    "from any of the Current file, Session or Database games dialogs, all available from the "
    "Games menu."
    "\n\n"
    "You can sort on any column. The first column (column '#') is provided only to allow "
    "a sort on initial order (for restoring or reversing the initial order). To reverse "
	"sort click twice. The moves column sort is statistical (most popular lines first) "
	"rather than alphabetical. Sort history is respected in tie breaks. For example, if you "
	"sort on Moves, then on Black, then on White; The games will be sorted by White "
	"player, but all opponents will be grouped together (because of the earlier sort on Black), "
	"and if there are multiple games between the same players, the games will be sorted according "
	"to the most common opening sequences between those two players (because of the earlier sort on Moves).";

    else if( id == ID_PGN_DIALOG_SESSION )
        helpText=
    "\nUse this panel to look at games you have worked with in this Tarrasch Chess GUI session."
    "\n\n"
    "You can sort on any column. The first column (column '#') is provided only to allow "
    "a sort on initial order (for restoring or reversing the initial order). To reverse "
	"sort click twice. The moves column sort is statistical (most popular lines first) "
	"rather than alphabetical. Sort history is respected in tie breaks. For example, if you "
	"sort on Moves, then on Black, then on White; The games will be sorted by White "
	"player, but all opponents will be grouped together (because of the earlier sort on Black), "
	"and if there are multiple games between the same players, the games will be sorted according "
	"to the most common opening sequences between those two players (because of the earlier sort on Moves).";
    wxMessageBox(helpText,
    wxT("Games Dialog Help"),
    wxOK|wxICON_INFORMATION, NULL );
}

void PgnDialog::GdvSearch() {}
void PgnDialog::GdvUtility() {}
void PgnDialog::GdvOnCancel() {}
void PgnDialog::GdvNextMove( int UNUSED(idx) ) {}

// PgnDialog constructors
PgnDialog::PgnDialog
 (
  wxWindow    *parent,
  GamesCache  *gc,
  GamesCache  *gc_clipboard,
  wxWindowID  id,
  const wxPoint& pos,
  const wxSize& size
  ) : GamesDialog( parent, NULL, gc, gc_clipboard, id, pos, size )
{
}

void PgnDialog::GdvListColClick( int compare_col_ )
{
    local_cache.clear();
    stack.clear();
    bool cancelled = false;

    // Load all games into memory
    int nbr = gc->gds.size();
    int old_percent = -1;
    void *context=0;
    bool end = false;
    if( compare_col_ == 0 )
        end = true; // we don't need to load into memory for column 0
    for( int i=0; !end && i<nbr; i++ )
    {

        // If all the games are already in memory, the whole loop will operate here
        if( !context )
            context = gc->gds[i]->LoadIntoMemory( context, i+1 >= nbr );

        // If we need to load games, put up a progress dialog box
        else
        {
            wxProgressDialog progress( "Loading games", "Loading games", 100, NULL,
                                      wxPD_APP_MODAL+
                                      wxPD_AUTO_HIDE+
                                      wxPD_ELAPSED_TIME+
                                      wxPD_CAN_ABORT+
                                      wxPD_ESTIMATED_TIME );
            for( ; !end && i<nbr; i++ )
            {
                end = (i+1 >= nbr);
                int percent = (i*100) / (nbr?nbr:1);
                if( percent < 1 )
                    percent = 1;
                if( percent != old_percent )
                {
                    old_percent = percent;
                    if( !progress.Update( percent>100 ? 100 : percent ) )
                    {
                        end = true;
                        cancelled = true;
                    }
                }
                context = gc->gds[i]->LoadIntoMemory( context, end );   // never exit without an end=true call
                                                                        //  prevents resource leaks
            }
        }
    }
    if( !cancelled )
        GamesDialog::GdvListColClick( compare_col_ );
}

bool PgnDialog::LoadGame( GameLogic *gl, GameDocument& gd )
{
    int selected_game_ = track->focus_idx;
    if( selected_game_ != -1 )
    {
		GameDocument *gd_file = gc->gds[selected_game_]->IsGameDocument();
		if( gd_file )
			gd = *gd_file;
		else
		{
			gc->gds[selected_game_]->ConvertToGameDocument(gd);
			make_smart_ptr(GameDocument, new_smart_ptr, gd);
			gc->gds[selected_game_] = std::move(new_smart_ptr);
		}

		// #Workflow)  Game pulled out of game dialog
		// if it's the working file dialog establish edit relationship
		if( gc == &gl->gc_pgn )
			gl->SetGameBeingEdited( gd, *gc->gds[selected_game_] );
        gd.SetNonZeroStartPosition(track->focus_offset);
    }
    return selected_game_ != -1;
}

int PgnDialog::GetSelectedGame( int *offset )
{
	*offset = track->focus_offset;
    return track->focus_idx;
}
<commit_msg>Extend ID_PGN_DIALOG_FILE specialisation to include new ID_PGN_DIALOG_CURRENT_FILE as well<commit_after>/****************************************************************************
 * Custom dialog - Pgn browser
 *  Author:  Bill Forster
 *  License: MIT license. Full text of license is in associated file LICENSE
 *  Copyright 2010-2014, Bill Forster <billforsternz at gmail dot com>
 ****************************************************************************/
#include "wx/wx.h"
#include "wx/valtext.h"
#include "wx/valgen.h"
#include "wx/listctrl.h"
#include "Portability.h"
#include "Appdefs.h"
#include "DebugPrintf.h"
#include "thc.h"
#include "GameDetailsDialog.h"
#include "GamePrefixDialog.h"
#include "GameLogic.h"
#include "Objects.h"
#include "CtrlChessBoard.h"
#include "PgnFiles.h"
#include "PgnDialog.h"
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;

void PgnDialog::GdvEnumerateGames()
{
}

wxSizer *PgnDialog::GdvAddExtraControls( bool WXUNUSED(big_display) )
{
    if( id==ID_PGN_DIALOG_FILE || id==ID_PGN_DIALOG_CURRENT_FILE )
    {
        // Edit game details
        wxButton* edit_game_details = new wxButton ( this, ID_PGN_DIALOG_GAME_DETAILS, wxT("Edit Game Details"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( edit_game_details );
        vsiz_panel_buttons->Add(edit_game_details, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Edit game prefix
        //wxButton* edit_game_prefix = new wxButton ( this, ID_PGN_DIALOG_GAME_PREFIX, wxT("Edit Game Prefix"),
        //    wxDefaultPosition, wxDefaultSize, 0 );
        //vsiz_panel_buttons->Add(edit_game_prefix, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Paste game / Board->Game
        wxButton* board2game = new wxButton ( this, ID_BOARD2GAME, wxT("Paste current game"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( board2game );
        vsiz_panel_buttons->Add(board2game, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Delete
        wxButton* delete_ = new wxButton ( this, wxID_DELETE, wxT("Delete"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( delete_ );
        vsiz_panel_buttons->Add(delete_, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Cut
        wxButton* cut = new wxButton ( this, wxID_CUT, wxT("Cut"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( cut );
        vsiz_panel_buttons->Add(cut, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Add to clipboard
        wxButton* add = new wxButton ( this, ID_ADD_TO_CLIPBOARD, wxT("Add to clipboard"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( add );
        vsiz_panel_buttons->Add(add, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Copy
        wxButton* copy = new wxButton ( this, wxID_COPY, wxT("Copy"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( copy );
        vsiz_panel_buttons->Add(copy, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Paste
        wxButton* paste = new wxButton ( this, wxID_PASTE, wxT("Paste"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( paste );
        vsiz_panel_buttons->Add(paste, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Publish
        wxButton* publish = new wxButton ( this, ID_PGN_DIALOG_PUBLISH, wxT("Publish"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( publish );
        vsiz_panel_buttons->Add(publish, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // ECO codes
        wxButton* eco_codes = new wxButton ( this, ID_DIALOG_ECO, wxT("ECO codes"),
            wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( eco_codes );
        vsiz_panel_buttons->Add(eco_codes, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
    }
    else if( id == ID_PGN_DIALOG_CLIPBOARD )
    {
        // Edit game details
        wxButton* edit_game_details = new wxButton ( this, ID_PGN_DIALOG_GAME_DETAILS, wxT("Edit Game Details"),
                                                    wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( edit_game_details );
        vsiz_panel_buttons->Add(edit_game_details, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Paste game / Board->Game
        wxButton* board2game = new wxButton ( this, ID_BOARD2GAME, wxT("Paste current game"),
                                             wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( board2game );
        vsiz_panel_buttons->Add(board2game, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Delete
        wxButton* delete_ = new wxButton ( this, wxID_DELETE, wxT("Delete"),
                                          wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( delete_ );
        vsiz_panel_buttons->Add(delete_, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    }
    else if( id == ID_PGN_DIALOG_SESSION )
    {
        // Add to clipboard
        wxButton* add = new wxButton ( this, ID_ADD_TO_CLIPBOARD, wxT("Add to clipboard"),
                                      wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( add );
        vsiz_panel_buttons->Add(add, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

        // Copy
        wxButton* copy = new wxButton ( this, wxID_COPY, wxT("Copy"),
                                       wxDefaultPosition, wxDefaultSize, 0 );
        gdr.RegisterPanelWindow( copy );
        vsiz_panel_buttons->Add(copy, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    }
    return vsiz_panel_buttons;
}

void PgnDialog::GetCachedDocumentRaw( int idx, GameDocument &gd )
{
    smart_ptr<ListableGame> &mb = gc->gds[idx];
    mb->ConvertToGameDocument(gd);
}

GameDocument * PgnDialog::GetCachedDocument( int idx )
{
    static GameDocument gd;
    CompactGame pact;
    smart_ptr<ListableGame> &mb = gc->gds[idx];
    mb->GetCompactGame(pact);
    pact.Upscale( gd );
    return &gd;
}

void PgnDialog::GdvReadItem( int item, CompactGame &info )
{
    if( 0<=item && static_cast<unsigned int>(item)<gc->gds.size() )
    {
        smart_ptr<ListableGame> &mb = gc->gds[item];
        mb->GetCompactGame( info );
    }
}

void PgnDialog::GdvHelpClick()
{
    wxString helpText;
    if( id==ID_PGN_DIALOG_FILE || id==ID_PGN_DIALOG_CURRENT_FILE )
        helpText=
    "\nUse this panel to preview the games in a .pgn file."
    "\n\n"
    "You can sort on any column. The first column (column '#') is provided only to allow "
    "a sort on initial order (for restoring or reversing the initial order). To reverse "
	"sort click twice. The moves column sort is statistical (most popular lines first) "
	"rather than alphabetical. Sort history is respected in tie breaks. For example, if you "
	"sort on Moves, then on Black, then on White; The games will be sorted by White "
	"player, but all opponents will be grouped together (because of the earlier sort on Black), "
	"and if there are multiple games between the same players, the games will be sorted according "
	"to the most common opening sequences between those two players (because of the earlier sort on Moves)."
    "\n\n"
    "Two special features are provided at the moment. ECO calculates ECO codes for games "
    "which do not have them yet."
    "\n\n"
    "The Publish button is used to create interactive web content. This is still under "
    "development and should be treated as an extra-for-experts. There is a file "
    "named web.zip in your Tarrasch installation directory with supplementary files "
    "and instructions for the keen and well motivated.";

    else if( id == ID_PGN_DIALOG_CLIPBOARD )
        helpText=
    "\nUse this panel to look at games in the clipboard. Games can be copied to the clipboard "
    "from any of the Current file, Session or Database games dialogs, all available from the "
    "Games menu."
    "\n\n"
    "You can sort on any column. The first column (column '#') is provided only to allow "
    "a sort on initial order (for restoring or reversing the initial order). To reverse "
	"sort click twice. The moves column sort is statistical (most popular lines first) "
	"rather than alphabetical. Sort history is respected in tie breaks. For example, if you "
	"sort on Moves, then on Black, then on White; The games will be sorted by White "
	"player, but all opponents will be grouped together (because of the earlier sort on Black), "
	"and if there are multiple games between the same players, the games will be sorted according "
	"to the most common opening sequences between those two players (because of the earlier sort on Moves).";

    else if( id == ID_PGN_DIALOG_SESSION )
        helpText=
    "\nUse this panel to look at games you have worked with in this Tarrasch Chess GUI session."
    "\n\n"
    "You can sort on any column. The first column (column '#') is provided only to allow "
    "a sort on initial order (for restoring or reversing the initial order). To reverse "
	"sort click twice. The moves column sort is statistical (most popular lines first) "
	"rather than alphabetical. Sort history is respected in tie breaks. For example, if you "
	"sort on Moves, then on Black, then on White; The games will be sorted by White "
	"player, but all opponents will be grouped together (because of the earlier sort on Black), "
	"and if there are multiple games between the same players, the games will be sorted according "
	"to the most common opening sequences between those two players (because of the earlier sort on Moves).";
    wxMessageBox(helpText,
    wxT("Games Dialog Help"),
    wxOK|wxICON_INFORMATION, NULL );
}

void PgnDialog::GdvSearch() {}
void PgnDialog::GdvUtility() {}
void PgnDialog::GdvOnCancel() {}
void PgnDialog::GdvNextMove( int UNUSED(idx) ) {}

// PgnDialog constructors
PgnDialog::PgnDialog
 (
  wxWindow    *parent,
  GamesCache  *gc,
  GamesCache  *gc_clipboard,
  wxWindowID  id,
  const wxPoint& pos,
  const wxSize& size
  ) : GamesDialog( parent, NULL, gc, gc_clipboard, id, pos, size )
{
}

void PgnDialog::GdvListColClick( int compare_col_ )
{
    local_cache.clear();
    stack.clear();
    bool cancelled = false;

    // Load all games into memory
    int nbr = gc->gds.size();
    int old_percent = -1;
    void *context=0;
    bool end = false;
    if( compare_col_ == 0 )
        end = true; // we don't need to load into memory for column 0
    for( int i=0; !end && i<nbr; i++ )
    {

        // If all the games are already in memory, the whole loop will operate here
        if( !context )
            context = gc->gds[i]->LoadIntoMemory( context, i+1 >= nbr );

        // If we need to load games, put up a progress dialog box
        else
        {
            wxProgressDialog progress( "Loading games", "Loading games", 100, NULL,
                                      wxPD_APP_MODAL+
                                      wxPD_AUTO_HIDE+
                                      wxPD_ELAPSED_TIME+
                                      wxPD_CAN_ABORT+
                                      wxPD_ESTIMATED_TIME );
            for( ; !end && i<nbr; i++ )
            {
                end = (i+1 >= nbr);
                int percent = (i*100) / (nbr?nbr:1);
                if( percent < 1 )
                    percent = 1;
                if( percent != old_percent )
                {
                    old_percent = percent;
                    if( !progress.Update( percent>100 ? 100 : percent ) )
                    {
                        end = true;
                        cancelled = true;
                    }
                }
                context = gc->gds[i]->LoadIntoMemory( context, end );   // never exit without an end=true call
                                                                        //  prevents resource leaks
            }
        }
    }
    if( !cancelled )
        GamesDialog::GdvListColClick( compare_col_ );
}

bool PgnDialog::LoadGame( GameLogic *gl, GameDocument& gd )
{
    int selected_game_ = track->focus_idx;
    if( selected_game_ != -1 )
    {
		GameDocument *gd_file = gc->gds[selected_game_]->IsGameDocument();
		if( gd_file )
			gd = *gd_file;
		else
		{
			gc->gds[selected_game_]->ConvertToGameDocument(gd);
			make_smart_ptr(GameDocument, new_smart_ptr, gd);
			gc->gds[selected_game_] = std::move(new_smart_ptr);
		}

		// #Workflow)  Game pulled out of game dialog
		// if it's the working file dialog establish edit relationship
		if( gc == &gl->gc_pgn )
			gl->SetGameBeingEdited( gd, *gc->gds[selected_game_] );
        gd.SetNonZeroStartPosition(track->focus_offset);
    }
    return selected_game_ != -1;
}

int PgnDialog::GetSelectedGame( int *offset )
{
	*offset = track->focus_offset;
    return track->focus_idx;
}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreStableHeaders.h"

#include "OgreDualQuaternion.h"

#include "OgreMath.h"
#include "OgreMatrix3.h"
#include "OgreVector3.h"

namespace Ogre {

	//Based on dqconv.c from http://isg.cs.tcd.ie/projects/DualQuaternions/
	//-----------------------------------------------------------------------
	void DualQuaternion::FromRotationTranslation (const Quaternion& q, const Vector3& trans)
	{
		// non-dual part (just copy the quaternion):
		w = q.w;
		x = q.x;
		y = q.y;
		z = q.z;

		// dual part:
		Real half = 0.5;
		dw = -half *  (trans.x * x + trans.y * y + trans.z * z );
		dx =  half *  (trans.x * w + trans.y * z - trans.z * y );
		dy =  half * (-trans.x * z + trans.y * w + trans.z * x );
		dz =  half *  (trans.x * y - trans.y * x + trans.z * w );
	}

	//Based on dqconv.c from http://isg.cs.tcd.ie/projects/DualQuaternions/
	//-----------------------------------------------------------------------
	void DualQuaternion::ToRotationTranslation (Quaternion& q, Vector3& translation) const
	{
		// regular quaternion (just copy the non-dual part):
		q.w = w;
		q.x = x;
		q.y = y;
		q.z = z;

		// translation vector:
		Real doub = 2.0;
		translation.x = doub * (-dw*x + dx*w - dy*z + dz*y);
		translation.y = doub * (-dw*y + dx*z + dy*w - dz*x);
		translation.z = doub * (-dw*z - dx*y + dy*x + dz*w);
	}

	//-----------------------------------------------------------------------
	void DualQuaternion::FromTransformationMatrix (const Matrix4& kTrans)
	{
		Vector3 pos;
		Vector3 scale;
		Quaternion rot;

		kTrans.decomposition(pos, scale, rot);
		FromRotationTranslation(rot, pos);
	}

	//-----------------------------------------------------------------------
	void DualQuaternion::ToTransformationMatrix (Matrix4& kTrans) const
	{
		Vector3 pos;
		Vector3 scale;
		Quaternion rot;

		ToRotationTranslation(rot, pos);
		kTrans.makeTransform(pos, scale, rot);
	}
}<commit_msg>Fixed DualQuaternion::ToTransformationMatrix to use Unit Scale instead of a zero vector for a scale factor.<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2009 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreStableHeaders.h"

#include "OgreDualQuaternion.h"

#include "OgreMath.h"
#include "OgreMatrix3.h"
#include "OgreVector3.h"

namespace Ogre {

	//Based on dqconv.c from http://isg.cs.tcd.ie/projects/DualQuaternions/
	//-----------------------------------------------------------------------
	void DualQuaternion::FromRotationTranslation (const Quaternion& q, const Vector3& trans)
	{
		// non-dual part (just copy the quaternion):
		w = q.w;
		x = q.x;
		y = q.y;
		z = q.z;

		// dual part:
		Real half = 0.5;
		dw = -half *  (trans.x * x + trans.y * y + trans.z * z );
		dx =  half *  (trans.x * w + trans.y * z - trans.z * y );
		dy =  half * (-trans.x * z + trans.y * w + trans.z * x );
		dz =  half *  (trans.x * y - trans.y * x + trans.z * w );
	}

	//Based on dqconv.c from http://isg.cs.tcd.ie/projects/DualQuaternions/
	//-----------------------------------------------------------------------
	void DualQuaternion::ToRotationTranslation (Quaternion& q, Vector3& translation) const
	{
		// regular quaternion (just copy the non-dual part):
		q.w = w;
		q.x = x;
		q.y = y;
		q.z = z;

		// translation vector:
		Real doub = 2.0;
		translation.x = doub * (-dw*x + dx*w - dy*z + dz*y);
		translation.y = doub * (-dw*y + dx*z + dy*w - dz*x);
		translation.z = doub * (-dw*z - dx*y + dy*x + dz*w);
	}

	//-----------------------------------------------------------------------
	void DualQuaternion::FromTransformationMatrix (const Matrix4& kTrans)
	{
		Vector3 pos;
		Vector3 scale;
		Quaternion rot;

		kTrans.decomposition(pos, scale, rot);
		FromRotationTranslation(rot, pos);
	}

	//-----------------------------------------------------------------------
	void DualQuaternion::ToTransformationMatrix (Matrix4& kTrans) const
	{
		Vector3 pos;
		Quaternion rot;
		ToRotationTranslation(rot, pos);

		Vector3 scale = Vector3::UNIT_SCALE;
		kTrans.makeTransform(pos, scale, rot);
	}
}<|endoftext|>


<commit_before>#ifndef SILICIUM_REACTIVE_VARIANT_HPP
#define SILICIUM_REACTIVE_VARIANT_HPP

#include <reactive/observable.hpp>
#include <reactive/exchange.hpp>
#include <reactive/config.hpp>
#include <silicium/fast_variant.hpp>
#include "detail/integer_sequence.hpp"

namespace rx
{
#define SILICIUM_RX_VARIANT_AVAILABLE !SILICIUM_BROKEN_VARIADIC_TEMPLATE_EXPANSION

#if SILICIUM_RX_VARIANT_AVAILABLE
	template <template <class ...T> class variant, class ...Parts>
	struct alternative : public rx::observable<variant<typename Parts::element_type...>>
	{
		typedef variant<typename Parts::element_type...> element_type;

		template <class ...P>
		explicit alternative(P &&...parts)
			: parts(std::forward<P>(parts)...)
		{
		}

		virtual void async_get_one(rx::observer<element_type> &receiver) SILICIUM_OVERRIDE
		{
			assert(!receiver_);
			receiver_ = &receiver;
			return async_get_one_impl<0, Parts...>();
		}

		virtual void cancel() SILICIUM_OVERRIDE
		{
			assert(receiver_);
			cancel_impl<0, sizeof...(Parts)>();
			receiver_ = nullptr;
		}

	private:

		template <class Element, std::size_t Index>
		struct tuple_observer : observer<Element>
		{
			alternative *combinator = nullptr;

			virtual void got_element(Element value) SILICIUM_OVERRIDE
			{
				cancel_others();
				rx::exchange(combinator->receiver_, nullptr)->got_element(element_type{std::move(value)});
			}

			virtual void ended() SILICIUM_OVERRIDE
			{
				cancel_others();
				rx::exchange(combinator->receiver_, nullptr)->ended();
			}

		private:

			void cancel_others()
			{
				combinator->cancel_impl<0, Index>();
				combinator->cancel_impl<Index + 1, sizeof...(Parts)>();
			}
		};

		template <class Indices>
		struct make_observers;

		template <std::size_t ...I>
		struct make_observers<ranges::v3::integer_sequence<I...>>
		{
			typedef std::tuple<tuple_observer<typename Parts::element_type, I>...> type;
		};

		typedef typename make_observers<typename ranges::v3::make_integer_sequence<sizeof...(Parts)>::type>::type observers_type;

		std::tuple<Parts...> parts;
		observers_type observers;
		rx::observer<element_type> *receiver_ = nullptr;

		template <std::size_t Index, class Head, class ...Tail>
		void async_get_one_impl()
		{
			auto &observer = std::get<Index>(observers);
			observer.combinator = this;
			auto &part = std::get<Index>(parts);
			part.async_get_one(observer);
			return async_get_one_impl<Index + 1, Tail...>();
		}

		template <std::size_t Index>
		void async_get_one_impl()
		{
		}

		template <std::size_t Begin, std::size_t End>
		void cancel_impl()
		{
			return cancel_impl<Begin, End>(std::integral_constant<bool, (Begin < End)>());
		}

		template <std::size_t Begin, std::size_t End>
		void cancel_impl(std::true_type)
		{
			assert(receiver_);
			auto &part = std::get<Begin>(parts);
			part.cancel();
			return cancel_impl<Begin + 1, End>();
		}

		template <std::size_t Begin, std::size_t End>
		void cancel_impl(std::false_type)
		{
		}
	};

	template <class ...Parts>
	auto make_variant(Parts &&...parts) -> alternative<Si::fast_variant, typename std::decay<Parts>::type...>
	{
		return alternative<Si::fast_variant, typename std::decay<Parts>::type...>(std::forward<Parts>(parts)...);
	}

	template <template <class ...T> class variant, class ...Parts>
	auto make_variant(Parts &&...parts) -> alternative<variant, typename std::decay<Parts>::type...>
	{
		return alternative<variant, typename std::decay<Parts>::type...>(std::forward<Parts>(parts)...);
	}
#endif
}

#endif
<commit_msg>make an include conform to project conventions<commit_after>#ifndef SILICIUM_REACTIVE_VARIANT_HPP
#define SILICIUM_REACTIVE_VARIANT_HPP

#include <reactive/observable.hpp>
#include <reactive/exchange.hpp>
#include <reactive/config.hpp>
#include <reactive/detail/integer_sequence.hpp>
#include <silicium/fast_variant.hpp>

namespace rx
{
#define SILICIUM_RX_VARIANT_AVAILABLE !SILICIUM_BROKEN_VARIADIC_TEMPLATE_EXPANSION

#if SILICIUM_RX_VARIANT_AVAILABLE
	template <template <class ...T> class variant, class ...Parts>
	struct alternative : public rx::observable<variant<typename Parts::element_type...>>
	{
		typedef variant<typename Parts::element_type...> element_type;

		template <class ...P>
		explicit alternative(P &&...parts)
			: parts(std::forward<P>(parts)...)
		{
		}

		virtual void async_get_one(rx::observer<element_type> &receiver) SILICIUM_OVERRIDE
		{
			assert(!receiver_);
			receiver_ = &receiver;
			return async_get_one_impl<0, Parts...>();
		}

		virtual void cancel() SILICIUM_OVERRIDE
		{
			assert(receiver_);
			cancel_impl<0, sizeof...(Parts)>();
			receiver_ = nullptr;
		}

	private:

		template <class Element, std::size_t Index>
		struct tuple_observer : observer<Element>
		{
			alternative *combinator = nullptr;

			virtual void got_element(Element value) SILICIUM_OVERRIDE
			{
				cancel_others();
				rx::exchange(combinator->receiver_, nullptr)->got_element(element_type{std::move(value)});
			}

			virtual void ended() SILICIUM_OVERRIDE
			{
				cancel_others();
				rx::exchange(combinator->receiver_, nullptr)->ended();
			}

		private:

			void cancel_others()
			{
				combinator->cancel_impl<0, Index>();
				combinator->cancel_impl<Index + 1, sizeof...(Parts)>();
			}
		};

		template <class Indices>
		struct make_observers;

		template <std::size_t ...I>
		struct make_observers<ranges::v3::integer_sequence<I...>>
		{
			typedef std::tuple<tuple_observer<typename Parts::element_type, I>...> type;
		};

		typedef typename make_observers<typename ranges::v3::make_integer_sequence<sizeof...(Parts)>::type>::type observers_type;

		std::tuple<Parts...> parts;
		observers_type observers;
		rx::observer<element_type> *receiver_ = nullptr;

		template <std::size_t Index, class Head, class ...Tail>
		void async_get_one_impl()
		{
			auto &observer = std::get<Index>(observers);
			observer.combinator = this;
			auto &part = std::get<Index>(parts);
			part.async_get_one(observer);
			return async_get_one_impl<Index + 1, Tail...>();
		}

		template <std::size_t Index>
		void async_get_one_impl()
		{
		}

		template <std::size_t Begin, std::size_t End>
		void cancel_impl()
		{
			return cancel_impl<Begin, End>(std::integral_constant<bool, (Begin < End)>());
		}

		template <std::size_t Begin, std::size_t End>
		void cancel_impl(std::true_type)
		{
			assert(receiver_);
			auto &part = std::get<Begin>(parts);
			part.cancel();
			return cancel_impl<Begin + 1, End>();
		}

		template <std::size_t Begin, std::size_t End>
		void cancel_impl(std::false_type)
		{
		}
	};

	template <class ...Parts>
	auto make_variant(Parts &&...parts) -> alternative<Si::fast_variant, typename std::decay<Parts>::type...>
	{
		return alternative<Si::fast_variant, typename std::decay<Parts>::type...>(std::forward<Parts>(parts)...);
	}

	template <template <class ...T> class variant, class ...Parts>
	auto make_variant(Parts &&...parts) -> alternative<variant, typename std::decay<Parts>::type...>
	{
		return alternative<variant, typename std::decay<Parts>::type...>(std::forward<Parts>(parts)...);
	}
#endif
}

#endif
<|endoftext|>


<commit_before>#include "PublicKey.hpp"

#include <algorithm>

namespace BitCrypto{

PublicKey::PublicKey()
{}

PublicKey::PublicKey(const Secp256k1ContextPtr &context) :
    LazySecp256k1Handler(context)
{}

PublicKey::PublicKey(const PublicKey &copy) :
    LazySecp256k1Handler(copy.getContext())
{
    std::copy(copy._data.data, copy._data.data+33, _data.data);
}

PublicKey::PublicKey(const Data &bin)
{
    std::copy(bin.begin(), bin.begin()+33, _data.data);
}

PublicKey::PublicKey(const Data &bin, const Secp256k1ContextPtr &context) :
    LazySecp256k1Handler(context)
{
    std::copy(bin.begin(), bin.begin()+33, _data.data);
}

PublicKey::operator secp256k1_pubkey & ()
{
    return _data;
}

PublicKey::operator const secp256k1_pubkey & () const
{
    return _data;
}

secp256k1_pubkey * PublicKey::operator & ()
{
    return &_data;
}

const secp256k1_pubkey * PublicKey::operator & () const
{
    return &_data;
}

const uint8_t * PublicKey::getData() const
{
    return _data.data;
}

uint8_t PublicKey::operator [](int i) const
{
    return _data.data[i];
}

PublicKey::Iterator PublicKey::begin()
{
    return _data.data;
}

PublicKey::Iterator PublicKey::end()
{
    return _data.data+33;
}

PublicKey::ConstIterator PublicKey::begin() const
{
    return _data.data;
}

PublicKey::ConstIterator PublicKey::end() const
{
    return _data.data+33;
}

PublicKey PublicKey::operator + (const PublicKey &key)
{
    PublicKey result(getContext());
    const secp256k1_pubkey * keys[2] = {&_data, &key._data};
    if(!secp256k1_ec_pubkey_combine(getContext().get(), &result, keys, 2))
    {
        throw std::runtime_error("PublicKey operation failed");
    }
    return result;
}

PublicKey PublicKey::operator + (const PrivateKey &secret)
{
    PublicKey result(*this);
    if(!secp256k1_ec_pubkey_tweak_add(getContext().get(), &result, secret.data()))
    {
        throw std::runtime_error("PublicKey operation failed");
    }

    return result;
}

PublicKey PublicKey::operator * (const PrivateKey &secret)
{
    PublicKey result(*this);
    if(!secp256k1_ec_pubkey_tweak_mul(getContext().get(), &result, secret.data()))
    {
        throw std::runtime_error("PublicKey operation failed");
    }
    return result;
}

//

PublicKey & PublicKey::operator += (const PublicKey &key)
{
    PublicKey result(getContext());
    const secp256k1_pubkey * keys[2] = {&_data, &key._data};
    if(!secp256k1_ec_pubkey_combine(getContext().get(), &result, keys, 2))
    {
        throw std::runtime_error("PublicKey operation failed");
    }
    *this = result;
    return *this;
}

PublicKey & PublicKey::operator += (const PrivateKey &secret)
{
    if(!secp256k1_ec_pubkey_tweak_add(getContext().get(), &_data, secret.data()))
    {
        throw std::runtime_error("PublicKey operation failed");
    }

    return *this;
}

PublicKey & PublicKey::operator *= (const PrivateKey &secret)
{
    if(!secp256k1_ec_pubkey_tweak_mul(getContext().get(), &_data, secret.data()))
    {
        throw std::runtime_error("PublicKey operation failed");
    }

    return *this;
}

PublicKey & PublicKey::operator = (const PublicKey &key)
{
    std::copy(key._data.data, key._data.data+33, _data.data);
    return *this;
}

}
<commit_msg>public key truncation bug<commit_after>#include "PublicKey.hpp"

#include <algorithm>

namespace BitCrypto{

PublicKey::PublicKey()
{}

PublicKey::PublicKey(const Secp256k1ContextPtr &context) :
    LazySecp256k1Handler(context)
{}

PublicKey::PublicKey(const PublicKey &copy) :
    LazySecp256k1Handler(copy.getContext())
{
    std::copy(copy._data.data, copy._data.data+64, _data.data);
}

PublicKey::PublicKey(const Data &bin)
{
    std::copy(bin.begin(), bin.begin()+64, _data.data);
}

PublicKey::PublicKey(const Data &bin, const Secp256k1ContextPtr &context) :
    LazySecp256k1Handler(context)
{
    std::copy(bin.begin(), bin.begin()+64, _data.data);
}

PublicKey::operator secp256k1_pubkey & ()
{
    return _data;
}

PublicKey::operator const secp256k1_pubkey & () const
{
    return _data;
}

secp256k1_pubkey * PublicKey::operator & ()
{
    return &_data;
}

const secp256k1_pubkey * PublicKey::operator & () const
{
    return &_data;
}

const uint8_t * PublicKey::getData() const
{
    return _data.data;
}

uint8_t PublicKey::operator [](int i) const
{
    return _data.data[i];
}

PublicKey::Iterator PublicKey::begin()
{
    return _data.data;
}

PublicKey::Iterator PublicKey::end()
{
    return _data.data+33;
}

PublicKey::ConstIterator PublicKey::begin() const
{
    return _data.data;
}

PublicKey::ConstIterator PublicKey::end() const
{
    return _data.data+33;
}

PublicKey PublicKey::operator + (const PublicKey &key)
{
    PublicKey result(getContext());
    const secp256k1_pubkey * keys[2] = {&_data, &key._data};
    if(!secp256k1_ec_pubkey_combine(getContext().get(), &result, keys, 2))
    {
        throw std::runtime_error("PublicKey operation failed");
    }
    return result;
}

PublicKey PublicKey::operator + (const PrivateKey &secret)
{
    PublicKey result(*this);
    if(!secp256k1_ec_pubkey_tweak_add(getContext().get(), &result, secret.data()))
    {
        throw std::runtime_error("PublicKey operation failed");
    }

    return result;
}

PublicKey PublicKey::operator * (const PrivateKey &secret)
{
    PublicKey result(*this);
    if(!secp256k1_ec_pubkey_tweak_mul(getContext().get(), &result, secret.data()))
    {
        throw std::runtime_error("PublicKey operation failed");
    }
    return result;
}

//

PublicKey & PublicKey::operator += (const PublicKey &key)
{
    PublicKey result(getContext());
    const secp256k1_pubkey * keys[2] = {&_data, &key._data};
    if(!secp256k1_ec_pubkey_combine(getContext().get(), &result, keys, 2))
    {
        throw std::runtime_error("PublicKey operation failed");
    }
    *this = result;
    return *this;
}

PublicKey & PublicKey::operator += (const PrivateKey &secret)
{
    if(!secp256k1_ec_pubkey_tweak_add(getContext().get(), &_data, secret.data()))
    {
        throw std::runtime_error("PublicKey operation failed");
    }

    return *this;
}

PublicKey & PublicKey::operator *= (const PrivateKey &secret)
{
    if(!secp256k1_ec_pubkey_tweak_mul(getContext().get(), &_data, secret.data()))
    {
        throw std::runtime_error("PublicKey operation failed");
    }

    return *this;
}

PublicKey & PublicKey::operator = (const PublicKey &key)
{
    std::copy(key._data.data, key._data.data+33, _data.data);
    return *this;
}

}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_FUN_ELT_MULTIPLY_HPP
#define STAN_MATH_REV_FUN_ELT_MULTIPLY_HPP

#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/eval.hpp>
#include <stan/math/rev/core.hpp>

namespace stan {
namespace math {

/**
 * Return the elementwise multiplication of the specified
 * matrices.
 *
 * @tparam Mat1 type of the first matrix or expression
 * @tparam Mat2 type of the second matrix or expression
 *
 * @param m1 First matrix or expression
 * @param m2 Second matrix or expression
 * @return Elementwise product of matrices.
 */
template <typename Mat1, typename Mat2,
    require_all_matrix_t<Mat1, Mat2>* = nullptr,
    require_any_rev_matrix_t<Mat1, Mat2>* = nullptr>
auto elt_multiply(const Mat1& m1, const Mat2& m2) {
  const auto& m1_ref = to_ref(m1);
  const auto& m2_ref = to_ref(m2);
  check_matching_dims("elt_multiply", "m1", m1_ref, "m2", m2_ref);
  using inner_ret_type = decltype(value_of(m1_ref).cwiseProduct(value_of(m2_ref)));
  using ret_type = promote_var_matrix_t<inner_ret_type, Mat1, Mat2>;
  if (!is_constant<Mat1>::value && !is_constant<Mat2>::value) {
    arena_t<Mat1> arena_m1 = m1_ref;
    arena_t<Mat2> arena_m2 = m2_ref;
    arena_t<promote_scalar_t<double, Mat1>> arena_val_m1 = value_of(arena_m1);
    arena_t<promote_scalar_t<double, Mat2>> arena_val_m2 = value_of(arena_m2);
    arena_t<ret_type> ret(arena_val_m1.cwiseProduct(arena_val_m2));
    reverse_pass_callback([ret, arena_m1, arena_m2, arena_val_m1, arena_val_m2]() mutable {
      decltype(auto) ret_adj = eval(ret.adj());
      using var_m1 = arena_t<promote_scalar_t<var, Mat1>>;
      using var_m2 = arena_t<promote_scalar_t<var, Mat2>>;
      forward_as<var_m1>(arena_m1).adj().array() += arena_val_m2.array() * ret_adj.array();
      forward_as<var_m2>(arena_m2).adj().array() += arena_val_m1.array() * ret_adj.array();
    });
    return ret_type(ret);
  } else if (!is_constant<Mat1>::value) {
    arena_t<Mat1> arena_m1 = m1_ref;
    arena_t<promote_scalar_t<double, Mat2>> arena_m2 = value_of(m2_ref);
    arena_t<ret_type> ret(value_of(arena_m1).cwiseProduct(arena_m2));
    reverse_pass_callback([ret, arena_m1, arena_m2]() mutable {
      using var_m1 = arena_t<promote_scalar_t<var, Mat1>>;
      forward_as<var_m1>(arena_m1).adj().array() += arena_m2.array() * ret.adj().array();
    });
    return ret_type(ret);
  } else if (!is_constant<Mat2>::value) {
    arena_t<Mat2> arena_m2 = m2_ref;
    arena_t<promote_scalar_t<double, Mat1>> arena_m1 = value_of(m1_ref);
    arena_t<ret_type> ret(arena_m1.cwiseProduct(value_of(arena_m2)));
    reverse_pass_callback([ret, arena_m2, arena_m1]() mutable {
      using var_m2 = arena_t<promote_scalar_t<var, Mat2>>;
      forward_as<var_m2>(arena_m2).adj().array() += arena_m1.array() * ret.adj().array();
    });
    return ret_type(ret);
  }
}
}  // namespace math
}  // namespace stan

#endif
<commit_msg>use cwiseProduct() for rev version of elt_multiply<commit_after>#ifndef STAN_MATH_REV_FUN_ELT_MULTIPLY_HPP
#define STAN_MATH_REV_FUN_ELT_MULTIPLY_HPP

#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/eval.hpp>
#include <stan/math/rev/core.hpp>

namespace stan {
namespace math {

/**
 * Return the elementwise multiplication of the specified
 * matrices.
 *
 * @tparam Mat1 type of the first matrix or expression
 * @tparam Mat2 type of the second matrix or expression
 *
 * @param m1 First matrix or expression
 * @param m2 Second matrix or expression
 * @return Elementwise product of matrices.
 */
template <typename Mat1, typename Mat2,
    require_all_matrix_t<Mat1, Mat2>* = nullptr,
    require_any_rev_matrix_t<Mat1, Mat2>* = nullptr>
auto elt_multiply(const Mat1& m1, const Mat2& m2) {
  const auto& m1_ref = to_ref(m1);
  const auto& m2_ref = to_ref(m2);
  check_matching_dims("elt_multiply", "m1", m1_ref, "m2", m2_ref);
  using inner_ret_type = decltype(value_of(m1_ref).cwiseProduct(value_of(m2_ref)));
  using ret_type = promote_var_matrix_t<inner_ret_type, Mat1, Mat2>;
  if (!is_constant<Mat1>::value && !is_constant<Mat2>::value) {
    arena_t<Mat1> arena_m1 = m1_ref;
    arena_t<Mat2> arena_m2 = m2_ref;
    arena_t<promote_scalar_t<double, Mat1>> arena_val_m1 = value_of(arena_m1);
    arena_t<promote_scalar_t<double, Mat2>> arena_val_m2 = value_of(arena_m2);
    arena_t<ret_type> ret(arena_val_m1.cwiseProduct(arena_val_m2));
    reverse_pass_callback([ret, arena_m1, arena_m2, arena_val_m1, arena_val_m2]() mutable {
      decltype(auto) ret_adj = eval(ret.adj());
      using var_m1 = arena_t<promote_scalar_t<var, Mat1>>;
      using var_m2 = arena_t<promote_scalar_t<var, Mat2>>;
      forward_as<var_m1>(arena_m1).adj() += arena_val_m2.cwiseProduct(ret_adj);
      forward_as<var_m2>(arena_m2).adj() += arena_val_m1.cwiseProduct(ret_adj);
    });
    return ret_type(ret);
  } else if (!is_constant<Mat1>::value) {
    arena_t<Mat1> arena_m1 = m1_ref;
    arena_t<promote_scalar_t<double, Mat2>> arena_m2 = value_of(m2_ref);
    arena_t<ret_type> ret(value_of(arena_m1).cwiseProduct(arena_m2));
    reverse_pass_callback([ret, arena_m1, arena_m2]() mutable {
      using var_m1 = arena_t<promote_scalar_t<var, Mat1>>;
      forward_as<var_m1>(arena_m1).adj() += arena_m2.cwiseProduct(ret.adj());
    });
    return ret_type(ret);
  } else if (!is_constant<Mat2>::value) {
    arena_t<Mat2> arena_m2 = m2_ref;
    arena_t<promote_scalar_t<double, Mat1>> arena_m1 = value_of(m1_ref);
    arena_t<ret_type> ret(arena_m1.cwiseProduct(value_of(arena_m2)));
    reverse_pass_callback([ret, arena_m2, arena_m1]() mutable {
      using var_m2 = arena_t<promote_scalar_t<var, Mat2>>;
      forward_as<var_m2>(arena_m2).adj() += arena_m1.cwiseProduct(ret.adj());
    });
    return ret_type(ret);
  }
}
}  // namespace math
}  // namespace stan

#endif
<|endoftext|>


<commit_before>#include <string>
#include <SDL.h>
#include <lua.hpp>
#include "src/debug.h"
#include "src/image.h"
#include "src/animatedimage.h"
#include "src/text.h"
#include "src/window.h"
#include "luacscript.h"
#include "luacimage.h"
#include "luacrectf.h"
#include "luacvector2f.h"
#include "luacwindow.h"

int LuaC::WindowLib::luaopen_window(lua_State *l){
    //Stack: lib name
    //Register the library as global table "Window"
    luaL_register(l, windowClass.c_str(), luaWindowLib);
    openFlipEnum(l);
    return 0;
}
void LuaC::WindowLib::openFlipEnum(lua_State *l){
    //Stack: lib name, table
    lua_pushinteger(l, SDL_FLIP_NONE);
    lua_setfield(l, -2, "FLIP_NONE");
    lua_pushinteger(l, SDL_FLIP_HORIZONTAL);
    lua_setfield(l, -2, "FLIP_HORIZONTAL");
    lua_pushinteger(l, SDL_FLIP_VERTICAL);
    lua_setfield(l, -2, "FLIP_VERTICAL");
}
const struct luaL_reg LuaC::WindowLib::luaWindowLib[] = {
    { "draw", draw },
    { "box", getBox },
    { NULL, NULL }
};
int LuaC::WindowLib::draw(lua_State *l){
    /*
    *  Multiple possible stacks, the 3 we check here are:
    *  1. Image, other params
    *  2. AnimatedImage, other params
    *  3. Text, other params
    */
    std::string type = LuaScriptLib::readType(l, 1);
    //Case 1
    if (type.at(0) == 'I')
        DrawImage(l);
    else if (type.at(0) == 'A')
        DrawAnimatedImage(l);
    else if (type.at(0) == 'T')
        DrawText(l);
    else
        Debug::Log("WindowLib:draw Error: " + type + " is not drawable");
    return 0;
}
int LuaC::WindowLib::getBox(lua_State *l){
    Rectf r = Window::Box();
    RectfLib::Push(&r, l);
    return 1;
}
void LuaC::WindowLib::DrawImage(lua_State *l){
    /**
    *  3 Possible stacks:
    *  1. Image, Rectf destination
    *  2. Image, Rectf destination, Rectf clip
    *  3. Image, Rectf destination, Rectf clip, float rotation,
    *     Vector2f pivot, int flip value
    */
    std::shared_ptr<Image> *img = ImageLib::Check(l, 1);
    //Case 1:
    if (lua_gettop(l) == 2){
        Rectf *dst = RectfLib::Check(l, 2);
        Window::Draw(img->get(), *dst);
    }
    //Case 2:
    else if (lua_gettop(l) == 3){
        Rectf *dst = RectfLib::Check(l, 2);
        Rectf *clipf = RectfLib::Check(l, 3);
        Recti clip = *clipf;
        Window::Draw(img->get(), *dst, &clip);
    }
    else if (lua_gettop(l) == 6){
        Rectf *dst = RectfLib::Check(l, 2);
        Rectf *clipf = RectfLib::Check(l, 3);
        Recti clip = *clipf;
        float rotation = luaL_checknumber(l, 4);
        Vector2f *pivot = Vector2fLib::Check(l, 5);
        int flip = luaL_checkint(l, 6);
        Window::Draw(img->get(), *dst, &clip, rotation, *pivot, flip);
    }
}
void LuaC::WindowLib::DrawAnimatedImage(lua_State *l){

}
void LuaC::WindowLib::DrawText(lua_State *l){

}
<commit_msg>I need a conversion for Recti *r = Rectf* rb<commit_after>#include <string>
#include <SDL.h>
#include <lua.hpp>
#include "src/debug.h"
#include "src/image.h"
#include "src/animatedimage.h"
#include "src/text.h"
#include "src/window.h"
#include "luacscript.h"
#include "luacimage.h"
#include "luacrectf.h"
#include "luacvector2f.h"
#include "luacwindow.h"

int LuaC::WindowLib::luaopen_window(lua_State *l){
    //Stack: lib name
    //Register the library as global table "Window"
    luaL_register(l, windowClass.c_str(), luaWindowLib);
    openFlipEnum(l);
    return 0;
}
void LuaC::WindowLib::openFlipEnum(lua_State *l){
    //Stack: lib name, table
    lua_pushinteger(l, SDL_FLIP_NONE);
    lua_setfield(l, -2, "FLIP_NONE");
    lua_pushinteger(l, SDL_FLIP_HORIZONTAL);
    lua_setfield(l, -2, "FLIP_HORIZONTAL");
    lua_pushinteger(l, SDL_FLIP_VERTICAL);
    lua_setfield(l, -2, "FLIP_VERTICAL");
}
const struct luaL_reg LuaC::WindowLib::luaWindowLib[] = {
    { "draw", draw },
    { "box", getBox },
    { NULL, NULL }
};
int LuaC::WindowLib::draw(lua_State *l){
    /*
    *  Multiple possible stacks, the 3 we check here are:
    *  1. Image, other params
    *  2. AnimatedImage, other params
    *  3. Text, other params
    */
    std::string type = LuaScriptLib::readType(l, 1);
    //Case 1
    if (type.at(0) == 'I')
        DrawImage(l);
    //Case 2
    else if (type.at(0) == 'A')
        DrawAnimatedImage(l);
    //Case 3
    else if (type.at(0) == 'T')
        DrawText(l);
    else
        Debug::Log("WindowLib:draw Error: " + type + " is not drawable");

    return 0;
}
int LuaC::WindowLib::getBox(lua_State *l){
    RectfLib::Push(&Window::Box(), l);
    return 1;
}
void LuaC::WindowLib::DrawImage(lua_State *l){
    /**
    *  3 Possible stacks:
    *  1. Image, Rectf destination
    *  2. Image, Rectf destination, Rectf clip
    *  3. Image, Rectf destination, Rectf clip, float rotation,
    *     Vector2f pivot, int flip value
    */
    std::shared_ptr<Image> *img = ImageLib::Check(l, 1);
    //Case 1:
    if (lua_gettop(l) == 2){
        Rectf *dst = RectfLib::Check(l, 2);
        Window::Draw(img->get(), *dst);
    }
    //Case 2:
    else if (lua_gettop(l) == 3){
        Rectf *dst = RectfLib::Check(l, 2);
        Rectf *clipf = RectfLib::Check(l, 3);
        Recti clip = *clipf;
        Window::Draw(img->get(), *dst, &clip);
    }
    else if (lua_gettop(l) == 6){
        Rectf *dst = RectfLib::Check(l, 2);
        Rectf *clipf = RectfLib::Check(l, 3);
        Recti clip = *clipf;
        float rotation = luaL_checknumber(l, 4);
        Vector2f *pivot = Vector2fLib::Check(l, 5);
        int flip = luaL_checkint(l, 6);
        Window::Draw(img->get(), *dst, &clip, rotation, *pivot, flip);
    }
}
void LuaC::WindowLib::DrawAnimatedImage(lua_State *l){

}
void LuaC::WindowLib::DrawText(lua_State *l){

}
<|endoftext|>