<commit_before>#include<stack>
#include<iostream>
#include<iomanip>
#include<queue>
#include <fstream>
#include "DiskManager.h"
#include "Folder.h"
#include "FileType.h"
#include "Access.h"
#include "FAT.h"
#include<direct.h>
#include<io.h>

const string ACCESS[] = { "只读","可修改","可执行" };
const string rootPath = "/Users/";
queue<FCB*> persistQueue;//持久化队列
FAT fat;
string blocks[N];
ofstream *out = NULL;
ifstream *in = NULL;

using namespace std;

void DiskManager::DiskWrite(File * file)
{
	//文件输出流

	printf("%s\n", file->path.c_str());

	//freopen(file->name.c_str(), "w", stdout);

	out = new ofstream(file->path.c_str());
	if (out->is_open())
	{
		out->close();
	}

	//cout << "hello world" << endl;

   // fclose(stdout);//关闭文件

}

bool DiskManager::DiskMkdir(string dirName)
{
	printf("%s\n",dirName.c_str());
	return _mkdir(dirName.c_str()) == 0;

}

bool DiskManager::DiskRmdir(string dirName)
{

	return rmdir(dirName.c_str()) == 0;
}

bool DiskManager::DiskCkdir(string dirName)
{

	if (_access(dirName.c_str(), 0) == -1)
	{
		return  _mkdir(dirName.c_str()) == 0;
	}
	return false;
}

void DiskManager::DiskRmdir(Folder *f)
{
	//DFS删除
	for (int i = 0; i < f->child.size(); i++) {
		if (f->child[i]->type == DOCUMENT) {
			printf("%s\n", f->child[i]->path.c_str());
			remove(f->child[i]->path.c_str());

		}else {
			this->DiskRmdir((Folder*)f->child[i]);
		}
	}
	printf("%s\n", f->path.c_str());
	this->DiskRmdir(f->path.c_str());
}

DiskManager::DiskManager()
{
	fat.init(blocks);

	root = new Folder(rootPath,FileType::FOLDER);
	root->path = rootPath;
	this->DiskMkdir(rootPath);
	//设置磁盘根为目录
	//设置根节点的父节点为自身
	root->father = root;
	cout << "欢迎！！-----------您可输入help获得帮助------------" << endl<< "\n[root@localhost "+rootPath+"]# ";
	string opear,cmd;
	while (cin >> cmd)
	{
		 if (cmd == "format") {
			this->format(blocks);
		}
		else if (cmd == "mkdir") {
			this->Mkdir();
		}
		else if (cmd == "rmdir") {
			this->Rmdir();
		}
		else if (cmd == "ls") {
			this->ls();
		}
		else if (cmd == "cd") {
			this->cd();
		}
		else if (cmd == "create") {
			this->create();
		}
		else if (cmd == "open") {
			this->open();
		}
		else if (cmd == "close") {
			this->close();
		}
		else if (cmd == "rm") {
			this->rm();
		}
		else if (cmd == "exit") {
			printf("%s\n", "再见！");
			break;
		}
		else if(cmd=="help"){
			cout << "\n●format:对文件存储器进行格式化.\n"<<
				"●mkdir:用于创建子目录\n" <<
				"●rmdir : 用于删除子目录\n" <<
				"●ls : 用于显示目录\n" <<
				"●cd : 用于更改当前目录\n" <<
				"●create : 用于创建文件\n" <<
				"●open : 用于打开文件\n" <<
				"●close : 用于关闭文件\n" <<
				"●write : 用于写文件\n" <<
				"●read : 用于读文件\n" <<
				"●rm : 用于删除文件\n" <<
				"●exit : 退出系统\n"
				<<endl;
		}
		else {
			cout << "输入指令错误，请重新输入！！" << endl;
		}
		cout << "\n[root@localhost "+this->root->path+" ]# ";

	}
}

DiskManager::~DiskManager()
{

}

void DiskManager::format(string *blocks)
{
	fat.init(blocks);

	//回退到根目录
	while (root->father != root) {
		this->root = (Folder*)(this->root->father);
	}

	this->DiskRmdir(this->root);

	root->child.clear();

	printf("%s\n", "磁盘格式化成功！");
}

void DiskManager::Mkdir()
{
	string name;
	cin >> name;

	Folder *childFile = new Folder(name,FileType::FOLDER);

	//设置父节点
	childFile->father = (this->root);
	childFile->path = this->root->path + name + "/" ;
	//判断是否文件重复

	if (this->root->count(childFile)) {
		//文件重复报错
		cout << "创建文件夹失败，文件夹名出现重复" << endl;
	}else {
		cout << "创建文件夹成功" << endl;
		this->DiskMkdir(childFile->path);
		this->root->addChild(childFile);

	}
}

void DiskManager::Rmdir()
{
	string name;
	cin >> name;
	Folder *childFile =new Folder(name, FOLDER);
	childFile = (Folder*) this->root->find(childFile);
	if (this->root->erase(childFile)) {
		//文件重复报错
		this->DiskRmdir(childFile);
		cout << "删除文件夹成功" << endl;
	}else {
		cout << "无此文件夹 ，删除文件夹失败" << endl;

	}
}

void DiskManager::ls()
{

	cout << setw(10) << "访问权限"
		<< setw(20) <<"文件大小"
		<< setw(25) << "修改日期"
		<< setw(20) << "文件名"
		<< endl;
	int size = this->root->size();

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

		cout << setw(10) << ACCESS[this->root->child[i]->access]
			<< setw(20) << (this->root->child[i]->type != FOLDER ? ((File*)this->root->child[i])->toString(blocks).size() : 4096)
			<< setw(25)<<this->root->child[i]->modifyDate
			<< setw(20)<<this->root->child[i]->name
			<<endl;

	}

}

void DiskManager::cd()
{
	string name;
	cin >> name;
	if (name == "..") {
		this->root = (Folder*)(this->root->father);
	}
	else {
		if (this->root->count(new Folder(name, FOLDER))) {

			if (this->root->find(new Folder(name, FOLDER))->type != FOLDER)
			{
				cout << "无此文件夹" << endl;
			}
			else
			{
				root = (Folder*)this->root->find(new Folder(name, FOLDER));
			}
		}
		else {
			cout << "无此文件夹 " << endl;
		}
	}

}

void DiskManager::create()
{
	string name;
	cin >> name;

	File *childFile =  new File( name, DOCUMENT,fat);
	//设置父节点
	childFile->father = (this->root);
	childFile->path = this->root->path + name;
	//判断是否文件重复
	if (this->root->count(childFile)) {
		//文件重复报错
		cout << "创建文件失败，文件名出现重复！！" << endl;
	}
	else {
		cout << "创建文件成功！" << endl;
		this->root->addChild(childFile);
		this->DiskWrite(childFile);
	}
}

void DiskManager::open()
{
	string name,cmd;
	cin >> name;

    File * file = (File*)this->root->find(new File(name, DOCUMENT,fat));
	if (file!=NULL) {

		printf("%s\n", "文件读写流打开成功!");
		cout << "\n[root@localhost " + this->root->path + " ]# ";
		while (cin>>cmd) {
			cout << "\n[root@localhost " + this->root->path + " ]# ";
			if (cmd == "write") {
				this->write(file->path.c_str(), file);
			}
			else if (cmd == "read") {
				this->read(file->path.c_str());
			}
			else if (cmd == "close") {
				this->close();
				break;
			}
		}
	}
	else {
		printf("%s\n", "无法打开文件读写流，无此文件！");
	}
}

void DiskManager::close()
{
	if (out == NULL||in==NULL) {
		printf("%s\n", "无文件读写流需要关闭!");
	}else {
		out->close();
		in->close();
		printf("%s\n", "文件读写流关闭成功!");
	}
}

void DiskManager::write(const char *s, File* file)
{
	string content;
	cin >> content;
	if (in != NULL)in->close();

	file->addContent(content.c_str(), blocks, fat);//添加内容到文件中

	content = file->toString(blocks);

	out = new ofstream(s);
	if (out->is_open())
	{
		*out << content;
	}
	out->close();
}

void DiskManager::read(const char *s)
{
	char *content = new char[N];
	if (out != NULL)out->close();
	in =  new ifstream(s);
	if (in->is_open())
	{
		*in >> content;
	}
	in->close();
	cout << content;

}

void DiskManager::rm()
{
	string name;
	cin >> name;
	File *childFile = new File(name, DOCUMENT,fat);
	if (this->root->count(childFile)) {
		//文件重复报错
		childFile =(File*) this->root->find(childFile);
		remove(childFile->path.c_str());
		childFile->release(fat,blocks);
		this->root->erase(childFile);

		cout << "删除文件成功！" << endl;
	}
	else {
		cout << "无此文件 ，删除文件失败" << endl;
	}

}
<commit_msg>fix: import mkdir method<commit_after>#include<stack>
#include<iostream>
#include<iomanip>
#include<queue>
#include <fstream>
#include "DiskManager.h"
#include "Folder.h"
#include "FileType.h"
#include "Access.h"
#include "FAT.h"
//#include<direct.h>
#include <dirent.h>
//#include <io.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>

const string ACCESS[] = { "只读","可修改","可执行" };
const string rootPath = "/Users/";
queue<FCB*> persistQueue;//持久化队列
FAT fat;
string blocks[N];
ofstream *out = NULL;
ifstream *in = NULL;

using namespace std;

