<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgViewer/GraphicsWindowWin32>

using namespace osgViewer;

namespace osgViewer
{

/** This is the class we need to create for pbuffers, note its not a GraphicsWindow as it won't need any of the event handling and window mapping facilities.*/
class GraphicsContextWin32 : public osg::GraphicsContext
{
    public:

        GraphicsContextWin32(osg::GraphicsContext::Traits* traits):
            _valid(false)
        {
            _traits = traits;
        }

        virtual bool valid() const { return _valid; }

        /** Realise the GraphicsContext implementation,
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual bool realizeImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow::realizeImplementation() not implemented."<<std::endl; return false; }

        /** Return true if the graphics context has been realised, and is ready to use, implementation.
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual bool isRealizedImplementation() const  { osg::notify(osg::NOTICE)<<"GraphicsWindow::isRealizedImplementation() not implemented."<<std::endl; return false; }

        /** Close the graphics context implementation.
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual void closeImplementation()  { osg::notify(osg::NOTICE)<<"GraphicsWindow::closeImplementation() not implemented."<<std::endl; }

        /** Make this graphics context current implementation.
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual bool makeCurrentImplementation()  { osg::notify(osg::NOTICE)<<"GraphicsWindow::makeCurrentImplementation() not implemented."<<std::endl; return false; }

        /** Make this graphics context current with specified read context implementation.
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual bool makeContextCurrentImplementation(GraphicsContext* /*readContext*/)  { osg::notify(osg::NOTICE)<<"GraphicsWindow::makeContextCurrentImplementation(..) not implemented."<<std::endl; return false;}

        /** Release the graphics context.*/
        virtual bool releaseContextImplementation() {  osg::notify(osg::NOTICE)<<"GraphicsWindow::releaseContextImplementation(..) not implemented."<<std::endl; return false; }

        /** Pure virtual, Bind the graphics context to associated texture implementation.
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual void bindPBufferToTextureImplementation(GLenum /*buffer*/)  { osg::notify(osg::NOTICE)<<"GraphicsWindow::void bindPBufferToTextureImplementation(..) not implemented."<<std::endl; }

        /** Swap the front and back buffers implementation.
          * Pure virtual - must be implemented by Concrate implementations of GraphicsContext. */
        virtual void swapBuffersImplementation()  { osg::notify(osg::NOTICE)<<"GraphicsWindow:: swapBuffersImplementation() not implemented."<<std::endl; }

    protected:

        bool        _valid;

};

}

void GraphicsWindowWin32::setWindowDecoration(bool flag)
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::setWindowDecoration() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::init()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::init() Please implement me!"<<std::endl;
}

bool GraphicsWindowWin32::realizeImplementation()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::realizeImplementation() Please implement me!"<<std::endl;
    return false;
}

bool GraphicsWindowWin32::makeCurrentImplementation()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::makeCurrentImplementation() Please implement me!"<<std::endl;
    return false;
}

bool GraphicWindowWin32::releaseContextImplementation()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::releaseContextImplementation() Please implement me!"<<std::endl;
    return false;
}

void GraphicsWindowWin32::closeImplementation()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::closeImplementation() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::swapBuffersImplementation()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::swapBuffersImplementation() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::checkEvents()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::checkEvents() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::grabFocus()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::grabFocus() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::grabFocusIfPointerInWindow()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::grabFocusIfPointerInWindow() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::transformMouseXY(float& x, float& y)
{
    if (getEventQueue()->getUseFixedMouseInputRange())
    {
        osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState();
        x = eventState->getXmin() + (eventState->getXmax()-eventState->getXmin())*x/float(_traits->width);
        y = eventState->getYmin() + (eventState->getYmax()-eventState->getYmin())*y/float(_traits->height);
    }
}

struct Win32WindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface
{

    Win32WindowingSystemInterface()
    {

    }

    virtual unsigned int getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si)
    {
        osg::notify(osg::NOTICE)<<"Win32WindowingSystemInterface::getNumScreens() Please implement me!"<<std::endl;
        return 1;
    }

    virtual void getScreenResolution(const osg::GraphicsContext::ScreenIdentifier& si, unsigned int& width, unsigned int& height)
    {
        osg::notify(osg::NOTICE)<<"Win32WindowingSystemInterface::getScreenResolution() Please implement me!"<<std::endl;
    }

    virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits)
    {
        if (traits->pbuffer)
        {
            osg::ref_ptr<osgViewer::GraphicsContextWin32> pbuffer = new GraphicsContextWin32(traits);
            if (pbuffer->valid()) return pbuffer.release();
            else return 0;
        }
        else
        {
            osg::ref_ptr<osgViewer::GraphicsWindowWin32> window = new GraphicsWindowWin32(traits);
            if (window->valid()) return window.release();
            else return 0;
        }
    }

};

struct RegisterWindowingSystemInterfaceProxy
{
    RegisterWindowingSystemInterfaceProxy()
    {
        osg::GraphicsContext::setWindowingSystemInterface(new Win32WindowingSystemInterface);
    }

    ~RegisterWindowingSystemInterfaceProxy()
    {
        osg::GraphicsContext::setWindowingSystemInterface(0);
    }
};

RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy;
<commit_msg>Fixed typo<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgViewer/GraphicsWindowWin32>

using namespace osgViewer;

namespace osgViewer
{

/** This is the class we need to create for pbuffers, note its not a GraphicsWindow as it won't need any of the event handling and window mapping facilities.*/
class GraphicsContextWin32 : public osg::GraphicsContext
{
    public:

        GraphicsContextWin32(osg::GraphicsContext::Traits* traits):
            _valid(false)
        {
            _traits = traits;
        }

        virtual bool valid() const { return _valid; }

        /** Realise the GraphicsContext implementation,
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual bool realizeImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow::realizeImplementation() not implemented."<<std::endl; return false; }

        /** Return true if the graphics context has been realised, and is ready to use, implementation.
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual bool isRealizedImplementation() const  { osg::notify(osg::NOTICE)<<"GraphicsWindow::isRealizedImplementation() not implemented."<<std::endl; return false; }

        /** Close the graphics context implementation.
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual void closeImplementation()  { osg::notify(osg::NOTICE)<<"GraphicsWindow::closeImplementation() not implemented."<<std::endl; }

        /** Make this graphics context current implementation.
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual bool makeCurrentImplementation()  { osg::notify(osg::NOTICE)<<"GraphicsWindow::makeCurrentImplementation() not implemented."<<std::endl; return false; }

        /** Make this graphics context current with specified read context implementation.
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual bool makeContextCurrentImplementation(GraphicsContext* /*readContext*/)  { osg::notify(osg::NOTICE)<<"GraphicsWindow::makeContextCurrentImplementation(..) not implemented."<<std::endl; return false;}

        /** Release the graphics context.*/
        virtual bool releaseContextImplementation() {  osg::notify(osg::NOTICE)<<"GraphicsWindow::releaseContextImplementation(..) not implemented."<<std::endl; return false; }

        /** Pure virtual, Bind the graphics context to associated texture implementation.
          * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */
        virtual void bindPBufferToTextureImplementation(GLenum /*buffer*/)  { osg::notify(osg::NOTICE)<<"GraphicsWindow::void bindPBufferToTextureImplementation(..) not implemented."<<std::endl; }

        /** Swap the front and back buffers implementation.
          * Pure virtual - must be implemented by Concrate implementations of GraphicsContext. */
        virtual void swapBuffersImplementation()  { osg::notify(osg::NOTICE)<<"GraphicsWindow:: swapBuffersImplementation() not implemented."<<std::endl; }

    protected:

        bool        _valid;

};

}

void GraphicsWindowWin32::setWindowDecoration(bool flag)
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::setWindowDecoration() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::init()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::init() Please implement me!"<<std::endl;
}

bool GraphicsWindowWin32::realizeImplementation()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::realizeImplementation() Please implement me!"<<std::endl;
    return false;
}

bool GraphicsWindowWin32::makeCurrentImplementation()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::makeCurrentImplementation() Please implement me!"<<std::endl;
    return false;
}

bool GraphicsWindowWin32::releaseContextImplementation()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::releaseContextImplementation() Please implement me!"<<std::endl;
    return false;
}

void GraphicsWindowWin32::closeImplementation()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::closeImplementation() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::swapBuffersImplementation()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::swapBuffersImplementation() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::checkEvents()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::checkEvents() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::grabFocus()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::grabFocus() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::grabFocusIfPointerInWindow()
{
    osg::notify(osg::NOTICE)<<"GraphicWindowWin32::grabFocusIfPointerInWindow() Please implement me!"<<std::endl;
}

void GraphicsWindowWin32::transformMouseXY(float& x, float& y)
{
    if (getEventQueue()->getUseFixedMouseInputRange())
    {
        osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState();
        x = eventState->getXmin() + (eventState->getXmax()-eventState->getXmin())*x/float(_traits->width);
        y = eventState->getYmin() + (eventState->getYmax()-eventState->getYmin())*y/float(_traits->height);
    }
}

struct Win32WindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface
{

    Win32WindowingSystemInterface()
    {

    }

    virtual unsigned int getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si)
    {
        osg::notify(osg::NOTICE)<<"Win32WindowingSystemInterface::getNumScreens() Please implement me!"<<std::endl;
        return 1;
    }

    virtual void getScreenResolution(const osg::GraphicsContext::ScreenIdentifier& si, unsigned int& width, unsigned int& height)
    {
        osg::notify(osg::NOTICE)<<"Win32WindowingSystemInterface::getScreenResolution() Please implement me!"<<std::endl;
    }

    virtual osg::GraphicsContext* createGraphicsContext(osg::GraphicsContext::Traits* traits)
    {
        if (traits->pbuffer)
        {
            osg::ref_ptr<osgViewer::GraphicsContextWin32> pbuffer = new GraphicsContextWin32(traits);
            if (pbuffer->valid()) return pbuffer.release();
            else return 0;
        }
        else
        {
            osg::ref_ptr<osgViewer::GraphicsWindowWin32> window = new GraphicsWindowWin32(traits);
            if (window->valid()) return window.release();
            else return 0;
        }
    }

};

struct RegisterWindowingSystemInterfaceProxy
{
    RegisterWindowingSystemInterfaceProxy()
    {
        osg::GraphicsContext::setWindowingSystemInterface(new Win32WindowingSystemInterface);
    }

    ~RegisterWindowingSystemInterfaceProxy()
    {
        osg::GraphicsContext::setWindowingSystemInterface(0);
    }
};

RegisterWindowingSystemInterfaceProxy createWindowingSystemInterfaceProxy;
<|endoftext|>


<commit_before>// == mojo ====================================================================
//
//    Copyright (c) gnawice@gnawice.com. All rights reserved.
//	  See LICENSE in root folder
//
//    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.
//
// ============================================================================
//    train_mnist.cpp:  train MNIST classifier
//
//    Instructions:
//	  Add the "mojo" folder in your include path.
//    Download MNIST data and unzip locally on your machine:
//		(http://yann.lecun.com/exdb/mnist/index.html)
//    Set the data_path variable in the code to point to your data location.
// ==================================================================== mojo ==

#include <iostream> // cout
#include <vector>
#include <sstream>
#include <fstream>
#include <stdio.h>
//#include <tchar.h>

//#define MOJO_CV3

#include <mojo.h>
#include <util.h>
#include "mnist_parser.h"

