<commit_before>/*
 * callable.hpp
 *
 *  Created on: 29 мая 2016 г.
 *      Author: sergey.fedorov
 */

#ifndef PUSHKIN_META_CALLABLE_HPP_
#define PUSHKIN_META_CALLABLE_HPP_

#include <pushkin/meta/index_tuple.hpp>
#include <tuple>
#include <type_traits>

namespace psst {
namespace meta {

template <typename Functor, typename ... Args>
struct is_callable {
private:
    using args_tuple    = ::std::tuple<Args...>;
    using indexes       = typename index_builder< sizeof ... (Args) >::type;
    static args_tuple& args;

    template <typename U, ::std::size_t ... Indexes>
    static ::std::true_type
    test(indexes_tuple<Indexes...> const&,
        decltype( ::std::declval<U>()( ::std::forward<Args>(::std::get<Indexes>(args))... ) ) const*);
    template <typename U>
    static ::std::false_type
    test(...);
public:
    static constexpr bool value = decltype( test<Functor>(indexes{}, nullptr) )::value;
};

template < typename Predicate >
struct not_ {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return !Predicate{}(::std::forward<Args>(args)...);
    }
};

template < typename ... Predicates >
struct and_;
template < typename ... Predicates >
struct or_;

template < typename Predicate, typename ... Rest >
struct and_<Predicate, Rest...> {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return Predicate{}(::std::forward<Args>(args)...)
            && and_<Rest...>{}(::std::forward<Args>(args)...);
    }
};

template < typename Predicate >
struct and_<Predicate> {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return Predicate{}(::std::forward<Args>(args)...);
    }
};

template <>
struct and_<> {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return false;
    }
};

template < typename Predicate, typename ... Rest >
struct or_<Predicate, Rest...> {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return Predicate{}(::std::forward<Args>(args)...)
            || and_<Rest...>{}(::std::forward<Args>(args)...);
    }
};

template < typename Predicate >
struct or_<Predicate> {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return Predicate{}(::std::forward<Args>(args)...);
    }
};

template <>
struct or_<> {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return true;
    }
};

}  /* namespace meta */
}  /* namespace pus */

#endif /* PUSHKIN_META_CALLABLE_HPP_ */
<commit_msg>Satisfy -Werror,-Wunused-parameter flags<commit_after>/*
 * callable.hpp
 *
 *  Created on: 29 мая 2016 г.
 *      Author: sergey.fedorov
 */

#ifndef PUSHKIN_META_CALLABLE_HPP_
#define PUSHKIN_META_CALLABLE_HPP_

#include <pushkin/meta/index_tuple.hpp>
#include <tuple>
#include <type_traits>

namespace psst {
namespace meta {

template <typename Functor, typename ... Args>
struct is_callable {
private:
    using args_tuple    = ::std::tuple<Args...>;
    using indexes       = typename index_builder< sizeof ... (Args) >::type;
    static args_tuple& args;

    template <typename U, ::std::size_t ... Indexes>
    static ::std::true_type
    test(indexes_tuple<Indexes...> const&,
        decltype( ::std::declval<U>()( ::std::forward<Args>(::std::get<Indexes>(args))... ) ) const*);
    template <typename U>
    static ::std::false_type
    test(...);
public:
    static constexpr bool value = decltype( test<Functor>(indexes{}, nullptr) )::value;
};

template < typename Predicate >
struct not_ {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return !Predicate{}(::std::forward<Args>(args)...);
    }
};

template < typename ... Predicates >
struct and_;
template < typename ... Predicates >
struct or_;

template < typename Predicate, typename ... Rest >
struct and_<Predicate, Rest...> {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return Predicate{}(::std::forward<Args>(args)...)
            && and_<Rest...>{}(::std::forward<Args>(args)...);
    }
};

template < typename Predicate >
struct and_<Predicate> {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return Predicate{}(::std::forward<Args>(args)...);
    }
};

template <>
struct and_<> {
    template < typename ... Args >
    bool
    operator()(Args&& ...) const
    {
        return false;
    }
};

template < typename Predicate, typename ... Rest >
struct or_<Predicate, Rest...> {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return Predicate{}(::std::forward<Args>(args)...)
            || and_<Rest...>{}(::std::forward<Args>(args)...);
    }
};

template < typename Predicate >
struct or_<Predicate> {
    template < typename ... Args >
    bool
    operator()(Args&& ... args) const
    {
        return Predicate{}(::std::forward<Args>(args)...);
    }
};

template <>
struct or_<> {
    template < typename ... Args >
    bool
    operator()(Args&& ...) const
    {
        return true;
    }
};

}  /* namespace meta */
}  /* namespace pus */

#endif /* PUSHKIN_META_CALLABLE_HPP_ */
<|endoftext|>


<commit_before>#ifndef GENERIC_SIZE_HPP
# define GENERIC_SIZE_HPP
# pragma once

namespace generic
{

// size
template <typename T, ::std::size_t N>
inline constexpr decltype(N) size(T const (&)[N]) noexcept
{
  return N;
}

}

#endif // GENERIC_SIZE_HPP
<commit_msg>some fixes<commit_after>#ifndef GENERIC_SIZE_HPP
# define GENERIC_SIZE_HPP
# pragma once

namespace generic
{

// size
template <typename T, ::std::size_t N>
inline constexpr decltype(N) size(T const (&)[N]) noexcept
{
  return N;
}

template <typename T, ::std::size_t M, ::std::size_t N>
inline constexpr decltype(N) size(T const (&array)[M][N]) noexcept
{
  return M * size(*array);
}

}

#endif // GENERIC_SIZE_HPP
<|endoftext|>


<commit_before>#ifndef LUA_H
	#include "lua_adapter.hpp"
#endif

int main (int argc, char *argv[]) {

    LuaAdapter lua("test.lua");

    //simply parameterize your application!
    int height {0};
    lua.get("height", height);
    std::cout << "height: " << height << "\n";

    // let's close ..
    lua.close();
    // and (re-)initialize for further tests..
    lua.init();

    // Hint: You CAN change a (default) value of a global lua variable BEFORE loading the actual lua-file
    if(lua.set("GlobalVar", 321)==false){
        std::cout << "Could not set 'GlobalVar'!\n";
    }

    // and THEN load the script:
    lua.load("test.lua");

    //get an int
    int width {0};
    lua.get("width", width);
    std::cout << "width: " << width << "\n";

    //get double
    double number {0};
    lua.get("number", number);
    std::cout << "Number: "<< number << "\n";

    //get string
    std::string title {"empty"};
    lua.get("title", title);
    std::cout << "title: " << title << "\n";

    std::cout << "\n";

    // tables
    if(lua.openTable("Table1")) {
        int ID {0};
        lua.getField("ID", ID);
        std::cout << "ID: " << ID << "\n";

        int Val {0};
        lua.getField("Val", Val);
        std::cout << "Val: " << Val << "\n";

        lua.closeTable(); // close "Table1"
    }

    std::cout << "\n";

    if(lua.openTable("matrix")) {
        for(unsigned char j=1; j<=3; j++){
            for(unsigned char i=1; i<=3; i++){
                int temp = 0;
                lua.getNestedField(j, i, temp); // matrix[j][i]
                std::cout << temp << " ";
            }
            std::cout << "\n";
        }
        lua.closeTable(); // close table "matrix"
    }
    std::cout << "\n";

    // more table-tests
    if(lua.openTable("Table2")) {
        int X {0};
        lua.getField("X", X);
        std::cout << "X: " << X << "\n";

        int Y {0};
        lua.getField("Y", Y);
        std::cout << "Y: " << Y << "\n";

        if(lua.openNestedTable("Test") )  {
            int A = 0;
            lua.getField("A", A);
            std::cout << "\t A: " << A << "\n";
            int B = 0;
            lua.getField("B", B);
            std::cout << "\t B: " << B << "\n";

            lua.closeTable(); // close nested table "Test"
        }
        lua.closeTable(); // close "Table2"
    }

    // Check lua's internal stack
    std::cout << "\n";
    std::cout << "Lua stack top: " << lua.getTop() << "\n"; // should be 0

    // calling a function from test.lua to compute stuff
    int test[] = {36, 24};
    int result {0};
    lua.callFunction("gcd", 2, test, result);
    std::cout << "gcd: " << result << "\n";

    return 0;
}
<commit_msg>Added C++-function-call-example.<commit_after>#ifndef LUA_H
	#include "lua_adapter.hpp"
#endif
static int testCFunction(lua_State *L);

int main (int argc, char *argv[]) {

    LuaAdapter lua("test.lua");

    //simply parameterize your application!
    int height {0};
    lua.get("height", height);
    std::cout << "height: " << height << "\n";

    // let's close ..
    lua.close();
    // and (re-)initialize for further tests..
    lua.init();

    // Hint: You CAN change a (default) value of a global lua variable BEFORE loading the actual lua-file
    if(lua.set("GlobalVar", 321)==false){
        std::cout << "Could not set 'GlobalVar'!\n";
    }

    // and THEN load the script:
    lua.load("test.lua");

    //get an int
    int width {0};
    lua.get("width", width);
    std::cout << "width: " << width << "\n";

    //get double
    double number {0};
    lua.get("number", number);
    std::cout << "Number: "<< number << "\n";

    //get string
    std::string title {"empty"};
    lua.get("title", title);
    std::cout << "title: " << title << "\n";

    std::cout << "\n";

    // tables
    if(lua.openTable("Table1")) {
        int ID {0};
        lua.getField("ID", ID);
        std::cout << "ID: " << ID << "\n";

        int Val {0};
        lua.getField("Val", Val);
        std::cout << "Val: " << Val << "\n";

        lua.closeTable(); // close "Table1"
    }

    std::cout << "\n";

    if(lua.openTable("matrix")) {
        for(unsigned char j=1; j<=3; j++){
            for(unsigned char i=1; i<=3; i++){
                int temp = 0;
                lua.getNestedField(j, i, temp); // matrix[j][i]
                std::cout << temp << " ";
            }
            std::cout << "\n";
        }
        lua.closeTable(); // close table "matrix"
    }
    std::cout << "\n";

    // more table-tests
    if(lua.openTable("Table2")) {
        int X {0};
        lua.getField("X", X);
        std::cout << "X: " << X << "\n";

        int Y {0};
        lua.getField("Y", Y);
        std::cout << "Y: " << Y << "\n";

        if(lua.openNestedTable("Test") )  {
            int A = 0;
            lua.getField("A", A);
            std::cout << "\t A: " << A << "\n";
            int B = 0;
            lua.getField("B", B);
            std::cout << "\t B: " << B << "\n";

            lua.closeTable(); // close nested table "Test"
        }
        lua.closeTable(); // close "Table2"
    }

    // Check lua's internal stack
    std::cout << "\n";
    std::cout << "Lua stack top: " << lua.getTop() << "\n"; // should be 0

    // calling a function from test.lua to compute stuff
    int test[] = {36, 24};
    int result {0};
    lua.callFunction("gcd", 2, test, result);
    std::cout << "gcd: " << result << "\n";
    std::cout << "\n";

    // Push a C/C++-function to our lua-stack...
    lua.pushFunction(testCFunction, "testFunction");

    // and call it!
    double result2 {0};
    lua.callFunction("testFunction", result2);
    std::cout << "testing C-Function: " << result2 << "\n";

    std::cout << "Lua stack top: " << lua.getTop() << "\n"; // 0
    return 0;
}

// This function can be called from Lua
static int testCFunction(lua_State *L){
    LuaAdapter lua {L};
    double number {0};
    lua.get("number", number);

    std::cout << "Number: "<< number << "\n";
    std::cout << "Lua stack top: " << lua.getTop() << "\n"; // 1

    number *=2;
    lua.push(number);
    return 1;
}
<|endoftext|>


<commit_before>#include <cv.h>
#include <highgui.h>
#include <math.h>
#include <iostream>

using namespace cv;

void showHistogram(Mat& img);

int main(int argc, char* argv[])
{
  Mat img, gray, post, anded;

  if(!(img=imread("pool1.jpg", 1)).data)
  {
      std::cout << "crap" << std::endl;
      return -1;
  }
  else
  {
      std::cout << "yay" << std::endl;
  }

  cvtColor(img,img, CV_BGR2HSV);
  inRange(img, Scalar(0, 0, 60), Scalar(180, 100, 200), post);

  bitwise_not(post, post);

  cvtColor(post,post, CV_GRAY2BGR);
  cvtColor(img,img, CV_HSV2BGR);

  bitwise_and(img, post, anded);

  cvtColor(post, gray, CV_BGR2GRAY);
  cvtColor(post, post, CV_BGR2GRAY);

  // smooth it, otherwise a lot of false circles may be detected
  GaussianBlur( gray, gray, Size(25, 25), 9, 9 );
  threshold(gray, gray, 40, 255, THRESH_BINARY);
  GaussianBlur( gray, gray, Size(9, 9), 2, 2 );

  vector<Vec3f> circles;
  HoughCircles(gray, circles, CV_HOUGH_GRADIENT,
                 2, 40, 200, 60, 10, 50 );

  for( size_t i = 0; i < circles.size(); i++ )
    {
         Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
         int radius = cvRound(circles[i][2]);
         // draw the circle center
         circle( anded, center, 3, Scalar(0,255,0), -1, 8, 0 );
         // draw the circle outline
         circle( anded, center, radius, Scalar(0,0,255), 3, 8, 0 );

	 // center and radius are the results of HoughCircle
	// mask is a CV_8UC1 image with 0

	Mat dst, mask = Mat::zeros( img.rows, img.cols, CV_8UC1 );
	circle( mask, center, radius, Scalar(255,255,255), -1, 8, 0 ); //-1 means filled
	bitwise_and(post, mask, mask);
	img.copyTo( dst, mask ); // copy values of img to dst if mask is > 0.
	Mat cropped( dst, Rect( center.x-radius, center.y-radius, radius*2, radius*2 ) );

	imshow("test", cropped);
	showHistogram(cropped);
	waitKey(0);
    }

//     imshow("img", img);
//     imshow("gray", gray);
//     imshow("anded", anded);
//     showHistogram(img);
//     waitKey(0);
//     imwrite( "post.jpg", post );
//
//     imwrite( "anded.jpg", anded );
//
//     imwrite( "gray.jpg", gray );
//
//     imwrite( "img.jpg", img );

    return 0;
}