void DiskManager::DiskWrite(File * file)
{
	//文件输出流

	printf("%s\n", file->path.c_str());

	//freopen(file->name.c_str(), "w", stdout);

	out = new ofstream(file->path.c_str());
	if (out->is_open())
	{
		out->close();
	}

	//cout << "hello world" << endl;

   // fclose(stdout);//关闭文件

}

bool DiskManager::DiskMkdir(string dirName)
{
	printf("%s\n",dirName.c_str());
	return mkdir(dirName.c_str(),S_IRWXU) == 0;

}

bool DiskManager::DiskRmdir(string dirName)
{

	return rmdir(dirName.c_str()) == 0;
}

bool DiskManager::DiskCkdir(string dirName)
{

	if (access(dirName.c_str(), 0) == -1)
	{
        return mkdir(dirName.c_str(),S_IRWXU) == 0;
	}
	return false;
}

void DiskManager::DiskRmdir(Folder *f)
{
	//DFS删除
	for (int i = 0; i < f->child.size(); i++) {
		if (f->child[i]->type == DOCUMENT) {
			printf("%s\n", f->child[i]->path.c_str());
			remove(f->child[i]->path.c_str());

		}else {
			this->DiskRmdir((Folder*)f->child[i]);
		}
	}
	printf("%s\n", f->path.c_str());
	this->DiskRmdir(f->path.c_str());
}

DiskManager::DiskManager()
{
	fat.init(blocks);

	root = new Folder(rootPath,FileType::FOLDER);
	root->path = rootPath;
	this->DiskMkdir(rootPath);
	//设置磁盘根为目录
	//设置根节点的父节点为自身
	root->father = root;
	cout << "欢迎！！-----------您可输入help获得帮助------------" << endl<< "\n[root@localhost "+rootPath+"]# ";
	string opear,cmd;
	while (cin >> cmd)
	{
		 if (cmd == "format") {
			this->format(blocks);
		}
		else if (cmd == "mkdir") {
			this->Mkdir();
		}
		else if (cmd == "rmdir") {
			this->Rmdir();
		}
		else if (cmd == "ls") {
			this->ls();
		}
		else if (cmd == "cd") {
			this->cd();
		}
		else if (cmd == "create") {
			this->create();
		}
		else if (cmd == "open") {
			this->open();
		}
		else if (cmd == "close") {
			this->close();
		}
		else if (cmd == "rm") {
			this->rm();
		}
		else if (cmd == "exit") {
			printf("%s\n", "再见！");
			break;
		}
		else if(cmd=="help"){
			cout << "\n●format:对文件存储器进行格式化.\n"<<
				"●mkdir:用于创建子目录\n" <<
				"●rmdir : 用于删除子目录\n" <<
				"●ls : 用于显示目录\n" <<
				"●cd : 用于更改当前目录\n" <<
				"●create : 用于创建文件\n" <<
				"●open : 用于打开文件\n" <<
				"●close : 用于关闭文件\n" <<
				"●write : 用于写文件\n" <<
				"●read : 用于读文件\n" <<
				"●rm : 用于删除文件\n" <<
				"●exit : 退出系统\n"
				<<endl;
		}
		else {
			cout << "输入指令错误，请重新输入！！" << endl;
		}
		cout << "\n[root@localhost "+this->root->path+" ]# ";

	}
}

DiskManager::~DiskManager()
{

}

void DiskManager::format(string *blocks)
{
	fat.init(blocks);

	//回退到根目录
	while (root->father != root) {
		this->root = (Folder*)(this->root->father);
	}

	this->DiskRmdir(this->root);

	root->child.clear();

	printf("%s\n", "磁盘格式化成功！");
}

void DiskManager::Mkdir()
{
	string name;
	cin >> name;

	Folder *childFile = new Folder(name,FileType::FOLDER);

	//设置父节点
	childFile->father = (this->root);
	childFile->path = this->root->path + name + "/" ;
	//判断是否文件重复

	if (this->root->count(childFile)) {
		//文件重复报错
		cout << "创建文件夹失败，文件夹名出现重复" << endl;
	}else {
		cout << "创建文件夹成功" << endl;
		this->DiskMkdir(childFile->path);
		this->root->addChild(childFile);

	}
}

void DiskManager::Rmdir()
{
	string name;
	cin >> name;
	Folder *childFile =new Folder(name, FOLDER);
	childFile = (Folder*) this->root->find(childFile);
	if (this->root->erase(childFile)) {
		//文件重复报错
		this->DiskRmdir(childFile);
		cout << "删除文件夹成功" << endl;
	}else {
		cout << "无此文件夹 ，删除文件夹失败" << endl;

	}
}

void DiskManager::ls()
{

	cout << setw(10) << "访问权限"
		<< setw(20) <<"文件大小"
		<< setw(25) << "修改日期"
		<< setw(20) << "文件名"
		<< endl;
	int size = this->root->size();

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

		cout << setw(10) << ACCESS[this->root->child[i]->access]
			<< setw(20) << (this->root->child[i]->type != FOLDER ? ((File*)this->root->child[i])->toString(blocks).size() : 4096)
			<< setw(25)<<this->root->child[i]->modifyDate
			<< setw(20)<<this->root->child[i]->name
			<<endl;

	}

}

void DiskManager::cd()
{
	string name;
	cin >> name;
	if (name == "..") {
		this->root = (Folder*)(this->root->father);
	}
	else {
		if (this->root->count(new Folder(name, FOLDER))) {

			if (this->root->find(new Folder(name, FOLDER))->type != FOLDER)
			{
				cout << "无此文件夹" << endl;
			}
			else
			{
				root = (Folder*)this->root->find(new Folder(name, FOLDER));
			}
		}
		else {
			cout << "无此文件夹 " << endl;
		}
	}

}

void DiskManager::create()
{
	string name;
	cin >> name;

	File *childFile =  new File( name, DOCUMENT,fat);
	//设置父节点
	childFile->father = (this->root);
	childFile->path = this->root->path + name;
	//判断是否文件重复
	if (this->root->count(childFile)) {
		//文件重复报错
		cout << "创建文件失败，文件名出现重复！！" << endl;
	}
	else {
		cout << "创建文件成功！" << endl;
		this->root->addChild(childFile);
		this->DiskWrite(childFile);
	}
}

void DiskManager::open()
{
	string name,cmd;
	cin >> name;

    File * file = (File*)this->root->find(new File(name, DOCUMENT,fat));
	if (file!=NULL) {

		printf("%s\n", "文件读写流打开成功!");
		cout << "\n[root@localhost " + this->root->path + " ]# ";
		while (cin>>cmd) {
			cout << "\n[root@localhost " + this->root->path + " ]# ";
			if (cmd == "write") {
				this->write(file->path.c_str(), file);
			}
			else if (cmd == "read") {
				this->read(file->path.c_str());
			}
			else if (cmd == "close") {
				this->close();
				break;
			}
		}
	}
	else {
		printf("%s\n", "无法打开文件读写流，无此文件！");
	}
}

void DiskManager::close()
{
	if (out == NULL||in==NULL) {
		printf("%s\n", "无文件读写流需要关闭!");
	}else {
		out->close();
		in->close();
		printf("%s\n", "文件读写流关闭成功!");
	}
}

void DiskManager::write(const char *s, File* file)
{
	string content;
	cin >> content;
	if (in != NULL)in->close();

	file->addContent(content.c_str(), blocks, fat);//添加内容到文件中

	content = file->toString(blocks);

	out = new ofstream(s);
	if (out->is_open())
	{
		*out << content;
	}
	out->close();
}

void DiskManager::read(const char *s)
{
	char *content = new char[N];
	if (out != NULL)out->close();
	in =  new ifstream(s);
	if (in->is_open())
	{
		*in >> content;
	}
	in->close();
	cout << content;

}

void DiskManager::rm()
{
	string name;
	cin >> name;
	File *childFile = new File(name, DOCUMENT,fat);
	if (this->root->count(childFile)) {
		//文件重复报错
		childFile =(File*) this->root->find(childFile);
		remove(childFile->path.c_str());
		childFile->release(fat,blocks);
		this->root->erase(childFile);

		cout << "删除文件成功！" << endl;
	}
	else {
		cout << "无此文件 ，删除文件失败" << endl;
	}

}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "core/Setup.h"

#if OUZEL_PLATFORM_ANDROID && OUZEL_COMPILE_OPENGL

#include "RenderDeviceOGLAndroid.hpp"
#include "core/android/WindowAndroid.hpp"
#include "core/Engine.hpp"
#include "utils/Log.hpp"

namespace ouzel
{
    namespace graphics
    {
        RenderDeviceOGLAndroid::~RenderDeviceOGLAndroid()
        {
            running = false;
            flushCommands();
            if (renderThread.joinable()) renderThread.join();

            if (context)
            {
                if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
                {
                    Log(Log::Level::ERR) << "Failed to unset EGL context";
                }

                if (!eglDestroyContext(display, context))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL context";
                }
            }

            if (surface)
            {
                if (!eglDestroySurface(display, surface))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL surface";
                }
            }