const int mini_batch_size = 24;
const float initial_learning_rate = 0.04f;
std::string solver = "adam";
std::string data_path="../data/mnist/";
using namespace mnist;

// performs validation testing
float test(mojo::network &cnn, const std::vector<std::vector<float>> &test_images, const std::vector<int> &test_labels)
{
	// use progress object for simple timing and status updating
	mojo::progress progress((int)test_images.size(), "  testing:\t\t");

	int out_size = cnn.out_size(); // we know this to be 10 for MNIST
	int correct_predictions = 0;
	const int record_cnt = (int)test_images.size();

	#pragma omp parallel for reduction(+:correct_predictions) schedule(dynamic)
	for (int k = 0; k<record_cnt; k++)
	{
		const int prediction = cnn.predict_class(test_images[k].data());
		if (prediction == test_labels[k]) correct_predictions += 1;
		if (k % 1000 == 0) progress.draw_progress(k);
	}

	float accuracy = (float)correct_predictions / record_cnt*100.f;
	return accuracy;
}

int main()
{
	// ==== parse data
	// array to hold image data (note that mojo does not require use of std::vector)
	std::vector<std::vector<float>> test_images;
	std::vector<int> test_labels;
	std::vector<std::vector<float>> train_images;
	std::vector<int> train_labels;

	// calls MNIST::parse_test_data  or  CIFAR10::parse_test_data depending on 'using'
	if (!parse_test_data(data_path, test_images, test_labels)) { std::cerr << "error: could not parse data.\n"; return 1; }
	if (!parse_train_data(data_path, train_images, train_labels)) { std::cerr << "error: could not parse data.\n"; return 1; }

	// ==== setup the network  - when you train you must specify an optimizer ("sgd", "rmsprop", "adagrad", "adam")
	mojo::network cnn(solver.c_str());
	// !! the threading must be enabled with thread count prior to loading or creating a model !!
	cnn.enable_external_threads();
	cnn.set_mini_batch_size(mini_batch_size);
	cnn.set_smart_training(true); // automate training
	cnn.set_learning_rate(initial_learning_rate);

	cnn.push_back("I1", "input 28 28 1");				// MNIST is 28x28x1
	cnn.push_back("C1", "convolution 5 8 1 elu");		// 5x5 kernel, 20 maps. stride 1. out size is 28-5+1=24
	cnn.push_back("P1", "semi_stochastic_pool 3 3");	// pool 3x3 blocks. stride 3. outsize is 8
	cnn.push_back("C2i", "convolution 1 16 1 elu");		// 1x1 'inceptoin' layer
	cnn.push_back("C2", "convolution 5 48 1 elu");		// 5x5 kernel, 200 maps.  out size is 8-5+1=4
	cnn.push_back("P2", "semi_stochastic_pool 2 2");	// pool 2x2 blocks. stride 2. outsize is 2x2
	cnn.push_back("FC2", "softmax 10");					// 'flatten' of 2x2 input is inferred

	// connect all the layers. Call connect() manually for all layer connections if you need more exotic networks.
	cnn.connect_all();

	std::cout << "==  Network Configuration  ====================================================" << std::endl;
	std::cout << cnn.get_configuration() << std::endl;

	// add headers for table of values we want to log out
	mojo::html_log log;
	log.set_table_header("epoch\ttest accuracy(%)\testimated accuracy(%)\tepoch time(s)\ttotal time(s)\tlearn rate\tmodel");
	log.set_note(cnn.get_configuration());

	// augment data random shifts only
	cnn.set_random_augmentation(1,1,0,0,mojo::edge);

	// setup timer/progress for overall training
	mojo::progress overall_progress(-1, "  overall:\t\t");
	const int train_samples = (int)train_images.size();
	float old_accuracy = 0;
	while (1)
	{
		overall_progress.draw_header(data_name() + "  Epoch  " + std::to_string((long long)cnn.get_epoch() + 1), true);
		// setup timer / progress for this one epoch
		mojo::progress progress(train_samples, "  training:\t\t");
		// set loss function
		cnn.start_epoch("cross_entropy");

		// manually loop through data. batches are handled internally. if data is to be shuffled, the must be performed externally
		#pragma omp parallel for schedule(dynamic)  // schedule dynamic to help make progress bar work correctly
		for (int k = 0; k<train_samples; k++)
		{
			cnn.train_class(train_images[k].data(), train_labels[k]);
			if (k % 1000 == 0) progress.draw_progress(k);
		}

		// draw weights of main convolution layers
		#ifdef MOJO_CV3
		mojo::show(mojo::draw_cnn_weights(cnn, "C1",mojo::tensorglow), 2 /* scale x 2 */, "C1 Weights");
		mojo::show(mojo::draw_cnn_weights(cnn, "C2",mojo::tensorglow), 2, "C2 Weights");
		#endif

		cnn.end_epoch();
		float dt = progress.elapsed_seconds();
		std::cout << "  mini batch:\t\t" << mini_batch_size << "                               " << std::endl;
		std::cout << "  training time:\t" << dt << " seconds on " << cnn.get_thread_count() << " threads" << std::endl;
		std::cout << "  model updates:\t" << cnn.train_updates << " (" << (int)(100.f*(1. - (float)cnn.train_skipped / cnn.train_samples)) << "% of records)" << std::endl;
		std::cout << "  estimated accuracy:\t" << cnn.estimated_accuracy << "%" << std::endl;

		/* if you want to run in-sample testing on the training set, include this code
		// == run training set
		progress.reset((int)train_images.size(), "  testing in-sample:\t");
		float train_accuracy=test(cnn, train_images, train_labels);
		std::cout << "  train accuracy:\t"<<train_accuracy<<"% ("<< 100.f - train_accuracy<<"% error)      "<<std::endl;
		*/

		// ==== run testing set
		progress.reset((int)test_images.size(), "  testing out-of-sample:\t");
		float accuracy = test(cnn, test_images, test_labels);
		std::cout << "  test accuracy:\t" << accuracy << "% (" << 100.f - accuracy << "% error)      " << std::endl;

		// if accuracy is improving, reset the training logic that may be thinking about quitting
		if (accuracy > old_accuracy)
		{
			cnn.reset_smart_training();
			old_accuracy = accuracy;
		}

		// save model
		std::string model_file = "../models/snapshots/tmp_" + std::to_string((long long)cnn.get_epoch()) + ".txt";
		cnn.write(model_file,true);
		std::cout << "  saved model:\t\t" << model_file << std::endl << std::endl;

		// write log file
		std::string log_out;
		log_out += float2str(dt) + "\t";
		log_out += float2str(overall_progress.elapsed_seconds()) + "\t";
		log_out += float2str(cnn.get_learning_rate()) + "\t";
		log_out += model_file;
		log.add_table_row(cnn.estimated_accuracy, accuracy, log_out);
		// will write this every epoch
		log.write("../models/snapshots/mojo_mnist_log.htm");

		// can't seem to improve
		if (cnn.elvis_left_the_building())
		{
			std::cout << "Elvis just left the building. No further improvement in training found.\nStopping.." << std::endl;
			break;
		}

	};
	std::cout << std::endl;
	return 0;
}<commit_msg>show use of quickstart files<commit_after>// == mojo ====================================================================
//
//    Copyright (c) gnawice@gnawice.com. All rights reserved.
//	  See LICENSE in root folder
//
//    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.
//
// ============================================================================
//    train_mnist.cpp:  train MNIST classifier
//
//    Instructions:
//	  Add the "mojo" folder in your include path.
//    Download MNIST data and unzip locally on your machine:
//		(http://yann.lecun.com/exdb/mnist/index.html)
//    Set the data_path variable in the code to point to your data location.
// ==================================================================== mojo ==

#include <iostream> // cout
#include <vector>
#include <sstream>
#include <fstream>
#include <stdio.h>
//#include <tchar.h>

//#define MOJO_CV3

#include <mojo.h>
#include <util.h>
#include "mnist_parser.h"

const int mini_batch_size = 24;
const float initial_learning_rate = 0.04f;
std::string solver = "adam";
std::string data_path="../data/mnist/";
using namespace mnist;

// performs validation testing
float test(mojo::network &cnn, const std::vector<std::vector<float>> &test_images, const std::vector<int> &test_labels)
{
	// use progress object for simple timing and status updating
	mojo::progress progress((int)test_images.size(), "  testing:\t\t");

	int out_size = cnn.out_size(); // we know this to be 10 for MNIST
	int correct_predictions = 0;
	const int record_cnt = (int)test_images.size();

	#pragma omp parallel for reduction(+:correct_predictions) schedule(dynamic)
	for (int k = 0; k<record_cnt; k++)
	{
		const int prediction = cnn.predict_class(test_images[k].data());
		if (prediction == test_labels[k]) correct_predictions += 1;
		if (k % 1000 == 0) progress.draw_progress(k);
	}

	float accuracy = (float)correct_predictions / record_cnt*100.f;
	return accuracy;
}