void showHistogram(Mat& img)
{
	int bins = 256;             // number of bins
	int nc = img.channels();    // number of channels

	vector<Mat> hist(nc);       // histogram arrays

	// Initalize histogram arrays
	for (int i = 0; i < hist.size(); i++)
		hist[i] = Mat::zeros(1, bins, CV_32SC1);

	// Calculate the histogram of the image
	for (int i = 0; i < img.rows; i++)
	{
		for (int j = 0; j < img.cols; j++)
		{
			if (!((img.at<Vec3b>(i,j)[0] == 0) &&
			      (img.at<Vec3b>(i,j)[1] == 0) &&
			      (img.at<Vec3b>(i,j)[2] == 0)))
			{
			for (int k = 0; k < nc; k++)
			{
				uchar val = nc == 1 ? img.at<uchar>(i,j) : img.at<Vec3b>(i,j)[k];
				hist[k].at<int>(val) += 1;
			}
			}
		}
	}

	// For each histogram arrays, obtain the maximum (peak) value
	// Needed to normalize the display later
	int hmax = 0;
	for (int i = 0; i < nc; i++)
	{
		for (int j = 0; j < bins-1; j++)
			hmax = hist[i].at<int>(j) > hmax ? hist[i].at<int>(j) : hmax;
	}

	const char* wname[3] = { "blue", "green", "red" };
	Scalar colors[3] = { Scalar(255,0,0), Scalar(0,255,0), Scalar(0,0,255) };

	vector<Mat> canvas(nc);

	// Display each histogram in a canvas
	for (int i = 0; i < nc; i++)
	{
		canvas[i] = Mat::ones(125, bins, CV_8UC3);

		for (int j = 0, rows = canvas[i].rows; j < bins-1; j++)
		{
			line(
				canvas[i],
				Point(j, rows),
				Point(j, rows - (hist[i].at<int>(j) * rows/hmax)),
				nc == 1 ? Scalar(200,200,200) : colors[i],
				1, 8, 0
			);
		}

		imshow(nc == 1 ? "value" : wname[i], canvas[i]);
	}
}<commit_msg>-Added build line comment temporarily.<commit_after>#include <cv.h>
#include <highgui.h>
#include <math.h>
#include <iostream>

using namespace cv;

//g++ -o PoolVisor test.cpp  `pkg-config --cflags --libs opencv`

void showHistogram(Mat& img);

int main(int argc, char* argv[])
{
  Mat img, gray, post, anded;

  if(!(img=imread("pool1.jpg", 1)).data)
  {
      std::cout << "crap" << std::endl;
      return -1;
  }
  else
  {
      std::cout << "yay" << std::endl;
  }

  cvtColor(img,img, CV_BGR2HSV);
  inRange(img, Scalar(0, 0, 60), Scalar(180, 100, 200), post);

  bitwise_not(post, post);

  cvtColor(post,post, CV_GRAY2BGR);
  cvtColor(img,img, CV_HSV2BGR);

  bitwise_and(img, post, anded);

  cvtColor(post, gray, CV_BGR2GRAY);
  cvtColor(post, post, CV_BGR2GRAY);

  // smooth it, otherwise a lot of false circles may be detected
  GaussianBlur( gray, gray, Size(25, 25), 9, 9 );
  threshold(gray, gray, 40, 255, THRESH_BINARY);
  GaussianBlur( gray, gray, Size(9, 9), 2, 2 );

  vector<Vec3f> circles;
  HoughCircles(gray, circles, CV_HOUGH_GRADIENT,
                 2, 40, 200, 60, 10, 50 );

  for( size_t i = 0; i < circles.size(); i++ )
    {
         Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
         int radius = cvRound(circles[i][2]);
         // draw the circle center
         circle( anded, center, 3, Scalar(0,255,0), -1, 8, 0 );
         // draw the circle outline
         circle( anded, center, radius, Scalar(0,0,255), 3, 8, 0 );

	 // center and radius are the results of HoughCircle
	// mask is a CV_8UC1 image with 0

	Mat dst, mask = Mat::zeros( img.rows, img.cols, CV_8UC1 );
	circle( mask, center, radius, Scalar(255,255,255), -1, 8, 0 ); //-1 means filled
	bitwise_and(post, mask, mask);
	img.copyTo( dst, mask ); // copy values of img to dst if mask is > 0.
	Mat cropped( dst, Rect( center.x-radius, center.y-radius, radius*2, radius*2 ) );

	imshow("test", cropped);
	showHistogram(cropped);
	waitKey(0);
    }

//     imshow("img", img);
//     imshow("gray", gray);
//     imshow("anded", anded);
//     showHistogram(img);
//     waitKey(0);
//     imwrite( "post.jpg", post );
//
//     imwrite( "anded.jpg", anded );
//
//     imwrite( "gray.jpg", gray );
//
//     imwrite( "img.jpg", img );

    return 0;
}

void showHistogram(Mat& img)
{
	int bins = 256;             // number of bins
	int nc = img.channels();    // number of channels

	vector<Mat> hist(nc);       // histogram arrays

	// Initalize histogram arrays
	for (int i = 0; i < hist.size(); i++)
		hist[i] = Mat::zeros(1, bins, CV_32SC1);

	// Calculate the histogram of the image
	for (int i = 0; i < img.rows; i++)
	{
		for (int j = 0; j < img.cols; j++)
		{
			if (!((img.at<Vec3b>(i,j)[0] == 0) &&
			      (img.at<Vec3b>(i,j)[1] == 0) &&
			      (img.at<Vec3b>(i,j)[2] == 0)))
			{
			for (int k = 0; k < nc; k++)
			{
				uchar val = nc == 1 ? img.at<uchar>(i,j) : img.at<Vec3b>(i,j)[k];
				hist[k].at<int>(val) += 1;
			}
			}
		}
	}

	// For each histogram arrays, obtain the maximum (peak) value
	// Needed to normalize the display later
	int hmax = 0;
	for (int i = 0; i < nc; i++)
	{
		for (int j = 0; j < bins-1; j++)
			hmax = hist[i].at<int>(j) > hmax ? hist[i].at<int>(j) : hmax;
	}

	const char* wname[3] = { "blue", "green", "red" };
	Scalar colors[3] = { Scalar(255,0,0), Scalar(0,255,0), Scalar(0,0,255) };

	vector<Mat> canvas(nc);

	// Display each histogram in a canvas
	for (int i = 0; i < nc; i++)
	{
		canvas[i] = Mat::ones(125, bins, CV_8UC3);

		for (int j = 0, rows = canvas[i].rows; j < bins-1; j++)
		{
			line(
				canvas[i],
				Point(j, rows),
				Point(j, rows - (hist[i].at<int>(j) * rows/hmax)),
				nc == 1 ? Scalar(200,200,200) : colors[i],
				1, 8, 0
			);
		}

		imshow(nc == 1 ? "value" : wname[i], canvas[i]);
	}
}<|endoftext|>


<commit_before>#include<iostream>
using namespace std;
int main()
{
	cout << "Hello World\n";
	return 0;
}
<commit_msg>Delete test.cpp<commit_after><|endoftext|>


<commit_before>#include"proj1.h"
#include"test.h"
using namespace std;
//checking input data
bool is_int(string input) //is integral
{
    int len=input.length();
	if(input[0]!='-'&&(input[0]<'0'||input[0]>'9'))
		return false;
    for(int i=1;i<len;i++)
    {
        if(input[i]<'0'||input[i]>'9')
            return false;
    }
    return true;
}
void help()
{
	cout<<"avaible commands: addition subtraction increase decrease derivative help root end"<<endl;
}
void menu(polynomial p1, polynomial p2)
{
	cin>>p1>>p2;
	string input;
	do
	{
		cin>>input;
		cout<<endl;
		if(input=="addition")
			{
				cout<<(p1+p2)<<endl;
			}
		else if(input=="subtraction")
			{
				cout<<(p1-p2)<<endl;
			}
		else if(input=="increase")
			{
				p1+=p2;
				cout<<p1<<endl;
			}
		else if(input=="decrease")
			{
				p1-=p2;
				cout<<p1<<endl;
			}
		else if(input=="derivative")
			{
				p1.derivative();
				cout<<endl;
			}
		else if(input=="help")
			{
				help();
			}
		else if(input=="root")
			{
				p1.root();
			}
	}
	while(input!="end");
}
<commit_msg>Delete test.cpp<commit_after><|endoftext|>


<commit_before>//
// (C) Jan de Vaan 2007-2009, all rights reserved. See the accompanying "License.txt" for licensed use.
//

#include "stdafx.h"
#include "stdio.h"
#include <vector>
#include <iostream>

#include "header.h"
#include "streams.h"
#include "defaulttraits.h"
#include "losslesstraits.h"
#include <windows.h>
#include "interface.h"

#pragma warning (disable: 4996)

double getTime()
{
	LARGE_INTEGER time;
	::QueryPerformanceCounter(&time);
	LARGE_INTEGER freq;
	::QueryPerformanceFrequency(&freq);

	return double(time.LowPart) * 1000.0/double(freq.LowPart);
}

int ReadJLSHeader(void* pdata, ScanInfo* pmetadata, int cbyte)
{
	JLSInputStream reader((BYTE*)pdata, cbyte);
	reader.ReadHeader();
	*pmetadata = reader.GetMetadata();
	return reader.GetBytesRead();
}

int Decode(void* pvoid, int cbyte, const BYTE* pbytecompressed, int cbytecompr, const void* pbyteExpected = NULL)
{
	JLSInputStream reader(pbytecompressed, cbytecompr);

	if (pbyteExpected != NULL)
	{
		::memcpy(pvoid, pbyteExpected, cbyte);
		reader.EnableCompare(true);
	}

	if (!reader.Read(pvoid))
		return -1;

	return reader.GetBytesRead();

}

int Encode(const void* pbyte, Size size, int cbit, int ccomp, interleavemode ilv, BYTE* pbytecompressed, int cbytecompr, int nearval, const void* pbyteExpected = NULL)
{
	JLSOutputStream stream;
	stream.Init(size, cbit, ccomp);

	if (ilv == ILV_NONE)
	{
		int cbytePlane = size.cx*size.cy*((cbit +7)/8);
		for (int icomp = 0; icomp < ccomp; ++icomp)
		{
			const BYTE* pbyteComp = static_cast<const BYTE*>(pbyte) + icomp*cbytePlane;
			stream.AddScan(pbyteComp, size, cbit, 1, ILV_NONE, nearval);
		}
	}
	else
	{
		stream.AddScan(pbyte, size, cbit, ccomp, ilv, nearval);
	}

	stream.Write(pbytecompressed, cbytecompr, pbyteExpected);

	return stream.GetBytesWritten();
}

// int double SZC int* void*
typedef const char* SZC;

template <class TYPE>
struct validprintfchar;

void WriteFile(SZC szcName, void* pvoidData, int cbyte)
{
	FILE* pfile = fopen(szcName, "wb");
	fwrite(pvoidData, 1, cbyte, pfile);
	fclose(pfile);
}

void ReadFile(SZC strName, std::vector<BYTE>* pvec, int ioffs = 0)
{
	FILE* pfile = fopen(strName, "rb");
	fseek(pfile, 0, SEEK_END);
	int cbyteFile = ftell(pfile);
	fseek(pfile, ioffs, SEEK_SET);
	pvec->resize(cbyteFile-ioffs);
	fread(&(*pvec)[0],1, pvec->size(), pfile);
	fclose(pfile);

}

void SwapBytes(std::vector<BYTE>* rgbyte)
{
	 for (UINT i = 0; i < rgbyte->size(); i += 2)
	 {
		 std::swap((*rgbyte)[i], (*rgbyte)[i + 1]);
	 }
}

void Test(const char* strName, const BYTE* rgbyteRaw, Size size, int cbit, int ccomp)
{
	std::vector<BYTE> pbyteCompressed;
	pbyteCompressed.resize(size.cx *size.cy * 4);

	std::vector<BYTE> rgbyteOut;
	rgbyteOut.resize(size.cx * size.cy * ((cbit + 7) / 8) * ccomp);

	double dblstart = getTime();

	size_t cbyteCompressed = Encode(rgbyteRaw, size, cbit, ccomp, ccomp == 3 ? ILV_SAMPLE : ILV_NONE, &pbyteCompressed[0], int(pbyteCompressed.size()), 0);

	//CString strDst = strName;
	//strDst = strDst + ".jls";
	//WriteFile(strDst.GetString(), &pbyteCompressed[0], cbyteCompressed);

	double dwtimeEncodeComplete = getTime();

	double dblfactor = 1.0 *  rgbyteOut.size() / cbyteCompressed;
	printf("Encode: %f Ratio: %f \n\r", dwtimeEncodeComplete - dblstart, dblfactor);

	Decode(&rgbyteOut[0], rgbyteOut.size(), &pbyteCompressed[0], int(cbyteCompressed));

	double dwtimeDecodeComplete = getTime();
	std::cout << "RoundTrip test for: " << strName << "\n\r";
	printf("Encode: %f Decode: %f Ratio: %f \n\r", dwtimeEncodeComplete - dblstart, dwtimeDecodeComplete - dwtimeEncodeComplete, dblfactor);

	BYTE* pbyteOut = &rgbyteOut[0];
	for (UINT i = 0; i < rgbyteOut.size(); ++i)
	{
		if (rgbyteRaw[i] != pbyteOut[i])
		{
			ASSERT(false);
			break;
		}
	}

}