            if (display)
            {
                if (!eglTerminate(display))
                {
                    Log(Log::Level::ERR) << "Failed to terminate EGL";
                }
            }
        }

        bool RenderDeviceOGLAndroid::init(Window* newWindow,
                                          const Size2&,
                                          uint32_t newSampleCount,
                                          Texture::Filter newTextureFilter,
                                          uint32_t newMaxAnisotropy,
                                          bool newVerticalSync,
                                          bool newDepth,
                                          bool newDebugRenderer)
        {
            display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

            if (!display)
            {
                Log(Log::Level::ERR) << "Failed to get display";
                return false;
            }

            if (!eglInitialize(display, nullptr, nullptr))
            {
                Log(Log::Level::ERR) << "Failed to initialize EGL";
                return false;
            }

            const EGLint attributeList[] =
            {
                EGL_RED_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_BLUE_SIZE, 8,
                EGL_ALPHA_SIZE, 8,
                EGL_DEPTH_SIZE, newDepth ? 24 : 0,
                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_SAMPLE_BUFFERS, (newSampleCount > 1) ? 1 : 0,
                EGL_SAMPLES, static_cast<int>(newSampleCount),
                EGL_NONE
            };
            EGLConfig config;
            EGLint numConfig;
            if (!eglChooseConfig(display, attributeList, &config, 1, &numConfig))
            {
                Log(Log::Level::ERR) << "Failed to choose EGL config";
                return false;
            }

            if (!eglBindAPI(EGL_OPENGL_ES_API))
            {
                Log(Log::Level::ERR) << "Failed to bind OpenGL ES API";
                return false;
            }

            EGLint format;
            if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format))
            {
                Log(Log::Level::ERR) << "Failed to get config attribute " << eglGetError();
                return false;
            }

            WindowAndroid* windowAndroid = static_cast<WindowAndroid*>(newWindow);

            ANativeWindow_setBuffersGeometry(windowAndroid->getNativeWindow(), 0, 0, format);

            surface = eglCreateWindowSurface(display, config, windowAndroid->getNativeWindow(), nullptr);
            if (surface == EGL_NO_SURFACE)
            {
                Log(Log::Level::ERR) << "Failed to create EGL window surface";
                return false;
            }

            for (EGLint version = 3; version >= 2; --version)
            {
                std::vector<EGLint> contextAttributes =
                {
                    EGL_CONTEXT_CLIENT_VERSION, version
                };

                if (newDebugRenderer)
                {
                    contextAttributes.push_back(EGL_CONTEXT_FLAGS_KHR);
                    contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR);
                }

                contextAttributes.push_back(EGL_NONE);

                context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes.data());

                if (context != EGL_NO_CONTEXT)
                {
                    apiMajorVersion = version;
                    apiMinorVersion = 0;
                    Log(Log::Level::INFO) << "EGL OpenGL ES " << version << " context created";
                    break;
                }
            }

            if (context == EGL_NO_CONTEXT)
            {
                Log(Log::Level::ERR) << "Failed to create EGL context";
                return false;
            }

            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context";
                return false;
            }

            if (!eglSwapInterval(display, newVerticalSync ? 1 : 0))
            {
                Log(Log::Level::ERR) << "Failed to set EGL frame interval";
                return false;
            }

            EGLint surfaceWidth;
            EGLint surfaceHeight;

            if (!eglQuerySurface(display, surface, EGL_WIDTH, &surfaceWidth) ||
                !eglQuerySurface(display, surface, EGL_HEIGHT, &surfaceHeight))
            {
                Log(Log::Level::ERR) << "Failed to get query window size " <<  eglGetError();
                return false;
            }

            frameBufferWidth = surfaceWidth;
            frameBufferHeight = surfaceHeight;

            Size2 backBufferSize = Size2(static_cast<float>(frameBufferWidth),
                                         static_cast<float>(frameBufferHeight));

            newWindow->setSize(backBufferSize / newWindow->getContentScale());

            if (!RenderDeviceOGL::init(newWindow,
                                       backBufferSize,
                                       newSampleCount,
                                       newTextureFilter,
                                       newMaxAnisotropy,
                                       newVerticalSync,
                                       newDepth,
                                       newDebugRenderer))
            {
                return false;
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context";
            }

            running = true;
            renderThread = std::thread(&RenderDeviceOGLAndroid::main, this);

            return true;
        }

        bool RenderDeviceOGLAndroid::reload()
        {
            running = false;
            flushCommands();
            if (renderThread.joinable()) renderThread.join();

            const EGLint attributeList[] =
            {
                EGL_RED_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_BLUE_SIZE, 8,
                EGL_ALPHA_SIZE, 8,
                EGL_DEPTH_SIZE, depth ? 24 : 0,
                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_SAMPLE_BUFFERS, (sampleCount > 1) ? 1 : 0,
                EGL_SAMPLES, static_cast<int>(sampleCount),
                EGL_NONE
            };
            EGLConfig config;
            EGLint numConfig;
            if (!eglChooseConfig(display, attributeList, &config, 1, &numConfig))
            {
                Log(Log::Level::ERR) << "Failed to choose EGL config";
                return false;
            }

            if (!eglBindAPI(EGL_OPENGL_ES_API))
            {
                Log(Log::Level::ERR) << "Failed to bind OpenGL ES API";
                return false;
            }

            EGLint format;
            if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format))
            {
                Log(Log::Level::ERR) << "Failed to get config attribute " << eglGetError();
                return false;
            }

            WindowAndroid* windowAndroid = static_cast<WindowAndroid*>(sharedEngine->getWindow());

            ANativeWindow_setBuffersGeometry(windowAndroid->getNativeWindow(), 0, 0, format);

            surface = eglCreateWindowSurface(display, config, windowAndroid->getNativeWindow(), nullptr);
            if (surface == EGL_NO_SURFACE)
            {
                Log(Log::Level::ERR) << "Failed to create EGL window surface";
                return false;
            }

            for (EGLint version = 3; version >= 2; --version)
            {
                std::vector<EGLint> contextAttributes =
                {
                    EGL_CONTEXT_CLIENT_VERSION, version
                };

                if (debugRenderer)
                {
                    contextAttributes.push_back(EGL_CONTEXT_FLAGS_KHR);
                    contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR);
                }

                contextAttributes.push_back(EGL_NONE);

                context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes.data());

                if (context != EGL_NO_CONTEXT)
                {
                    apiMajorVersion = version;
                    apiMinorVersion = 0;
                    Log(Log::Level::INFO) << "EGL OpenGL ES " << version << " context created";
                    break;
                }
            }

            if (context == EGL_NO_CONTEXT)
            {
                Log(Log::Level::ERR) << "Failed to create EGL context";
                return false;
            }

            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context";
                return false;
            }

            if (!eglSwapInterval(display, verticalSync ? 1 : 0))
            {
                Log(Log::Level::ERR) << "Failed to set EGL frame interval";
                return false;
            }

            EGLint surfaceWidth;
            EGLint surfaceHeight;

            if (!eglQuerySurface(display, surface, EGL_WIDTH, &surfaceWidth) ||
                !eglQuerySurface(display, surface, EGL_HEIGHT, &surfaceHeight))
            {
                Log(Log::Level::ERR) << "Failed to get query window size " <<  eglGetError();
                return false;
            }

            frameBufferWidth = surfaceWidth;
            frameBufferHeight = surfaceHeight;

            Size2 backBufferSize = Size2(static_cast<float>(frameBufferWidth),
                                         static_cast<float>(frameBufferHeight));

            windowAndroid->setSize(backBufferSize / windowAndroid->getContentScale());

            stateCache = StateCache();

            glDisable(GL_DITHER);
            glDepthFunc(GL_LEQUAL);

            if (checkOpenGLError())
            {
                Log(Log::Level::ERR) << "Failed to set depth function";
                return false;
            }

            {
                std::lock_guard<std::mutex> lock(resourceMutex);

                for (const std::unique_ptr<Resource>& resource : resources)
                {
                    if (!resource->reload())
                    {
                        return false;
                    }
                }
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context";
            }

            running = true;
            renderThread = std::thread(&RenderDeviceOGLAndroid::main, this);

            return true;
        }

        bool RenderDeviceOGLAndroid::destroy()
        {
            running = false;
            flushCommands();
            if (renderThread.joinable()) renderThread.join();

            if (context)
            {
                if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
                {
                    Log(Log::Level::ERR) << "Failed to unset EGL context";
                }

                if (!eglDestroyContext(display, context))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL context";
                }

                context = nullptr;
            }

            if (surface)
            {
                if (!eglDestroySurface(display, surface))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL surface";
                }

                surface = nullptr;
            }

            return true;
        }

        bool RenderDeviceOGLAndroid::lockContext()
        {
            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context, error: " << eglGetError();
                return false;
            }

            return true;
        }

        bool RenderDeviceOGLAndroid::swapBuffers()
        {
            if (eglSwapBuffers(display, surface) != EGL_TRUE)
            {
                Log(Log::Level::ERR) << "Failed to swap buffers " << eglGetError();
                return false;
            }

            return true;
        }

        void RenderDeviceOGLAndroid::main()
        {
            sharedEngine->setCurrentThreadName("Render");

            while (running)
            {
                process();
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context, error: " << eglGetError();
            }
        }
    } // namespace graphics
} // namespace ouzel

#endif
<commit_msg>Fix Android build<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "core/Setup.h"

#if OUZEL_PLATFORM_ANDROID && OUZEL_COMPILE_OPENGL

#include "RenderDeviceOGLAndroid.hpp"
#include "core/android/WindowAndroid.hpp"
#include "core/Engine.hpp"
#include "utils/Log.hpp"