int main()
{
	// ==== parse data
	// array to hold image data (note that mojo does not require use of std::vector)
	std::vector<std::vector<float>> test_images;
	std::vector<int> test_labels;
	std::vector<std::vector<float>> train_images;
	std::vector<int> train_labels;

	// calls MNIST::parse_test_data  or  CIFAR10::parse_test_data depending on 'using'
	if (!parse_test_data(data_path, test_images, test_labels)) { std::cerr << "error: could not parse data.\n"; return 1; }
	if (!parse_train_data(data_path, train_images, train_labels)) { std::cerr << "error: could not parse data.\n"; return 1; }

	// ==== setup the network  - when you train you must specify an optimizer ("sgd", "rmsprop", "adagrad", "adam")
	mojo::network cnn(solver.c_str());
	// !! the threading must be enabled with thread count prior to loading or creating a model !!
	cnn.enable_external_threads();
	cnn.set_mini_batch_size(mini_batch_size);
	cnn.set_smart_training(true); // automate training
	cnn.set_learning_rate(initial_learning_rate);

	// Note, network descriptions can be read from a text file with similar format to the API
	cnn.read("../models/mnist_quickstart.txt");

	/*
	// to construct the model through API calls...
	cnn.push_back("I1", "input 28 28 1");				// MNIST is 28x28x1
	cnn.push_back("C1", "convolution 5 8 1 elu");		// 5x5 kernel, 20 maps. stride 1. out size is 28-5+1=24
	cnn.push_back("P1", "semi_stochastic_pool 3 3");	// pool 3x3 blocks. stride 3. outsize is 8
	cnn.push_back("C2i", "convolution 1 16 1 elu");		// 1x1 'inceptoin' layer
	cnn.push_back("C2", "convolution 5 48 1 elu");		// 5x5 kernel, 200 maps.  out size is 8-5+1=4
	cnn.push_back("P2", "semi_stochastic_pool 2 2");	// pool 2x2 blocks. stride 2. outsize is 2x2
	cnn.push_back("FC2", "softmax 10");					// 'flatten' of 2x2 input is inferred
	// connect all the layers. Call connect() manually for all layer connections if you need more exotic networks.
	cnn.connect_all();
	// */

	std::cout << "==  Network Configuration  ====================================================" << std::endl;
	std::cout << cnn.get_configuration() << std::endl;

	// add headers for table of values we want to log out
	mojo::html_log log;
	log.set_table_header("epoch\ttest accuracy(%)\testimated accuracy(%)\tepoch time(s)\ttotal time(s)\tlearn rate\tmodel");
	log.set_note(cnn.get_configuration());

	// augment data random shifts only
	cnn.set_random_augmentation(1,1,0,0,mojo::edge);

	// setup timer/progress for overall training
	mojo::progress overall_progress(-1, "  overall:\t\t");
	const int train_samples = (int)train_images.size();
	float old_accuracy = 0;
	while (1)
	{
		overall_progress.draw_header(data_name() + "  Epoch  " + std::to_string((long long)cnn.get_epoch() + 1), true);
		// setup timer / progress for this one epoch
		mojo::progress progress(train_samples, "  training:\t\t");
		// set loss function
		cnn.start_epoch("cross_entropy");

		// manually loop through data. batches are handled internally. if data is to be shuffled, the must be performed externally
		#pragma omp parallel for schedule(dynamic)  // schedule dynamic to help make progress bar work correctly
		for (int k = 0; k<train_samples; k++)
		{
			cnn.train_class(train_images[k].data(), train_labels[k]);
			if (k % 1000 == 0) progress.draw_progress(k);
		}

		// draw weights of main convolution layers
		#ifdef MOJO_CV3
		mojo::show(mojo::draw_cnn_weights(cnn, "C1",mojo::tensorglow), 2 /* scale x 2 */, "C1 Weights");
		mojo::show(mojo::draw_cnn_weights(cnn, "C2",mojo::tensorglow), 2, "C2 Weights");
		#endif

		cnn.end_epoch();
		float dt = progress.elapsed_seconds();
		std::cout << "  mini batch:\t\t" << mini_batch_size << "                               " << std::endl;
		std::cout << "  training time:\t" << dt << " seconds on " << cnn.get_thread_count() << " threads" << std::endl;
		std::cout << "  model updates:\t" << cnn.train_updates << " (" << (int)(100.f*(1. - (float)cnn.train_skipped / cnn.train_samples)) << "% of records)" << std::endl;
		std::cout << "  estimated accuracy:\t" << cnn.estimated_accuracy << "%" << std::endl;

		/* if you want to run in-sample testing on the training set, include this code
		// == run training set
		progress.reset((int)train_images.size(), "  testing in-sample:\t");
		float train_accuracy=test(cnn, train_images, train_labels);
		std::cout << "  train accuracy:\t"<<train_accuracy<<"% ("<< 100.f - train_accuracy<<"% error)      "<<std::endl;
		*/

		// ==== run testing set
		progress.reset((int)test_images.size(), "  testing out-of-sample:\t");
		float accuracy = test(cnn, test_images, test_labels);
		std::cout << "  test accuracy:\t" << accuracy << "% (" << 100.f - accuracy << "% error)      " << std::endl;

		// if accuracy is improving, reset the training logic that may be thinking about quitting
		if (accuracy > old_accuracy)
		{
			cnn.reset_smart_training();
			old_accuracy = accuracy;
		}

		// save model
		std::string model_file = "../models/snapshots/tmp_" + std::to_string((long long)cnn.get_epoch()) + ".txt";
		cnn.write(model_file,true);
		std::cout << "  saved model:\t\t" << model_file << std::endl << std::endl;

		// write log file
		std::string log_out;
		log_out += float2str(dt) + "\t";
		log_out += float2str(overall_progress.elapsed_seconds()) + "\t";
		log_out += float2str(cnn.get_learning_rate()) + "\t";
		log_out += model_file;
		log.add_table_row(cnn.estimated_accuracy, accuracy, log_out);
		// will write this every epoch
		log.write("../models/snapshots/mojo_mnist_log.htm");

		// can't seem to improve
		if (cnn.elvis_left_the_building())
		{
			std::cout << "Elvis just left the building. No further improvement in training found.\nStopping.." << std::endl;
			break;
		}

	};
	std::cout << std::endl;
	return 0;
}<|endoftext|>


<commit_before>// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.

#pragma once

#if !defined(RXCPP_RX_SYNCHRONIZE_HPP)
#define RXCPP_RX_SYNCHRONIZE_HPP

#include "../rx-includes.hpp"

namespace rxcpp {

namespace subjects {

namespace detail {

template<class T>
class synchronize_observer : public detail::multicast_observer<T>
{
    typedef synchronize_observer<T> this_type;
    typedef detail::multicast_observer<T> base_type;

    struct synchronize_observer_state : public std::enable_shared_from_this<synchronize_observer_state>
    {
        typedef rxn::notification<T> notification_type;
        typedef typename notification_type::type base_notification_type;
        typedef std::deque<base_notification_type> queue_type;

        struct mode
        {
            enum type {
                Invalid = 0,
                Processing,
                Empty,
                Disposed
            };
        };

        mutable std::mutex lock;
        mutable std::condition_variable wake;
        mutable queue_type queue;
        composite_subscription lifetime;
        rxsc::worker processor;
        mutable typename mode::type current;
        subscriber<T> destination;

        void ensure_processing(std::unique_lock<std::mutex>& guard) const {
            if (!guard.owns_lock()) {
                abort();
            }
            if (current == mode::Empty) {
                current = mode::Processing;
                auto keepAlive = this->shared_from_this();
                processor.schedule(lifetime, [keepAlive, this](const rxsc::schedulable& self){
                    try {
                        std::unique_lock<std::mutex> guard(lock);
                        if (!lifetime.is_subscribed() || !destination.is_subscribed()) {
                            current = mode::Disposed;
                            queue.clear();
                            guard.unlock();
                            lifetime.unsubscribe();
                            destination.unsubscribe();
                            return;
                        }
                        if (queue.empty()) {
                            current = mode::Empty;
                            return;
                        }
                        auto notification = std::move(queue.front());
                        queue.pop_front();
                        guard.unlock();
                        notification->accept(destination);
                        self();
                    } catch(...) {
                        destination.on_error(std::current_exception());
                        std::unique_lock<std::mutex> guard(lock);
                        current = mode::Empty;
                    }
                });
            }
        }

        synchronize_observer_state(rxsc::worker w, composite_subscription cs, subscriber<T> scbr)
            : lifetime(cs)
            , processor(w)
            , current(mode::Empty)
            , destination(scbr)
        {
        }

        template<class V>
        void on_next(V v) const {
            if (lifetime.is_subscribed()) {
                std::unique_lock<std::mutex> guard(lock);
                queue.push_back(notification_type::on_next(std::move(v)));
                wake.notify_one();
                ensure_processing(guard);
            }
        }
        void on_error(std::exception_ptr e) const {
            if (lifetime.is_subscribed()) {
                std::unique_lock<std::mutex> guard(lock);
                queue.push_back(notification_type::on_error(e));
                wake.notify_one();
                ensure_processing(guard);
            }
        }
        void on_completed() const {
            if (lifetime.is_subscribed()) {
                std::unique_lock<std::mutex> guard(lock);
                queue.push_back(notification_type::on_completed());
                wake.notify_one();
                ensure_processing(guard);
            }
        }
    };

    std::shared_ptr<synchronize_observer_state> state;

public:
    synchronize_observer(rxsc::worker w, composite_subscription cs)
        : base_type(cs)
        , state(std::make_shared<synchronize_observer_state>(
            w, cs, make_subscriber<T>(cs, make_observer_dynamic<T>( *static_cast<base_type*>(this) ))))
    {}

    template<class V>
    void on_next(V v) const {
        state->on_next(std::move(v));
    }
    void on_error(std::exception_ptr e) const {
        state->on_error(e);
    }
    void on_completed() const {
        state->on_completed();
    }
};

}

template<class T>
class synchronize
{
    rxsc::worker controller;
    composite_subscription lifetime;
    detail::synchronize_observer<T> s;

public:
    explicit synchronize(rxsc::worker w, composite_subscription cs = composite_subscription())
        : controller(w)
        , lifetime(cs)
        , s(w, cs)
    {
    }

    bool has_observers() const {
        return s.has_observers();
    }

    subscriber<T> get_subscriber() const {
        return make_subscriber<T>(lifetime, make_observer_dynamic<T>(observer<T, detail::synchronize_observer<T>>(s)));
    }

    observable<T> get_observable() const {
        return make_observable_dynamic<T>([this](subscriber<T> o){
            this->s.add(std::move(o));
        });
    }
};

//
// this type is used by operators that subscribe to
// multiple sources to ensure that the notifications are serialized
//
class synchronize_observable
{
    rxsc::scheduler factory;
    rxsc::worker controller;
public:
    synchronize_observable(rxsc::scheduler sc)
        : factory(sc)
        , controller(sc.create_worker())
    {
    }
    synchronize_observable(const synchronize_observable& o)
        : factory(o.factory)
        // new worker for each copy. this spreads work across threads
        // but keeps each use serialized
        , controller(factory.create_worker())
    {
    }
    synchronize_observable(synchronize_observable&& o)
        : factory(std::move(o.factory))
        , controller(std::move(o.controller))
    {
    }
    synchronize_observable& operator=(synchronize_observable o)
    {
        factory = std::move(o.factory);
        controller = std::move(o.controller);
        return *this;
    }
    template<class Observable>
    auto operator()(Observable o)
        -> decltype(o.synchronize(controller).ref_count()) {
        return      o.synchronize(controller).ref_count();
        static_assert(is_observable<Observable>::value, "can only synchronize observables");
    }
};

}

}

#endif
<commit_msg>split input and output lifetimes<commit_after>// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.

#pragma once

#if !defined(RXCPP_RX_SYNCHRONIZE_HPP)
#define RXCPP_RX_SYNCHRONIZE_HPP

#include "../rx-includes.hpp"

namespace rxcpp {

namespace subjects {

namespace detail {

template<class T>
class synchronize_observer : public detail::multicast_observer<T>
{
    typedef synchronize_observer<T> this_type;
    typedef detail::multicast_observer<T> base_type;

    struct synchronize_observer_state : public std::enable_shared_from_this<synchronize_observer_state>
    {
        typedef rxn::notification<T> notification_type;
        typedef typename notification_type::type base_notification_type;
        typedef std::deque<base_notification_type> queue_type;

        struct mode
        {
            enum type {
                Invalid = 0,
                Processing,
                Empty,
                Disposed
            };
        };

        mutable std::mutex lock;
        mutable std::condition_variable wake;
        mutable queue_type queue;
        composite_subscription lifetime;
        rxsc::worker processor;
        mutable typename mode::type current;
        subscriber<T> destination;

        void ensure_processing(std::unique_lock<std::mutex>& guard) const {
            if (!guard.owns_lock()) {
                abort();
            }
            if (current == mode::Empty) {
                current = mode::Processing;
                auto keepAlive = this->shared_from_this();
                processor.schedule(lifetime, [keepAlive, this](const rxsc::schedulable& self){
                    try {
                        std::unique_lock<std::mutex> guard(lock);
                        if (!destination.is_subscribed()) {
                            current = mode::Disposed;
                            queue.clear();
                            guard.unlock();
                            lifetime.unsubscribe();
                            return;
                        }
                        if (queue.empty()) {
                            current = mode::Empty;
                            return;
                        }
                        auto notification = std::move(queue.front());
                        queue.pop_front();
                        guard.unlock();
                        notification->accept(destination);
                        self();
                    } catch(...) {
                        destination.on_error(std::current_exception());
                        std::unique_lock<std::mutex> guard(lock);
                        current = mode::Empty;
                    }
                });
            }
        }