void TestJls(std::vector<BYTE>& rgbyteRaw, Size size, int cbit, int ccomp, interleavemode ilv, const BYTE* rgbyteFile, int cbyteCompressed, bool bNear)
{
	if (cbit > 8 && cbit <= 16)
	{
		SwapBytes(&rgbyteRaw);
	}

	std::vector<BYTE> rgbyteTest;
	rgbyteTest.resize(2 *cbyteCompressed );

	UINT cbyte = Encode(&rgbyteRaw[0], size, cbit, ccomp, ilv, &rgbyteTest[0], int(rgbyteTest.size()), bNear ? 3 : 0, rgbyteFile);

	WriteFile("test.jls", &rgbyteTest[0], cbyte);

	JLSInputStream reader(rgbyteFile, cbyteCompressed);

	std::vector<BYTE> rgbyteUnc;
	rgbyteUnc.resize(size.cx * size.cy * ((cbit + 7) / 8) * ccomp);

	Decode(&rgbyteUnc[0], rgbyteUnc.size(), rgbyteFile, cbyteCompressed, &rgbyteRaw[0]);

	WriteFile("test.raw", &rgbyteUnc[0], rgbyteUnc.size());
}

void TestNear(char* strNameEncoded, Size size, int cbit)
{
	std::vector<BYTE> rgbyteFile;
	ReadFile(strNameEncoded, &rgbyteFile);

	std::vector<BYTE> rgbyteUnc;
	rgbyteUnc.resize(size.cx * size.cy * ((cbit + 7) / 8));

	Decode(&rgbyteUnc[0], rgbyteUnc.size(), &rgbyteFile[0], rgbyteFile.size());
}

void Triplet2Planar(std::vector<BYTE>& rgbyte, Size size)
{
	std::vector<BYTE> rgbytePlanar(rgbyte.size());

	int cbytePlane = size.cx * size.cy;
	for (int ipixel = 0; ipixel < cbytePlane; ipixel++)
	{
		rgbytePlanar[ipixel]				= rgbyte[ipixel * 3 + 0];
		rgbytePlanar[ipixel + 1*cbytePlane]	= rgbyte[ipixel * 3 + 1];
		rgbytePlanar[ipixel + 2*cbytePlane] = rgbyte[ipixel * 3 + 2];
	}
	std::swap(rgbyte, rgbytePlanar);
}

void DecompressFile(SZC strNameEncoded, SZC strNameRaw, int ioffs)
{
	std::cout << "Conformance test:" << strNameEncoded << "\n\r";
	std::vector<BYTE> rgbyteFile;
	ReadFile(strNameEncoded, &rgbyteFile);

 	std::vector<BYTE> rgbyteRaw;
	ReadFile(strNameRaw, &rgbyteRaw, ioffs);

	JlsParamaters metadata;
	if (JpegLsReadHeader(&rgbyteFile[0], rgbyteFile.size(), &metadata) != OK)
	{
		ASSERT(false);
		return;
	}

	Size size = Size(metadata.width, metadata.height);

	if (metadata.ilv == ILV_NONE && metadata.components == 3)
	{
		Triplet2Planar(rgbyteRaw, Size(metadata.width, metadata.height));
	}

	TestJls(rgbyteRaw, size, metadata.bitspersample, metadata.components, metadata.ilv, &rgbyteFile[0], rgbyteFile.size(), metadata.allowedlossyerror != 0);
}

void TestFile(SZC strName, int ioffs, Size size2, int cbit, int ccomp)
{
	std::vector<BYTE> rgbyteNoise;

	ReadFile(strName, &rgbyteNoise, ioffs);

	Test(strName, &rgbyteNoise[0], size2, cbit, ccomp);

};

	const BYTE rgbyte[] = { 0,   0,  90,  74,
							68,  50,  43, 205,
							64, 145, 145, 145,
							100, 145, 145, 145};
	const BYTE rgbyteComp[] =   {	0xFF, 0xD8, 0xFF, 0xF7, 0x00, 0x0B, 0x08, 0x00, 0x04, 0x00, 0x04, 0x01, 0x01, 0x11, 0x00, 0xFF, 0xDA, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
							0xC0, 0x00, 0x00, 0x6C, 0x80, 0x20, 0x8E,
							0x01, 0xC0, 0x00, 0x00, 0x57, 0x40, 0x00, 0x00, 0x6E, 0xE6, 0x00, 0x00, 0x01, 0xBC, 0x18, 0x00,
							0x00, 0x05, 0xD8, 0x00, 0x00, 0x91, 0x60, 0xFF, 0xD9};

void TestAnnexH3()
{
	Size size = Size(4,4);
	std::vector<BYTE> vecRaw(16);
	memcpy(&vecRaw[0], rgbyte, 16);
	TestJls(vecRaw, size, 8, 1, ILV_NONE, rgbyteComp, sizeof(rgbyteComp), false);
}

void TestConformanceLosslessMode()
{
//	DecompressFile("..\\test\\mars\\phoenixmars.jls", "..\\test\\mars\\phoenixmars.ppm",40);

	// Test 1
	DecompressFile("..\\test\\conformance\\t8c0e0.jls", "..\\test\\conformance\\test8.ppm",15);

	// Test 2

	// Test 3
	DecompressFile("..\\test\\conformance\\t8c2e0.jls", "..\\test\\conformance\\test8.ppm", 15);

	// Test 4
	DecompressFile("..\\test\\conformance\\t8c0e3.jls", "..\\test\\conformance\\test8.ppm",15);

	// Test 5

	// Test 6
	DecompressFile("..\\test\\conformance\\t8c2e3.jls", "..\\test\\conformance\\test8.ppm",15);

	// Test 7
	// Test 8

	// Test 9
	DecompressFile("..\\test\\conformance\\t8nde0.jls", "..\\test\\conformance\\test8bs2.pgm",15);

	// Test 10
	DecompressFile("..\\test\\conformance\\t8nde3.jls", "..\\test\\conformance\\test8bs2.pgm",15);

	// Test 11
	DecompressFile("..\\test\\conformance\\t16e0.jls", "..\\test\\conformance\\test16.pgm",16);

	// Test 12
	DecompressFile("..\\test\\conformance\\t16e3.jls", "..\\test\\conformance\\test16.pgm",16);

	// additional, Lena compressed with other codec (UBC?), vfy with CharLS
	DecompressFile("..\\test\\lena8b.jls", "..\\test\\lena8b.raw",0);

}

void TestNoiseImage()
{
	srand(21344);
	Size size2 = Size(1024, 1024);
	std::vector<BYTE> rgbyteNoise;
	rgbyteNoise.resize(	size2.cx * size2.cy);

	for (int iline = 0; iline<size2.cy; ++iline)
	{
		for (int icol= 0; icol<size2.cx; ++icol)
		{
			BYTE val = BYTE(rand());
			rgbyteNoise[iline*size2.cx + icol] = BYTE(val & 0x7F);// < iline ? val : 0;
		}
	}

	Test("noise", &rgbyteNoise[0], size2, 7, 1);
}

void TestPerformance()
{
	Size size1024 = Size(1024, 1024);
	Size size512 = Size(512, 512);

//	TestFile("..\\test\\mars\\phoenixmars.ppm", 40, Size(5300,4300),  8, 3);
	TestFile("..\\test\\mr2_unc", 1728, size1024,  16, 1);
	TestFile("..\\test\\0015.raw", 0, size1024,  8, 1);
	TestFile("..\\test\\lena8b.raw", 0, size512,  8, 1);

}

void TestTraits16bit()
{
	DefaultTraitsT<USHORT,USHORT> traits1 = DefaultTraitsT<USHORT,USHORT>(4095,0);
	LosslessTraitsT<USHORT,12> traits2 = LosslessTraitsT<USHORT,12>();

	ASSERT(traits1.LIMIT == traits2.LIMIT);
	ASSERT(traits1.MAXVAL == traits2.MAXVAL);
	ASSERT(traits1.RESET == traits2.RESET);
	ASSERT(traits1.bpp == traits2.bpp);
	ASSERT(traits1.qbpp == traits2.qbpp);

	for (int i = -4096; i < 4096; ++i)
	{
		ASSERT(traits1.ModRange(i) == traits2.ModRange(i));
		ASSERT(traits1.ComputeErrVal(i) == traits2.ComputeErrVal(i));
	}

	for (int i = -8095; i < 8095; ++i)
	{
		ASSERT(traits1.CorrectPrediction(i) == traits2.CorrectPrediction(i));
		ASSERT(traits1.IsNear(i,2) == traits2.IsNear(i,2));
	}
}

void TestTraits8bit()
{
	DefaultTraitsT<BYTE,BYTE> traits1 = DefaultTraitsT<BYTE,BYTE>(255,0);
	LosslessTraitsT<BYTE,8> traits2 = LosslessTraitsT<BYTE,8>();

	ASSERT(traits1.LIMIT == traits2.LIMIT);
	ASSERT(traits1.MAXVAL == traits2.MAXVAL);
	ASSERT(traits1.RESET == traits2.RESET);
	ASSERT(traits1.bpp == traits2.bpp);
	ASSERT(traits1.qbpp == traits2.qbpp);

	for (int i = -255; i < 255; ++i)
	{
		ASSERT(traits1.ModRange(i) == traits2.ModRange(i));
		ASSERT(traits1.ComputeErrVal(i) == traits2.ComputeErrVal(i));
	}

	for (int i = -255; i < 512; ++i)
	{
		ASSERT(traits1.CorrectPrediction(i) == traits2.CorrectPrediction(i));
		ASSERT(traits1.IsNear(i,2) == traits2.IsNear(i,2));
	}
}

extern "C"
{

void __declspec(dllexport) __cdecl Test()
{
	TestTraits16bit();
	TestTraits8bit();
	TestConformanceLosslessMode();
	TestPerformance();
	TestNoiseImage();
	TestAnnexH3();

}

}<commit_msg>moved unit tests<commit_after><|endoftext|>


<commit_before>#include "Entity.h"

Entity::Entity()
{
}

Entity::~Entity()
{
}

int Entity::SyncComponents()
{
	int result = 1;

	if (this->m_pComp != nullptr)
	{
		if (this->m_aiComp != nullptr)
		{
			// Works for now since we're only handling platforms
			if (this->m_aiComp->AC_triggered)
				this->m_pComp->PC_velocity = DirectX::XMVectorScale(this->m_aiComp->AC_dir, this->m_aiComp->AC_speed);
			else
				this->m_pComp->PC_velocity = { 0 };
			this->m_aiComp->AC_position = this->m_pComp->PC_pos;
			//TODO: test physcomp vs aicomp positions are still updated after they are released from duty
		}
		if (this->m_gComp != nullptr)
		{
			//rotate and translate the obb in the game
			if (this->m_pComp->PC_BVtype == BV_OBB)
			{
				if (this->m_entityID == 1 || this->m_entityID == 2) // 1 or 2 == player
				{
					this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_pComp->PC_OBB.ort, DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));
					this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_gComp->worldMatrix, DirectX::XMMatrixTranslationFromVector(DirectX::XMVectorSet(0, -this->m_pComp->PC_OBB.ext[1], 0, 0)));
				}
				else
				{
					this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_pComp->PC_OBB.ort, DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));

				}
			}
			else
			{
				this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(DirectX::XMMatrixRotationRollPitchYawFromVector(this->m_pComp->PC_rotation), DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));
			}

			result = 1;
		}
		else
		{
			result = -2;
		}
	}
	else
	{
		if (this->m_gComp == nullptr)
		{
			result = -3;
		}
		result = -1;
	}

	return result;
}

int Entity::AddObserver(Observer * observer, int entityID)
{
	this->m_subject.AddObserver(observer, entityID);

	return 0;
}

void Entity::UnsafeSyncComponents()
{
	//rotate and translate the obb in the game
	if (this->m_pComp->PC_BVtype == BV_OBB)
	{
		//this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(DirectX::XMMatrixRotationQuaternion(this->m_pComp->PC_OBB.quat), DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));
		if (this->m_entityID == 1 || this->m_entityID == 2) // 1 or 2 == player
		{
			this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_pComp->PC_OBB.ort, DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));
			this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_gComp->worldMatrix, DirectX::XMMatrixTranslationFromVector(DirectX::XMVectorSet(0, -this->m_pComp->PC_OBB.ext[1], 0, 0)));
		}
		else
		{
			this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_pComp->PC_OBB.ort, DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));

		}
	}
	else
	{
		this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(DirectX::XMMatrixRotationRollPitchYawFromVector(this->m_pComp->PC_rotation), DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));
	}
}