namespace ouzel
{
    namespace graphics
    {
        RenderDeviceOGLAndroid::~RenderDeviceOGLAndroid()
        {
            running = false;
            flushCommands();
            if (renderThread.joinable()) renderThread.join();

            if (context)
            {
                if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
                {
                    Log(Log::Level::ERR) << "Failed to unset EGL context";
                }

                if (!eglDestroyContext(display, context))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL context";
                }
            }

            if (surface)
            {
                if (!eglDestroySurface(display, surface))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL surface";
                }
            }

            if (display)
            {
                if (!eglTerminate(display))
                {
                    Log(Log::Level::ERR) << "Failed to terminate EGL";
                }
            }
        }

        bool RenderDeviceOGLAndroid::init(Window* newWindow,
                                          const Size2&,
                                          uint32_t newSampleCount,
                                          Texture::Filter newTextureFilter,
                                          uint32_t newMaxAnisotropy,
                                          bool newVerticalSync,
                                          bool newDepth,
                                          bool newDebugRenderer)
        {
            display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

            if (!display)
            {
                Log(Log::Level::ERR) << "Failed to get display";
                return false;
            }

            if (!eglInitialize(display, nullptr, nullptr))
            {
                Log(Log::Level::ERR) << "Failed to initialize EGL";
                return false;
            }

            const EGLint attributeList[] =
            {
                EGL_RED_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_BLUE_SIZE, 8,
                EGL_ALPHA_SIZE, 8,
                EGL_DEPTH_SIZE, newDepth ? 24 : 0,
                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_SAMPLE_BUFFERS, (newSampleCount > 1) ? 1 : 0,
                EGL_SAMPLES, static_cast<int>(newSampleCount),
                EGL_NONE
            };
            EGLConfig config;
            EGLint numConfig;
            if (!eglChooseConfig(display, attributeList, &config, 1, &numConfig))
            {
                Log(Log::Level::ERR) << "Failed to choose EGL config";
                return false;
            }

            if (!eglBindAPI(EGL_OPENGL_ES_API))
            {
                Log(Log::Level::ERR) << "Failed to bind OpenGL ES API";
                return false;
            }

            EGLint format;
            if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format))
            {
                Log(Log::Level::ERR) << "Failed to get config attribute " << eglGetError();
                return false;
            }

            WindowAndroid* windowAndroid = static_cast<WindowAndroid*>(newWindow);

            ANativeWindow_setBuffersGeometry(windowAndroid->getNativeWindow(), 0, 0, format);

            surface = eglCreateWindowSurface(display, config, windowAndroid->getNativeWindow(), nullptr);
            if (surface == EGL_NO_SURFACE)
            {
                Log(Log::Level::ERR) << "Failed to create EGL window surface";
                return false;
            }

            for (EGLint version = 3; version >= 2; --version)
            {
                std::vector<EGLint> contextAttributes =
                {
                    EGL_CONTEXT_CLIENT_VERSION, version
                };

                if (newDebugRenderer)
                {
                    contextAttributes.push_back(EGL_CONTEXT_FLAGS_KHR);
                    contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR);
                }

                contextAttributes.push_back(EGL_NONE);

                context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes.data());

                if (context != EGL_NO_CONTEXT)
                {
                    apiMajorVersion = version;
                    apiMinorVersion = 0;
                    Log(Log::Level::INFO) << "EGL OpenGL ES " << version << " context created";
                    break;
                }
            }

            if (context == EGL_NO_CONTEXT)
            {
                Log(Log::Level::ERR) << "Failed to create EGL context";
                return false;
            }

            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context";
                return false;
            }

            if (!eglSwapInterval(display, newVerticalSync ? 1 : 0))
            {
                Log(Log::Level::ERR) << "Failed to set EGL frame interval";
                return false;
            }

            EGLint surfaceWidth;
            EGLint surfaceHeight;

            if (!eglQuerySurface(display, surface, EGL_WIDTH, &surfaceWidth) ||
                !eglQuerySurface(display, surface, EGL_HEIGHT, &surfaceHeight))
            {
                Log(Log::Level::ERR) << "Failed to get query window size " <<  eglGetError();
                return false;
            }

            frameBufferWidth = surfaceWidth;
            frameBufferHeight = surfaceHeight;

            Size2 backBufferSize = Size2(static_cast<float>(frameBufferWidth),
                                         static_cast<float>(frameBufferHeight));

            newWindow->setSize(backBufferSize);

            if (!RenderDeviceOGL::init(newWindow,
                                       backBufferSize,
                                       newSampleCount,
                                       newTextureFilter,
                                       newMaxAnisotropy,
                                       newVerticalSync,
                                       newDepth,
                                       newDebugRenderer))
            {
                return false;
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context";
            }

            running = true;
            renderThread = std::thread(&RenderDeviceOGLAndroid::main, this);

            return true;
        }

        bool RenderDeviceOGLAndroid::reload()
        {
            running = false;
            flushCommands();
            if (renderThread.joinable()) renderThread.join();

            const EGLint attributeList[] =
            {
                EGL_RED_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_BLUE_SIZE, 8,
                EGL_ALPHA_SIZE, 8,
                EGL_DEPTH_SIZE, depth ? 24 : 0,
                EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
                EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
                EGL_SAMPLE_BUFFERS, (sampleCount > 1) ? 1 : 0,
                EGL_SAMPLES, static_cast<int>(sampleCount),
                EGL_NONE
            };
            EGLConfig config;
            EGLint numConfig;
            if (!eglChooseConfig(display, attributeList, &config, 1, &numConfig))
            {
                Log(Log::Level::ERR) << "Failed to choose EGL config";
                return false;
            }

            if (!eglBindAPI(EGL_OPENGL_ES_API))
            {
                Log(Log::Level::ERR) << "Failed to bind OpenGL ES API";
                return false;
            }

            EGLint format;
            if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format))
            {
                Log(Log::Level::ERR) << "Failed to get config attribute " << eglGetError();
                return false;
            }

            WindowAndroid* windowAndroid = static_cast<WindowAndroid*>(sharedEngine->getWindow());

            ANativeWindow_setBuffersGeometry(windowAndroid->getNativeWindow(), 0, 0, format);

            surface = eglCreateWindowSurface(display, config, windowAndroid->getNativeWindow(), nullptr);
            if (surface == EGL_NO_SURFACE)
            {
                Log(Log::Level::ERR) << "Failed to create EGL window surface";
                return false;
            }

            for (EGLint version = 3; version >= 2; --version)
            {
                std::vector<EGLint> contextAttributes =
                {
                    EGL_CONTEXT_CLIENT_VERSION, version
                };

                if (debugRenderer)
                {
                    contextAttributes.push_back(EGL_CONTEXT_FLAGS_KHR);
                    contextAttributes.push_back(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR);
                }

                contextAttributes.push_back(EGL_NONE);

                context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes.data());

                if (context != EGL_NO_CONTEXT)
                {
                    apiMajorVersion = version;
                    apiMinorVersion = 0;
                    Log(Log::Level::INFO) << "EGL OpenGL ES " << version << " context created";
                    break;
                }
            }

            if (context == EGL_NO_CONTEXT)
            {
                Log(Log::Level::ERR) << "Failed to create EGL context";
                return false;
            }

            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context";
                return false;
            }

            if (!eglSwapInterval(display, verticalSync ? 1 : 0))
            {
                Log(Log::Level::ERR) << "Failed to set EGL frame interval";
                return false;
            }

            EGLint surfaceWidth;
            EGLint surfaceHeight;

            if (!eglQuerySurface(display, surface, EGL_WIDTH, &surfaceWidth) ||
                !eglQuerySurface(display, surface, EGL_HEIGHT, &surfaceHeight))
            {
                Log(Log::Level::ERR) << "Failed to get query window size " <<  eglGetError();
                return false;
            }

            frameBufferWidth = surfaceWidth;
            frameBufferHeight = surfaceHeight;

            Size2 backBufferSize = Size2(static_cast<float>(frameBufferWidth),
                                         static_cast<float>(frameBufferHeight));

            windowAndroid->setSize(backBufferSize);

            stateCache = StateCache();

            glDisable(GL_DITHER);
            glDepthFunc(GL_LEQUAL);

            if (checkOpenGLError())
            {
                Log(Log::Level::ERR) << "Failed to set depth function";
                return false;
            }

            {
                std::lock_guard<std::mutex> lock(resourceMutex);

                for (const std::unique_ptr<Resource>& resource : resources)
                {
                    if (!resource->reload())
                    {
                        return false;
                    }
                }
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context";
            }

            running = true;
            renderThread = std::thread(&RenderDeviceOGLAndroid::main, this);

            return true;
        }

        bool RenderDeviceOGLAndroid::destroy()
        {
            running = false;
            flushCommands();
            if (renderThread.joinable()) renderThread.join();

            if (context)
            {
                if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
                {
                    Log(Log::Level::ERR) << "Failed to unset EGL context";
                }

                if (!eglDestroyContext(display, context))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL context";
                }

                context = nullptr;
            }

            if (surface)
            {
                if (!eglDestroySurface(display, surface))
                {
                    Log(Log::Level::ERR) << "Failed to destroy EGL surface";
                }

                surface = nullptr;
            }

            return true;
        }

        bool RenderDeviceOGLAndroid::lockContext()
        {
            if (!eglMakeCurrent(display, surface, surface, context))
            {
                Log(Log::Level::ERR) << "Failed to set current EGL context, error: " << eglGetError();
                return false;
            }

            return true;
        }

        bool RenderDeviceOGLAndroid::swapBuffers()
        {
            if (eglSwapBuffers(display, surface) != EGL_TRUE)
            {
                Log(Log::Level::ERR) << "Failed to swap buffers " << eglGetError();
                return false;
            }

            return true;
        }

        void RenderDeviceOGLAndroid::main()
        {
            sharedEngine->setCurrentThreadName("Render");

            while (running)
            {
                process();
            }

            if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
            {
                Log(Log::Level::ERR) << "Failed to unset EGL context, error: " << eglGetError();
            }
        }
    } // namespace graphics
} // namespace ouzel