        synchronize_observer_state(rxsc::worker w, composite_subscription cs, subscriber<T> scbr)
            : lifetime(cs)
            , processor(w)
            , current(mode::Empty)
            , destination(scbr)
        {
        }

        template<class V>
        void on_next(V v) const {
            if (lifetime.is_subscribed()) {
                std::unique_lock<std::mutex> guard(lock);
                queue.push_back(notification_type::on_next(std::move(v)));
                ensure_processing(guard);
            }
            wake.notify_one();
        }
        void on_error(std::exception_ptr e) const {
            if (lifetime.is_subscribed()) {
                std::unique_lock<std::mutex> guard(lock);
                queue.push_back(notification_type::on_error(e));
                ensure_processing(guard);
            }
            wake.notify_one();
        }
        void on_completed() const {
            if (lifetime.is_subscribed()) {
                std::unique_lock<std::mutex> guard(lock);
                queue.push_back(notification_type::on_completed());
                ensure_processing(guard);
            }
            wake.notify_one();
        }
    };

    std::shared_ptr<synchronize_observer_state> state;

public:
    synchronize_observer(rxsc::worker w, composite_subscription dl, composite_subscription il)
        : base_type(dl)
        , state(std::make_shared<synchronize_observer_state>(
            w, il, make_subscriber<T>(dl, make_observer_dynamic<T>( *static_cast<base_type*>(this) ))))
    {}

    template<class V>
    void on_next(V v) const {
        state->on_next(std::move(v));
    }
    void on_error(std::exception_ptr e) const {
        state->on_error(e);
    }
    void on_completed() const {
        state->on_completed();
    }
};

}

template<class T>
class synchronize
{
    rxsc::worker controller;
    composite_subscription lifetime;
    detail::synchronize_observer<T> s;

public:
    explicit synchronize(rxsc::worker w, composite_subscription cs = composite_subscription())
        : controller(w)
        , lifetime(composite_subscription())
        , s(w, cs, lifetime)
    {
    }

    bool has_observers() const {
        return s.has_observers();
    }

    subscriber<T> get_subscriber() const {
        return make_subscriber<T>(lifetime, make_observer_dynamic<T>(observer<T, detail::synchronize_observer<T>>(s)));
    }

    observable<T> get_observable() const {
        return make_observable_dynamic<T>([this](subscriber<T> o){
            this->s.add(std::move(o));
        });
    }
};

//
// this type is used by operators that subscribe to
// multiple sources to ensure that the notifications are serialized
//
class synchronize_observable
{
    rxsc::scheduler factory;
    rxsc::worker controller;
public:
    synchronize_observable(rxsc::scheduler sc)
        : factory(sc)
        , controller(sc.create_worker())
    {
    }
    synchronize_observable(const synchronize_observable& o)
        : factory(o.factory)
        // new worker for each copy. this spreads work across threads
        // but keeps each use serialized
        , controller(factory.create_worker())
    {
    }
    synchronize_observable(synchronize_observable&& o)
        : factory(std::move(o.factory))
        , controller(std::move(o.controller))
    {
    }
    synchronize_observable& operator=(synchronize_observable o)
    {
        factory = std::move(o.factory);
        controller = std::move(o.controller);
        return *this;
    }
    template<class Observable>
    auto operator()(Observable o)
        -> decltype(o.synchronize(controller).ref_count()) {
        return      o.synchronize(controller).ref_count();
        static_assert(is_observable<Observable>::value, "can only synchronize observables");
    }
};

}

}

#endif
<|endoftext|>