PhysicsComponent* Entity::SetPhysicsComponent(PhysicsComponent * pComp)
{
	PhysicsComponent* tempReturn = this->m_pComp;
	this->m_pComp = pComp;
	return tempReturn;
}

GraphicsComponent* Entity::SetGraphicsComponent(GraphicsComponent * gComp)
{
	GraphicsComponent* tempReturn = this->m_gComp;
	this->m_gComp = gComp;
	return tempReturn;
}

AIComponent * Entity::SetAIComponent(AIComponent * aiComp)
{
	AIComponent* tempReturn = this->m_aiComp;
	this->m_aiComp = aiComp;
	return tempReturn;
}

AnimationComponent * Entity::SetAnimationComponent(AnimationComponent * aComp)
{
	AnimationComponent* tempReturn = this->m_aComp;
	this->m_aComp = aComp;
	return tempReturn;
}

bool Entity::SetGrabbed(Entity* isGrabbedBy)
{
	bool lastValue = this->m_isGrabbed;;
	this->m_isGrabbedBy = isGrabbedBy;

	if (this->m_isGrabbedBy != nullptr)
	{
		this->m_isGrabbed = true;
		this->m_pComp->PC_velocity = DirectX::XMVectorSet(0, 0, 0, 0);

	}
	else {
		if (this->m_entityID == 3)
		{
			int a = 0;
		}
		this->m_isGrabbed = false;
		//this->m_pComp->PC_velocity = DirectX::XMVectorSet(0, 0, 0, 0);
	}

	return lastValue;
}

bool Entity::IsGrabbed()
{
	return this->m_isGrabbed;
}

int Entity::SetEntityID(int entityID)
{
	int lastValue = this->m_entityID;
	this->m_entityID = entityID;
	return lastValue;
}

PhysicsComponent * Entity::GetPhysicsComponent()
{
	return this->m_pComp;
}

GraphicsComponent * Entity::GetGraphicComponent()
{
	return this->m_gComp;
}

AIComponent * Entity::GetAIComponent()
{
	return this->m_aiComp;
}

AnimationComponent * Entity::GetAnimationComponent()
{
	return this->m_aComp;
}

bool Entity::GetGrabbed()
{
	return this->m_isGrabbed;
}

int Entity::GetEntityID()
{
	return this->m_entityID;
}

int Entity::InitializeBase(int entityID, PhysicsComponent* pComp, GraphicsComponent* gComp, AnimationComponent* aComp, AIComponent* aiComp)
{
	int result = 1;
	this->m_isGrabbed = false;
	this->m_subject = Subject();
	this->m_entityID = entityID;
	this->m_pComp = pComp;
	this->m_gComp = gComp;
	this->m_aComp = aComp;
	this->m_aiComp = aiComp;
	this->m_isGrabbedBy = nullptr;
	return result;
}
<commit_msg>REMOVE test code and unnecessary spacing<commit_after>#include "Entity.h"

Entity::Entity(){}
Entity::~Entity(){}

int Entity::SyncComponents()
{
	int result = 1;
	if (this->m_pComp != nullptr)
	{
		if (this->m_aiComp != nullptr)
		{
			// Works for now since we're only handling platforms
			if (this->m_aiComp->AC_triggered)
				this->m_pComp->PC_velocity = DirectX::XMVectorScale(this->m_aiComp->AC_dir, this->m_aiComp->AC_speed);
			else
				this->m_pComp->PC_velocity = { 0 };
			this->m_aiComp->AC_position = this->m_pComp->PC_pos;
			//TODO: test physcomp vs aicomp positions are still updated after they are released from duty
		}
		if (this->m_gComp != nullptr)
		{
			//rotate and translate the obb in the game
			if (this->m_pComp->PC_BVtype == BV_OBB)
			{
				if (this->m_entityID == 1 || this->m_entityID == 2) // 1 or 2 == player
				{
					this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_pComp->PC_OBB.ort, DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));
					this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_gComp->worldMatrix, DirectX::XMMatrixTranslationFromVector(DirectX::XMVectorSet(0, -this->m_pComp->PC_OBB.ext[1], 0, 0)));
				}
				else
				{
					this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_pComp->PC_OBB.ort, DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));
				}
			}
			else
			{
				this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(DirectX::XMMatrixRotationRollPitchYawFromVector(this->m_pComp->PC_rotation), DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));
			}

			result = 1;
		}
		else
		{
			result = -2;
		}
	}
	else
	{
		if (this->m_gComp == nullptr)
		{
			result = -3;
		}
		result = -1;
	}
	return result;
}

int Entity::AddObserver(Observer * observer, int entityID)
{
	this->m_subject.AddObserver(observer, entityID);
	return 1;
}

void Entity::UnsafeSyncComponents()
{
	//rotate and translate the obb in the game
	if (this->m_pComp->PC_BVtype == BV_OBB)
	{
		if (this->m_entityID == 1 || this->m_entityID == 2) // 1 or 2 == player
		{
			this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_pComp->PC_OBB.ort, DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));
			this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_gComp->worldMatrix, DirectX::XMMatrixTranslationFromVector(DirectX::XMVectorSet(0, -this->m_pComp->PC_OBB.ext[1], 0, 0)));
		}
		else
		{
			this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(this->m_pComp->PC_OBB.ort, DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));
		}
	}
	else
	{
		this->m_gComp->worldMatrix = DirectX::XMMatrixMultiply(DirectX::XMMatrixRotationRollPitchYawFromVector(this->m_pComp->PC_rotation), DirectX::XMMatrixTranslationFromVector(this->m_pComp->PC_pos));
	}
}

PhysicsComponent* Entity::SetPhysicsComponent(PhysicsComponent * pComp)
{
	PhysicsComponent* tempReturn = this->m_pComp;
	this->m_pComp = pComp;
	return tempReturn;
}

GraphicsComponent* Entity::SetGraphicsComponent(GraphicsComponent * gComp)
{
	GraphicsComponent* tempReturn = this->m_gComp;
	this->m_gComp = gComp;
	return tempReturn;
}

AIComponent * Entity::SetAIComponent(AIComponent * aiComp)
{
	AIComponent* tempReturn = this->m_aiComp;
	this->m_aiComp = aiComp;
	return tempReturn;
}

AnimationComponent * Entity::SetAnimationComponent(AnimationComponent * aComp)
{
	AnimationComponent* tempReturn = this->m_aComp;
	this->m_aComp = aComp;
	return tempReturn;
}

bool Entity::SetGrabbed(Entity* isGrabbedBy)
{
	bool lastValue = this->m_isGrabbed;;
	this->m_isGrabbedBy = isGrabbedBy;

	if (this->m_isGrabbedBy != nullptr)
	{
		this->m_isGrabbed = true;
		this->m_pComp->PC_velocity = DirectX::XMVectorSet(0, 0, 0, 0);
	}
	else
	{
		this->m_isGrabbed = false;
	}
	return lastValue;
}

bool Entity::IsGrabbed()
{
	return this->m_isGrabbed;
}

int Entity::SetEntityID(int entityID)
{
	int lastValue = this->m_entityID;
	this->m_entityID = entityID;
	return lastValue;
}

PhysicsComponent * Entity::GetPhysicsComponent()
{
	return this->m_pComp;
}

GraphicsComponent * Entity::GetGraphicComponent()
{
	return this->m_gComp;
}

AIComponent * Entity::GetAIComponent()
{
	return this->m_aiComp;
}

AnimationComponent * Entity::GetAnimationComponent()
{
	return this->m_aComp;
}

bool Entity::GetGrabbed()
{
	return this->m_isGrabbed;
}

int Entity::GetEntityID()
{
	return this->m_entityID;
}

int Entity::InitializeBase(int entityID, PhysicsComponent* pComp, GraphicsComponent* gComp, AnimationComponent* aComp, AIComponent* aiComp)
{
	int result = 1;
	this->m_isGrabbed = false;
	this->m_subject = Subject();
	this->m_entityID = entityID;
	this->m_pComp = pComp;
	this->m_gComp = gComp;
	this->m_aComp = aComp;
	this->m_aiComp = aiComp;
	this->m_isGrabbedBy = nullptr;
	return result;
}
<|endoftext|>


<commit_before>#include "codeGenVisitor.h"

void CodeGenVisitor::populateSwitchMap() {
	switchMap.insert(std::make_pair("+", BOP_PLUS));
	switchMap.insert(std::make_pair("-", BOP_MINUS));
	switchMap.insert(std::make_pair("*", BOP_MULT));
	switchMap.insert(std::make_pair("/", BOP_DIV));
	switchMap.insert(std::make_pair(">=", BOP_GTE));
	switchMap.insert(std::make_pair("<=", BOP_LTE));
	switchMap.insert(std::make_pair(">", BOP_GT));
	switchMap.insert(std::make_pair("<", BOP_LT));
	switchMap.insert(std::make_pair("!=", BOP_NEQ));
	switchMap.insert(std::make_pair("==", BOP_EQ));
	switchMap.insert(std::make_pair(".", BOP_DOT));
}

llvm::Value* CodeGenVisitor::ErrorV(const char* str) {
  fprintf(stderr, "Error: %s\n", str);
  return nullptr;
}

llvm::Function* CodeGenVisitor::generateFunction(FunctionDefinition* f) {
	std::string type = f->type->name;
	llvm::FunctionType* funcType = nullptr;
	llvm::Function* func = nullptr;
	std::vector<llvm::Type*> inputArgs;
	for(size_t i = 0, end = f->args->size(); i < end; ++i) {
		std::string type = f->args[i][0]->type->name;
		if(type == "float") {
			inputArgs.push_back(llvm::Type::getDoubleTy(*context));
		}
		else if(type == "int") {
			inputArgs.push_back(llvm::Type::getInt64Ty(*context));
		}
		else
			return nullptr;
	}
	if(type == "void") {
		funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(*context), inputArgs, false); //return is float
	}
	else if(type == "float") {
		funcType = llvm::FunctionType::get(llvm::Type::getDoubleTy(*context), inputArgs, false); //return is float
	}
	else if(type == "int") {
		funcType = llvm::FunctionType::get(llvm::Type::getInt64Ty(*context), inputArgs, false); //return is float
	}
	func = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, f->ident->name, theModule.get()); //pass unique ptr to function
	unsigned i = 0;
	for (auto &arg : func->args())
	  arg.setName(f->args[i++][0]->ident->name);
	return func;
}

CodeGenVisitor::CodeGenVisitor(std::string name) {
	populateSwitchMap();
	context = &llvm::getGlobalContext();
	theModule = llvm::make_unique<llvm::Module>(name, *context);
	builder = llvm::make_unique<llvm::IRBuilder<>>(*context);
}

/*===================================Node===================================*/
llvm::Value* CodeGenVisitor::visitNode(Node* n) {
	return ErrorV("Attempt to generate code for generic Node");
}

/*================================Expression================================*/
llvm::Value* CodeGenVisitor::visitExpression(Expression* e) {
	return ErrorV("Attempt to generate code for generic Expression");
}

/*================================Statement=================================*/
llvm::Value* CodeGenVisitor::visitStatement(Statement* s) {
	return ErrorV("Attempt to generate code for generic Statement");
}

/*=================================Integer==================================*/
llvm::Value* CodeGenVisitor::visitInteger(Integer* i) {
	return llvm::ConstantInt::get(*context, llvm::APInt(i->value, 64));
}

/*==================================Float===================================*/
llvm::Value* CodeGenVisitor::visitFloat(Float* f) {
	return llvm::ConstantFP::get(*context, llvm::APFloat(f->value));
}

/*================================Identifier================================*/
llvm::Value* CodeGenVisitor::visitIdentifier(Identifier* i) {
  llvm::Value* val = namedValues[i->name];
  if (!val)
    return ErrorV("Attempt to generate code for not previously defined variable");
  return val;
}

/*=============================NullaryOperator==============================*/
llvm::Value* CodeGenVisitor::visitNullaryOperator(NullaryOperator* n) {
	if(*n->op == ';') {
		//commit action
		return nullptr;
	}
	return ErrorV("Invalid nullary operator");
}

/*==============================UnaryOperator===============================*/
llvm::Value* CodeGenVisitor::visitUnaryOperator(UnaryOperator* u) {
	llvm::Value* expr = u->exp->acceptVisitor(this);
	switch(*u->op) {
		case '-':
		return builder->CreateFMul(llvm::ConstantInt::get(*context, llvm::APInt(-1, 64)), expr, "multmp");
		case '!':
		case '*':
		return ErrorV("Not yet specified unary operator");
		default:
		return ErrorV("Invalid unary operator");
	}
}

/*==============================BinaryOperator==============================*/
llvm::Value* CodeGenVisitor::visitBinaryOperator(BinaryOperator* b) {
	llvm::Value* left = b->left->acceptVisitor(this);
 	llvm::Value* right = b->right->acceptVisitor(this);
 	//grab left and right
	if (!left || !right)
		return ErrorV("Could not evaluate binary operator");
	//use map for binary operators
	switch (switchMap.find(b->op)->second) {
		case BOP_PLUS:
		return builder->CreateFAdd(left, right, "addtmp");
		case BOP_MINUS:
		return builder->CreateFSub(left, right, "subtmp");
		case BOP_MULT:
		return builder->CreateFMul(left, right, "multmp");
		case BOP_DIV:
		return builder->CreateFDiv(left, right, "divtmp");
		case BOP_NEQ:
		case BOP_EQ:
		case BOP_GTE:
		case BOP_LTE:
		case BOP_GT:
		case BOP_LT:
		case BOP_DOT:
		return ErrorV("Attempt to generate code for not yet implemented binary operator");
		//assignment op separate
		default:
		return ErrorV("Invalid binary operator");
	}
}