#endif
<|endoftext|>


<commit_before>
#include "Player.h"

#include "NNAudioSystem.h"
#include "NNNetworkSystem.h"
#include "NNParticleSystem.h"
#include "NNInputSystem.h"
#include "NNApplication.h"

#include "EffectManager.h"
#include "ATypeEffect.h"
#include "AUserEffect.h"
#include "BTypeEffect.h"
#include "BUserEffect.h"
#include "CTypeEffect.h"
#include "CUserEffect.h"

CPlayer::CPlayer( void )
	: m_PlayerSprite(NULL),m_MoveDirection(NNPoint(0,0)),
	m_Hp(100),m_RebirthDelayTime(10)
{
	TransState(PlayerState::IDLE);

	m_PlayerUI = PlayerUI::Create();
	AddChild( m_PlayerUI );

	m_PlayerType = TYPE_A;
	memset(m_SkillCount, 0, sizeof(m_SkillCount));
	memset(m_SkillCooldown, 0, sizeof(m_SkillCooldown));
}

CPlayer::~CPlayer( void )
{
}

void CPlayer::CreateSkillEffect(PlayerType type, PlayerState skillType)
{
	switch (type)
	{
	case TYPE_A :
		if (skillType == TYPE_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new ATypeEffect(this));
		if (skillType == USER_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new AUserEffect(this));
		break;

	case TYPE_B :
		if (skillType == TYPE_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new BTypeEffect(this));
		if (skillType == USER_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new BTypeEffect(this));
		break;

	case TYPE_C :
		if (skillType == TYPE_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new CTypeEffect(this));
		if (skillType == USER_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new CTypeEffect(this));
		break;
	}
}
void CPlayer::TransState( PlayerState state )
{
	float width = (float)NNApplication::GetInstance()->GetScreenWidth();
	float height = (float)NNApplication::GetInstance()->GetScreenHeight();
	float rotation = m_Rotation;

	m_PlayerState = state;

	if (m_PlayerSprite != NULL)
	{
		RemoveChild(m_PlayerSprite);
	}

	std::wstring imagePath = L"";

	switch (state)
	{
	case IDLE:
		imagePath = L"Sprite/idle_0.png";
		break;

	case WALK:
		imagePath = L"Sprite/walk_0.png";
		break;

	case ATTAACK:
		imagePath = L"Sprite/attack_0.png";

		//RemoveChild(m_BuffEffect);

		//m_BuffEffect = NNParticleSystem::Create()
		break;

	case DIE:
		imagePath = L"Sprite/die.png";
		m_RebirthTimer = NNLabel::Create(L"~ ~ X 츮   غô", L" ", 40.f);
		m_RebirthTimer->SetCenter(width / 2, height / 2 - 200);
		break;

	case USER_ACTIVE_SKILL:
		imagePath = L"Sprite/skill_0.png";
		if (GetSkillCooldown(USER_ACTIVE_SKILL) == false)
		{
			SetSkillCooldown(true, USER_ACTIVE_SKILL);
			CreateSkillEffect(m_PlayerType, USER_ACTIVE_SKILL);
		}
		break;

	case TYPE_ACTIVE_SKILL:
		imagePath = L"Sprite/skill_1.png";
		if (GetSkillCooldown(TYPE_ACTIVE_SKILL) == false)
		{
			SetSkillCooldown(true, TYPE_ACTIVE_SKILL);
			CreateSkillEffect(m_PlayerType, TYPE_ACTIVE_SKILL);
		}
		break;
	default:
		break;
	}

	/* Player Sprite Setting */
	m_PlayerSprite = NNSprite::Create( imagePath );
	AddChild( m_PlayerSprite );

	m_PlayerSprite->SetCenter( m_PlayerSprite->GetImageWidth()/2.f, m_PlayerSprite->GetImageHeight()/2.f );
	//Sprite ٲٸ Rotation ڵ 0Ǵϱ  ٽ
	m_PlayerSprite->SetRotation(rotation);
	/* // */
}

void CPlayer::Update( float dTime )
{
	NNObject::Update( dTime );

	m_PlayerUI->SetHP( m_Hp );

	switch (m_PlayerState)
	{
	case IDLE:
		{
		}
		break;
	case WALK:
		{
			//Move myPlayer with Game Key States.
			//Check Moving Input, and set Position to d
			SetPosition( GetPosition() + m_MoveDirection * dTime * 100.f );
			break;
		}
	case ATTAACK:
		{
		}
		break;
	case DIE:
		{
		}
		break;
		// ų ߵ Ű ߰ by mooneegee
	case USER_ACTIVE_SKILL:
		{

		}
		break;
	case TYPE_ACTIVE_SKILL:
		{

		}
		break;
	default:
		break;
	}

	/*
	for (const auto& node : m_ChildList )
	{
		NNParticleSystem* temp = dynamic_cast<NNParticleSystem*>(node);

		if ( temp != NULL ) {

		}
	}
	fof;lkJSIf;lug 0v
	;'dlfjalfjwoefuaoiwnbSv r( */
	/*
	m_ParticleSystemList.push_back(* );
	Ad-*+++++++

	jdkdkdkdfjfdiensk,cxnxcj,zwlhfisjfsdjsdl dkldjfeineifjdkfkjdlfjflvkd6ltjsguqdls2h5g2o2d295dl95didl6di1g9h8dl18d1l8tj8sdk1wale34hg8alwerjfl;askdji;woer fjoaisjkdlfhs;adjjjjjjjjjjjjjjj m dChild(* );

	for (auto& iter=m_ParticleSystemList.begin(); iter!=m_ParticleSystemList.end(); iter++ )
	{
		if ((*iter)->IsAlive() == false)
		{
			RemoveChild( *iter );
			iter = m_ParticleSystemList.erase( iter );
			if ( iter == m_ParticleSystemList.end() )
			{
				break;
			}
		}
	}*/
}

void CPlayer::Render()
{
	NNObject::Render();
}
<commit_msg>@ player.cpp code modified<commit_after>
#include "Player.h"

#include "NNAudioSystem.h"
#include "NNNetworkSystem.h"
#include "NNParticleSystem.h"
#include "NNInputSystem.h"
#include "NNApplication.h"
#include "NNAnimation.h"

#include "EffectManager.h"
#include "ATypeEffect.h"
#include "AUserEffect.h"
#include "BTypeEffect.h"
#include "BUserEffect.h"
#include "CTypeEffect.h"
#include "CUserEffect.h"

CPlayer::CPlayer( void )
	: m_PlayerSprite(NULL),m_MoveDirection(NNPoint(0,0)),
	m_Hp(100),m_RebirthDelayTime(10)
{
	TransState(PlayerState::IDLE);

	m_PlayerUI = PlayerUI::Create();
	AddChild( m_PlayerUI );

	m_PlayerType = TYPE_B;
	memset(m_SkillCount, 0, sizeof(m_SkillCount));
	memset(m_SkillCooldown, 0, sizeof(m_SkillCooldown));
}

CPlayer::~CPlayer( void )
{
}

void CPlayer::CreateSkillEffect(PlayerType type, PlayerState skillType)
{
	switch (type)
	{
	case TYPE_A :
		if (skillType == TYPE_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new ATypeEffect(this));
		if (skillType == USER_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new AUserEffect(this));
		break;

	case TYPE_B :
		if (skillType == TYPE_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new BTypeEffect(this));
		if (skillType == USER_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new BTypeEffect(this));
		break;

	case TYPE_C :
		if (skillType == TYPE_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new CTypeEffect(this));
		if (skillType == USER_ACTIVE_SKILL) EffectManager::GetInstance()->AddEffect(new CTypeEffect(this));
		break;
	}
}
void CPlayer::TransState( PlayerState state )
{
	float width = (float)NNApplication::GetInstance()->GetScreenWidth();
	float height = (float)NNApplication::GetInstance()->GetScreenHeight();
	float rotation = m_Rotation;

	m_PlayerState = state;

	if (m_PlayerSprite != NULL)
	{
		RemoveChild(m_PlayerSprite);
	}

	std::wstring imagePath = L"";

	switch (state)
	{
	case IDLE:
		imagePath = L"Sprite/idle_0.png";
		break;

	case WALK:
		imagePath = L"Sprite/walk_0.png";
		break;

	case ATTAACK:
		imagePath = L"Sprite/attack_0.png";

		//RemoveChild(m_BuffEffect);

		//m_BuffEffect = NNParticleSystem::Create()
		break;

	case DIE:
		imagePath = L"Sprite/die.png";
		m_RebirthTimer = NNLabel::Create(L"~ ~ X 츮   غô", L" ", 40.f);
		m_RebirthTimer->SetCenter(width / 2, height / 2 - 200);
		break;

	case USER_ACTIVE_SKILL:
		imagePath = L"Sprite/skill_0.png";
		if (GetSkillCooldown(USER_ACTIVE_SKILL) == false)
		{
			SetSkillCooldown(true, USER_ACTIVE_SKILL);
			CreateSkillEffect(m_PlayerType, USER_ACTIVE_SKILL);
		}
		break;

	case TYPE_ACTIVE_SKILL:
		imagePath = L"Sprite/skill_1.png";
		if (GetSkillCooldown(TYPE_ACTIVE_SKILL) == false)
		{
			SetSkillCooldown(true, TYPE_ACTIVE_SKILL);
			CreateSkillEffect(m_PlayerType, TYPE_ACTIVE_SKILL);
		}
		break;
	default:
		break;
	}

	/* Player Sprite Setting */
	m_PlayerSprite = NNSprite::Create( imagePath );
	AddChild( m_PlayerSprite );

	m_PlayerSprite->SetCenter( m_PlayerSprite->GetImageWidth()/2.f, m_PlayerSprite->GetImageHeight()/2.f );
	//Sprite ٲٸ Rotation ڵ 0Ǵϱ  ٽ
	m_PlayerSprite->SetRotation(rotation);
	/* // */
}