<commit_before>/*
* Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
*  http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

#include <aws/text-to-speech/windows/WaveOutPCMOutputDriver.h>
#include <aws/core/utils/StringUtils.h>
#include <aws/core/utils/logging/LogMacros.h>

#include <windows.h>

using namespace Aws::Utils;

static void CALLBACK waveOutProc(HWAVEOUT waveOut, UINT uMsg, DWORD_PTR, DWORD_PTR dwParam1, DWORD_PTR)
{
    switch (uMsg)
    {
    case WOM_CLOSE:
        return;
    case WOM_DONE:
        waveOutUnprepareHeader(waveOut, (WAVEHDR*)dwParam1, sizeof(WAVEHDR));
        Aws::DeleteArray(((WAVEHDR*)dwParam1)->lpData);
        Aws::Delete((WAVEHDR*)dwParam1);
        return;
    case WOM_OPEN:
        return;
    default:
        return;

    }
}

namespace Aws
{
    namespace TextToSpeech
    {
        static const char* CLASS_TAG = "WaveOutPCMOutputDriver";

        WaveOutPCMOutputDriver::WaveOutPCMOutputDriver() : m_waveOut(nullptr) {}

        WaveOutPCMOutputDriver::~WaveOutPCMOutputDriver()
        {
            if (m_waveOut)
            {
                waveOutClose(m_waveOut);
                m_waveOut = nullptr;
            }
        }

        bool WaveOutPCMOutputDriver::WriteBufferToDevice(const unsigned char* buffer, size_t size)
        {
            InitDevice();

            WAVEHDR* waveHdr = Aws::New<WAVEHDR>(CLASS_TAG);
            char* buf = Aws::NewArray<char>(size, CLASS_TAG);
            memcpy(buf, buffer, size);
            waveHdr->lpData = buf;
            waveHdr->dwBufferLength = static_cast<DWORD>(size);
            waveHdr->dwFlags = 0;
            waveHdr->dwLoops = 0;
            waveHdr->dwUser = NULL;

			std::lock_guard<std::recursive_mutex> m(m_driverLock);
			if (m_waveOut)
			{
				auto res = waveOutPrepareHeader(m_waveOut, waveHdr, sizeof(WAVEHDR));
				if (res != MMSYSERR_NOERROR)
				{
					AWS_LOGSTREAM_ERROR(CLASS_TAG, "Error code " << res << " returned from waveOutPrepareHeader");
					return false;
				}

				res = waveOutWrite(m_waveOut, waveHdr, sizeof(WAVEHDR));
				if (res != MMSYSERR_NOERROR)
				{
					AWS_LOGSTREAM_ERROR(CLASS_TAG, "Error code " << res << " returned from waveOutWrite");
					return false;
				}
			}

            return true;
        }

        const char* WaveOutPCMOutputDriver::GetName() const
        {
            return "Win32 WaveOut";
        }

        void WaveOutPCMOutputDriver::InitDevice()
        {
            if (!m_isInit)
            {
                AWS_LOGSTREAM_INFO(CLASS_TAG, "Initializing device " << m_activeDevice.deviceName);
				std::lock_guard<std::recursive_mutex> m(m_driverLock);
                if (m_waveOut)
                {
                    AWS_LOGSTREAM_TRACE(CLASS_TAG, "Cleaning up current device ");
                    waveOutClose(m_waveOut);
                    m_waveOut = nullptr;
                }

                WAVEFORMATEX format;
                format.nChannels = static_cast<WORD>(m_selectedCaps.channels);
                format.nSamplesPerSec = static_cast<DWORD>(m_selectedCaps.sampleRate);
                format.wBitsPerSample = static_cast<WORD>(m_selectedCaps.sampleWidthBits);
                format.wFormatTag = WAVE_FORMAT_PCM;
                format.nBlockAlign = (format.nChannels * format.wBitsPerSample) / 8;
                format.cbSize = 0;
                format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;

                if (m_activeDevice.deviceId.empty())
                {
                    AWS_LOGSTREAM_INFO(CLASS_TAG, "No device configured, letting windows figure out the best default.");

                    auto res = waveOutOpen(&m_waveOut, WAVE_MAPPER, &format, (DWORD_PTR)&waveOutProc, NULL,
                        CALLBACK_FUNCTION | WAVE_ALLOWSYNC | WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE);
                    m_isInit = !res;
                }
                else
                {
                    unsigned id = static_cast<unsigned>(StringUtils::ConvertToInt32(m_activeDevice.deviceId.c_str()));
                    auto res = waveOutOpen(&m_waveOut, id, &format, (DWORD_PTR)&waveOutProc, NULL,
                        CALLBACK_FUNCTION | WAVE_ALLOWSYNC);
                    m_isInit = !res;
                }

                if (!m_isInit)
                {
                    AWS_LOGSTREAM_ERROR(CLASS_TAG, "Failed to initialize device");
                }
            }
        }

        void WaveOutPCMOutputDriver::SetActiveDevice(const DeviceInfo& device, const CapabilityInfo& caps)
        {
            std::lock_guard<std::recursive_mutex> m(m_driverLock);
            m_activeDevice = device;
            m_selectedCaps = caps;
            m_isInit = false;
            InitDevice();
        }

        Aws::Vector<DeviceInfo> WaveOutPCMOutputDriver::EnumerateDevices() const
        {
            Aws::Vector<DeviceInfo> devices;

            auto deviceCount = waveOutGetNumDevs();

            for (UINT i = 0; i < deviceCount; ++i)
            {
                WAVEOUTCAPSA waveoutCaps;
                auto res = waveOutGetDevCapsA(i, &waveoutCaps, sizeof(WAVEOUTCAPSA));

                if (!res)
                {
                    DeviceInfo devInfo;
                    devInfo.deviceId = StringUtils::to_string(i);
                    devInfo.deviceName = waveoutCaps.szPname;

                    if ((waveoutCaps.dwFormats & WAVE_FORMAT_1M16) == WAVE_FORMAT_1M16)
                    {
                        CapabilityInfo capsInfo;
                        capsInfo.channels = MONO;
                        capsInfo.sampleRate = KHZ_8;
                        capsInfo.sampleWidthBits = BIT_WIDTH_16;

                        devInfo.capabilities.push_back(capsInfo);

                        capsInfo.channels = MONO;
                        capsInfo.sampleRate = KHZ_16;
                        capsInfo.sampleWidthBits = BIT_WIDTH_16;

                        devInfo.capabilities.push_back(capsInfo);
                    }

                    if ((waveoutCaps.dwFormats & WAVE_FORMAT_2M16) == WAVE_FORMAT_2M16)
                    {
                        CapabilityInfo capsInfo;
                        capsInfo.channels = MONO;
                        capsInfo.sampleRate = KHZ_22_5;
                        capsInfo.sampleWidthBits = KHZ_16;

                        devInfo.capabilities.push_back(capsInfo);
                    }

                    devices.push_back(devInfo);
                }
            }

            return devices;
        }
    }
}<commit_msg>fix bit width on windows pcm driver<commit_after>/*
* Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
*  http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

#include <aws/text-to-speech/windows/WaveOutPCMOutputDriver.h>
#include <aws/core/utils/StringUtils.h>
#include <aws/core/utils/logging/LogMacros.h>

#include <windows.h>

using namespace Aws::Utils;

static void CALLBACK waveOutProc(HWAVEOUT waveOut, UINT uMsg, DWORD_PTR, DWORD_PTR dwParam1, DWORD_PTR)
{
    switch (uMsg)
    {
    case WOM_CLOSE:
        return;
    case WOM_DONE:
        waveOutUnprepareHeader(waveOut, (WAVEHDR*)dwParam1, sizeof(WAVEHDR));
        Aws::DeleteArray(((WAVEHDR*)dwParam1)->lpData);
        Aws::Delete((WAVEHDR*)dwParam1);
        return;
    case WOM_OPEN:
        return;
    default:
        return;

    }
}

namespace Aws
{
    namespace TextToSpeech
    {
        static const char* CLASS_TAG = "WaveOutPCMOutputDriver";

        WaveOutPCMOutputDriver::WaveOutPCMOutputDriver() : m_waveOut(nullptr) {}

        WaveOutPCMOutputDriver::~WaveOutPCMOutputDriver()
        {
            if (m_waveOut)
            {
                waveOutClose(m_waveOut);
                m_waveOut = nullptr;
            }
        }

        bool WaveOutPCMOutputDriver::WriteBufferToDevice(const unsigned char* buffer, size_t size)
        {
            InitDevice();

            WAVEHDR* waveHdr = Aws::New<WAVEHDR>(CLASS_TAG);
            char* buf = Aws::NewArray<char>(size, CLASS_TAG);
            memcpy(buf, buffer, size);
            waveHdr->lpData = buf;
            waveHdr->dwBufferLength = static_cast<DWORD>(size);
            waveHdr->dwFlags = 0;
            waveHdr->dwLoops = 0;
            waveHdr->dwUser = NULL;

			std::lock_guard<std::recursive_mutex> m(m_driverLock);
			if (m_waveOut)
			{
				auto res = waveOutPrepareHeader(m_waveOut, waveHdr, sizeof(WAVEHDR));
				if (res != MMSYSERR_NOERROR)
				{
					AWS_LOGSTREAM_ERROR(CLASS_TAG, "Error code " << res << " returned from waveOutPrepareHeader");
					return false;
				}

				res = waveOutWrite(m_waveOut, waveHdr, sizeof(WAVEHDR));
				if (res != MMSYSERR_NOERROR)
				{
					AWS_LOGSTREAM_ERROR(CLASS_TAG, "Error code " << res << " returned from waveOutWrite");
					return false;
				}
			}

            return true;
        }

        const char* WaveOutPCMOutputDriver::GetName() const
        {
            return "Win32 WaveOut";
        }

        void WaveOutPCMOutputDriver::InitDevice()
        {
            if (!m_isInit)
            {
                AWS_LOGSTREAM_INFO(CLASS_TAG, "Initializing device " << m_activeDevice.deviceName);
				std::lock_guard<std::recursive_mutex> m(m_driverLock);
                if (m_waveOut)
                {
                    AWS_LOGSTREAM_TRACE(CLASS_TAG, "Cleaning up current device ");
                    waveOutClose(m_waveOut);
                    m_waveOut = nullptr;
                }

                WAVEFORMATEX format;
                format.nChannels = static_cast<WORD>(m_selectedCaps.channels);
                format.nSamplesPerSec = static_cast<DWORD>(m_selectedCaps.sampleRate);
                format.wBitsPerSample = static_cast<WORD>(m_selectedCaps.sampleWidthBits);
                format.wFormatTag = WAVE_FORMAT_PCM;
                format.nBlockAlign = (format.nChannels * format.wBitsPerSample) / 8;
                format.cbSize = 0;
                format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;

                if (m_activeDevice.deviceId.empty())
                {
                    AWS_LOGSTREAM_INFO(CLASS_TAG, "No device configured, letting windows figure out the best default.");

                    auto res = waveOutOpen(&m_waveOut, WAVE_MAPPER, &format, (DWORD_PTR)&waveOutProc, NULL,
                        CALLBACK_FUNCTION | WAVE_ALLOWSYNC | WAVE_MAPPED_DEFAULT_COMMUNICATION_DEVICE);
                    m_isInit = !res;
                }
                else
                {
                    unsigned id = static_cast<unsigned>(StringUtils::ConvertToInt32(m_activeDevice.deviceId.c_str()));
                    auto res = waveOutOpen(&m_waveOut, id, &format, (DWORD_PTR)&waveOutProc, NULL,
                        CALLBACK_FUNCTION | WAVE_ALLOWSYNC);
                    m_isInit = !res;
                }

                if (!m_isInit)
                {
                    AWS_LOGSTREAM_ERROR(CLASS_TAG, "Failed to initialize device");
                }
            }
        }

        void WaveOutPCMOutputDriver::SetActiveDevice(const DeviceInfo& device, const CapabilityInfo& caps)
        {
            std::lock_guard<std::recursive_mutex> m(m_driverLock);
            m_activeDevice = device;
            m_selectedCaps = caps;
            m_isInit = false;
            InitDevice();
        }

        Aws::Vector<DeviceInfo> WaveOutPCMOutputDriver::EnumerateDevices() const
        {
            Aws::Vector<DeviceInfo> devices;

            auto deviceCount = waveOutGetNumDevs();

            for (UINT i = 0; i < deviceCount; ++i)
            {
                WAVEOUTCAPSA waveoutCaps;
                auto res = waveOutGetDevCapsA(i, &waveoutCaps, sizeof(WAVEOUTCAPSA));

                if (!res)
                {
                    DeviceInfo devInfo;
                    devInfo.deviceId = StringUtils::to_string(i);
                    devInfo.deviceName = waveoutCaps.szPname;

                    if ((waveoutCaps.dwFormats & WAVE_FORMAT_1M16) == WAVE_FORMAT_1M16)
                    {
                        CapabilityInfo capsInfo;
                        capsInfo.channels = MONO;
                        capsInfo.sampleRate = KHZ_8;
                        capsInfo.sampleWidthBits = BIT_WIDTH_16;

                        devInfo.capabilities.push_back(capsInfo);

                        capsInfo.channels = MONO;
                        capsInfo.sampleRate = KHZ_16;
                        capsInfo.sampleWidthBits = BIT_WIDTH_16;

                        devInfo.capabilities.push_back(capsInfo);
                    }

                    if ((waveoutCaps.dwFormats & WAVE_FORMAT_2M16) == WAVE_FORMAT_2M16)
                    {
                        CapabilityInfo capsInfo;
                        capsInfo.channels = MONO;
                        capsInfo.sampleRate = KHZ_22_5;
                        capsInfo.sampleWidthBits = BIT_WIDTH_16;

                        devInfo.capabilities.push_back(capsInfo);
                    }

                    devices.push_back(devInfo);
                }
            }

            return devices;
        }
    }
}<|endoftext|>


<commit_before>Matrix3i m = Matrix3i::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is m.minor(1,1):" << endl << m.minor(1,1) << endl;
<commit_msg>Remove doc/snippets/MatrixBase_minor.cpp because minor() was removed.<commit_after><|endoftext|>


<commit_before>/**
*  Copyright (C) 2018 3D Repo Ltd
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Affero General Public License as
*  published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
*  You should have received a copy of the GNU Affero General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

//ODA [ BIM BIM-EX RX DB ]
#include "Common/BmBuildSettings.h"
#include <OdaCommon.h>
#include <StaticRxObject.h>
#include <RxInit.h>
#include <RxDynamicModule.h>
#include <DynamicLinker.h>
#include <RxDynamicModule.h>
#include <ExSystemServices.h>
#include "ExBimHostAppServices.h"
#include "BimCommon.h"
#include "RxObjectImpl.h"
#include "Database/BmDatabase.h"
#include "Database/GiContextForBmDatabase.h"
#include "Database/Entities/BmDBDrawing.h"
#include "ModelerGeometry/BmModelerModule.h"
#include "Database/Entities/BmUnitsElem.h"
#include "Database/BmUnitUtils.h"
#include "Database/Managers/BmUnitsTracking.h"

//3d repo bouncer
#include "file_processor_rvt.h"
#include "data_processor_rvt.h"

//help
#include "vectorise_device_rvt.h"

using namespace repo::manipulator::modelconvertor::odaHelper;

const bool USE_NEW_TESSELLATION = true;
const double TRIANGULATION_EDGE_LENGTH = 1;
const double ROUNDING_ACCURACY = 0.000001;

class StubDeviceModuleRvt : public OdGsBaseModule
{
private:
	OdBmDatabasePtr database;
	GeometryCollector *collector;

public:
	void init(GeometryCollector* const collector, OdBmDatabasePtr database)
	{
		this->collector = collector;
		this->database = database;
	}
protected:
	OdSmartPtr<OdGsBaseVectorizeDevice> createDeviceObject()
	{
		return OdRxObjectImpl<VectoriseDeviceRvt, OdGsBaseVectorizeDevice>::createObject();
	}
	OdSmartPtr<OdGsViewImpl> createViewObject()
	{
		OdSmartPtr<OdGsViewImpl> pP = OdRxObjectImpl<DataProcessorRvt, OdGsViewImpl>::createObject();
		((DataProcessorRvt*)pP.get())->init(collector, database);
		return pP;
	}
};
ODRX_DEFINE_PSEUDO_STATIC_MODULE(StubDeviceModuleRvt);

class RepoRvtServices : public ExSystemServices, public OdExBimHostAppServices
{
protected:
    ODRX_USING_HEAP_OPERATORS(ExSystemServices);
};

OdString Get3DLayout(OdDbBaseDatabasePEPtr baseDatabase, OdBmDatabasePtr bimDatabase)
{
	OdString layoutName;
	OdRxIteratorPtr layouts = baseDatabase->layouts(bimDatabase);

	for (; !layouts->done(); layouts->next())
	{
		OdBmDBDrawingPtr pDBDrawing = layouts->object();
		OdDbBaseLayoutPEPtr pLayout(layouts->object());

		if (pDBDrawing->getBaseViewNameFormat() == OdBm::ViewType::_3d)
		{
			//.. NOTE: set first 3D view available
			if (layoutName.isEmpty())
				layoutName = pLayout->name(layouts->object());

			//.. NOTE: try to find 3D view with a valid default name
			if (pDBDrawing->getName().find(L"3D") != -1)
				return pLayout->name(layouts->object());
		}
	}

	return layoutName;
}

repo::manipulator::modelconvertor::odaHelper::FileProcessorRvt::~FileProcessorRvt()
{

}

void FileProcessorRvt::setTessellationParams(wrTriangulationParams params)
{
	OdSmartPtr<BmModelerModule> pModModule;
	OdRxModulePtr pModule = odrxDynamicLinker()->loadModule(OdBmModelerModuleName);
	if (pModule.get())
	{
		pModModule = BmModelerModule::cast(pModule);
		pModModule->setTriangulationParams(params);
	}
}

void setupUnitsFormat(OdBmDatabasePtr pDb, double accuracy)
{
	OdBmUnitsTrackingPtr pUnitsTracking = pDb->getAppInfo(OdBm::ManagerType::UnitsTracking);
	OdBmUnitsElemPtr pUnitsElem = pUnitsTracking->getUnitsElemId().safeOpenObject();
	if (pUnitsElem.isNull())
		return;

	OdBmAUnitsPtr units = pUnitsElem->getUnits();
	if (units.isNull())
		return;

	OdBmFormatOptionsPtrArray formatOptionsArr;
	units->getFormatOptionsArr(formatOptionsArr);
	for (uint32_t i = 0; i < formatOptionsArr.size(); i++)
	{
		OdBmFormatOptions* formatOptions = formatOptionsArr[i];
		//.. NOTE: Here the format of units is configured
		formatOptions->setAccuracy(accuracy);
		formatOptions->setRoundingMethod(OdBm::RoundingMethod::Nearest);
	}
}

uint8_t FileProcessorRvt::readFile()
{
	int nRes = REPOERR_OK;
	OdStaticRxObject<RepoRvtServices> svcs;
	odrxInitialize(&svcs);
	OdRxModule* pModule = ::odrxDynamicLinker()->loadModule(OdBmLoaderModuleName, false);
	try
	{
		//.. change tessellation params here
		wrTriangulationParams triParams(USE_NEW_TESSELLATION);
		triParams.maxFacetEdgeLength = TRIANGULATION_EDGE_LENGTH;

		setTessellationParams(triParams);

		odgsInitialize();
		OdBmDatabasePtr pDb = svcs.readFile(OdString(file.c_str()));
		if (!pDb.isNull())
		{
			OdDbBaseDatabasePEPtr pDbPE(pDb);
			OdString layout = Get3DLayout(pDbPE, pDb);
			if (layout.isEmpty())
				return REPOERR_VALID_3D_VIEW_NOT_FOUND;

			pDbPE->setCurrentLayout(pDb, layout);

			OdGiContextForBmDatabasePtr pBimContext = OdGiContextForBmDatabase::createObject();
			OdGsModulePtr pGsModule = ODRX_STATIC_MODULE_ENTRY_POINT(StubDeviceModuleRvt)(OD_T("StubDeviceModuleRvt"));

			((StubDeviceModuleRvt*)pGsModule.get())->init(collector, pDb);
			OdGsDevicePtr pDevice = pGsModule->createDevice();

			pBimContext->setDatabase(pDb);
			pDevice = pDbPE->setupActiveLayoutViews(pDevice, pBimContext);
			OdGsDCRect screenRect(OdGsDCPoint(0, 0), OdGsDCPoint(1000, 1000)); //Set the screen space to the borders of the scene
			pDevice->onSize(screenRect);
			setupUnitsFormat(pDb, ROUNDING_ACCURACY);
			pDevice->update();
		}
	}
	catch (OdError& e)
	{
		nRes = REPOERR_LOAD_SCENE_FAIL;
		repoError << e.description().c_str();
	}

	return nRes;
}

<commit_msg>ISSUE #291 - set default tessellation params<commit_after>/**
*  Copyright (C) 2018 3D Repo Ltd
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Affero General Public License as
*  published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
*
*  You should have received a copy of the GNU Affero General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

//ODA [ BIM BIM-EX RX DB ]
#include "Common/BmBuildSettings.h"
#include <OdaCommon.h>
#include <StaticRxObject.h>
#include <RxInit.h>
#include <RxDynamicModule.h>
#include <DynamicLinker.h>
#include <RxDynamicModule.h>
#include <ExSystemServices.h>
#include "ExBimHostAppServices.h"
#include "BimCommon.h"
#include "RxObjectImpl.h"
#include "Database/BmDatabase.h"
#include "Database/GiContextForBmDatabase.h"
#include "Database/Entities/BmDBDrawing.h"
#include "ModelerGeometry/BmModelerModule.h"
#include "Database/Entities/BmUnitsElem.h"
#include "Database/BmUnitUtils.h"
#include "Database/Managers/BmUnitsTracking.h"

//3d repo bouncer
#include "file_processor_rvt.h"
#include "data_processor_rvt.h"

//help
#include "vectorise_device_rvt.h"

using namespace repo::manipulator::modelconvertor::odaHelper;

const bool USE_NEW_TESSELLATION = true;
const double TRIANGULATION_EDGE_LENGTH = 1;
const double ROUNDING_ACCURACY = 0.000001;

class StubDeviceModuleRvt : public OdGsBaseModule
{
private:
	OdBmDatabasePtr database;
	GeometryCollector *collector;

public:
	void init(GeometryCollector* const collector, OdBmDatabasePtr database)
	{
		this->collector = collector;
		this->database = database;
	}
protected:
	OdSmartPtr<OdGsBaseVectorizeDevice> createDeviceObject()
	{
		return OdRxObjectImpl<VectoriseDeviceRvt, OdGsBaseVectorizeDevice>::createObject();
	}
	OdSmartPtr<OdGsViewImpl> createViewObject()
	{
		OdSmartPtr<OdGsViewImpl> pP = OdRxObjectImpl<DataProcessorRvt, OdGsViewImpl>::createObject();
		((DataProcessorRvt*)pP.get())->init(collector, database);
		return pP;
	}
};
ODRX_DEFINE_PSEUDO_STATIC_MODULE(StubDeviceModuleRvt);

class RepoRvtServices : public ExSystemServices, public OdExBimHostAppServices
{
protected:
    ODRX_USING_HEAP_OPERATORS(ExSystemServices);
};

OdString Get3DLayout(OdDbBaseDatabasePEPtr baseDatabase, OdBmDatabasePtr bimDatabase)
{
	OdString layoutName;
	OdRxIteratorPtr layouts = baseDatabase->layouts(bimDatabase);

	for (; !layouts->done(); layouts->next())
	{
		OdBmDBDrawingPtr pDBDrawing = layouts->object();
		OdDbBaseLayoutPEPtr pLayout(layouts->object());

		if (pDBDrawing->getBaseViewNameFormat() == OdBm::ViewType::_3d)
		{
			//.. NOTE: set first 3D view available
			if (layoutName.isEmpty())
				layoutName = pLayout->name(layouts->object());

			//.. NOTE: try to find 3D view with a valid default name
			if (pDBDrawing->getName().find(L"3D") != -1)
				return pLayout->name(layouts->object());
		}
	}

	return layoutName;
}

repo::manipulator::modelconvertor::odaHelper::FileProcessorRvt::~FileProcessorRvt()
{

}

void FileProcessorRvt::setTessellationParams(wrTriangulationParams params)
{
	OdSmartPtr<BmModelerModule> pModModule;
	OdRxModulePtr pModule = odrxDynamicLinker()->loadModule(OdBmModelerModuleName);
	if (pModule.get())
	{
		pModModule = BmModelerModule::cast(pModule);
		pModModule->setTriangulationParams(params);
	}
}

void setupUnitsFormat(OdBmDatabasePtr pDb, double accuracy)
{
	OdBmUnitsTrackingPtr pUnitsTracking = pDb->getAppInfo(OdBm::ManagerType::UnitsTracking);
	OdBmUnitsElemPtr pUnitsElem = pUnitsTracking->getUnitsElemId().safeOpenObject();
	if (pUnitsElem.isNull())
		return;

	OdBmAUnitsPtr units = pUnitsElem->getUnits();
	if (units.isNull())
		return;

	OdBmFormatOptionsPtrArray formatOptionsArr;
	units->getFormatOptionsArr(formatOptionsArr);
	for (uint32_t i = 0; i < formatOptionsArr.size(); i++)
	{
		OdBmFormatOptions* formatOptions = formatOptionsArr[i];
		//.. NOTE: Here the format of units is configured
		formatOptions->setAccuracy(accuracy);
		formatOptions->setRoundingMethod(OdBm::RoundingMethod::Nearest);
	}
}

uint8_t FileProcessorRvt::readFile()
{
	int nRes = REPOERR_OK;
	OdStaticRxObject<RepoRvtServices> svcs;
	odrxInitialize(&svcs);
	OdRxModule* pModule = ::odrxDynamicLinker()->loadModule(OdBmLoaderModuleName, false);
	try
	{
		//.. change tessellation params here
		wrTriangulationParams triParams(USE_NEW_TESSELLATION);
		setTessellationParams(triParams);

		odgsInitialize();
		OdBmDatabasePtr pDb = svcs.readFile(OdString(file.c_str()));
		if (!pDb.isNull())
		{
			OdDbBaseDatabasePEPtr pDbPE(pDb);
			OdString layout = Get3DLayout(pDbPE, pDb);
			if (layout.isEmpty())
				return REPOERR_VALID_3D_VIEW_NOT_FOUND;

			pDbPE->setCurrentLayout(pDb, layout);

			OdGiContextForBmDatabasePtr pBimContext = OdGiContextForBmDatabase::createObject();
			OdGsModulePtr pGsModule = ODRX_STATIC_MODULE_ENTRY_POINT(StubDeviceModuleRvt)(OD_T("StubDeviceModuleRvt"));

			((StubDeviceModuleRvt*)pGsModule.get())->init(collector, pDb);
			OdGsDevicePtr pDevice = pGsModule->createDevice();

			pBimContext->setDatabase(pDb);
			pDevice = pDbPE->setupActiveLayoutViews(pDevice, pBimContext);
			OdGsDCRect screenRect(OdGsDCPoint(0, 0), OdGsDCPoint(1000, 1000)); //Set the screen space to the borders of the scene
			pDevice->onSize(screenRect);
			setupUnitsFormat(pDb, ROUNDING_ACCURACY);
			pDevice->update();
		}
	}
	catch (OdError& e)
	{
		nRes = REPOERR_LOAD_SCENE_FAIL;
		repoError << e.description().c_str();
	}

	return nRes;
}

<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "locatorplugin.h"
#include "locatorconstants.h"
#include "locatorfiltersfilter.h"
#include "locatormanager.h"
#include "locatorwidget.h"
#include "opendocumentsfilter.h"
#include "filesystemfilter.h"
#include "settingspage.h"

#include <QtCore/QSettings>
#include <QtCore/QtPlugin>
#include <QtCore/QFuture>
#include <QtCore/QFutureWatcher>

#include <coreplugin/statusbarwidget.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/settingsdatabase.h>
#include <coreplugin/icore.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
#include <extensionsystem/pluginmanager.h>
#include <qtconcurrent/QtConcurrentTools>

/*!
    \namespace Locator
    The Locator namespace provides the hooks for Locator content.
*/
/*!
    \namespace Locator::Internal
    \internal
*/