/*==================================Block===================================*/
llvm::Value* CodeGenVisitor::visitBlock(Block* b) {
	llvm::Value* lastVisited;
	std::vector<Statement*,gc_allocator<Statement*>>* statements = b->statements;
	for(size_t i = 0, end = statements->size(); i != end; ++i) {
		lastVisited = statements[i][0]->acceptVisitor(this);
		//if(!lastVisited) //TODO:nullary operator needs more explicit handling
		//	return nullptr;
	}
	return lastVisited;
}

/*===============================FunctionCall===============================*/
llvm::Value* CodeGenVisitor::visitFunctionCall(FunctionCall* f) {
	//grab function and evaluate with arguments
	llvm::Function* func = theModule->getFunction(f->ident->name);
	if(!func)
		return ErrorV("Unknown function reference");
	if(func->arg_size() != f->args->size())
		return ErrorV("Wrong number of arguments passed");

	std::vector<llvm::Value*> argVector;
	for(size_t i = 0, end = f->args->size(); i != end; ++i) {
		argVector.push_back(f->args[i][0]->acceptVisitor(this));
		if(!argVector.back())
			return nullptr;
	}
	return builder->CreateCall(func, argVector, "calltmp");
}

/*=================================Keyword==================================*/
llvm::Value* CodeGenVisitor::visitKeyword(Keyword* k) {
	return ErrorV("Attempt to generate code for dangling keyword");
}

/*============================VariableDefinition============================*/
llvm::Value* CodeGenVisitor::visitVariableDefinition(VariableDefinition* v) {
	std::string type = v->type->name; //int float or void
	llvm::Value* val = nullptr;
	if(type == "int") {
		int64_t i = 0; //TODO: Figure out why variable necessary
		val = llvm::ConstantInt::get(*context, llvm::APInt(i, 64));
	}
	else if(type == "float")
		val = llvm::ConstantFP::get(*context, llvm::APFloat(0.0));
	if(!val) //add default value variable to map
		namedValues.insert(std::make_pair(v->ident->name, val));
	return val;
}

/*===========================StructureDefinition============================*/
llvm::Value* CodeGenVisitor::visitStructureDefinition(StructureDefinition* s) {
	return ErrorV("Attempt to evaluate not yet implemented structure definition");
}

/*============================FunctionDefinition============================*/
llvm::Value* CodeGenVisitor::visitFunctionDefinition(FunctionDefinition* f) {
	llvm::Function* func = theModule->getFunction(f->ident->name);
	if(!func)
		func = generateFunction(f); //create function object with type|ident|args
	if(!func) //generateFunction returned nullptr
		return nullptr;
	if(!func->empty())
		return ErrorV("Function is already defined");
	llvm::BasicBlock* block = llvm::BasicBlock::Create(*context, "function start", func);
	builder->SetInsertPoint(block);
	namedValues.clear();
	for (auto &arg : func->args())
		namedValues[arg.getName()] = &arg;
	if(llvm::Value* retVal = f->block->acceptVisitor(this)) {//TODO:nullptr return happens when using return;
		func->dump();//Function IR dump
		return retVal;
	}
	func->eraseFromParent();//erase if nullptr returned
	return nullptr;
}

/*==========================StructureDeclaration============================*/
llvm::Value* CodeGenVisitor::visitStructureDeclaration(StructureDeclaration* s) {
	return ErrorV("Attempt to evaluate not yet implemented structure declaration");
}

/*===========================ExpressionStatement============================*/
llvm::Value* CodeGenVisitor::visitExpressionStatement(ExpressionStatement* e) {
	return e->exp->acceptVisitor(this);	//evaluated but value discarded
}

/*=============================ReturnStatement==============================*/
llvm::Value* CodeGenVisitor::visitReturnStatement(ReturnStatement* r) {
	llvm::Value* returnVal = r->exp->acceptVisitor(this);
	if(returnVal) {
		builder->CreateRet(returnVal); //builder returns value
	}
	return returnVal;
}

/*=============================AssignStatement==============================*/
llvm::Value* CodeGenVisitor::visitAssignStatement(AssignStatement* a) {
	//TODO: map a value to an exisiting identifier
	//look for identifier
	//map target to value
	return nullptr;
}

/*===============================IfStatement================================*/
llvm::Value* CodeGenVisitor::visitIfStatement(IfStatement* i) {
	return ErrorV("Attempt to evaluate not yet implemented if statement");
}
<commit_msg>Added type checking for return types with erase parent functionality | fixed some coding issues<commit_after>#include "codeGenVisitor.h"

void CodeGenVisitor::populateSwitchMap() {
	switchMap.insert(std::make_pair("+", BOP_PLUS));
	switchMap.insert(std::make_pair("-", BOP_MINUS));
	switchMap.insert(std::make_pair("*", BOP_MULT));
	switchMap.insert(std::make_pair("/", BOP_DIV));
	switchMap.insert(std::make_pair(">=", BOP_GTE));
	switchMap.insert(std::make_pair("<=", BOP_LTE));
	switchMap.insert(std::make_pair(">", BOP_GT));
	switchMap.insert(std::make_pair("<", BOP_LT));
	switchMap.insert(std::make_pair("!=", BOP_NEQ));
	switchMap.insert(std::make_pair("==", BOP_EQ));
	switchMap.insert(std::make_pair(".", BOP_DOT));
}

llvm::Value* CodeGenVisitor::ErrorV(const char* str) {
  fprintf(stderr, "Error: %s\n", str);
  return nullptr;
}

llvm::Function* CodeGenVisitor::generateFunction(FunctionDefinition* f) {
	std::string type = f->type->name;
	llvm::FunctionType* funcType = nullptr;
	llvm::Function* func = nullptr;
	std::vector<llvm::Type*> inputArgs; //set input args as float or int
	for(size_t i = 0, end = f->args->size(); i < end; ++i) {
		std::string type = f->args[i][0]->type->name;
		if(type == "float") {
			inputArgs.push_back(llvm::Type::getDoubleTy(*context));
		}
		else if(type == "int") {
			inputArgs.push_back(llvm::Type::getInt64Ty(*context));
		}
		else
			return nullptr;
	}
	if(type == "void") { //set function return type
		funcType = llvm::FunctionType::get(llvm::Type::getVoidTy(*context), inputArgs, false);
	}
	else if(type == "float") {
		funcType = llvm::FunctionType::get(llvm::Type::getDoubleTy(*context), inputArgs, false);
	}
	else if(type == "int") {
		funcType = llvm::FunctionType::get(llvm::Type::getInt64Ty(*context), inputArgs, false);
	}
	func = llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, f->ident->name, theModule.get()); //pass unique ptr to function
	{
	size_t i = 0;
	for (auto &arg : func->args())
	  arg.setName(f->args[i++][0]->ident->name);
	}
	return func;
}

CodeGenVisitor::CodeGenVisitor(std::string name) {
	populateSwitchMap();
	context = &llvm::getGlobalContext();
	theModule = llvm::make_unique<llvm::Module>(name, *context);
	builder = llvm::make_unique<llvm::IRBuilder<>>(*context);
}

/*===================================Node===================================*/
llvm::Value* CodeGenVisitor::visitNode(Node* n) {
	return ErrorV("Attempt to generate code for generic Node");
}

/*================================Expression================================*/
llvm::Value* CodeGenVisitor::visitExpression(Expression* e) {
	return ErrorV("Attempt to generate code for generic Expression");
}

/*================================Statement=================================*/
llvm::Value* CodeGenVisitor::visitStatement(Statement* s) {
	return ErrorV("Attempt to generate code for generic Statement");
}

/*=================================Integer==================================*/
llvm::Value* CodeGenVisitor::visitInteger(Integer* i) {
	return llvm::ConstantInt::get(*context, llvm::APInt(i->value, 64));
}

/*==================================Float===================================*/
llvm::Value* CodeGenVisitor::visitFloat(Float* f) {
	return llvm::ConstantFP::get(*context, llvm::APFloat(f->value));
}

/*================================Identifier================================*/
llvm::Value* CodeGenVisitor::visitIdentifier(Identifier* i) {
  llvm::Value* val = namedValues[i->name];
  if (!val)
    return ErrorV("Attempt to generate code for not previously defined variable");
  return val;
}

/*=============================NullaryOperator==============================*/
llvm::Value* CodeGenVisitor::visitNullaryOperator(NullaryOperator* n) {
	if(*n->op == ';') {
		//commit action
		return nullptr;
	}
	return ErrorV("Invalid nullary operator");
}

/*==============================UnaryOperator===============================*/
llvm::Value* CodeGenVisitor::visitUnaryOperator(UnaryOperator* u) {
	llvm::Value* expr = u->exp->acceptVisitor(this);
	switch(*u->op) {
		case '-':
		return builder->CreateFMul(llvm::ConstantInt::get(*context, llvm::APInt(-1, 64)), expr, "multmp");
		case '!':
		case '*':
		return ErrorV("Not yet specified unary operator");
		default:
		return ErrorV("Invalid unary operator");
	}
}

/*==============================BinaryOperator==============================*/
llvm::Value* CodeGenVisitor::visitBinaryOperator(BinaryOperator* b) {
	llvm::Value* left = b->left->acceptVisitor(this);
 	llvm::Value* right = b->right->acceptVisitor(this);
 	//grab left and right
	if (!left || !right)
		return ErrorV("Could not evaluate binary operator");
	//use map for binary operators
	switch (switchMap.find(b->op)->second) {
		case BOP_PLUS:
		return builder->CreateFAdd(left, right, "addtmp");
		case BOP_MINUS:
		return builder->CreateFSub(left, right, "subtmp");
		case BOP_MULT:
		return builder->CreateFMul(left, right, "multmp");
		case BOP_DIV:
		return builder->CreateFDiv(left, right, "divtmp");
		case BOP_NEQ:
		case BOP_EQ:
		case BOP_GTE:
		case BOP_LTE:
		case BOP_GT:
		case BOP_LT:
		case BOP_DOT:
		return ErrorV("Attempt to generate code for not yet implemented binary operator");
		//assignment op separate
		default:
		return ErrorV("Invalid binary operator");
	}
}

/*==================================Block===================================*/
llvm::Value* CodeGenVisitor::visitBlock(Block* b) {
	llvm::Value* lastVisited;
	std::vector<Statement*,gc_allocator<Statement*>>* statements = b->statements;
	for(size_t i = 0, end = statements->size(); i != end; ++i) {
		lastVisited = statements[i][0]->acceptVisitor(this);
		//if(!lastVisited) //TODO:nullary operator needs more explicit handling
		//	return nullptr;
	}
	return lastVisited;
}

/*===============================FunctionCall===============================*/
llvm::Value* CodeGenVisitor::visitFunctionCall(FunctionCall* f) {
	//grab function and evaluate with arguments
	llvm::Function* func = theModule->getFunction(f->ident->name);
	if(!func)
		return ErrorV("Unknown function reference");
	if(func->arg_size() != f->args->size())
		return ErrorV("Wrong number of arguments passed");

	std::vector<llvm::Value*> argVector;
	for(size_t i = 0, end = f->args->size(); i != end; ++i) {
		argVector.push_back(f->args[i][0]->acceptVisitor(this));
		if(!argVector.back())
			return nullptr;
	}
	return builder->CreateCall(func, argVector, "calltmp");
}

/*=================================Keyword==================================*/
llvm::Value* CodeGenVisitor::visitKeyword(Keyword* k) {
	return ErrorV("Attempt to generate code for dangling keyword");
}

/*============================VariableDefinition============================*/
llvm::Value* CodeGenVisitor::visitVariableDefinition(VariableDefinition* v) {
	std::string type = v->type->name; //int float or void
	llvm::Value* val = nullptr;
	if(type == "int") {
		int64_t i = 0; //TODO: Figure out why variable necessary, attempted casting already
		val = llvm::ConstantInt::get(*context, llvm::APInt(i, 64));
	}
	else if(type == "float")
		val = llvm::ConstantFP::get(*context, llvm::APFloat(0.0));
	if(!val) //add default value variable to map
		namedValues.insert(std::make_pair(v->ident->name, val));
	return val;
}

/*===========================StructureDefinition============================*/
llvm::Value* CodeGenVisitor::visitStructureDefinition(StructureDefinition* s) {
	return ErrorV("Attempt to evaluate not yet implemented structure definition");
}

/*============================FunctionDefinition============================*/
llvm::Value* CodeGenVisitor::visitFunctionDefinition(FunctionDefinition* f) {
	llvm::Function* func = theModule->getFunction(f->ident->name);
	if(!func)
		func = generateFunction(f); //create function object with type|ident|args
	if(!func) //generateFunction returned nullptr
		return nullptr;
	if(!func->empty())
		return ErrorV("Function is already defined");
	llvm::BasicBlock* block = llvm::BasicBlock::Create(*context, "function start", func);
	builder->SetInsertPoint(block);
	namedValues.clear();
	for (auto &arg : func->args())
		namedValues[arg.getName()] = &arg;
		func->dump();//Function IR dump
		llvm::Value* retVal = f->block->acceptVisitor(this);
	if(retVal->getType()->getTypeID() == func->getReturnType()->getTypeID()) {
		return retVal;
	}
	func->eraseFromParent();//erase if incorrect type returned
	return nullptr;
}