void CPlayer::Update( float dTime )
{
	NNObject::Update( dTime );

	m_PlayerUI->SetHP( m_Hp );

	switch (m_PlayerState)
	{
	case IDLE:
		{
		}
		break;
	case WALK:
		{
			//Move myPlayer with Game Key States.
			//Check Moving Input, and set Position to d
			SetPosition( GetPosition() + m_MoveDirection * dTime * 100.f );
			break;
		}
	case ATTAACK:
		{
		}
		break;
	case DIE:
		{
		}
		break;
		// ų ߵ Ű ߰ by mooneegee
	case USER_ACTIVE_SKILL:
		{

		}
		break;
	case TYPE_ACTIVE_SKILL:
		{

		}
		break;
	default:
		break;
	}

	/*
	for (const auto& node : m_ChildList )
	{
		NNParticleSystem* temp = dynamic_cast<NNParticleSystem*>(node);

		if ( temp != NULL ) {

		}
	}
	fof;lkJSIf;lug 0v
	;'dlfjalfjwoefuaoiwnbSv r( */
	/*
	m_ParticleSystemList.push_back(* );
	Ad-*+++++++

	jdkdkdkdfjfdiensk,cxnxcj,zwlhfisjfsdjsdl dkldjfeineifjdkfkjdlfjflvkd6ltjsguqdls2h5g2o2d295dl95didl6di1g9h8dl18d1l8tj8sdk1wale34hg8alwerjfl;askdji;woer fjoaisjkdlfhs;adjjjjjjjjjjjjjjj m dChild(* );

	for (auto& iter=m_ParticleSystemList.begin(); iter!=m_ParticleSystemList.end(); iter++ )
	{
		if ((*iter)->IsAlive() == false)
		{
			RemoveChild( *iter );
			iter = m_ParticleSystemList.erase( iter );
			if ( iter == m_ParticleSystemList.end() )
			{
				break;
			}
		}
	}*/
}

void CPlayer::Render()
{
	NNObject::Render();
}
<|endoftext|>


<commit_before>// @Alan
//
// Exercise 11.18:
// Write the type of map_it from the loop on page 430 without using auto or decltype.
//

#include <iostream>
#include <map>
#include <string>

int main()
{
    std::map<std::string, size_t> word_count;

    // the orignal codes:
    //auto map_it = word_count.cbegin();

    std::map<std::string, size_t>::const_iterator map_it = word_count.cbegin();
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// the type ex11.18 required.

    // compare the current iterator to the off-the-end iterator
    while (map_it != word_count.cend())
    {
        // dereference the iterator to print the element key--value pairs
        std::cout << map_it->first << " occurs "
             << map_it->second << " times" << std::endl;
        ++map_it;  // increment the iterator to denote the next element
    }

    return 0;
}
<commit_msg>Update ex11_18.cpp<commit_after>//
// @Yue Wang
//
// Exercise 11.18:
// Write the type of map_it from the loop on page 430 without using auto or decltype.
//      std::map<std::string, size_t>::const_iterator
//

int main()
{
    return 0;
}
<|endoftext|>


<commit_before>
// g++ -std=c++11 -DSTANDALONE_TEST -L/opt/local/lib chebyshev_cl.cpp -lOpenCL -lboost_system
//#include <cstdlib>
#include "chebyshev_cl.hpp"

// Print elements of vector to stdout
template<class T>
void printvector(const T &v){
    for(int i=0;i<v.size();++i) {
        std::cout << v[i] << std::endl;
    }
    std::cout << std::endl;
}

Chebyshev::Chebyshev(int n)
    : N(n), M(2 * N - 2),
      ctx(
            vex::Filter::Type(CL_DEVICE_TYPE_GPU) &&
            vex::Filter::DoublePrecision &&
            vex::Filter::Count(1)
         ),
      fft(ctx, M), ifft(ctx, M, vex::fft::inverse),
      cplx_ifft(ctx, M, vex::fft::inverse),
      sum(ctx),
      slice(vex::extents[M]),
      X2(ctx, M),
      w0(ctx, N),
      wi(ctx, N-2),
      wN(ctx, N)
{
    dev_dvec k2(ctx, N);

    auto i = vex::tag<1>(vex::element_index());

    k2 = 2 * i * i;

    // 2,8,18,...,2*(N-2)^2,(N-1)^2
    k2[N - 1] = (N - 1) * (N - 1);

    coeff_to_nodal(k2,w0);
    w0 = w0 / (N - 1);

    w0[0]     = 0.5 * w0[0];
    w0[N - 1] = 0.5 * w0[N - 1];

    wN = -vex::permutation(N - 1 - i)(w0);
    wi = 1 / ( sin(vex::constants::pi() * (i + 1) / (N - 1)) );
}

std::string Chebyshev::get_device_name() {

    std::ostringstream os;

    // Write device name to output string stream
    os << ctx.queue(0);

    // extract string
    std::string devName = os.str();

    return devName;
}

void Chebyshev::catrev(const dev_dvec &a, dev_dvec &A2) {

    // First half of A2 holds a:
    slice[vex::range(0,N)](A2) = a;

    // Second half of A2 holds reversed copy of a (with endpoints removed):
    slice[vex::range(N, M)](A2) = vex::permutation( N - 2 - vex::element_index() )(A2);
}

host_dvec Chebyshev::coeff_to_nodal(const host_dvec &a) {

    dev_dvec A(ctx, a);
    dev_dvec B(ctx, N);
    host_dvec b(N);
    coeff_to_nodal(A,B);
    vex::copy(B,b);
    return b;
}

void Chebyshev::coeff_to_nodal(const dev_dvec &a, dev_dvec &b) {

    catrev(a,X2);

    X2[0]   = 2 * a[0];
    X2[N-1] = 2 * a[N-1];

    X2 = fft(X2) / 2;

    b = slice[vex::range(0,N)](X2);
}

// Compute Chebyshev expansion coefficient from grid values
void Chebyshev::nodal_to_coeff(const dev_dvec &b, dev_dvec &a){

    catrev(b, X2);

    X2 = ifft(X2) * 2;

    a = slice[vex::range(0,N)](X2);

    a[0]   = 0.5*a[0];
    a[N-1] = 0.5*a[N-1];

}

host_dvec Chebyshev::nodal_to_coeff(const host_dvec &b) {

    dev_dvec B(ctx, b);
    dev_dvec A(ctx,N);
    host_dvec a(N);
    nodal_to_coeff(B,A);
    vex::copy(A,a);
    return a;
}

// Differentiate a function on the grid
void Chebyshev::nodal_diff(const dev_dvec &u, dev_dvec &v){

    catrev(u,X2);

    // 0,1,...,N-1,-(N-1),-(N-2),...,-1
    VEX_FUNCTION(double, kkrev, (ptrdiff_t, N)(ptrdiff_t, i),
            if (i < N) return i;
            return -2 * N + i + 2;
            );

    X2 = fft(X2) * kkrev(N, vex::element_index());
    X2[N-1] = 0;

    // Extract imaginary part of vector
    VEX_FUNCTION(double, imag, (cl_double2, c),
            return c.y;
            );

    X2 = imag(cplx_ifft(X2));

    v[0] = sum(u*w0);

    slice[vex::range(1,N-1)](v) = slice[vex::range(1,N-1)](X2) * wi;

    v[N-1] = sum(wN*u);
}

host_dvec Chebyshev::nodal_diff(const host_dvec &u) {

    dev_dvec U(ctx, u);
    dev_dvec V(ctx, N);

    host_dvec v(N);

    nodal_diff(U,V);

    vex::copy(V,v);
    return v;
}

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

    int N = argc > 1 ? atoi(argv[1]) : 16;
    int k = argc > 2 ? atoi(argv[2]) : 0;

    try {
        Chebyshev cheb(N);
        std::cout << cheb.get_device_name() << std::endl;

        host_dvec a(N,0);
        a[k] = 1;

        auto b = cheb.coeff_to_nodal(a);
        auto bx = cheb.nodal_diff(b);
        auto c = cheb.nodal_to_coeff(bx);

        printvector(b);
        printvector(bx);

    } catch (const cl::Error &e) {
        std::cerr << "OpenCL error: " << e << std::endl;
    } catch (const std::exception &e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }

}
#endif
<commit_msg>Fix the misleading comment<commit_after>
// g++ -std=c++11 -DSTANDALONE_TEST -L/opt/local/lib chebyshev_cl.cpp -lOpenCL -lboost_system
//#include <cstdlib>
#include "chebyshev_cl.hpp"