using namespace Locator;
using namespace Locator::Internal;

namespace {
    static bool filterLessThan(const ILocatorFilter *first, const ILocatorFilter *second)
    {
        if (first->priority() < second->priority())
            return true;
        if (first->priority() > second->priority())
            return false;
        if (first->id().compare(second->id(), Qt::CaseInsensitive) < 0)
            return true;
        return false;
    }
}

LocatorPlugin::LocatorPlugin()
{
    m_refreshTimer.setSingleShot(false);
    connect(&m_refreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
}

LocatorPlugin::~LocatorPlugin()
{
    removeObject(m_openDocumentsFilter);
    removeObject(m_fileSystemFilter);
    removeObject(m_settingsPage);
    delete m_openDocumentsFilter;
    delete m_fileSystemFilter;
    delete m_settingsPage;
    qDeleteAll(m_customFilters);
}

bool LocatorPlugin::initialize(const QStringList &, QString *)
{
    Core::ICore *core = Core::ICore::instance();
    m_settingsPage = new SettingsPage(this);
    addObject(m_settingsPage);

    m_locatorWidget = new LocatorWidget(this);
    m_locatorWidget->setEnabled(false);
    Core::StatusBarWidget *view = new Core::StatusBarWidget;
    view->setWidget(m_locatorWidget);
    view->setContext(Core::Context("LocatorWidget"));
    view->setPosition(Core::StatusBarWidget::First);
    addAutoReleasedObject(view);

    const QString actionId = QLatin1String("QtCreator.Locate");
    QAction *action = new QAction(m_locatorWidget->windowIcon(), m_locatorWidget->windowTitle(), this);
    Core::Command *cmd = core->actionManager()->registerAction(action, actionId, Core::Context(Core::Constants::C_GLOBAL));
    cmd->setDefaultKeySequence(QKeySequence("Ctrl+K"));
    connect(action, SIGNAL(triggered()), this, SLOT(openLocator()));

    Core::ActionContainer *mtools = core->actionManager()->actionContainer(Core::Constants::M_TOOLS);
    mtools->addAction(cmd);

    addObject(new LocatorManager(m_locatorWidget));

    m_openDocumentsFilter = new OpenDocumentsFilter(core->editorManager());
    addObject(m_openDocumentsFilter);

    m_fileSystemFilter = new FileSystemFilter(core->editorManager(), m_locatorWidget);
    addObject(m_fileSystemFilter);

    addAutoReleasedObject(new LocatorFiltersFilter(this, m_locatorWidget));

    connect(core, SIGNAL(coreOpened()), this, SLOT(startSettingsLoad()));
    return true;
}

void LocatorPlugin::openLocator()
{
    m_locatorWidget->show("");
}

void LocatorPlugin::extensionsInitialized()
{
    m_filters = ExtensionSystem::PluginManager::instance()->getObjects<ILocatorFilter>();
    qSort(m_filters.begin(), m_filters.end(), filterLessThan);
}

void LocatorPlugin::startSettingsLoad()
{
    m_loadWatcher.setFuture(QtConcurrent::run(this, &LocatorPlugin::loadSettings));
    connect(&m_loadWatcher, SIGNAL(finished()), this, SLOT(settingsLoaded()));
}

void LocatorPlugin::loadSettings()
{
    Core::ICore *core = Core::ICore::instance();
    QSettings *qs = core->settings();

    // Backwards compatibility to old settings location
    if (qs->contains("QuickOpen/FiltersFilter")) {
        loadSettingsHelper(qs);
    } else {
        Core::SettingsDatabase *settings = core->settingsDatabase();
        loadSettingsHelper(settings);
    }

    qs->remove("QuickOpen");
}

void LocatorPlugin::settingsLoaded()
{
    m_locatorWidget->updateFilterList();
    m_locatorWidget->setEnabled(true);
    if (m_refreshTimer.interval() > 0)
        m_refreshTimer.start();
}

void LocatorPlugin::saveSettings()
{
    Core::ICore *core = Core::ICore::instance();
    if (core && core->settingsDatabase()) {
        Core::SettingsDatabase *s = core->settingsDatabase();
        s->beginGroup("QuickOpen");
        s->remove("");
        s->setValue("RefreshInterval", refreshInterval());
        foreach (ILocatorFilter *filter, m_filters) {
            if (!m_customFilters.contains(filter))
                s->setValue(filter->id(), filter->saveState());
        }
        s->beginGroup("CustomFilters");
        int i = 0;
        foreach (ILocatorFilter *filter, m_customFilters) {
            s->setValue(QString("directory%1").arg(i), filter->saveState());
            ++i;
        }
        s->endGroup();
        s->endGroup();
    }
}

/*!
    \fn QList<ILocatorFilter*> LocatorPlugin::filters()

    Return all filters, including the ones created by the user.
*/
QList<ILocatorFilter*> LocatorPlugin::filters()
{
    return m_filters;
}

/*!
    \fn QList<ILocatorFilter*> LocatorPlugin::customFilters()

    This returns a subset of all the filters, that contains only the filters that
    have been created by the user at some point (maybe in a previous session).
 */
QList<ILocatorFilter*> LocatorPlugin::customFilters()
{
    return m_customFilters;
}

void LocatorPlugin::setFilters(QList<ILocatorFilter*> f)
{
    m_filters = f;
    m_locatorWidget->updateFilterList();
}

void LocatorPlugin::setCustomFilters(QList<ILocatorFilter *> filters)
{
    m_customFilters = filters;
}

int LocatorPlugin::refreshInterval()
{
    return m_refreshTimer.interval() / 60000;
}

void LocatorPlugin::setRefreshInterval(int interval)
{
    if (interval < 1) {
        m_refreshTimer.stop();
        m_refreshTimer.setInterval(0);
        return;
    }
    m_refreshTimer.setInterval(interval * 60000);
    m_refreshTimer.start();
}

void LocatorPlugin::refresh(QList<ILocatorFilter*> filters)
{
    if (filters.isEmpty())
        filters = m_filters;
    QFuture<void> task = QtConcurrent::run(&ILocatorFilter::refresh, filters);
    Core::FutureProgress *progress = Core::ICore::instance()
            ->progressManager()->addTask(task, tr("Indexing"),
                                         Locator::Constants::TASK_INDEX);
    connect(progress, SIGNAL(finished()), this, SLOT(saveSettings()));
}

Q_EXPORT_PLUGIN(LocatorPlugin)
<commit_msg>Fix possible race condition<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "locatorplugin.h"
#include "locatorconstants.h"
#include "locatorfiltersfilter.h"
#include "locatormanager.h"
#include "locatorwidget.h"
#include "opendocumentsfilter.h"
#include "filesystemfilter.h"
#include "settingspage.h"

#include <QtCore/QSettings>
#include <QtCore/QtPlugin>
#include <QtCore/QFuture>
#include <QtCore/QFutureWatcher>

#include <coreplugin/statusbarwidget.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/settingsdatabase.h>
#include <coreplugin/icore.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/progressmanager/futureprogress.h>
#include <extensionsystem/pluginmanager.h>
#include <qtconcurrent/QtConcurrentTools>

/*!
    \namespace Locator
    The Locator namespace provides the hooks for Locator content.
*/
/*!
    \namespace Locator::Internal
    \internal
*/

using namespace Locator;
using namespace Locator::Internal;

namespace {
    static bool filterLessThan(const ILocatorFilter *first, const ILocatorFilter *second)
    {
        if (first->priority() < second->priority())
            return true;
        if (first->priority() > second->priority())
            return false;
        if (first->id().compare(second->id(), Qt::CaseInsensitive) < 0)
            return true;
        return false;
    }
}

LocatorPlugin::LocatorPlugin()
{
    m_refreshTimer.setSingleShot(false);
    connect(&m_refreshTimer, SIGNAL(timeout()), this, SLOT(refresh()));
}

LocatorPlugin::~LocatorPlugin()
{
    removeObject(m_openDocumentsFilter);
    removeObject(m_fileSystemFilter);
    removeObject(m_settingsPage);
    delete m_openDocumentsFilter;
    delete m_fileSystemFilter;
    delete m_settingsPage;
    qDeleteAll(m_customFilters);
}

bool LocatorPlugin::initialize(const QStringList &, QString *)
{
    Core::ICore *core = Core::ICore::instance();
    m_settingsPage = new SettingsPage(this);
    addObject(m_settingsPage);

    m_locatorWidget = new LocatorWidget(this);
    m_locatorWidget->setEnabled(false);
    Core::StatusBarWidget *view = new Core::StatusBarWidget;
    view->setWidget(m_locatorWidget);
    view->setContext(Core::Context("LocatorWidget"));
    view->setPosition(Core::StatusBarWidget::First);
    addAutoReleasedObject(view);

    const QString actionId = QLatin1String("QtCreator.Locate");
    QAction *action = new QAction(m_locatorWidget->windowIcon(), m_locatorWidget->windowTitle(), this);
    Core::Command *cmd = core->actionManager()->registerAction(action, actionId, Core::Context(Core::Constants::C_GLOBAL));
    cmd->setDefaultKeySequence(QKeySequence("Ctrl+K"));
    connect(action, SIGNAL(triggered()), this, SLOT(openLocator()));

    Core::ActionContainer *mtools = core->actionManager()->actionContainer(Core::Constants::M_TOOLS);
    mtools->addAction(cmd);

    addObject(new LocatorManager(m_locatorWidget));

    m_openDocumentsFilter = new OpenDocumentsFilter(core->editorManager());
    addObject(m_openDocumentsFilter);

    m_fileSystemFilter = new FileSystemFilter(core->editorManager(), m_locatorWidget);
    addObject(m_fileSystemFilter);

    addAutoReleasedObject(new LocatorFiltersFilter(this, m_locatorWidget));

    connect(core, SIGNAL(coreOpened()), this, SLOT(startSettingsLoad()));
    return true;
}

void LocatorPlugin::openLocator()
{
    m_locatorWidget->show("");
}

void LocatorPlugin::extensionsInitialized()
{
    m_filters = ExtensionSystem::PluginManager::instance()->getObjects<ILocatorFilter>();
    qSort(m_filters.begin(), m_filters.end(), filterLessThan);
}

void LocatorPlugin::startSettingsLoad()
{
    connect(&m_loadWatcher, SIGNAL(finished()), this, SLOT(settingsLoaded()));
    m_loadWatcher.setFuture(QtConcurrent::run(this, &LocatorPlugin::loadSettings));
}

void LocatorPlugin::loadSettings()
{
    Core::ICore *core = Core::ICore::instance();
    QSettings *qs = core->settings();

    // Backwards compatibility to old settings location
    if (qs->contains("QuickOpen/FiltersFilter")) {
        loadSettingsHelper(qs);
    } else {
        Core::SettingsDatabase *settings = core->settingsDatabase();
        loadSettingsHelper(settings);
    }

    qs->remove("QuickOpen");
}

void LocatorPlugin::settingsLoaded()
{
    m_locatorWidget->updateFilterList();
    m_locatorWidget->setEnabled(true);
    if (m_refreshTimer.interval() > 0)
        m_refreshTimer.start();
}

void LocatorPlugin::saveSettings()
{
    Core::ICore *core = Core::ICore::instance();
    if (core && core->settingsDatabase()) {
        Core::SettingsDatabase *s = core->settingsDatabase();
        s->beginGroup("QuickOpen");
        s->remove("");
        s->setValue("RefreshInterval", refreshInterval());
        foreach (ILocatorFilter *filter, m_filters) {
            if (!m_customFilters.contains(filter))
                s->setValue(filter->id(), filter->saveState());
        }
        s->beginGroup("CustomFilters");
        int i = 0;
        foreach (ILocatorFilter *filter, m_customFilters) {
            s->setValue(QString("directory%1").arg(i), filter->saveState());
            ++i;
        }
        s->endGroup();
        s->endGroup();
    }
}

/*!
    \fn QList<ILocatorFilter*> LocatorPlugin::filters()

    Return all filters, including the ones created by the user.
*/
QList<ILocatorFilter*> LocatorPlugin::filters()
{
    return m_filters;
}

/*!
    \fn QList<ILocatorFilter*> LocatorPlugin::customFilters()

    This returns a subset of all the filters, that contains only the filters that
    have been created by the user at some point (maybe in a previous session).
 */
QList<ILocatorFilter*> LocatorPlugin::customFilters()
{
    return m_customFilters;
}

void LocatorPlugin::setFilters(QList<ILocatorFilter*> f)
{
    m_filters = f;
    m_locatorWidget->updateFilterList();
}

void LocatorPlugin::setCustomFilters(QList<ILocatorFilter *> filters)
{
    m_customFilters = filters;
}

int LocatorPlugin::refreshInterval()
{
    return m_refreshTimer.interval() / 60000;
}

void LocatorPlugin::setRefreshInterval(int interval)
{
    if (interval < 1) {
        m_refreshTimer.stop();
        m_refreshTimer.setInterval(0);
        return;
    }
    m_refreshTimer.setInterval(interval * 60000);
    m_refreshTimer.start();
}

void LocatorPlugin::refresh(QList<ILocatorFilter*> filters)
{
    if (filters.isEmpty())
        filters = m_filters;
    QFuture<void> task = QtConcurrent::run(&ILocatorFilter::refresh, filters);
    Core::FutureProgress *progress = Core::ICore::instance()
            ->progressManager()->addTask(task, tr("Indexing"),
                                         Locator::Constants::TASK_INDEX);
    connect(progress, SIGNAL(finished()), this, SLOT(saveSettings()));
}

Q_EXPORT_PLUGIN(LocatorPlugin)
<|endoftext|>


<commit_before>/*
 * This file is part of the IAN project - https://github.com/Meoo/IAN
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <spdlog/spdlog.h>

#define IAN__LOG_WRAP(x) do{ x ;}while((void)0,0)

#ifdef NDEBUG
#define IAN_TRACE(logger, ...) IAN__LOG_WRAP()
#define IAN_DEBUG(logger, ...) IAN__LOG_WRAP()
#else
#define IAN_TRACE(logger, ...) IAN__LOG_WRAP((logger)->trace(__VA_ARGS__))
#define IAN_DEBUG(logger, ...) IAN__LOG_WRAP((logger)->debug(__VA_ARGS__))
#endif

#define IAN_INFO(logger, ...) IAN__LOG_WRAP((logger)->info(__VA_ARGS__))
#define IAN_WARN(logger, ...) IAN__LOG_WRAP((logger)->warn(__VA_ARGS__))
#define IAN_ERROR(logger, ...) IAN__LOG_WRAP((logger)->error(__VA_ARGS__))
#define IAN_CRITICAL(logger, ...) IAN__LOG_WRAP((logger)->critical(__VA_ARGS__))
<commit_msg>Fix log warnings + multi include<commit_after>/*
 * This file is part of the IAN project - https://github.com/Meoo/IAN
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include <spdlog/spdlog.h>

#define IAN__LOG_WRAP(x) do{ x ;}while((void)0,0)

#ifdef NDEBUG
#define IAN_TRACE(logger, ...) IAN__LOG_WRAP(;)
#define IAN_DEBUG(logger, ...) IAN__LOG_WRAP(;)
#else
#define IAN_TRACE(logger, ...) IAN__LOG_WRAP((logger)->trace(__VA_ARGS__))
#define IAN_DEBUG(logger, ...) IAN__LOG_WRAP((logger)->debug(__VA_ARGS__))
#endif

#define IAN_INFO(logger, ...) IAN__LOG_WRAP((logger)->info(__VA_ARGS__))
#define IAN_WARN(logger, ...) IAN__LOG_WRAP((logger)->warn(__VA_ARGS__))
#define IAN_ERROR(logger, ...) IAN__LOG_WRAP((logger)->error(__VA_ARGS__))
#define IAN_CRITICAL(logger, ...) IAN__LOG_WRAP((logger)->critical(__VA_ARGS__))
<|endoftext|>


<commit_before>/*
 * test1.cpp
 *
 *  Created on: Aug 21, 2016
 *      Author: pavel
 */

#include <memory>
#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include <fun.h>

using namespace std;
using namespace fun;

bool parse(const std::string& source) {
    stringstream ss;
    ss << source;
    FunLexer lexer("", &ss);
    Ast ast;
    FunParser parser(lexer, &ast);
    parser.set_debug_level(0);
    int result = parser.parse();
    return result == 0;
}

TEST(Parse, Test1) {
    {
        ASSERT_EQ(parse(R"()"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Test2) {
    {
        ASSERT_EQ(parse(R"(
print 42
print 3.14
print "foo"
print nil
print false
print true
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Test3) {
    {
        ASSERT_EQ(parse(R"(
foo =
)"), false);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Test4) {
    {
        ASSERT_EQ(parse(R"(
foo = 42)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Test5) {
    {
        ASSERT_EQ(parse(R"(
foo = 42)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

struct Result {
    std::unique_ptr<Interpreter> v;
    std::unique_ptr<Debugger> d;
    std::unique_ptr<Ast> ast;
};

class DebuggerMock: public Debugger {
public:
    MOCK_METHOD1(onCatchBreakpoint, void(const Breakpoint &));
    MOCK_METHOD1(onOperandsChanged, void(const std::vector<Terminal*> &));
    MOCK_METHOD1(onMemoryChanged, void(const std::unordered_map<std::string, Terminal*>&));
};

Result interpret(const std::string& source) {
    std::unique_ptr<Debugger> debugger(new DebuggerMock);
    std::unique_ptr<Interpreter> interpreter(new Interpreter(debugger.get()));
    std::unique_ptr<Ast> ast(new Ast);
    stringstream ss;
    ss << source;
    FunLexer lexer("", &ss);
    FunParser parser(lexer, ast.get());
    parser.set_debug_level(0);
    bool result = parser.parse();
    ast->accept(interpreter.get());
    return {move(interpreter), move(debugger), move(ast)};
}

TEST(Fun, leakTest1) {
    {
        auto result = interpret(R"(foo = 42)");

        ASSERT_EQ(Statement::counter(), 3);

        ASSERT_EQ(result.v->getOperands().size(), 0);
        ASSERT_EQ(result.v->getMemory()[0].size(), 1);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Fun, test2) {
    {
        auto result = interpret(R"(
foo = 42
print foo
)");
        ASSERT_EQ(Statement::counter(), 5);
    }
    ASSERT_EQ(Statement::counter(), 0);
}
<commit_msg>добавил тестов<commit_after>/*
 * test1.cpp
 *
 *  Created on: Aug 21, 2016
 *      Author: pavel
 */

#include <memory>
#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include <fun.h>

using namespace std;
using namespace fun;

bool parse(const std::string& source) {
    stringstream ss;
    ss << source;
    FunLexer lexer("", &ss);
    Ast ast;
    FunParser parser(lexer, &ast);
    parser.set_debug_level(0);
    int result = parser.parse();
    return result == 0;
}

TEST(Parse, Empty_0) {
    {
        ASSERT_EQ(parse(R"()"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Integer_0) {
    {
        ASSERT_EQ(parse(R"(
42
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Integer_1) {
    {
        ASSERT_EQ(parse(R"(
1000000000
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Integer_2) {
    {
        ASSERT_EQ(parse(R"(
0
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Integer_3) {
    {
        ASSERT_EQ(parse(R"(
100
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Bool_0) {
    {
        ASSERT_EQ(parse(R"(
true
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Bool_1) {
    {
        ASSERT_EQ(parse(R"(
false
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Float_0) {
    {
        ASSERT_EQ(parse(R"(
0.0
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Float_1) {
    {
        ASSERT_EQ(parse(R"(
1.0
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Float_2) {
    {
        ASSERT_EQ(parse(R"(
.0
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Float_3) {
    {
        ASSERT_EQ(parse(R"(
10.
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Float_4) {
    {
        ASSERT_EQ(parse(R"(
1.0e1
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Float_5) {
    {
        ASSERT_EQ(parse(R"(
1.0E1
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Float_6) {
    {
        ASSERT_EQ(parse(R"(
.1e-3
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Float_7) {
    {
        ASSERT_EQ(parse(R"(
.13145E-12
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Test2) {
    {
        ASSERT_EQ(parse(R"(
print 42
print 3.14
print "foo"
print nil
print false
print true
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Test3) {
    {
        ASSERT_EQ(parse(R"(
foo =
)"), false);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Test4) {
    {
        ASSERT_EQ(parse(R"(
foo = 42)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, Test5) {
    {
        ASSERT_EQ(parse(R"(
foo = 42)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, If_1) {
    {
        ASSERT_EQ(parse(R"(
if
)"), false);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, If_2) {
    {
        ASSERT_EQ(parse(R"(
if
end
)"), false);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, If_3) {
    {
        ASSERT_EQ(parse(R"(
if nil
end
)"), false);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, If_4) {
    {
        ASSERT_EQ(parse(R"(
if:
end
)"), false);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, If_5) {
    {
        ASSERT_EQ(parse(R"(
if nil:
end
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, If_6) {
    {
        ASSERT_EQ(parse(R"(
if 0:
if 1:
end
)"), false);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, If_7) {
    {
        ASSERT_EQ(parse(R"(
if 0:
elif 1:
end
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, If_8) {
    {
        ASSERT_EQ(parse(R"(
if 0:
elif 1:
else
end
)"), true);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Parse, If_9) {
    {
        ASSERT_EQ(parse(R"(
if 0:
    ""
elif 1:
    5
else
    4
else
    2
end
)"), false);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

struct Result {
    std::unique_ptr<Interpreter> v;
    std::unique_ptr<Debugger> d;
    std::unique_ptr<Ast> ast;
};

class DebuggerMock: public Debugger {
public:
    MOCK_METHOD1(onCatchBreakpoint, void(const Breakpoint &));
    MOCK_METHOD1(onOperandsChanged, void(const std::vector<Terminal*> &));
    MOCK_METHOD1(onMemoryChanged, void(const std::unordered_map<std::string, Terminal*>&));
};

Result interpret(const std::string& source) {
    std::unique_ptr<Debugger> debugger(new DebuggerMock);
    std::unique_ptr<Interpreter> interpreter(new Interpreter(debugger.get()));
    std::unique_ptr<Ast> ast(new Ast);
    stringstream ss;
    ss << source;
    FunLexer lexer("", &ss);
    FunParser parser(lexer, ast.get());
    parser.set_debug_level(0);
    bool result = parser.parse();
    ast->accept(interpreter.get());
    return {move(interpreter), move(debugger), move(ast)};
}

TEST(Fun, leakTest1) {
    {
        auto result = interpret(R"(foo = 42)");

        ASSERT_EQ(Statement::counter(), 3);

        ASSERT_EQ(result.v->getOperands().size(), 0);
        ASSERT_EQ(result.v->getMemory()[0].size(), 1);
    }
    ASSERT_EQ(Statement::counter(), 0);
}

TEST(Fun, test2) {
    {
        auto result = interpret(R"(
foo = 42
print foo
)");
        ASSERT_EQ(Statement::counter(), 5);
    }
    ASSERT_EQ(Statement::counter(), 0);
}
<|endoftext|>


<commit_before>#pragma once

#include <cstring>
#include <vector>

using std::vector;

class Solution {
public:
    int strStr(char* haystack, char* needle) {
        auto haySZ = strlen(haystack);
        auto neeSZ = strlen(needle);

        vector<int> overlap;
        buildOverlapTable(needle, neeSZ, overlap);
    }

private:
    void buildOverlapTable(char* neeedle, size_t sz, vector<int>& table) {
        table.push_back(0);
        --sz;

        for (int i = 0; i < sz; ++i) {
            char ch = neeedle[i + 1];
            int overlap = table[i];

            for (; overlap != 0 && neeedle[i + 1] != ch; overlap = table[overlap]);

            if (neeedle[i + 1] == ch) {
                table.push_back(overlap + 1);
            } else {
                table.push_back(0);
            }
        }
    }
};
<commit_msg>mismatch table generator function implemented<commit_after>#pragma once

#include <cstring>
#include <vector>
#include <iostream>

#include "../../../../include/cpp/pretty_print.hxx"

using std::vector;
using std::cout;
using std::endl;

class Solution {
public:
    int strStr(char* T, char* P) {
        vector<int> overlap;
        buildOverlapTable(P, overlap);

        cout << overlap << endl;

        return -1;
    }

private:
    void buildOverlapTable(char*needle, vector<int>& table) {
        table.clear();
        table.push_back(0);

        int prefix{};

        for (char* ptr = needle + 1; *ptr != '\0'; ++ptr) {
            while (prefix && needle[prefix] != *ptr) {
                prefix = table[prefix - 1];
            }

            if (*ptr == needle[prefix]) {
                ++prefix;
            }

            table.push_back(prefix);
        }
    }
};
<|endoftext|>