/*==========================StructureDeclaration============================*/
llvm::Value* CodeGenVisitor::visitStructureDeclaration(StructureDeclaration* s) {
	return ErrorV("Attempt to evaluate not yet implemented structure declaration");
}

/*===========================ExpressionStatement============================*/
llvm::Value* CodeGenVisitor::visitExpressionStatement(ExpressionStatement* e) {
	return e->exp->acceptVisitor(this);	//evaluated but value discarded
}

/*=============================ReturnStatement==============================*/
llvm::Value* CodeGenVisitor::visitReturnStatement(ReturnStatement* r) {
	llvm::Value* returnVal = r->exp->acceptVisitor(this);
	if(returnVal) {
		builder->CreateRet(returnVal); //builder returns value
	}
	return returnVal;
}

/*=============================AssignStatement==============================*/
llvm::Value* CodeGenVisitor::visitAssignStatement(AssignStatement* a) {
	//TODO: map a value to an exisiting identifier
	//look for identifier
	//map target to value
	return nullptr;
}

/*===============================IfStatement================================*/
llvm::Value* CodeGenVisitor::visitIfStatement(IfStatement* i) {
	return ErrorV("Attempt to evaluate not yet implemented if statement");
}
<|endoftext|>


<commit_before>#pragma once
#include <cstdint>
#include <array>
#include <memory>
#include <vector>
#include <algorithm>

#ifdef __EMSCRIPTEN__
#include "SDL2/SDL.h"
#else
#include "SDL.h"
#endif

#include "vm/utils.hpp"
#include "vm/context.hpp"

namespace yagbe
{
	class sdl2_renderer
	{
	public:
		sdl2_renderer(const ipoint &size, int scale = 4) : _w(size.x), _h(size.y)
		{
			if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0)
				throw std::runtime_error("SDL_Init");

			_window.reset(SDL_CreateWindow("YAGBE", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, _w * scale, _h * scale, SDL_WINDOW_SHOWN));
			if (!_window) throw std::runtime_error("SDL_CreateWindow");

			_renderer.reset(SDL_CreateRenderer(_window.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC));
			if (!_renderer) throw std::runtime_error("SDL_CreateRenderer");

			_texture.reset(SDL_CreateTexture(_renderer.get(), SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, _w, _h));
			if (!_texture) throw std::runtime_error("SDL_CreateTexture");

			open_audio();
		}

		~sdl2_renderer()
		{
			SDL_CloseAudioDevice(_audio);
			SDL_Quit();
		}

		void initialize(yagbe::context &ctx)
		{
			ctx.gpu.onFrameReady = [&](auto& frame)
			{
				accept_image(frame);
			};

			ctx.apu.configure(_audioSpec.freq, _audioSpec.freq / 60);
			ctx.apu.onSamplesReady = [&](auto&& samples)
			{
				accept_samples(std::move(samples));
			};
		}

		bool frame_drawn()
		{
			return _frame_drawn;
		}

		void next_frame()
		{
			_frame_drawn = false;
		}

		bool step()
		{
			handle_events();
			return _running;
		}

		void accept_image(const std::vector<uint8_t>& image)
		{
			if (image.size() != _w * _h * channels)
				throw std::runtime_error("accept_image wrong size");

			accept_raw_image(image.data());
		}

		void accept_image(const std::vector<uint32_t>& image)
		{
			if (image.size() != _w * _h)
				throw std::runtime_error("accept_image wrong size");

			accept_raw_image((uint8_t*)image.data());
		}

		void accept_image(const std::vector<color>& image)
		{
			if (image.size() != _w * _h)
				throw std::runtime_error("accept_image wrong size");

			accept_raw_image((uint8_t*)image.data());
		}

		void accept_samples(const std::vector<float>&& samples)
		{
			SDL_QueueAudio(_audio, samples.data(), (Uint32)samples.size() * sizeof(float));
		}

		bool running() { return _running; }

		struct key_info
		{
			bool shift = false;
		};

		std::function<void(SDL_Keycode, bool, const key_info&)> onKeyChanged;
	protected:
		void audio_callback(float* buff, int len)
		{

			int channels = 2;
			for (int i = 0; i < len; i += channels)
			{
				auto& outLeft = buff[i];
				auto& outRight = buff[i + 1];

				auto sine = [=](double freq) {
					static double secondsFromStart = 0;
					secondsFromStart += _audioStep;
					return (float)sin(secondsFromStart * freq * M_PI * 2.0);
				};

				auto square = [=](double freq) {
					static double len = 1.0 / freq / 2.0;
					static double acc = 0.0;
					static double v = 0.25;
					acc += _audioStep;
					if (acc > len) { acc = 0.0; v = -v; };
					return v;
				};

				auto silence = [=]() {
					return 0.0;
				};

				//square 1000

				outLeft = outRight = (float)silence();
			}
		}

		void open_audio()
		{
			SDL_AudioSpec want;

			SDL_memset(&_audioSpec, 0, sizeof(_audioSpec));
			SDL_memset(&want, 0, sizeof(want)); /* or SDL_zero(want) */
			want.freq = 48000;
			want.format = AUDIO_F32;
			want.channels = 2;
			want.samples = 4096;
			want.userdata = this;
			want.callback = nullptr;

			_audio = SDL_OpenAudioDevice(NULL, 0, &want, &_audioSpec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
			if (_audio == 0) {
				SDL_Log("Failed to open audio: %s", SDL_GetError());
			}
			else {
				_audioStep = 1.0 / (double)_audioSpec.freq;
				SDL_PauseAudioDevice(_audio, 0); /* start audio playing. */
			}
		}

		void accept_raw_image(const uint8_t *input)
		{
			_frame_drawn = true;
			auto texture = _texture.get();
			uint8_t *pixels;
			int pitch;
			if (SDL_LockTexture(texture, nullptr, &(void*&)pixels, &pitch) != 0)
				throw std::runtime_error("SDL_LockTexture");

			auto it = input;
			for (auto y = 0; y < _h; y++)
			{
				std::copy(it, it + _w*channels, pixels);
				it += _w*channels;
				pixels += pitch;
			}

			SDL_UnlockTexture(texture);

			auto ren = _renderer.get();

			SDL_RenderCopy(ren, _texture.get(), NULL, NULL);
			SDL_RenderPresent(ren);
		}

		void handle_events()
		{
			SDL_Event e;
			while (SDL_PollEvent(&e))
			{
				if (e.type == SDL_QUIT)
					_running = false;

				if (e.type == SDL_KEYDOWN || e.type == SDL_KEYUP)
				{
					auto key_code = e.key.keysym.sym;
					key_info info;
					info.shift = (e.key.keysym.mod & KMOD_SHIFT) != 0;

					if (onKeyChanged)
						onKeyChanged(key_code, e.type == SDL_KEYDOWN, info);
					return;
				}
			}
		}

		int _w, _h;
		bool _frame_drawn = false;
		const static int channels = 4;
		std::unique_ptr<SDL_Window, void(*)(SDL_Window*)> _window = { nullptr, SDL_DestroyWindow };
		std::unique_ptr<SDL_Renderer, void(*)(SDL_Renderer*)> _renderer = { nullptr, SDL_DestroyRenderer };
		std::unique_ptr<SDL_Texture, void(*)(SDL_Texture*)> _texture = { nullptr, SDL_DestroyTexture };
		SDL_AudioDeviceID _audio = 0;
		SDL_AudioSpec _audioSpec = {};
		double _audioStep = 0.0f;
		bool _running = true;
	};

};<commit_msg>Define M_PI<commit_after>#pragma once
#include <cstdint>
#include <array>
#include <memory>
#include <vector>
#include <algorithm>

#ifdef __EMSCRIPTEN__
#include "SDL2/SDL.h"
#else
#include "SDL.h"
#endif

#include "vm/utils.hpp"
#include "vm/context.hpp"

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

namespace yagbe
{
	class sdl2_renderer
	{
	public:
		sdl2_renderer(const ipoint &size, int scale = 4) : _w(size.x), _h(size.y)
		{
			if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0)
				throw std::runtime_error("SDL_Init");

			_window.reset(SDL_CreateWindow("YAGBE", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, _w * scale, _h * scale, SDL_WINDOW_SHOWN));
			if (!_window) throw std::runtime_error("SDL_CreateWindow");

			_renderer.reset(SDL_CreateRenderer(_window.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC));
			if (!_renderer) throw std::runtime_error("SDL_CreateRenderer");

			_texture.reset(SDL_CreateTexture(_renderer.get(), SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, _w, _h));
			if (!_texture) throw std::runtime_error("SDL_CreateTexture");

			open_audio();
		}

		~sdl2_renderer()
		{
			SDL_CloseAudioDevice(_audio);
			SDL_Quit();
		}

		void initialize(yagbe::context &ctx)
		{
			ctx.gpu.onFrameReady = [&](auto& frame)
			{
				accept_image(frame);
			};

			ctx.apu.configure(_audioSpec.freq, _audioSpec.freq / 60);
			ctx.apu.onSamplesReady = [&](auto&& samples)
			{
				accept_samples(std::move(samples));
			};
		}

		bool frame_drawn()
		{
			return _frame_drawn;
		}

		void next_frame()
		{
			_frame_drawn = false;
		}

		bool step()
		{
			handle_events();
			return _running;
		}

		void accept_image(const std::vector<uint8_t>& image)
		{
			if (image.size() != _w * _h * channels)
				throw std::runtime_error("accept_image wrong size");

			accept_raw_image(image.data());
		}

		void accept_image(const std::vector<uint32_t>& image)
		{
			if (image.size() != _w * _h)
				throw std::runtime_error("accept_image wrong size");

			accept_raw_image((uint8_t*)image.data());
		}

		void accept_image(const std::vector<color>& image)
		{
			if (image.size() != _w * _h)
				throw std::runtime_error("accept_image wrong size");

			accept_raw_image((uint8_t*)image.data());
		}

		void accept_samples(const std::vector<float>&& samples)
		{
			SDL_QueueAudio(_audio, samples.data(), (Uint32)samples.size() * sizeof(float));
		}

		bool running() { return _running; }

		struct key_info
		{
			bool shift = false;
		};

		std::function<void(SDL_Keycode, bool, const key_info&)> onKeyChanged;
	protected:
		void audio_callback(float* buff, int len)
		{

			int channels = 2;
			for (int i = 0; i < len; i += channels)
			{
				auto& outLeft = buff[i];
				auto& outRight = buff[i + 1];

				auto sine = [=](double freq) {
					static double secondsFromStart = 0;
					secondsFromStart += _audioStep;
					return (float)sin(secondsFromStart * freq * M_PI * 2.0);
				};

				auto square = [=](double freq) {
					static double len = 1.0 / freq / 2.0;
					static double acc = 0.0;
					static double v = 0.25;
					acc += _audioStep;
					if (acc > len) { acc = 0.0; v = -v; };
					return v;
				};

				auto silence = [=]() {
					return 0.0;
				};

				//square 1000

				outLeft = outRight = (float)silence();
			}
		}

		void open_audio()
		{
			SDL_AudioSpec want;

			SDL_memset(&_audioSpec, 0, sizeof(_audioSpec));
			SDL_memset(&want, 0, sizeof(want)); /* or SDL_zero(want) */
			want.freq = 48000;
			want.format = AUDIO_F32;
			want.channels = 2;
			want.samples = 4096;
			want.userdata = this;
			want.callback = nullptr;

			_audio = SDL_OpenAudioDevice(NULL, 0, &want, &_audioSpec, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
			if (_audio == 0) {
				SDL_Log("Failed to open audio: %s", SDL_GetError());
			}
			else {
				_audioStep = 1.0 / (double)_audioSpec.freq;
				SDL_PauseAudioDevice(_audio, 0); /* start audio playing. */
			}
		}

		void accept_raw_image(const uint8_t *input)
		{
			_frame_drawn = true;
			auto texture = _texture.get();
			uint8_t *pixels;
			int pitch;
			if (SDL_LockTexture(texture, nullptr, &(void*&)pixels, &pitch) != 0)
				throw std::runtime_error("SDL_LockTexture");

			auto it = input;
			for (auto y = 0; y < _h; y++)
			{
				std::copy(it, it + _w*channels, pixels);
				it += _w*channels;
				pixels += pitch;
			}

			SDL_UnlockTexture(texture);

			auto ren = _renderer.get();

			SDL_RenderCopy(ren, _texture.get(), NULL, NULL);
			SDL_RenderPresent(ren);
		}

		void handle_events()
		{
			SDL_Event e;
			while (SDL_PollEvent(&e))
			{
				if (e.type == SDL_QUIT)
					_running = false;

				if (e.type == SDL_KEYDOWN || e.type == SDL_KEYUP)
				{
					auto key_code = e.key.keysym.sym;
					key_info info;
					info.shift = (e.key.keysym.mod & KMOD_SHIFT) != 0;

					if (onKeyChanged)
						onKeyChanged(key_code, e.type == SDL_KEYDOWN, info);
					return;
				}
			}
		}

		int _w, _h;
		bool _frame_drawn = false;
		const static int channels = 4;
		std::unique_ptr<SDL_Window, void(*)(SDL_Window*)> _window = { nullptr, SDL_DestroyWindow };
		std::unique_ptr<SDL_Renderer, void(*)(SDL_Renderer*)> _renderer = { nullptr, SDL_DestroyRenderer };
		std::unique_ptr<SDL_Texture, void(*)(SDL_Texture*)> _texture = { nullptr, SDL_DestroyTexture };
		SDL_AudioDeviceID _audio = 0;
		SDL_AudioSpec _audioSpec = {};
		double _audioStep = 0.0f;
		bool _running = true;
	};

};
<|endoftext|>