// Print elements of vector to stdout
template<class T>
void printvector(const T &v){
    for(int i=0;i<v.size();++i) {
        std::cout << v[i] << std::endl;
    }
    std::cout << std::endl;
}

Chebyshev::Chebyshev(int n)
    : N(n), M(2 * N - 2),
      ctx(
            vex::Filter::Type(CL_DEVICE_TYPE_GPU) &&
            vex::Filter::DoublePrecision &&
            vex::Filter::Count(1)
         ),
      fft(ctx, M), ifft(ctx, M, vex::fft::inverse),
      cplx_ifft(ctx, M, vex::fft::inverse),
      sum(ctx),
      slice(vex::extents[M]),
      X2(ctx, M),
      w0(ctx, N),
      wi(ctx, N-2),
      wN(ctx, N)
{
    dev_dvec k2(ctx, N);

    auto i = vex::tag<1>(vex::element_index());

    k2 = 2 * i * i;

    // 2,8,18,...,2*(N-2)^2,(N-1)^2
    k2[N - 1] = (N - 1) * (N - 1);

    coeff_to_nodal(k2,w0);
    w0 = w0 / (N - 1);

    w0[0]     = 0.5 * w0[0];
    w0[N - 1] = 0.5 * w0[N - 1];

    wN = -vex::permutation(N - 1 - i)(w0);
    wi = 1 / ( sin(vex::constants::pi() * (i + 1) / (N - 1)) );
}

std::string Chebyshev::get_device_name() {

    std::ostringstream os;

    // Write device name to output string stream
    os << ctx.queue(0);

    // extract string
    std::string devName = os.str();

    return devName;
}

void Chebyshev::catrev(const dev_dvec &a, dev_dvec &A2) {

    // First half of A2 holds a:
    slice[vex::range(0,N)](A2) = a;

    // Second half of A2 holds reversed copy of a (with endpoints removed):
    slice[vex::range(N, M)](A2) = vex::permutation( N - 2 - vex::element_index() )(A2);
}

host_dvec Chebyshev::coeff_to_nodal(const host_dvec &a) {

    dev_dvec A(ctx, a);
    dev_dvec B(ctx, N);
    host_dvec b(N);
    coeff_to_nodal(A,B);
    vex::copy(B,b);
    return b;
}

void Chebyshev::coeff_to_nodal(const dev_dvec &a, dev_dvec &b) {

    catrev(a,X2);

    X2[0]   = 2 * a[0];
    X2[N-1] = 2 * a[N-1];

    X2 = fft(X2) / 2;

    b = slice[vex::range(0,N)](X2);
}

// Compute Chebyshev expansion coefficient from grid values
void Chebyshev::nodal_to_coeff(const dev_dvec &b, dev_dvec &a){

    catrev(b, X2);

    X2 = ifft(X2) * 2;

    a = slice[vex::range(0,N)](X2);

    a[0]   = 0.5*a[0];
    a[N-1] = 0.5*a[N-1];

}

host_dvec Chebyshev::nodal_to_coeff(const host_dvec &b) {

    dev_dvec B(ctx, b);
    dev_dvec A(ctx,N);
    host_dvec a(N);
    nodal_to_coeff(B,A);
    vex::copy(A,a);
    return a;
}

// Differentiate a function on the grid
void Chebyshev::nodal_diff(const dev_dvec &u, dev_dvec &v){

    catrev(u,X2);

    // 0,1,...,N-1,-(N-2),...,-1
    VEX_FUNCTION(double, kkrev, (ptrdiff_t, N)(ptrdiff_t, i),
            if (i < N) return i;
            return -2 * N + i + 2;
            );

    X2 = fft(X2) * kkrev(N, vex::element_index());
    X2[N-1] = 0;

    // Extract imaginary part of vector
    VEX_FUNCTION(double, imag, (cl_double2, c),
            return c.y;
            );

    X2 = imag(cplx_ifft(X2));

    v[0] = sum(u*w0);

    slice[vex::range(1,N-1)](v) = slice[vex::range(1,N-1)](X2) * wi;

    v[N-1] = sum(wN*u);
}

host_dvec Chebyshev::nodal_diff(const host_dvec &u) {

    dev_dvec U(ctx, u);
    dev_dvec V(ctx, N);

    host_dvec v(N);

    nodal_diff(U,V);

    vex::copy(V,v);
    return v;
}

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

    int N = argc > 1 ? atoi(argv[1]) : 16;
    int k = argc > 2 ? atoi(argv[2]) : 0;

    try {
        Chebyshev cheb(N);
        std::cout << cheb.get_device_name() << std::endl;

        host_dvec a(N,0);
        a[k] = 1;

        auto b = cheb.coeff_to_nodal(a);
        auto bx = cheb.nodal_diff(b);
        auto c = cheb.nodal_to_coeff(bx);

        printvector(b);
        printvector(bx);

    } catch (const cl::Error &e) {
        std::cerr << "OpenCL error: " << e << std::endl;
    } catch (const std::exception &e) {
        std::cerr << "Error: " << e.what() << std::endl;
    }

}
#endif
<|endoftext|>


<commit_before>#include <botan/botan.h>
using namespace Botan;

#include "common.h"
#include <time.h>

/*
  Using clock() or similiar is bad news when using a hardware-based Engine,
  as all the stuff is offloaded and we use zero CPU time, which makes the
  benchmarks and such take forever.
*/

#define USE_CLOCK         0
#define USE_TIMES         0
#define USE_POSIX_GETTIME 0
#define USE_RDTSC         1

/* If using USE_RDTSC, set to your CPU's Mhz */
#define CPU_MHZ 2400

#if USE_CLOCK

   u64bit get_clock() { return clock(); }
   u64bit get_ticks() { return CLOCKS_PER_SEC; }

#elif USE_TIMES

  #include <sys/times.h>
  #include <unistd.h>
  u64bit get_clock() { return times(0); }
  u64bit get_ticks() { return sysconf(_SC_CLK_TCK); }

#elif USE_POSIX_GETTIME

u64bit get_clock()
   {
   struct timespec tv;
   clock_gettime(CLOCK_REALTIME, &tv);

   return (tv.tv_sec * 1000000000 + tv.tv_nsec) / 1000;
   }

u64bit get_ticks() { return 1000000; }
#elif USE_RDTSC

  u64bit get_clock()
     {
     u64bit rtc = 0;
     u32bit rtc_low = 0, rtc_high = 0;
     asm volatile("rdtsc" : "=d" (rtc_high), "=a" (rtc_low));
     rtc = ((u64bit)rtc_high << 32) | rtc_low;
     return rtc / 1000;
     }

  u64bit get_ticks() { return CPU_MHZ * 1000; }
#else
  #error "Must choose a timing method!"
#endif
<commit_msg>Default to using clock(), not rdtsc<commit_after>#include <botan/botan.h>
using namespace Botan;

#include "common.h"
#include <time.h>

/*
  Using clock() or similiar is bad news when using a hardware-based Engine,
  as all the stuff is offloaded and we use zero CPU time, which makes the
  benchmarks and such take forever.
*/

#define USE_CLOCK         1
#define USE_TIMES         0
#define USE_POSIX_GETTIME 0
#define USE_RDTSC         0

/* If using USE_RDTSC, set to your CPU's Mhz */
#define CPU_MHZ 2400

#if USE_CLOCK

   u64bit get_clock() { return clock(); }
   u64bit get_ticks() { return CLOCKS_PER_SEC; }

#elif USE_TIMES

  #include <sys/times.h>
  #include <unistd.h>
  u64bit get_clock() { return times(0); }
  u64bit get_ticks() { return sysconf(_SC_CLK_TCK); }

#elif USE_POSIX_GETTIME

u64bit get_clock()
   {
   struct timespec tv;
   clock_gettime(CLOCK_REALTIME, &tv);

   return (tv.tv_sec * 1000000000 + tv.tv_nsec) / 1000;
   }

u64bit get_ticks() { return 1000000; }
#elif USE_RDTSC

  u64bit get_clock()
     {
     u64bit rtc = 0;
     u32bit rtc_low = 0, rtc_high = 0;
     asm volatile("rdtsc" : "=d" (rtc_high), "=a" (rtc_low));
     rtc = ((u64bit)rtc_high << 32) | rtc_low;
     return rtc / 1000;
     }

  u64bit get_ticks() { return CPU_MHZ * 1000; }
#else
  #error "Must choose a timing method!"
#endif
<|endoftext|>


<commit_before>/*
 Copyright (c) 2011, The Cinder Project, All rights reserved.
 This code is intended for use with the Cinder C++ library: http://libcinder.org

 Based on the sc-Choreograph CinderBlock by David Wicks: http://sansumbrella.com/

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and
	the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
	the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
*/

#include "cinder/TimelineItem.h"
#include "cinder/Timeline.h"
#include "cinder/CinderMath.h"

namespace cinder {

TimelineItem::TimelineItem( class Timeline *parent )
	: mParent( parent ), mTarget( 0 ), mStartTime( 0 ), mDirtyDuration( false ), mDuration( 0 ), mInvDuration( 0 ), mHasStarted( false ), mHasReverseStarted( false ),
		mComplete( false ), mReverseComplete( false ), mMarkedForRemoval( false ), mAutoRemove( true ),
		mInfinite( false ), mLoop( false ), mPingPong( false ), mLastLoopIteration( -1 ), mUseAbsoluteTime( false )
{
}

TimelineItem::TimelineItem( Timeline *parent, void *target, float startTime, float duration )
	: mParent( parent ), mTarget( target ), mStartTime( startTime ), mDirtyDuration( false ), mDuration( std::max( duration, 0.0f ) ), mInvDuration( duration <= 0 ? 0 : (1 / duration) ),
		mHasStarted( false ), mHasReverseStarted( false ), mComplete( false ), mReverseComplete( false ), mMarkedForRemoval( false ), mAutoRemove( true ),
		mInfinite( false ), mLoop( false ), mPingPong( false ), mLastLoopIteration( -1 ), mUseAbsoluteTime( false )
{
}

void TimelineItem::removeSelf()
{
	mMarkedForRemoval = true;
}

void TimelineItem::stepTo( float newTime, bool reverse )
{
	if( mMarkedForRemoval )
		return;

	const float absTime = newTime - mStartTime;
	const float endTime = mStartTime + mDuration;

	updateDuration();

	if( ( ! mHasReverseStarted ) && reverse && ( newTime < mStartTime ) ) {
		// first update the current time to be the start time
		update( ( mUseAbsoluteTime ) ? mStartTime : 0 );
		// then issue reverse start
		mHasReverseStarted = true;
		mHasStarted = false;
		start( true );
	}
	else if( newTime >= mStartTime ) {
		float relTime;
		if( mPingPong ) {
			relTime = math<float>::fmod( absTime * mInvDuration, 2 ); // varies from 0-2
			if( relTime > 1 )
				relTime = ( 2 - relTime );
		}
		else if( mLoop ) {
			relTime = math<float>::fmod( absTime * mInvDuration, 1 );
		}
		else
			relTime = math<float>::min( absTime * mInvDuration, 1 );

		if( ( ! mHasStarted ) && ( ! reverse ) ) {
			mHasStarted = true;
			mHasReverseStarted = false;
			mLastLoopIteration = 0;
			loopStart();
			start( false );
		}

		float time = ( mUseAbsoluteTime ) ? absTime : relTime;

		// accommodate a tween with a duration <= 0
		if( ( ! mUseAbsoluteTime ) && ( mInvDuration <= 0 ) )
			time = 1.0f;

		if( mLoop || mPingPong ) {
			int32_t loopIteration = static_cast<int32_t>( ( newTime - mStartTime ) * mInvDuration );
			if( loopIteration != mLastLoopIteration ) {
				mLastLoopIteration = loopIteration;
				loopStart();
				update( time );
			}
			else
				update( time );
		}
		else
			update( time );
	}

	if( newTime < endTime ) {
		if( ( ! mReverseComplete ) && reverse ) {
			mReverseComplete = true;
			mComplete = false;
			complete( true );
		}
	}
	else if( ( ! mLoop ) && ( ! mInfinite ) ) { // newTime >= endTime
		if( ( ! mComplete ) && ( ! reverse ) ) {
			mComplete = true;
			mReverseComplete = false;
			complete( false );
		}
	}
}

void TimelineItem::setStartTime( float time )
{
	mStartTime = time;
	if( mParent )
		mParent->itemTimeChanged( this );
}

void TimelineItem::updateDuration() const
{
	if( mDirtyDuration ) {
		mDuration = std::max( calcDuration(), 0.0f );
		mInvDuration = ( mDuration == 0 ) ? 1.0f : ( 1.0f / mDuration );
		mDirtyDuration = false;
	}
}

void TimelineItem::setDuration( float duration )
{
	mDuration = duration;
	mInvDuration = duration == 0 ? 1 : ( 1 / duration );
	if( mParent )
		mParent->itemTimeChanged( this );
}

float TimelineItem::loopTime( float absTime )
{
	float result = absTime;

	if( mPingPong ) {
		result = math<float>::fmod( result * mInvDuration, 2 ); // varies from 0-2
		if( result <= 1 )
			result *= mDuration;
		else
			result = ( 2 - result ) * mDuration;
	}
	else if( mLoop ) {
		result = math<float>::fmod( result * mInvDuration, 1 );
		result *= mDuration;
	}

	return result;
}

} // namespace cinder<commit_msg>Fix Timeline::isComplete immediately after changes<commit_after>/*
 Copyright (c) 2011, The Cinder Project, All rights reserved.
 This code is intended for use with the Cinder C++ library: http://libcinder.org

 Based on the sc-Choreograph CinderBlock by David Wicks: http://sansumbrella.com/

 Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and
	the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
	the following disclaimer in the documentation and/or other materials provided with the distribution.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGE.
*/

#include "cinder/TimelineItem.h"
#include "cinder/Timeline.h"
#include "cinder/CinderMath.h"

namespace cinder {

TimelineItem::TimelineItem( class Timeline *parent )
	: mParent( parent ), mTarget( 0 ), mStartTime( 0 ), mDirtyDuration( false ), mDuration( 0 ), mInvDuration( 0 ), mHasStarted( false ), mHasReverseStarted( false ),
		mComplete( false ), mReverseComplete( false ), mMarkedForRemoval( false ), mAutoRemove( true ),
		mInfinite( false ), mLoop( false ), mPingPong( false ), mLastLoopIteration( -1 ), mUseAbsoluteTime( false )
{
}

TimelineItem::TimelineItem( Timeline *parent, void *target, float startTime, float duration )
	: mParent( parent ), mTarget( target ), mStartTime( startTime ), mDirtyDuration( false ), mDuration( std::max( duration, 0.0f ) ), mInvDuration( duration <= 0 ? 0 : (1 / duration) ),
		mHasStarted( false ), mHasReverseStarted( false ), mComplete( false ), mReverseComplete( false ), mMarkedForRemoval( false ), mAutoRemove( true ),
		mInfinite( false ), mLoop( false ), mPingPong( false ), mLastLoopIteration( -1 ), mUseAbsoluteTime( false )
{
}

void TimelineItem::removeSelf()
{
	mMarkedForRemoval = true;
}

void TimelineItem::stepTo( float newTime, bool reverse )
{
	if( mMarkedForRemoval )
		return;

	updateDuration();

	const float absTime = newTime - mStartTime;
	const float endTime = mStartTime + mDuration;

	if( ( ! mHasReverseStarted ) && reverse && ( newTime < mStartTime ) ) {
		// first update the current time to be the start time
		update( ( mUseAbsoluteTime ) ? mStartTime : 0 );
		// then issue reverse start
		mHasReverseStarted = true;
		mHasStarted = false;
		start( true );
	}
	else if( newTime >= mStartTime ) {
		float relTime;
		if( mPingPong ) {
			relTime = math<float>::fmod( absTime * mInvDuration, 2 ); // varies from 0-2
			if( relTime > 1 )
				relTime = ( 2 - relTime );
		}
		else if( mLoop ) {
			relTime = math<float>::fmod( absTime * mInvDuration, 1 );
		}
		else
			relTime = math<float>::min( absTime * mInvDuration, 1 );

		if( ( ! mHasStarted ) && ( ! reverse ) ) {
			mHasStarted = true;
			mHasReverseStarted = false;
			mLastLoopIteration = 0;
			loopStart();
			start( false );
		}

		float time = ( mUseAbsoluteTime ) ? absTime : relTime;

		// accommodate a tween with a duration <= 0
		if( ( ! mUseAbsoluteTime ) && ( mInvDuration <= 0 ) )
			time = 1.0f;

		if( mLoop || mPingPong ) {
			int32_t loopIteration = static_cast<int32_t>( ( newTime - mStartTime ) * mInvDuration );
			if( loopIteration != mLastLoopIteration ) {
				mLastLoopIteration = loopIteration;
				loopStart();
				update( time );
			}
			else
				update( time );
		}
		else
			update( time );
	}

	if( newTime < endTime ) {
		if( ( ! mReverseComplete ) && reverse ) {
			mReverseComplete = true;
			mComplete = false;
			complete( true );
		}
	}
	else if( ( ! mLoop ) && ( ! mInfinite ) ) { // newTime >= endTime
		if( ( ! mComplete ) && ( ! reverse ) ) {
			mComplete = true;
			mReverseComplete = false;
			complete( false );
		}
	}
}

void TimelineItem::setStartTime( float time )
{
	mStartTime = time;
	if( mParent )
		mParent->itemTimeChanged( this );
}

void TimelineItem::updateDuration() const
{
	if( mDirtyDuration ) {
		mDuration = std::max( calcDuration(), 0.0f );
		mInvDuration = ( mDuration == 0 ) ? 1.0f : ( 1.0f / mDuration );
		mDirtyDuration = false;
	}
}

void TimelineItem::setDuration( float duration )
{
	mDuration = duration;
	mInvDuration = duration == 0 ? 1 : ( 1 / duration );
	if( mParent )
		mParent->itemTimeChanged( this );
}

float TimelineItem::loopTime( float absTime )
{
	float result = absTime;

	if( mPingPong ) {
		result = math<float>::fmod( result * mInvDuration, 2 ); // varies from 0-2
		if( result <= 1 )
			result *= mDuration;
		else
			result = ( 2 - result ) * mDuration;
	}
	else if( mLoop ) {
		result = math<float>::fmod( result * mInvDuration, 1 );
		result *= mDuration;
	}

	return result;
}

} // namespace cinder
<|endoftext|>