<commit_before>//
//  async_activator.hpp
//  fibio
//
//  Created by Chen Xu on 14-3-30.
//  Copyright (c) 2014 0d0a.com. All rights reserved.
//

#ifndef fibio_fibers_asio_detail_async_activator_hpp
#define fibio_fibers_asio_detail_async_activator_hpp

#include <chrono>
#include <memory>
#include <functional>
#include <boost/asio/basic_waitable_timer.hpp>
#include <boost/system/error_code.hpp>
#include <fibio/fibers/detail/fiber_base.hpp>

namespace fibio { namespace fibers { namespace asio { namespace detail {
    struct async_activator : std::enable_shared_from_this<async_activator> {
        typedef std::shared_ptr<async_activator> ptr_t;

        async_activator(fibio::fibers::detail::fiber_base::ptr_t this_fiber,
                        uint64_t timeout,
                        std::function<void()> &&cancelation)
        : fiber_(this_fiber)
        , timeout_(timeout)
        , cancelation_(std::move(cancelation))
        , timer_(std::make_shared<yield_timer_t>(fiber_->get_fiber_strand().get_io_service()))
        , timer_triggered(false)
        , async_op_triggered(false)
        {}

        async_activator(const async_activator&)=delete;
        async_activator(async_activator&&)=delete;

        void activate() {
            async_op_triggered=true;
            // Operation completed, cancel timer
            if(timeout_>0 && !timer_triggered) timer_->cancel();
            if(timeout_==0 || timer_triggered) {
                // Both callback are called, resume fiber
                //fiber_->activate();
                ptr_t pthis(shared_from_this());
                fiber_->get_fiber_strand().dispatch([pthis](){ pthis->fiber_->activate(); });
            }
        }

        void start_timer_with_cancelation() {
            if (timeout_>0) {
                timer_->expires_from_now(std::chrono::microseconds(timeout_));
                ptr_t pthis(shared_from_this());
                timer_->async_wait(fiber_->get_fiber_strand().wrap(std::bind(&async_activator::on_timeout, pthis, std::placeholders::_1)));
            }
        }

        // private:
        void on_timeout(const boost::system::error_code &ec) {
            timer_triggered=true;
            if(async_op_triggered) {
                // Both callback are called, resume fiber
                //fiber_->activate();
                ptr_t pthis(shared_from_this());
                fiber_->get_fiber_strand().dispatch([pthis](){ pthis->fiber_->activate(); });
            } else {
                if(cancelation_) cancelation_();
            }
        }

        typedef boost::asio::basic_waitable_timer<std::chrono::steady_clock> yield_timer_t;
        typedef std::shared_ptr<boost::asio::basic_waitable_timer<std::chrono::steady_clock>> timer_ptr_t;

        fibio::fibers::detail::fiber_base::ptr_t fiber_;
        uint64_t timeout_;
        std::function<void()> cancelation_;
        timer_ptr_t timer_;
        bool timer_triggered;
        bool async_op_triggered;
    };
}}}}    // End of namespace fibio::fibers::asio::detail

#endif
<commit_msg>remove unused code<commit_after><|endoftext|>


<commit_before>#include "chord.h"
#include "succ_list.h"
#include <location.h>
#include <locationtable.h>
#include <id_utils.h>
#include <misc_utils.h>

#include <configurator.h>

/*
 * The idea of the succ_list class is to maintain a list of
 * immediate successors to the current node. The actual number
 * of successors needed is up to nsucc. The location information
 * is maintained in locationtable.
 */
succ_list::succ_list (ptr<vnode> v,
		      ptr<locationtable> locs)
  : myID (v->my_ID ()), myvnode (v), locations (locs)
{
  nnodes = 0;

  bool ok = Configurator::only ().get_int ("chord.nsucc", nsucc_);
  assert (ok);

  oldsucc = v->my_location ();
  stable_succlist = false;
  stable_succlist2 = false;
  nout_backoff = 0;
  nout_continuous = 0;

  locations->pin (myID, 1);
  locations->pin (myID, nsucc_);
}

ptr<location>
succ_list::succ ()
{
  return locations->closestsuccloc (incID (myID));
}

vec<ptr<location> >
succ_list::succs ()
{
  vec<ptr<location> > ret;

  ptr<location> cur = succ ();
  ret.push_back (cur);

  for (u_int i = 1; i < num_succ (); i++) {
    cur = locations->closestsuccloc (incID (cur->id ()));
    ret.push_back (cur);
  }
  return ret;
}

unsigned int
succ_list::num_succ ()
{
  int goodnodes = locations->usablenodes () - 1;
  int newnsucc = (nsucc_ > goodnodes) ? goodnodes : nsucc_;

  if (newnsucc < 0) {
    warn << "succ_list::num_succ () n:" << newnsucc << " g:" << goodnodes << "\n";
    newnsucc = 0;
  }
  return newnsucc;
}

void
succ_list::print (strbuf &outbuf)
{
  vec<ptr<location> > s = succs ();
  for (u_int i = 0; i < s.size (); i++)
    outbuf << myID << ": succ " << i + 1 << " : " << s[i]->id () << "\n";
}

u_long
succ_list::estimate_nnodes ()
{
  u_long n;
  ptr<location> lastsucc = myvnode->my_location ();
  int nsucc = num_succ ();
  for (int i = 0; i < nsucc; i++)
    lastsucc = locations->closestsuccloc (incID (lastsucc->id ()));

  chordID d = diff (myID, lastsucc->id ());
  if ((d > 0) && (nsucc > 0)) {
    chordID s = d / nsucc;
    chordID c = bigint (1) << NBIT;
    chordID q = c / s;
    n = q.getui ();
  } else
    n = 1;
  return n;
}

void
succ_list::fill_nodelistresext (chord_nodelistextres *res)
{
  // succ[0] is me. the rest are our actual successors.
  int curnsucc = num_succ ();
  ptr<location> cursucc = myvnode->my_location ();
  res->resok->nlist.setsize (curnsucc + 1);
  for (int i = 0; i <= curnsucc; i++) {
    cursucc->fill_node_ext (res->resok->nlist[i]);
    cursucc = locations->closestsuccloc (incID (cursucc->id ()));
  }
}

void
succ_list::fill_nodelistres (chord_nodelistres *res)
{
  // succ[0] is me. the rest are our actual successors.
  int curnsucc = num_succ ();
  ptr<location> cursucc = myvnode->my_location ();
  res->resok->nlist.setsize (curnsucc + 1);
  for (int i = 0; i <= curnsucc; i++) {
    cursucc->fill_node (res->resok->nlist[i]);
    cursucc = locations->closestsuccloc (incID (cursucc->id ()));
  }
}

void
succ_list::stabilize_succlist ()
{
  assert (nout_backoff == 0);

  stable_succlist2 = stable_succlist;
  stable_succlist = true;

  u_long n = estimate_nnodes ();
  locations->replace_estimate (nnodes, n);
  if (nnodes != n) {
    warnx << myID << ": estimating total number of nodes as "
	  << locations->estimate_nodes () << "\n";
  }
  nnodes = n;

  nout_backoff++;
  ptr<location> s = succ ();
  myvnode->get_succlist
    (s, wrap (this, &succ_list::stabilize_getsucclist_cb, s));
}

void
succ_list::stabilize_getsucclist_cb (ptr<location> s, vec<chord_node> nlist,
				     chordstat status)
{
  nout_backoff--;
  if (status) {
    warnx << myID << ": stabilize_getsucclist_cb: " << s << " : "
	  << "failure " << status << "\n";
    stable_succlist = false;
    return;
  }
  assert (s->id () == nlist[0].x);

  // PODC paper says, set our succlist to successors succlist mod last guy
  // We're going to merge his succlist with our succlist and make sure
  // deletions and insertions are accurate from our POV.
  unsigned int i, j;
  vec<ptr<location> > succlist = succs ();
  size_t curnsucc = succlist.size ();

  i = 0; j = 0;
  unsigned int newnsucc = nlist.size () - 1; // drop last guy.
  while ((i < curnsucc) && (j < newnsucc)) {
    if (succlist[i]->id () == nlist[j].x) {
      succlist[i]->set_coords (nlist[j]);
      i++; j++; continue;
    }
    if (between (myID, nlist[j].x, succlist[i]->id ())) {
      // if succlist[i] < nlist[j].x
      // then, maybe someone we knew about is dead now. best be sure.
      nout_backoff++;
      myvnode->ping
	(succlist[i], wrap (this, &succ_list::stabilize_getsucclist_check,
			    s, succlist[i]->id ()));
      i++;
      continue;
    }
    if (between (myID, succlist[i]->id (), nlist[j].x)) {
      // if succlist[i] > nlist[j].x
      // then maybe a new node joined. check it out.
      ptr<location> newsucc = locations->insert (nlist[j]);
      if (!newsucc || !newsucc->alive ()) {
	warnx << myID << ": stabilize_succlist: received bad successor "
	      << nlist[j].x << " from " << s << "\n";
	// XXX do something about it?
      } else {
	stable_succlist = false;
	warnx << myID << ": stabilize_succlist: received new successor "
	      << nlist[j].x << " from " << s << "\n";
      }
      j++;
      continue;
    }
  }
  bool check = false;
  while (i < curnsucc) {
    check = true;
    nout_backoff++;
    myvnode->ping
      (succlist[i], wrap (this, &succ_list::stabilize_getsucclist_check,
			  s, succlist[i]->id ()));
    i++;
  }

  while (j < newnsucc && curnsucc < (u_int)nsucc_) {
    assert (!check);
    ptr<location> newsucc = locations->insert (nlist[j]);
    if (!newsucc || !newsucc->alive ()) {
      warnx << myID << ": stabilize_succlist: received bad successor "
	    << nlist[j].x << " from " << s << "\n";
      // XXX do something about it?
    } else {
      curnsucc++;
      stable_succlist = false;
      warnx << myID << ": stabilize_succlist (2): received new successor "
	    << nlist[j].x << " from " << s << "\n";
    }
    j++;
  }
}

void
succ_list::stabilize_getsucclist_check (ptr<location> src, chordID chk,
					chordstat status)
{
  nout_backoff--;
  if (status) {
    stable_succlist = false;
    warnx << myID << ": stabilize_succlist: found dead successor " << chk
	  << " from " << src << "\n";
  }
}

// ============
void
succ_list::stabilize_succ ()
{
  assert (nout_continuous == 0);
  ptr<location> cursucc = succ ();
  if (cursucc != oldsucc) {
    warnx << myID << ": my successor changed from "
	  << oldsucc->id () << " to " << cursucc->id () << "\n";
    myvnode->notify (cursucc, myID);
    oldsucc = cursucc;
    // Wait until next round to check on this guy.
  } else {
    nout_continuous++;
    myvnode->get_predecessor
      (cursucc, wrap (this, &succ_list::stabilize_getpred_cb, cursucc));
  }
}

void
succ_list::stabilize_getpred_cb (ptr<location> sd, chord_node p, chordstat status)
{
  nout_continuous--;
  // receive predecessor from my successor; in stable case it is me
  if (status) {
    warnx << myID << ": stabilize_getpred_cb " << sd->id ()
    	  << " failure status " << status << "\n";
    if (status == CHORD_ERRNOENT) {
      warnx << myID << ": stabilize_getpred_cb " << sd->id ()
	    << " doesn't know about his predecessor?? notifying...\n";
      myvnode->notify (sd, myID);
    }
    // other failures we will address next round.
  } else {
    if (myID == p.x) {
      // Good, things are as we expect.
    } else if (betweenleftincl (myID, sd->id (), p.x)) {
      // Did we get someone strictly better?
      ptr<location> newsucc = locations->insert (p);
      if (newsucc && newsucc->alive ())
	oldsucc = newsucc;
    } else {
      // Our successor appears to be confused, better tell
      // him what we think.
      myvnode->notify (sd, myID);
    }
  }
}

// XXX currently an exhaustive search of the successors
ptr<location>
succ_list::closestpred (const chordID &x, vec<chordID> failed)
{
  ptr<location> best = myvnode->my_location ();
  for (u_int i = 0; i < num_succ (); i++) {
    ptr<location> n = locations->closestsuccloc (incID (best->id ()));
    if (between (myID, x, n->id ()) && (!in_vector (failed, n->id ())))
      best = n;
  }
  return best;
}

<commit_msg>update successor lists' age<commit_after>#include "chord.h"
#include "succ_list.h"
#include <location.h>
#include <locationtable.h>
#include <id_utils.h>
#include <misc_utils.h>

#include <configurator.h>

/*
 * The idea of the succ_list class is to maintain a list of
 * immediate successors to the current node. The actual number
 * of successors needed is up to nsucc. The location information
 * is maintained in locationtable.
 */
succ_list::succ_list (ptr<vnode> v,
		      ptr<locationtable> locs)
  : myID (v->my_ID ()), myvnode (v), locations (locs)
{
  nnodes = 0;

  bool ok = Configurator::only ().get_int ("chord.nsucc", nsucc_);
  assert (ok);

  oldsucc = v->my_location ();
  stable_succlist = false;
  stable_succlist2 = false;
  nout_backoff = 0;
  nout_continuous = 0;

  locations->pin (myID, 1);
  locations->pin (myID, nsucc_);
}

ptr<location>
succ_list::succ ()
{
  return locations->closestsuccloc (incID (myID));
}

vec<ptr<location> >
succ_list::succs ()
{
  vec<ptr<location> > ret;

  ptr<location> cur = succ ();
  ret.push_back (cur);

  for (u_int i = 1; i < num_succ (); i++) {
    cur = locations->closestsuccloc (incID (cur->id ()));
    ret.push_back (cur);
  }
  return ret;
}

unsigned int
succ_list::num_succ ()
{
  int goodnodes = locations->usablenodes () - 1;
  int newnsucc = (nsucc_ > goodnodes) ? goodnodes : nsucc_;

  if (newnsucc < 0) {
    warn << "succ_list::num_succ () n:" << newnsucc << " g:" << goodnodes << "\n";
    newnsucc = 0;
  }
  return newnsucc;
}

void
succ_list::print (strbuf &outbuf)
{
  vec<ptr<location> > s = succs ();
  for (u_int i = 0; i < s.size (); i++)
    outbuf << myID << ": succ " << i + 1 << " : " << s[i]->id () << "\n";
}

u_long
succ_list::estimate_nnodes ()
{
  u_long n;
  ptr<location> lastsucc = myvnode->my_location ();
  int nsucc = num_succ ();
  for (int i = 0; i < nsucc; i++)
    lastsucc = locations->closestsuccloc (incID (lastsucc->id ()));

  chordID d = diff (myID, lastsucc->id ());
  if ((d > 0) && (nsucc > 0)) {
    chordID s = d / nsucc;
    chordID c = bigint (1) << NBIT;
    chordID q = c / s;
    n = q.getui ();
  } else
    n = 1;
  return n;
}

void
succ_list::fill_nodelistresext (chord_nodelistextres *res)
{
  // succ[0] is me. the rest are our actual successors.
  int curnsucc = num_succ ();
  ptr<location> cursucc = myvnode->my_location ();
  res->resok->nlist.setsize (curnsucc + 1);
  for (int i = 0; i <= curnsucc; i++) {
    cursucc->fill_node_ext (res->resok->nlist[i]);
    cursucc = locations->closestsuccloc (incID (cursucc->id ()));
  }
}

void
succ_list::fill_nodelistres (chord_nodelistres *res)
{
  // succ[0] is me. the rest are our actual successors.
  int curnsucc = num_succ ();
  ptr<location> cursucc = myvnode->my_location ();
  res->resok->nlist.setsize (curnsucc + 1);
  for (int i = 0; i <= curnsucc; i++) {
    cursucc->fill_node (res->resok->nlist[i]);
    cursucc = locations->closestsuccloc (incID (cursucc->id ()));
  }
}

void
succ_list::stabilize_succlist ()
{
  assert (nout_backoff == 0);

  stable_succlist2 = stable_succlist;
  stable_succlist = true;

  u_long n = estimate_nnodes ();
  locations->replace_estimate (nnodes, n);
  if (nnodes != n) {
    warnx << myID << ": estimating total number of nodes as "
	  << locations->estimate_nodes () << "\n";
  }
  nnodes = n;

  nout_backoff++;
  ptr<location> s = succ ();
  myvnode->get_succlist
    (s, wrap (this, &succ_list::stabilize_getsucclist_cb, s));
}

void
succ_list::stabilize_getsucclist_cb (ptr<location> s, vec<chord_node> nlist,
				     chordstat status)
{
  nout_backoff--;
  if (status) {
    warnx << myID << ": stabilize_getsucclist_cb: " << s << " : "
	  << "failure " << status << "\n";
    stable_succlist = false;
    return;
  }
  assert (s->id () == nlist[0].x);

  // PODC paper says, set our succlist to successors succlist mod last guy
  // We're going to merge his succlist with our succlist and make sure
  // deletions and insertions are accurate from our POV.
  unsigned int i, j;
  vec<ptr<location> > succlist = succs ();
  size_t curnsucc = succlist.size ();

  i = 0; j = 0;
  unsigned int newnsucc = nlist.size () - 1; // drop last guy.
  while ((i < curnsucc) && (j < newnsucc)) {
    if (succlist[i]->id () == nlist[j].x) {
      succlist[i]->update (nlist[j]);
      i++; j++; continue;
    }
    if (between (myID, nlist[j].x, succlist[i]->id ())) {
      // if succlist[i] < nlist[j].x
      // then, maybe someone we knew about is dead now. best be sure.
      nout_backoff++;
      myvnode->ping
	(succlist[i], wrap (this, &succ_list::stabilize_getsucclist_check,
			    s, succlist[i]->id ()));
      i++;
      continue;
    }
    if (between (myID, succlist[i]->id (), nlist[j].x)) {
      // if succlist[i] > nlist[j].x
      // then maybe a new node joined. check it out.
      ptr<location> newsucc = locations->insert (nlist[j]);
      if (!newsucc || !newsucc->alive ()) {
	warnx << myID << ": stabilize_succlist: received bad successor "
	      << nlist[j].x << " from " << s << "\n";
	// XXX do something about it?
      } else {
	stable_succlist = false;
	warnx << myID << ": stabilize_succlist: received new successor "
	      << nlist[j].x << "," << nlist[j].knownup << ","
	      << nlist[j].age << " from " << (s->id ()>>144) << "," << s->knownup ()
	      << "," << s->age () << "\n";
      }
      j++;
      continue;
    }
  }
  bool check = false;
  while (i < curnsucc) {
    check = true;
    nout_backoff++;
    myvnode->ping
      (succlist[i], wrap (this, &succ_list::stabilize_getsucclist_check,
			  s, succlist[i]->id ()));
    i++;
  }

  while (j < newnsucc && curnsucc < (u_int)nsucc_) {
    assert (!check);
    ptr<location> newsucc = locations->insert (nlist[j]);
    if (!newsucc || !newsucc->alive ()) {
      warnx << myID << ": stabilize_succlist: received bad successor "
	    << nlist[j].x << " from " << s << "\n";
      // XXX do something about it?
    } else {
      curnsucc++;
      stable_succlist = false;
      warnx << myID << ": stabilize_succlist (2): received new successor "
	    << nlist[j].x << " from " << s << "\n";
    }
    j++;
  }
}

void
succ_list::stabilize_getsucclist_check (ptr<location> src, chordID chk,
					chordstat status)
{
  nout_backoff--;
  if (status) {
    stable_succlist = false;
    warnx << myID << ": stabilize_succlist: found dead successor " << chk
	  << " from " << src << "\n";
  }
}

// ============
void
succ_list::stabilize_succ ()
{
  assert (nout_continuous == 0);
  ptr<location> cursucc = succ ();
  if (cursucc != oldsucc) {
    warnx << myID << ": my successor changed from "
	  << oldsucc->id () << " to " << cursucc->id () << "\n";
    myvnode->notify (cursucc, myID);
    oldsucc = cursucc;
    // Wait until next round to check on this guy.
  } else {
    nout_continuous++;
    myvnode->get_predecessor
      (cursucc, wrap (this, &succ_list::stabilize_getpred_cb, cursucc));
  }
}

void
succ_list::stabilize_getpred_cb (ptr<location> sd, chord_node p, chordstat status)
{
  nout_continuous--;
  // receive predecessor from my successor; in stable case it is me
  if (status) {
    warnx << myID << ": stabilize_getpred_cb " << sd->id ()
    	  << " failure status " << status << "\n";
    if (status == CHORD_ERRNOENT) {
      warnx << myID << ": stabilize_getpred_cb " << sd->id ()
	    << " doesn't know about his predecessor?? notifying...\n";
      myvnode->notify (sd, myID);
    }
    // other failures we will address next round.
  } else {
    if (myID == p.x) {
      // Good, things are as we expect.
    } else if (betweenleftincl (myID, sd->id (), p.x)) {
      // Did we get someone strictly better?
      ptr<location> newsucc = locations->insert (p);
      if (newsucc && newsucc->alive ())
	oldsucc = newsucc;
    } else {
      // Our successor appears to be confused, better tell
      // him what we think.
      myvnode->notify (sd, myID);
    }
  }
}

// XXX currently an exhaustive search of the successors
ptr<location>
succ_list::closestpred (const chordID &x, vec<chordID> failed)
{
  ptr<location> best = myvnode->my_location ();
  for (u_int i = 0; i < num_succ (); i++) {
    ptr<location> n = locations->closestsuccloc (incID (best->id ()));
    if (between (myID, x, n->id ()) && (!in_vector (failed, n->id ())))
      best = n;
  }
  return best;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: cmdstrm.hxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: mh $ $Date: 2002-11-18 15:53:37 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2002
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2002 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2002 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _CMDSTRM_HXX
#define _CMDSTRM_HXX

#include <objtest.hxx>
#include <testapp.hxx>
#include "cmdbasestream.hxx"

class CmdStream : public CmdBaseStream
{
public:
    CmdStream();
    ~CmdStream();

    void WriteSortedParams( SbxArray* rPar, BOOL IsKeyString = FALSE );

    void GenCmdCommand( USHORT nNr, SbxArray* rPar );

    void GenCmdSlot( USHORT nNr, SbxArray* rPar );

    void GenCmdUNOSlot( const String &aURL );

    void GenCmdControl( ULONG nUId, USHORT nMethodId, SbxArray* rPar );
    void GenCmdControl( String aUId, USHORT nMethodId, SbxArray* rPar );

/*  void GenCmdControl (ULONG nUId, USHORT nMethodId = 0);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, String aString);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, String aString, USHORT nNr);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, String aString, BOOL bBool);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, USHORT nNr);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, USHORT nNr1, USHORT nNr2);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, USHORT nNr, BOOL bBool);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, ULONG nNr);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, BOOL bBool);*/

    void GenCmdFlow( USHORT nArt );
    void GenCmdFlow( USHORT nArt, USHORT nNr1 );
    void GenCmdFlow( USHORT nArt, ULONG nNr1 );
    void GenCmdFlow( USHORT nArt, String aString1 );

    void Reset(ULONG nSequence);

    SvMemoryStream* GetStream();

    static CNames *pKeyCodes;           // Namen der Sondertasten  MOD1, F1, LEFT ...
    static ControlDefLoad __READONLY_DATA arKeyCodes [];

private:
    String WandleKeyEventString( String aKeys );    // Nutzt pKeyCodes.  <RETURN> <SHIFT LEFT LEFT>

//  CmdBaseStream::Write;
    void Write( comm_USHORT nNr ){CmdBaseStream::Write( nNr );}
    void Write( comm_ULONG nNr ){CmdBaseStream::Write( nNr );}
    void Write( const comm_UniChar* aString, comm_USHORT nLenInChars ){CmdBaseStream::Write( aString, nLenInChars );}
    void Write( comm_BOOL bBool ){CmdBaseStream::Write( bBool );}
//  new
    void Write( String aString, BOOL IsKeyString = FALSE );

    SvMemoryStream *pSammel;
};

#endif
<commit_msg>INTEGRATION: CWS ooo19126 (1.1.186); FILE MERGED 2005/09/05 17:17:27 rt 1.1.186.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cmdstrm.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 19:30:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CMDSTRM_HXX
#define _CMDSTRM_HXX

#include <objtest.hxx>
#include <testapp.hxx>
#include "cmdbasestream.hxx"

class CmdStream : public CmdBaseStream
{
public:
    CmdStream();
    ~CmdStream();

    void WriteSortedParams( SbxArray* rPar, BOOL IsKeyString = FALSE );

    void GenCmdCommand( USHORT nNr, SbxArray* rPar );

    void GenCmdSlot( USHORT nNr, SbxArray* rPar );

    void GenCmdUNOSlot( const String &aURL );

    void GenCmdControl( ULONG nUId, USHORT nMethodId, SbxArray* rPar );
    void GenCmdControl( String aUId, USHORT nMethodId, SbxArray* rPar );

/*  void GenCmdControl (ULONG nUId, USHORT nMethodId = 0);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, String aString);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, String aString, USHORT nNr);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, String aString, BOOL bBool);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, USHORT nNr);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, USHORT nNr1, USHORT nNr2);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, USHORT nNr, BOOL bBool);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, ULONG nNr);
    void GenCmdControl (ULONG nUId, USHORT nMethodId, BOOL bBool);*/

    void GenCmdFlow( USHORT nArt );
    void GenCmdFlow( USHORT nArt, USHORT nNr1 );
    void GenCmdFlow( USHORT nArt, ULONG nNr1 );
    void GenCmdFlow( USHORT nArt, String aString1 );

    void Reset(ULONG nSequence);

    SvMemoryStream* GetStream();

    static CNames *pKeyCodes;           // Namen der Sondertasten  MOD1, F1, LEFT ...
    static ControlDefLoad __READONLY_DATA arKeyCodes [];

private:
    String WandleKeyEventString( String aKeys );    // Nutzt pKeyCodes.  <RETURN> <SHIFT LEFT LEFT>

//  CmdBaseStream::Write;
    void Write( comm_USHORT nNr ){CmdBaseStream::Write( nNr );}
    void Write( comm_ULONG nNr ){CmdBaseStream::Write( nNr );}
    void Write( const comm_UniChar* aString, comm_USHORT nLenInChars ){CmdBaseStream::Write( aString, nLenInChars );}
    void Write( comm_BOOL bBool ){CmdBaseStream::Write( bBool );}
//  new
    void Write( String aString, BOOL IsKeyString = FALSE );

    SvMemoryStream *pSammel;
};

#endif
<|endoftext|>