<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "sal/config.h"

#include "osl/diagnose.h"

#include "rtl/alloc.h"
#include "rtl/bootstrap.hxx"
#include "rtl/string.hxx"

#include <uno/lbnames.h>
#include "uno/mapping.hxx"
#include "uno/environment.hxx"

#include "cppuhelper/bootstrap.hxx"

#include "com/sun/star/lang/XComponent.hpp"
#include "com/sun/star/lang/XSingleComponentFactory.hpp"

#include "jni.h"
#include "jvmaccess/virtualmachine.hxx"
#include "jvmaccess/unovirtualmachine.hxx"

#include "juhx-export-functions.hxx"
#include "vm.hxx"

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

namespace javaunohelper
{

inline OUString jstring_to_oustring( jstring jstr, JNIEnv * jni_env )
{
    OSL_ASSERT( sizeof (sal_Unicode) == sizeof (jchar) );
    jsize len = jni_env->GetStringLength( jstr );
    rtl_uString * ustr =
        static_cast<rtl_uString *>(rtl_allocateMemory( sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ));
    jni_env->GetStringRegion( jstr, 0, len, ustr->buffer );
    OSL_ASSERT( JNI_FALSE == jni_env->ExceptionCheck() );
    ustr->refCount = 1;
    ustr->length = len;
    ustr->buffer[ len ] = '\0';
    return OUString( ustr, SAL_NO_ACQUIRE );
}

}

jobject Java_com_sun_star_comp_helper_Bootstrap_cppuhelper_1bootstrap(
    JNIEnv * jni_env, SAL_UNUSED_PARAMETER jclass, jstring juno_rc, jobjectArray jpairs,
    jobject loader )
{
    try
    {
        if (0 != jpairs)
        {
            jsize nPos = 0, len = jni_env->GetArrayLength( jpairs );
            while (nPos < len)
            {
                // name
                jstring jstr = static_cast<jstring>(jni_env->GetObjectArrayElement( jpairs, nPos ));
                if (JNI_FALSE != jni_env->ExceptionCheck())
                {
                    jni_env->ExceptionClear();
                    throw RuntimeException( "index out of bounds?!" );
                }
                if (0 != jstr)
                {
                    OUString name( ::javaunohelper::jstring_to_oustring( jstr, jni_env ) );
                    // value
                    jstr = static_cast<jstring>(jni_env->GetObjectArrayElement( jpairs, nPos +1 ));
                    if (JNI_FALSE != jni_env->ExceptionCheck())
                    {
                        jni_env->ExceptionClear();
                        throw RuntimeException( "index out of bounds?!" );
                    }
                    if (0 != jstr)
                    {
                        OUString value( ::javaunohelper::jstring_to_oustring( jstr, jni_env ) );

                        // set bootstrap parameter
                        ::rtl::Bootstrap::set( name, value );
                    }
                }
                nPos += 2;
            }
        }

        // bootstrap uno
        Reference< XComponentContext > xContext;
        if (0 == juno_rc)
        {
            xContext = ::cppu::defaultBootstrap_InitialComponentContext();
        }
        else
        {
            OUString uno_rc( ::javaunohelper::jstring_to_oustring( juno_rc, jni_env ) );
            xContext = ::cppu::defaultBootstrap_InitialComponentContext( uno_rc );
        }

        // create vm access
        ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > vm_access(
            ::javaunohelper::create_vm_access( jni_env, loader ) );
        // wrap vm singleton entry
        xContext = ::javaunohelper::install_vm_singleton( xContext, vm_access );

        // get uno envs
        OUString cpp_env_name = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
        OUString java_env_name = UNO_LB_JAVA;
        Environment java_env, cpp_env;
        uno_getEnvironment(reinterpret_cast<uno_Environment **>(&cpp_env), cpp_env_name.pData, NULL);
        uno_getEnvironment(reinterpret_cast<uno_Environment **>(&java_env), java_env_name.pData, vm_access.get() );

        // map to java
        Mapping mapping( cpp_env.get(), java_env.get() );
        if (! mapping.is())
        {
            Reference< lang::XComponent > xComp( xContext, UNO_QUERY );
            if (xComp.is())
                xComp->dispose();
            throw RuntimeException("cannot get mapping C++ <-> Java!" );
        }

        jobject jret = static_cast<jobject>(mapping.mapInterface( xContext.get(), ::getCppuType( &xContext ) ));
        jobject jlocal = jni_env->NewLocalRef( jret );
        jni_env->DeleteGlobalRef( jret );

        return jlocal;
    }
    catch (const RuntimeException & exc)
    {
        jclass c = jni_env->FindClass( "com/sun/star/uno/RuntimeException" );
        if (0 != c)
        {
            OString cstr( OUStringToOString(
                              exc.Message, RTL_TEXTENCODING_JAVA_UTF8 ) );
            OSL_TRACE( __FILE__": forwarding RuntimeException: %s", cstr.getStr() );
            jni_env->ThrowNew( c, cstr.getStr() );
        }
    }
    catch (const Exception & exc)
    {
        jclass c = jni_env->FindClass( "com/sun/star/uno/Exception" );
        if (0 != c)
        {
            OString cstr( OUStringToOString(
                              exc.Message, RTL_TEXTENCODING_JAVA_UTF8 ) );
            OSL_TRACE( __FILE__": forwarding Exception: %s", cstr.getStr() );
            jni_env->ThrowNew( c, cstr.getStr() );
        }
    }

    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Replace remaining getCppuType et al with cppu::UnoType<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "sal/config.h"

#include "osl/diagnose.h"

#include "rtl/alloc.h"
#include "rtl/bootstrap.hxx"
#include "rtl/string.hxx"

#include <uno/lbnames.h>
#include "uno/mapping.hxx"
#include "uno/environment.hxx"

#include "cppuhelper/bootstrap.hxx"

#include "com/sun/star/lang/XComponent.hpp"
#include "com/sun/star/lang/XSingleComponentFactory.hpp"

#include "jni.h"
#include "jvmaccess/virtualmachine.hxx"
#include "jvmaccess/unovirtualmachine.hxx"

#include "juhx-export-functions.hxx"
#include "vm.hxx"

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

namespace javaunohelper
{

inline OUString jstring_to_oustring( jstring jstr, JNIEnv * jni_env )
{
    OSL_ASSERT( sizeof (sal_Unicode) == sizeof (jchar) );
    jsize len = jni_env->GetStringLength( jstr );
    rtl_uString * ustr =
        static_cast<rtl_uString *>(rtl_allocateMemory( sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ));
    jni_env->GetStringRegion( jstr, 0, len, ustr->buffer );
    OSL_ASSERT( JNI_FALSE == jni_env->ExceptionCheck() );
    ustr->refCount = 1;
    ustr->length = len;
    ustr->buffer[ len ] = '\0';
    return OUString( ustr, SAL_NO_ACQUIRE );
}

}

jobject Java_com_sun_star_comp_helper_Bootstrap_cppuhelper_1bootstrap(
    JNIEnv * jni_env, SAL_UNUSED_PARAMETER jclass, jstring juno_rc, jobjectArray jpairs,
    jobject loader )
{
    try
    {
        if (0 != jpairs)
        {
            jsize nPos = 0, len = jni_env->GetArrayLength( jpairs );
            while (nPos < len)
            {
                // name
                jstring jstr = static_cast<jstring>(jni_env->GetObjectArrayElement( jpairs, nPos ));
                if (JNI_FALSE != jni_env->ExceptionCheck())
                {
                    jni_env->ExceptionClear();
                    throw RuntimeException( "index out of bounds?!" );
                }
                if (0 != jstr)
                {
                    OUString name( ::javaunohelper::jstring_to_oustring( jstr, jni_env ) );
                    // value
                    jstr = static_cast<jstring>(jni_env->GetObjectArrayElement( jpairs, nPos +1 ));
                    if (JNI_FALSE != jni_env->ExceptionCheck())
                    {
                        jni_env->ExceptionClear();
                        throw RuntimeException( "index out of bounds?!" );
                    }
                    if (0 != jstr)
                    {
                        OUString value( ::javaunohelper::jstring_to_oustring( jstr, jni_env ) );

                        // set bootstrap parameter
                        ::rtl::Bootstrap::set( name, value );
                    }
                }
                nPos += 2;
            }
        }

        // bootstrap uno
        Reference< XComponentContext > xContext;
        if (0 == juno_rc)
        {
            xContext = ::cppu::defaultBootstrap_InitialComponentContext();
        }
        else
        {
            OUString uno_rc( ::javaunohelper::jstring_to_oustring( juno_rc, jni_env ) );
            xContext = ::cppu::defaultBootstrap_InitialComponentContext( uno_rc );
        }

        // create vm access
        ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > vm_access(
            ::javaunohelper::create_vm_access( jni_env, loader ) );
        // wrap vm singleton entry
        xContext = ::javaunohelper::install_vm_singleton( xContext, vm_access );

        // get uno envs
        OUString cpp_env_name = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
        OUString java_env_name = UNO_LB_JAVA;
        Environment java_env, cpp_env;
        uno_getEnvironment(reinterpret_cast<uno_Environment **>(&cpp_env), cpp_env_name.pData, NULL);
        uno_getEnvironment(reinterpret_cast<uno_Environment **>(&java_env), java_env_name.pData, vm_access.get() );

        // map to java
        Mapping mapping( cpp_env.get(), java_env.get() );
        if (! mapping.is())
        {
            Reference< lang::XComponent > xComp( xContext, UNO_QUERY );
            if (xComp.is())
                xComp->dispose();
            throw RuntimeException("cannot get mapping C++ <-> Java!" );
        }

        jobject jret = static_cast<jobject>(mapping.mapInterface( xContext.get(), cppu::UnoType<decltype(xContext)>::get() ));
        jobject jlocal = jni_env->NewLocalRef( jret );
        jni_env->DeleteGlobalRef( jret );

        return jlocal;
    }
    catch (const RuntimeException & exc)
    {
        jclass c = jni_env->FindClass( "com/sun/star/uno/RuntimeException" );
        if (0 != c)
        {
            OString cstr( OUStringToOString(
                              exc.Message, RTL_TEXTENCODING_JAVA_UTF8 ) );
            OSL_TRACE( __FILE__": forwarding RuntimeException: %s", cstr.getStr() );
            jni_env->ThrowNew( c, cstr.getStr() );
        }
    }
    catch (const Exception & exc)
    {
        jclass c = jni_env->FindClass( "com/sun/star/uno/Exception" );
        if (0 != c)
        {
            OString cstr( OUStringToOString(
                              exc.Message, RTL_TEXTENCODING_JAVA_UTF8 ) );
            OSL_TRACE( __FILE__": forwarding Exception: %s", cstr.getStr() );
            jni_env->ThrowNew( c, cstr.getStr() );
        }
    }

    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before><commit_msg>Formatting cleanup.<commit_after><|endoftext|>


<commit_before>#include <common/buffer.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

#include <io/channel.h>
#include <io/pipe.h>
#include <io/splice.h>

/*
 * A Splice passes data unidirectionall between StreamChannels across a Pipe.
 */

Splice::Splice(StreamChannel *source, Pipe *pipe, StreamChannel *sink)
: log_("/splice"),
  source_(source),
  pipe_(pipe),
  sink_(sink),
  callback_(NULL),
  callback_action_(NULL),
  read_eos_(false),
  read_action_(NULL),
  input_action_(NULL),
  output_action_(NULL),
  write_action_(NULL),
  shutdown_action_(NULL)
{
	ASSERT(source_ != NULL);
	ASSERT(pipe_ != NULL);
	ASSERT(sink_ != NULL);
}

Splice::~Splice()
{
	ASSERT(callback_ == NULL);
	ASSERT(callback_action_ == NULL);
	ASSERT(read_action_ == NULL);
	ASSERT(input_action_ == NULL);
	ASSERT(output_action_ == NULL);
	ASSERT(write_action_ == NULL);
	ASSERT(shutdown_action_ == NULL);
}

Action *
Splice::start(EventCallback *cb)
{
	ASSERT(callback_ == NULL && callback_action_ == NULL);
	callback_ = cb;

	EventCallback *scb = callback(this, &Splice::read_complete);
	read_action_ = source_->read(0, scb);

	EventCallback *pcb = callback(this, &Splice::output_complete);
	output_action_ = pipe_->output(pcb);

	return (cancellation(this, &Splice::cancel));
}

void
Splice::cancel(void)
{
	if (callback_ != NULL) {
		delete callback_;
		callback_ = NULL;

		ASSERT(callback_action_ == NULL);

		if (read_action_ != NULL) {
			read_action_->cancel();
			read_action_ = NULL;
		}

		if (input_action_ != NULL) {
			input_action_->cancel();
			input_action_ = NULL;
		}

		if (output_action_ != NULL) {
			output_action_->cancel();
			output_action_ = NULL;
		}

		if (write_action_ != NULL) {
			write_action_->cancel();
			write_action_ = NULL;
		}

		if (shutdown_action_ != NULL) {
			shutdown_action_->cancel();
			shutdown_action_ = NULL;
		}
	} else {
		ASSERT(callback_action_ != NULL);
		callback_action_->cancel();
		callback_action_ = NULL;
	}
}

void
Splice::complete(Event e)
{
	ASSERT(callback_ != NULL);
	ASSERT(callback_action_ == NULL);

	if (read_action_ != NULL) {
		read_action_->cancel();
		read_action_ = NULL;
	}

	if (input_action_ != NULL) {
		input_action_->cancel();
		input_action_ = NULL;
	}

	if (output_action_ != NULL) {
		output_action_->cancel();
		output_action_ = NULL;
	}

	if (write_action_ != NULL) {
		write_action_->cancel();
		write_action_ = NULL;
	}

	callback_->param(e);
	callback_action_ = EventSystem::instance()->schedule(callback_);
	callback_ = NULL;
}

void
Splice::read_complete(Event e)
{
	read_action_->cancel();
	read_action_ = NULL;

	ASSERT(!read_eos_);

	switch (e.type_) {
	case Event::Done:
	case Event::EOS:
		break;
	default:
		DEBUG(log_) << "Unexpected event: " << e;
		complete(e);
		return;
	}

	if (e.buffer_.empty()) {
		ASSERT(e.type_ == Event::EOS);

		read_eos_ = true;
	}

	ASSERT(input_action_ == NULL);
	EventCallback *cb = callback(this, &Splice::input_complete);
	input_action_ = pipe_->input(&e.buffer_, cb);
}

void
Splice::input_complete(Event e)
{
	input_action_->cancel();
	input_action_ = NULL;

	switch (e.type_) {
	case Event::Done:
		break;
	default:
		DEBUG(log_) << "Unexpected event: " << e;
		complete(e);
		return;
	}

	ASSERT(read_action_ == NULL);
	if (!read_eos_) {
		EventCallback *cb = callback(this, &Splice::read_complete);
		read_action_ = source_->read(0, cb);
	}
}

void
Splice::output_complete(Event e)
{
	output_action_->cancel();
	output_action_ = NULL;

	switch (e.type_) {
	case Event::Done:
	case Event::EOS:
		break;
	default:
		DEBUG(log_) << "Unexpected event: " << e;
		complete(e);
		return;
	}

	if (e.type_ == Event::EOS && e.buffer_.empty()) {
		EventCallback *cb = callback(this, &Splice::shutdown_complete);
		shutdown_action_ = sink_->shutdown(false, true, cb);
		return;
	}

	ASSERT(write_action_ == NULL);
	EventCallback *cb = callback(this, &Splice::write_complete);
	write_action_ = sink_->write(&e.buffer_, cb);
}

void
Splice::write_complete(Event e)
{
	write_action_->cancel();
	write_action_ = NULL;

	switch (e.type_) {
	case Event::Done:
		break;
	default:
		DEBUG(log_) << "Unexpected event: " << e;
		complete(e);
		return;
	}

	ASSERT(output_action_ == NULL);
	EventCallback *cb = callback(this, &Splice::output_complete);
	output_action_ = pipe_->output(cb);
}

void
Splice::shutdown_complete(Event e)
{
	shutdown_action_->cancel();
	shutdown_action_ = NULL;

	switch (e.type_) {
	case Event::Done:
	case Event::Error:
		break;
	default:
		HALT(log_) << "Unexpected event: " << e;
		return;
	}

	if (e.type_ == Event::Error)
		DEBUG(log_) << "Could not shut down write channel.";
	complete(Event::EOS);
}
<commit_msg>Clean up shutdown actions when the splice is finished, too.<commit_after>#include <common/buffer.h>

#include <event/action.h>
#include <event/callback.h>
#include <event/event_system.h>

#include <io/channel.h>
#include <io/pipe.h>
#include <io/splice.h>

/*
 * A Splice passes data unidirectionall between StreamChannels across a Pipe.
 */

Splice::Splice(StreamChannel *source, Pipe *pipe, StreamChannel *sink)
: log_("/splice"),
  source_(source),
  pipe_(pipe),
  sink_(sink),
  callback_(NULL),
  callback_action_(NULL),
  read_eos_(false),
  read_action_(NULL),
  input_action_(NULL),
  output_action_(NULL),
  write_action_(NULL),
  shutdown_action_(NULL)
{
	ASSERT(source_ != NULL);
	ASSERT(pipe_ != NULL);
	ASSERT(sink_ != NULL);
}

Splice::~Splice()
{
	ASSERT(callback_ == NULL);
	ASSERT(callback_action_ == NULL);
	ASSERT(read_action_ == NULL);
	ASSERT(input_action_ == NULL);
	ASSERT(output_action_ == NULL);
	ASSERT(write_action_ == NULL);
	ASSERT(shutdown_action_ == NULL);
}

Action *
Splice::start(EventCallback *cb)
{
	ASSERT(callback_ == NULL && callback_action_ == NULL);
	callback_ = cb;

	EventCallback *scb = callback(this, &Splice::read_complete);
	read_action_ = source_->read(0, scb);

	EventCallback *pcb = callback(this, &Splice::output_complete);
	output_action_ = pipe_->output(pcb);

	return (cancellation(this, &Splice::cancel));
}

void
Splice::cancel(void)
{
	if (callback_ != NULL) {
		delete callback_;
		callback_ = NULL;

		ASSERT(callback_action_ == NULL);

		if (read_action_ != NULL) {
			read_action_->cancel();
			read_action_ = NULL;
		}

		if (input_action_ != NULL) {
			input_action_->cancel();
			input_action_ = NULL;
		}

		if (output_action_ != NULL) {
			output_action_->cancel();
			output_action_ = NULL;
		}

		if (write_action_ != NULL) {
			write_action_->cancel();
			write_action_ = NULL;
		}

		if (shutdown_action_ != NULL) {
			shutdown_action_->cancel();
			shutdown_action_ = NULL;
		}
	} else {
		ASSERT(callback_action_ != NULL);
		callback_action_->cancel();
		callback_action_ = NULL;
	}
}

void
Splice::complete(Event e)
{
	ASSERT(callback_ != NULL);
	ASSERT(callback_action_ == NULL);

	if (read_action_ != NULL) {
		read_action_->cancel();
		read_action_ = NULL;
	}

	if (input_action_ != NULL) {
		input_action_->cancel();
		input_action_ = NULL;
	}

	if (output_action_ != NULL) {
		output_action_->cancel();
		output_action_ = NULL;
	}

	if (write_action_ != NULL) {
		write_action_->cancel();
		write_action_ = NULL;
	}

	if (shutdown_action_ != NULL) {
		shutdown_action_->cancel();
		shutdown_action_ = NULL;
	}

	callback_->param(e);
	callback_action_ = EventSystem::instance()->schedule(callback_);
	callback_ = NULL;
}

void
Splice::read_complete(Event e)
{
	read_action_->cancel();
	read_action_ = NULL;

	ASSERT(!read_eos_);

	switch (e.type_) {
	case Event::Done:
	case Event::EOS:
		break;
	default:
		DEBUG(log_) << "Unexpected event: " << e;
		complete(e);
		return;
	}

	if (e.buffer_.empty()) {
		ASSERT(e.type_ == Event::EOS);

		read_eos_ = true;
	}

	ASSERT(input_action_ == NULL);
	EventCallback *cb = callback(this, &Splice::input_complete);
	input_action_ = pipe_->input(&e.buffer_, cb);
}

void
Splice::input_complete(Event e)
{
	input_action_->cancel();
	input_action_ = NULL;

	switch (e.type_) {
	case Event::Done:
		break;
	default:
		DEBUG(log_) << "Unexpected event: " << e;
		complete(e);
		return;
	}

	ASSERT(read_action_ == NULL);
	if (!read_eos_) {
		EventCallback *cb = callback(this, &Splice::read_complete);
		read_action_ = source_->read(0, cb);
	}
}

void
Splice::output_complete(Event e)
{
	output_action_->cancel();
	output_action_ = NULL;

	switch (e.type_) {
	case Event::Done:
	case Event::EOS:
		break;
	default:
		DEBUG(log_) << "Unexpected event: " << e;
		complete(e);
		return;
	}

	if (e.type_ == Event::EOS && e.buffer_.empty()) {
		EventCallback *cb = callback(this, &Splice::shutdown_complete);
		shutdown_action_ = sink_->shutdown(false, true, cb);
		return;
	}

	ASSERT(write_action_ == NULL);
	EventCallback *cb = callback(this, &Splice::write_complete);
	write_action_ = sink_->write(&e.buffer_, cb);
}

void
Splice::write_complete(Event e)
{
	write_action_->cancel();
	write_action_ = NULL;

	switch (e.type_) {
	case Event::Done:
		break;
	default:
		DEBUG(log_) << "Unexpected event: " << e;
		complete(e);
		return;
	}

	ASSERT(output_action_ == NULL);
	EventCallback *cb = callback(this, &Splice::output_complete);
	output_action_ = pipe_->output(cb);
}

void
Splice::shutdown_complete(Event e)
{
	shutdown_action_->cancel();
	shutdown_action_ = NULL;

	switch (e.type_) {
	case Event::Done:
	case Event::Error:
		break;
	default:
		HALT(log_) << "Unexpected event: " << e;
		return;
	}

	if (e.type_ == Event::Error)
		DEBUG(log_) << "Could not shut down write channel.";
	complete(Event::EOS);
}
<|endoftext|>


<commit_before>#pragma once
/**
	@file
	@brief finite field extension class
	@author MITSUNARI Shigeo(@herumi)
	@license modified new BSD license
	http://opensource.org/licenses/BSD-3-Clause
*/
#include <mcl/fp.hpp>

namespace mcl {

/*
	beta = -1
	Fp2 = F[u] / (u^2 + 1)
	x = a_ + b u
*/
template<class Fp>
class Fp2T {
	typedef fp::Unit Unit;
	static Fp xi_c_;
public:
	Fp a, b;
	Fp2T() { }
	Fp2T(int x)
		: a(x), b(0)
	{
	}
	Fp2T(const Fp& a, const Fp& b) : a(a), b(b) { }
	Fp2T(int64_t a, int64_t b) : a(a), b(b) { }
	Fp2T(const std::string& a, const std::string& b, int base = 0) : a(a, base), b(b, base) {}
	Fp* get() { return &a; }
	const Fp* get() const { return &a; }
	void clear()
	{
		a.clear();
		b.clear();
	}
	static inline void add(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::op_.fp2_add(z.a.v_, x.a.v_, y.a.v_); }
	static inline void sub(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::op_.fp2_sub(z.a.v_, x.a.v_, y.a.v_); }
	static inline void mul(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::op_.fp2_mul(z.a.v_, x.a.v_, y.a.v_); }
	static inline void inv(Fp2T& y, const Fp2T& x) { Fp::op_.fp2_inv(y.a.v_, x.a.v_); }
	static inline void neg(Fp2T& y, const Fp2T& x) { Fp::op_.fp2_neg(y.a.v_, x.a.v_); }
	static inline void sqr(Fp2T& y, const Fp2T& x) { Fp::op_.fp2_sqr(y.a.v_, x.a.v_); }
	static inline void mul_xi(Fp2T& y, const Fp2T& x) { Fp::op_.fp2_mul_xi(y.a.v_, x.a.v_); }
	static inline void div(Fp2T& z, const Fp2T& x, const Fp2T& y)
	{
		Fp2T rev;
		inv(rev, y);
		mul(z, x, rev);
	}
	inline friend Fp2T operator+(const Fp2T& x, const Fp2T& y) { Fp2T z; add(z, x, y); return z; }
	inline friend Fp2T operator-(const Fp2T& x, const Fp2T& y) { Fp2T z; sub(z, x, y); return z; }
	inline friend Fp2T operator*(const Fp2T& x, const Fp2T& y) { Fp2T z; mul(z, x, y); return z; }
	inline friend Fp2T operator/(const Fp2T& x, const Fp2T& y) { Fp2T z; div(z, x, y); return z; }
	Fp2T& operator+=(const Fp2T& x) { add(*this, *this, x); return *this; }
	Fp2T& operator-=(const Fp2T& x) { sub(*this, *this, x); return *this; }
	Fp2T& operator*=(const Fp2T& x) { mul(*this, *this, x); return *this; }
	Fp2T& operator/=(const Fp2T& x) { div(*this, *this, x); return *this; }
	Fp2T operator-() const { Fp2T x; neg(x, *this); return x; }
	/*
		Fp2T = '[' + <a> + ',' + <b> + ']'
	*/
	void getStr(std::string& str, int base = 10, bool withPrefix = false) const
	{
		str = '[';
		str += a.getStr(base, withPrefix);
		str += ',';
		str += b.getStr(base, withPrefix);
		str += ']';
	}
	void setStr(const std::string& str, int base = 0)
	{
		const size_t size = str.size();
		const size_t pos = str.find(',');
		if (size >= 5 && str[0] == '[' && pos != std::string::npos && str[size - 1] == ']') {
			a.setStr(str.substr(1, pos - 1), base);
			b.setStr(str.substr(pos + 1, size - pos - 2), base);
			return;
		}
		throw cybozu::Exception("Fp2T:setStr:bad format") << str;
	}
	std::string getStr(int base = 10, bool withPrefix = false) const
	{
		std::string str;
		getStr(str, base, withPrefix);
		return str;
	}
	friend inline std::ostream& operator<<(std::ostream& os, const Fp2T& self)
	{
		const std::ios_base::fmtflags f = os.flags();
		if (f & std::ios_base::oct) throw cybozu::Exception("Fp2T:operator<<:oct is not supported");
		const int base = (f & std::ios_base::hex) ? 16 : 10;
		const bool showBase = (f & std::ios_base::showbase) != 0;
		return os << self.getStr(base, showBase);
	}
	friend inline std::istream& operator>>(std::istream& is, Fp2T& self)
	{
		const std::ios_base::fmtflags f = is.flags();
		if (f & std::ios_base::oct) throw cybozu::Exception("fpT:operator>>:oct is not supported");
		const int base = (f & std::ios_base::hex) ? 16 : 0;
		std::string str;
		is >> str;
		self.setStr(str, base);
		return is;
	}
	bool isZero() const { return a.isZero() && b.isZero(); }
	bool operator==(const Fp2T& rhs) const { return a == rhs.a && b == rhs.b; }
	bool operator!=(const Fp2T& rhs) const { return !operator==(rhs); }
	void normalize() {} // dummy method
	template<class tag2, size_t maxBitSize2>
	static inline void power(Fp2T& z, const Fp2T& x, const FpT<tag2, maxBitSize2>& y)
	{
		fp::Block b;
		y.getBlock(b);
		powerArray(z, x, b.p, b.n, false);
	}
	static inline void power(Fp2T& z, const Fp2T& x, int y)
	{
		const fp::Unit u = abs(y);
		powerArray(z, x, &u, 1, y < 0);
	}
	static inline void power(Fp2T& z, const Fp2T& x, const mpz_class& y)
	{
		powerArray(z, x, Gmp::getUnit(y), abs(y.get_mpz_t()->_mp_size), y < 0);
	}
	static inline void init(int xi_c)
	{
		if (Fp::maxSize > 256) {
			throw cybozu::Exception("Fp2T:init:not support size") << Fp::maxSize;
		}
		xi_c_ = xi_c;
		Fp::op_.fp2_add = fp2_addW;
		Fp::op_.fp2_sub = fp2_subW;
		Fp::op_.fp2_mul = fp2_mulW;
		Fp::op_.fp2_neg = fp2_negW;
		Fp::op_.fp2_inv = fp2_invW;
		Fp::op_.fp2_sqr = fp2_sqrW;
		Fp::op_.fp2_mul_xi = fp2_mul_xiW;
	}
private:
	/*
		default Fp2 operator
		Fp2 = Fp[u]/(u^2 + 1)
	*/
	static inline void fp2_addW(Unit *z, const Unit *x, const Unit *y)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		const Fp *py = reinterpret_cast<const Fp*>(y);
		Fp *pz = reinterpret_cast<Fp*>(z);
		Fp::add(pz[0], px[0], py[0]);
		Fp::add(pz[1], px[1], py[1]);
	}
	static inline void fp2_subW(Unit *z, const Unit *x, const Unit *y)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		const Fp *py = reinterpret_cast<const Fp*>(y);
		Fp *pz = reinterpret_cast<Fp*>(z);
		Fp::sub(pz[0], px[0], py[0]);
		Fp::sub(pz[1], px[1], py[1]);
	}
	static inline void fp2_negW(Unit *y, const Unit *x)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		Fp *py = reinterpret_cast<Fp*>(y);
		Fp::neg(py[0], px[0]);
		Fp::neg(py[1], px[1]);
	}
	/*
		x = a + bu, y = c + du, u^2 = -1
		z = xy = (a + bu)(c + du) = (ac - bd) + (ad + bc)u
		ad+bc = (a + b)(c + d) - ac - bd
	*/
	static inline void fp2_mulW(Unit *z, const Unit *x, const Unit *y)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		const Fp *py = reinterpret_cast<const Fp*>(y);
		Fp *pz = reinterpret_cast<Fp*>(z);
		const Fp& a = px[0];
		const Fp& b = px[1];
		const Fp& c = py[0];
		const Fp& d = py[1];
		Fp t1, t2, ac, bd;
		Fp::add(t1, a, b);
		Fp::add(t2, c, d);
		t1 *= t2; // (a + b)(c + d)
		Fp::mul(ac, a, c);
		Fp::mul(bd, b, d);
		Fp::sub(pz[0], ac, bd); // ac - bd
		Fp::sub(pz[1], t1, ac);
		pz[1] -= bd;
	}
	/*
		x = a + bu, u^2 = -1
		y = x^2 = (a + bu)^2 = (a^2 - b^2) + 2abu
	*/
	static inline void fp2_sqrW(Unit *y, const Unit *x)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		Fp *py = reinterpret_cast<Fp*>(y);
		const Fp& a = px[0];
		const Fp& b = px[1];
		Fp aa, bb, t;
		Fp::sqr(aa, a);
		Fp::sqr(bb, b);
		Fp::mul(t, a, b);
		Fp::sub(py[0], aa, bb); // a^2 - b^2
		Fp::add(py[1], t, t); // 2ab
	}
	/*
		x = a + bu
		y = (a + bu)xi = (a + bu)(xi_c + u)
		=(a * x_ic - b) + (a + b xi_c)u
	*/
	static inline void fp2_mul_xiW(Unit *y, const Unit *x)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		Fp *py = reinterpret_cast<Fp*>(y);
		const Fp& a = px[0];
		const Fp& b = px[1];
		Fp t;
		Fp::mul(t, a, xi_c_);
		t -= b;
		Fp::mul(py[1], b, xi_c_);
		py[1] += a;
		py[0] = t;
	}
	/*
		x = a + bu
		1 / x = (a - bu) / (a^2 + b^2)
	*/
	static inline void fp2_invW(Unit *y, const Unit *x)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		Fp *py = reinterpret_cast<Fp*>(y);
		const Fp& a = px[0];
		const Fp& b = px[1];
		Fp aa, bb;
		Fp::sqr(aa, a);
		Fp::sqr(bb, b);
		aa += bb;
		Fp::inv(aa, aa); // aa = 1 / (a^2 + b^2)
		py[0] *= aa;
		py[1] *= aa;
		Fp::neg(py[1], py[1]);
	}
	static inline void powerArray(Fp2T& z, const Fp2T& x, const fp::Unit *y, size_t yn, bool isNegative)
	{
		Fp2T tmp;
		const Fp2T *px = &x;
		if (&z == &x) {
			tmp = x;
			px = &tmp;
		}
		z = 1;
		fp::powerGeneric(z, *px, y, yn, Fp2T::mul, Fp2T::sqr);
		if (isNegative) {
			Fp2T::inv(z, z);
		}
	}
};

template<class Fp> Fp Fp2T<Fp>::xi_c_;

/*
	Fp6T = Fp2[v] / (v^3 - xi)
	xi = -u - 1
	x = a + b v + c v^2
*/
template<class Fp>
class Fp6T {
	typedef Fp2T<Fp> Fp2;
public:
};

} // mcl

<commit_msg>use assert<commit_after>#pragma once
/**
	@file
	@brief finite field extension class
	@author MITSUNARI Shigeo(@herumi)
	@license modified new BSD license
	http://opensource.org/licenses/BSD-3-Clause
*/
#include <mcl/fp.hpp>

namespace mcl {

/*
	beta = -1
	Fp2 = F[u] / (u^2 + 1)
	x = a_ + b u
*/
template<class Fp>
class Fp2T {
	typedef fp::Unit Unit;
	static Fp xi_c_;
public:
	Fp a, b;
	Fp2T() { }
	Fp2T(int x)
		: a(x), b(0)
	{
	}
	Fp2T(const Fp& a, const Fp& b) : a(a), b(b) { }
	Fp2T(int64_t a, int64_t b) : a(a), b(b) { }
	Fp2T(const std::string& a, const std::string& b, int base = 0) : a(a, base), b(b, base) {}
	Fp* get() { return &a; }
	const Fp* get() const { return &a; }
	void clear()
	{
		a.clear();
		b.clear();
	}
	static inline void add(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::op_.fp2_add(z.a.v_, x.a.v_, y.a.v_); }
	static inline void sub(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::op_.fp2_sub(z.a.v_, x.a.v_, y.a.v_); }
	static inline void mul(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::op_.fp2_mul(z.a.v_, x.a.v_, y.a.v_); }
	static inline void inv(Fp2T& y, const Fp2T& x) { Fp::op_.fp2_inv(y.a.v_, x.a.v_); }
	static inline void neg(Fp2T& y, const Fp2T& x) { Fp::op_.fp2_neg(y.a.v_, x.a.v_); }
	static inline void sqr(Fp2T& y, const Fp2T& x) { Fp::op_.fp2_sqr(y.a.v_, x.a.v_); }
	static inline void mul_xi(Fp2T& y, const Fp2T& x) { Fp::op_.fp2_mul_xi(y.a.v_, x.a.v_); }
	static inline void div(Fp2T& z, const Fp2T& x, const Fp2T& y)
	{
		Fp2T rev;
		inv(rev, y);
		mul(z, x, rev);
	}
	inline friend Fp2T operator+(const Fp2T& x, const Fp2T& y) { Fp2T z; add(z, x, y); return z; }
	inline friend Fp2T operator-(const Fp2T& x, const Fp2T& y) { Fp2T z; sub(z, x, y); return z; }
	inline friend Fp2T operator*(const Fp2T& x, const Fp2T& y) { Fp2T z; mul(z, x, y); return z; }
	inline friend Fp2T operator/(const Fp2T& x, const Fp2T& y) { Fp2T z; div(z, x, y); return z; }
	Fp2T& operator+=(const Fp2T& x) { add(*this, *this, x); return *this; }
	Fp2T& operator-=(const Fp2T& x) { sub(*this, *this, x); return *this; }
	Fp2T& operator*=(const Fp2T& x) { mul(*this, *this, x); return *this; }
	Fp2T& operator/=(const Fp2T& x) { div(*this, *this, x); return *this; }
	Fp2T operator-() const { Fp2T x; neg(x, *this); return x; }
	/*
		Fp2T = '[' + <a> + ',' + <b> + ']'
	*/
	void getStr(std::string& str, int base = 10, bool withPrefix = false) const
	{
		str = '[';
		str += a.getStr(base, withPrefix);
		str += ',';
		str += b.getStr(base, withPrefix);
		str += ']';
	}
	void setStr(const std::string& str, int base = 0)
	{
		const size_t size = str.size();
		const size_t pos = str.find(',');
		if (size >= 5 && str[0] == '[' && pos != std::string::npos && str[size - 1] == ']') {
			a.setStr(str.substr(1, pos - 1), base);
			b.setStr(str.substr(pos + 1, size - pos - 2), base);
			return;
		}
		throw cybozu::Exception("Fp2T:setStr:bad format") << str;
	}
	std::string getStr(int base = 10, bool withPrefix = false) const
	{
		std::string str;
		getStr(str, base, withPrefix);
		return str;
	}
	friend inline std::ostream& operator<<(std::ostream& os, const Fp2T& self)
	{
		const std::ios_base::fmtflags f = os.flags();
		if (f & std::ios_base::oct) throw cybozu::Exception("Fp2T:operator<<:oct is not supported");
		const int base = (f & std::ios_base::hex) ? 16 : 10;
		const bool showBase = (f & std::ios_base::showbase) != 0;
		return os << self.getStr(base, showBase);
	}
	friend inline std::istream& operator>>(std::istream& is, Fp2T& self)
	{
		const std::ios_base::fmtflags f = is.flags();
		if (f & std::ios_base::oct) throw cybozu::Exception("fpT:operator>>:oct is not supported");
		const int base = (f & std::ios_base::hex) ? 16 : 0;
		std::string str;
		is >> str;
		self.setStr(str, base);
		return is;
	}
	bool isZero() const { return a.isZero() && b.isZero(); }
	bool operator==(const Fp2T& rhs) const { return a == rhs.a && b == rhs.b; }
	bool operator!=(const Fp2T& rhs) const { return !operator==(rhs); }
	void normalize() {} // dummy method
	template<class tag2, size_t maxBitSize2>
	static inline void power(Fp2T& z, const Fp2T& x, const FpT<tag2, maxBitSize2>& y)
	{
		fp::Block b;
		y.getBlock(b);
		powerArray(z, x, b.p, b.n, false);
	}
	static inline void power(Fp2T& z, const Fp2T& x, int y)
	{
		const fp::Unit u = abs(y);
		powerArray(z, x, &u, 1, y < 0);
	}
	static inline void power(Fp2T& z, const Fp2T& x, const mpz_class& y)
	{
		powerArray(z, x, Gmp::getUnit(y), abs(y.get_mpz_t()->_mp_size), y < 0);
	}
	static inline void init(int xi_c)
	{
		assert(Fp::maxSize <= 256);
		xi_c_ = xi_c;
		Fp::op_.fp2_add = fp2_addW;
		Fp::op_.fp2_sub = fp2_subW;
		Fp::op_.fp2_mul = fp2_mulW;
		Fp::op_.fp2_neg = fp2_negW;
		Fp::op_.fp2_inv = fp2_invW;
		Fp::op_.fp2_sqr = fp2_sqrW;
		Fp::op_.fp2_mul_xi = fp2_mul_xiW;
	}
private:
	/*
		default Fp2 operator
		Fp2 = Fp[u]/(u^2 + 1)
	*/
	static inline void fp2_addW(Unit *z, const Unit *x, const Unit *y)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		const Fp *py = reinterpret_cast<const Fp*>(y);
		Fp *pz = reinterpret_cast<Fp*>(z);
		Fp::add(pz[0], px[0], py[0]);
		Fp::add(pz[1], px[1], py[1]);
	}
	static inline void fp2_subW(Unit *z, const Unit *x, const Unit *y)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		const Fp *py = reinterpret_cast<const Fp*>(y);
		Fp *pz = reinterpret_cast<Fp*>(z);
		Fp::sub(pz[0], px[0], py[0]);
		Fp::sub(pz[1], px[1], py[1]);
	}
	static inline void fp2_negW(Unit *y, const Unit *x)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		Fp *py = reinterpret_cast<Fp*>(y);
		Fp::neg(py[0], px[0]);
		Fp::neg(py[1], px[1]);
	}
	/*
		x = a + bu, y = c + du, u^2 = -1
		z = xy = (a + bu)(c + du) = (ac - bd) + (ad + bc)u
		ad+bc = (a + b)(c + d) - ac - bd
	*/
	static inline void fp2_mulW(Unit *z, const Unit *x, const Unit *y)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		const Fp *py = reinterpret_cast<const Fp*>(y);
		Fp *pz = reinterpret_cast<Fp*>(z);
		const Fp& a = px[0];
		const Fp& b = px[1];
		const Fp& c = py[0];
		const Fp& d = py[1];
		Fp t1, t2, ac, bd;
		Fp::add(t1, a, b);
		Fp::add(t2, c, d);
		t1 *= t2; // (a + b)(c + d)
		Fp::mul(ac, a, c);
		Fp::mul(bd, b, d);
		Fp::sub(pz[0], ac, bd); // ac - bd
		Fp::sub(pz[1], t1, ac);
		pz[1] -= bd;
	}
	/*
		x = a + bu, u^2 = -1
		y = x^2 = (a + bu)^2 = (a^2 - b^2) + 2abu
	*/
	static inline void fp2_sqrW(Unit *y, const Unit *x)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		Fp *py = reinterpret_cast<Fp*>(y);
		const Fp& a = px[0];
		const Fp& b = px[1];
		Fp aa, bb, t;
		Fp::sqr(aa, a);
		Fp::sqr(bb, b);
		Fp::mul(t, a, b);
		Fp::sub(py[0], aa, bb); // a^2 - b^2
		Fp::add(py[1], t, t); // 2ab
	}
	/*
		x = a + bu
		y = (a + bu)xi = (a + bu)(xi_c + u)
		=(a * x_ic - b) + (a + b xi_c)u
	*/
	static inline void fp2_mul_xiW(Unit *y, const Unit *x)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		Fp *py = reinterpret_cast<Fp*>(y);
		const Fp& a = px[0];
		const Fp& b = px[1];
		Fp t;
		Fp::mul(t, a, xi_c_);
		t -= b;
		Fp::mul(py[1], b, xi_c_);
		py[1] += a;
		py[0] = t;
	}
	/*
		x = a + bu
		1 / x = (a - bu) / (a^2 + b^2)
	*/
	static inline void fp2_invW(Unit *y, const Unit *x)
	{
		const Fp *px = reinterpret_cast<const Fp*>(x);
		Fp *py = reinterpret_cast<Fp*>(y);
		const Fp& a = px[0];
		const Fp& b = px[1];
		Fp aa, bb;
		Fp::sqr(aa, a);
		Fp::sqr(bb, b);
		aa += bb;
		Fp::inv(aa, aa); // aa = 1 / (a^2 + b^2)
		py[0] *= aa;
		py[1] *= aa;
		Fp::neg(py[1], py[1]);
	}
	static inline void powerArray(Fp2T& z, const Fp2T& x, const fp::Unit *y, size_t yn, bool isNegative)
	{
		Fp2T tmp;
		const Fp2T *px = &x;
		if (&z == &x) {
			tmp = x;
			px = &tmp;
		}
		z = 1;
		fp::powerGeneric(z, *px, y, yn, Fp2T::mul, Fp2T::sqr);
		if (isNegative) {
			Fp2T::inv(z, z);
		}
	}
};

template<class Fp> Fp Fp2T<Fp>::xi_c_;

/*
	Fp6T = Fp2[v] / (v^3 - xi)
	xi = -u - 1
	x = a + b v + c v^2
*/
template<class Fp>
class Fp6T {
	typedef Fp2T<Fp> Fp2;
public:
};

} // mcl

<|endoftext|>


<commit_before>#include "Particle.hpp"

#include "Random.hpp"
#include "Sprite.hpp"
#include "ParticleEffector.hpp"
#include "Debug.hpp"

#include <algorithm>

vector<Particle*>	Particle::m_particles;
Sprite				Particle::m_spriteInterface;

struct Particle_cmp
{
	inline bool operator() (const Particle *a, const Particle *b)
	{
		return a->m_texture<b->m_texture;
	}
};

Particle::Particle()
	: m_modifiers(NULL)
{
	m_particles.push_back(this);
}

Particle::~Particle()
{
}

bool Particle::Update(GLfloat delta)
{
	m_life-=delta;
	if(m_life<=0.0f)
	{
		return true;
	}
	if(m_modifiers)
	{
		for(vector<ParticleEffector*>::iterator it=(*m_modifiers).begin();it!=(*m_modifiers).end();++it)
		{
			(*it)->UpdateParticle(this,delta);
		}
	}
	m_position+=m_velocity*delta;
	m_rotation+=m_angularVelocity*delta;
	while(m_rotation>360.0f)
	{
		m_rotation-=360.0f;
	}
	return false;
}

void Particle::UpdateAll(GLfloat delta)
{
	vector<Particle*> temp;
	for(vector<Particle*>::iterator it=m_particles.begin();it!=m_particles.end();++it)
	{
		if(!(*it)->Update(delta))
		{
			temp.push_back(*it);
		}
		else
		{
			delete *it;
		}
	}
	m_particles=temp;
}

void Particle::RenderAll()
{
	//sort(m_particles.begin(),m_particles.end(),Particle_cmp());

	for(vector<Particle*>::iterator it=m_particles.begin();it!=m_particles.end();++it)
	{
		m_spriteInterface.m_position=(*it)->m_position;
		m_spriteInterface.m_rotation=(*it)->m_rotation;
		m_spriteInterface.m_spriteShadingType=SpriteVertex::ALPHA_TEST;
		m_spriteInterface.SetTexture((*it)->m_texture);
		m_spriteInterface.SetSize((*it)->m_width,(*it)->m_height);
		m_spriteInterface.SetColor((*it)->m_color);
		m_spriteInterface.Render();
	}
}
<commit_msg>Added particle rendering using Sprites<commit_after>#include "Particle.hpp"

#include "Random.hpp"
#include "Sprite.hpp"
#include "ParticleEffector.hpp"
#include "Debug.hpp"

#include <algorithm>

vector<Particle*>	Particle::m_particles;
Sprite				Particle::m_spriteInterface;

struct Particle_cmp
{
	inline bool operator() (const Particle *a, const Particle *b)
	{
		return a->m_texture<b->m_texture;
	}
};

Particle::Particle()
	: m_modifiers(NULL), m_width(20.0f), m_height(20.0f)
{
	m_particles.push_back(this);
}

Particle::~Particle()
{
}

bool Particle::Update(GLfloat delta)
{
	m_life-=delta;
	if(m_life<=0.0f)
	{
		return false;
	}
	if(m_modifiers)
	{
		for(vector<ParticleEffector*>::iterator it=(*m_modifiers).begin();it!=(*m_modifiers).end();++it)
		{
			(*it)->UpdateParticle(this,delta);
		}
	}
	m_position+=m_velocity*delta;
	m_rotation+=m_angularVelocity*delta;
	while(m_rotation>360.0f)
	{
		m_rotation-=360.0f;
	}
	return true;
}

void Particle::UpdateAll(GLfloat delta)
{
	LOGD("particles = %d",m_particles.size());

	vector<Particle*> temp;
	for(vector<Particle*>::iterator it=m_particles.begin();it!=m_particles.end();++it)
	{
		if((*it)->Update(delta))
		{
			temp.push_back(*it);
		}
		else
		{
			delete *it;
		}
	}
	m_particles=temp;
}

void Particle::RenderAll()
{
	//sort(m_particles.begin(),m_particles.end(),Particle_cmp());

	for(vector<Particle*>::iterator it=m_particles.begin();it!=m_particles.end();++it)
	{
		m_spriteInterface.m_position=(*it)->m_position;
		m_spriteInterface.m_rotation=(*it)->m_rotation;
		m_spriteInterface.m_spriteShadingType=SpriteVertex::NONE;//SpriteVertex::ALPHA_TEST;
		m_spriteInterface.SetTexture((*it)->m_texture);
		m_spriteInterface.SetSize((*it)->m_width,(*it)->m_height);
		m_spriteInterface.SetColor((*it)->m_color);
		m_spriteInterface.Render();
	}
}
<|endoftext|>


<commit_before>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, 2014 Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

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

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. 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 OWNER 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.

******************************************************************************/
#ifndef NOMLIB_STDINT_TYPES_HPP
#define NOMLIB_STDINT_TYPES_HPP

#include <string> // std::size_t
#include <vector>

#include "nomlib/platforms.hpp"

// RTTI for library objects.
#include "nomlib/core/ObjectTypeInfo.hpp"

/*
  TODO: This should be replaced by an actual CMake script -- think:
        compile-time check for the necessary feature support for C++11 style
        headers support.

        Look into why GCC doesn't like the inclusion of <cstdint> -- otherwise
        known as stdint.h. MSVCPP2013 & llvm-clang are fine with it).
*/

#ifndef NOM_PLATFORM_LINUX  // To be replace with NOM_COMPILER_FEATURE_NULLPTR
                            // (see above TODO note).
  #include <cstdint>
#else
  #include <sys/types.h>
#endif

// Borrowed from /usr/include/MacTypes.h && /usr/include/objc/objc.h:
#ifndef NULL
  #if defined( NOM_COMPILER_FEATURE_NULLPTR )
    #define NULL nullptr
  #else
    #define NULL 0 //__DARWIN_NULL
  #endif
#endif // ! NULL

#ifndef nil
  #if defined( NOM_COMPILER_FEATURE_NULLPTR )
    #define nil nullptr
  #else
    #define nil 0 //__DARWIN_NULL
  #endif
#endif // ! nil

// Portable fixed-size data types derive from stdint.h
namespace nom {

/// \brief Signed 8-bit integer.
typedef int8_t int8;

/// \brief Unsigned 8-bit integer.
typedef uint8_t uint8;

/// \brief Signed 16-bit integer.
typedef int16_t int16;

/// \brief Unsigned 16-bit integer.
typedef uint16_t uint16;

/// \brief Signed 32-bit integer.
typedef int32_t int32;

/// \brief Unsigned 16-bit integer.
typedef uint32_t uint32;

/// \brief 64-bit integer types
/// \note As per **/usr/include/MacTypes.h**:
///
/// "The MS Visual C/C++ compiler uses __int64 instead of long long".
#if defined( NOM_COMPILER_MSVCPP ) && defined( NOM_PLATFORM_ARCH_X86 )
  typedef signed __int64 int64;
  typedef unsigned __int64 uint64;
#else // Blindly assume a 64-bit architecture
  typedef int64_t int64;    //typedef signed long long int int64;
  typedef uint64_t uint64;  //typedef unsigned long long int uint64;
#endif

// Additional integer type definitions

/// \brief Unsigned 8-bit character.
typedef unsigned char uchar;

/// \brief Variable-size (platform-defined) signed integer.
typedef signed int sint;

/// \brief Variable-size (platform-defined) unsigned integer.
typedef unsigned int uint;

typedef std::size_t size_type;

typedef sint* sint_ptr;
typedef uint* uint_ptr;

typedef int32_t* int32_ptr;
typedef uint32_t* uint32_ptr;

typedef void* void_ptr;

typedef unsigned long ulong;

/// \brief An integer indicating that there is no match, an error or NULL.
static const int npos = -1;

/// \brief The default standard point size for fonts.
///
/// \remarks Used in default initialization of nom::Text, nom::UIWidget, etc.
static const int DEFAULT_FONT_SIZE = 12;

/// \brief Upper limit of exact-width integer types
#if defined( INT32_MAX )

  /// \note As per /usr/include/stdint.h under OS X v10.9.x "Mavericks".
  static const int MAX_INT = INT32_MAX;
#endif

/// \brief Alignment types.
///
/// \remarks See also, nom::Anchor enumeration.
///
/// \note Borrowed from [maelstrom's screenlib](https://hg.libsdl.org/Maelstrom/)
enum Alignment: uint32
{
  NONE = 0x0,
  X_LEFT = 0x01,
  X_CENTER = 0x02,
  X_RIGHT = 0x4,

  /// \remarks Horizontal
  X_MASK = ( X_LEFT | X_CENTER | X_RIGHT ),

  Y_TOP = 0x10,
  Y_CENTER = 0x20,
  Y_BOTTOM = 0x40,

  /// \remarks Vertical
  Y_MASK = ( Y_TOP | Y_CENTER | Y_BOTTOM )
};

/// \note Borrowed from [maelstrom's screenlib](https://hg.libsdl.org/Maelstrom/)
enum Anchor: uint32
{
  None = NONE,                          // 0
  Left = X_LEFT,                        // 1
  Center = X_CENTER,                    // 2
  Right = X_RIGHT,                      // 4

  TopLeft = Y_TOP | X_LEFT,             // Hex: 0x11, Dec: 17
  TopCenter = Y_TOP | X_CENTER,         // Hex: 0x12, Dec: 18
  TopRight = Y_TOP | X_RIGHT,           // Hex: 0x14, Dec: 20

  MiddleLeft = Y_CENTER | X_LEFT,       // Hex: 0x21, Dec: 33
  MiddleCenter = Y_CENTER | X_CENTER,   // Hex: 0x22, Dec: 34
  MiddleRight = Y_CENTER | X_RIGHT,     // Hex: 0x24, Dec: 36

  BottomLeft = Y_BOTTOM | X_LEFT,       // Hex: 0x41, Dec: 65
  BottomCenter = Y_BOTTOM | X_CENTER,   // Hex: 0x42, Dec: 66
  BottomRight = Y_BOTTOM | X_RIGHT      // Hex: 0x44, Dec: 68
};

typedef std::vector<std::string> StringList;

} // namespace nom

/// Ensure our data types have the right sizes using C++11 compile-time asserts.
static_assert ( sizeof ( nom::uint8 ) == 1, "nom::uint8" );
static_assert ( sizeof ( nom::int8 ) == 1, "nom::int8" );

static_assert ( sizeof ( nom::uint16 ) == 2, "nom::uint16" );
static_assert ( sizeof ( nom::int16 ) == 2, "nom::int16" );

static_assert ( sizeof ( nom::uint32 ) == 4, "nom::uint32" );
static_assert ( sizeof ( nom::int32 ) == 4, "nom::int32" );

static_assert ( sizeof ( nom::uint64 ) == 8, "nom::uint64" );
static_assert ( sizeof ( nom::int64 ) == 8, "nom::int64" );

static_assert ( sizeof ( nom::uchar ) == 1, "nom::uchar" );

// Blindly assumes we are on either a 64-bit or 32-bit platform.
#if defined( NOM_PLATFORM_ARCH_X86_64 )
  static_assert( sizeof ( nom::ulong ) == 8, "nom::ulong" );
#else // #elif defined( NOM_PLATFORM_ARCH_X86_86 )
  static_assert( sizeof ( nom::ulong ) == 4, "nom::ulong" );
#endif

// Blindly assumes we are on either a 64-bit or 32-bit platform.
#if defined( NOM_PLATFORM_ARCH_X86_64 )
  static_assert( sizeof ( nom::int32_ptr ) == ( sizeof(long) ), "nom::int32_ptr" );
  static_assert( sizeof ( nom::uint32_ptr ) == ( sizeof(nom::ulong) ), "nom::uint32_ptr" );
#else // #elif defined(NOM_PLATFORM_ARCH_X86)
  static_assert( sizeof( nom::int32_ptr ) == ( sizeof( long ) ), "nom::int32_ptr" );
  static_assert( sizeof( nom::uint32_ptr ) == ( sizeof( nom::ulong ) ), "nom::uint32_ptr" );
#endif

/// Additional type definitions

const nom::sint NOM_EXIT_FAILURE = 1; // EXIT_FAILURE from cstdlib headers
const nom::sint NOM_EXIT_SUCCESS = 0; // EXIT_SUCCESS from cstdlib headers

//#if defined(HAVE_SDL2)
const nom::sint SDL_SUCCESS = 0; // Non-error return value for SDL2 API
//#endif

#endif // include guard defined
<commit_msg>types.hpp: Add static sanity checks for typedef nom::size_type<commit_after>/******************************************************************************

  nomlib - C++11 cross-platform game engine

Copyright (c) 2013, 2014 Jeffrey Carpenter <i8degrees@gmail.com>
All rights reserved.

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

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
2. 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 OWNER 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.

******************************************************************************/
#ifndef NOMLIB_STDINT_TYPES_HPP
#define NOMLIB_STDINT_TYPES_HPP

#include <string> // std::size_t
#include <vector>

#include "nomlib/platforms.hpp"

// RTTI for library objects.
#include "nomlib/core/ObjectTypeInfo.hpp"

/*
  TODO: This should be replaced by an actual CMake script -- think:
        compile-time check for the necessary feature support for C++11 style
        headers support.

        Look into why GCC doesn't like the inclusion of <cstdint> -- otherwise
        known as stdint.h. MSVCPP2013 & llvm-clang are fine with it).
*/

#ifndef NOM_PLATFORM_LINUX  // To be replace with NOM_COMPILER_FEATURE_NULLPTR
                            // (see above TODO note).
  #include <cstdint>
#else
  #include <sys/types.h>
#endif

// Borrowed from /usr/include/MacTypes.h && /usr/include/objc/objc.h:
#ifndef NULL
  #if defined( NOM_COMPILER_FEATURE_NULLPTR )
    #define NULL nullptr
  #else
    #define NULL 0 //__DARWIN_NULL
  #endif
#endif // ! NULL

#ifndef nil
  #if defined( NOM_COMPILER_FEATURE_NULLPTR )
    #define nil nullptr
  #else
    #define nil 0 //__DARWIN_NULL
  #endif
#endif // ! nil

// Portable fixed-size data types derive from stdint.h
namespace nom {

/// \brief Signed 8-bit integer.
typedef int8_t int8;

/// \brief Unsigned 8-bit integer.
typedef uint8_t uint8;

/// \brief Signed 16-bit integer.
typedef int16_t int16;

/// \brief Unsigned 16-bit integer.
typedef uint16_t uint16;

/// \brief Signed 32-bit integer.
typedef int32_t int32;

/// \brief Unsigned 16-bit integer.
typedef uint32_t uint32;

/// \brief 64-bit integer types
/// \note As per **/usr/include/MacTypes.h**:
///
/// "The MS Visual C/C++ compiler uses __int64 instead of long long".
#if defined( NOM_COMPILER_MSVCPP ) && defined( NOM_PLATFORM_ARCH_X86 )
  typedef signed __int64 int64;
  typedef unsigned __int64 uint64;
#else // Blindly assume a 64-bit architecture
  typedef int64_t int64;    //typedef signed long long int int64;
  typedef uint64_t uint64;  //typedef unsigned long long int uint64;
#endif

// Additional integer type definitions

/// \brief Unsigned 8-bit character.
typedef unsigned char uchar;

/// \brief Variable-size (platform-defined) signed integer.
/// \deprecated This will be removed in a future version; use int type instead.
typedef signed int sint;

/// \brief Variable-size (platform-defined) unsigned integer.
typedef unsigned int uint;

typedef std::size_t size_type;

typedef intptr_t* int_ptr;
typedef uintptr_t* uint_ptr;

/// \deprecated This will be removed in a future version; use int_ptr type
/// instead.
typedef sint* sint_ptr;

typedef int32_t* int32_ptr;
typedef uint32_t* uint32_ptr;

typedef void* void_ptr;

typedef unsigned long ulong;

/// \brief An integer indicating that there is no match, an error or NULL.
static const int npos = -1;

/// \brief The default standard point size for fonts.
///
/// \remarks Used in default initialization of nom::Text, nom::UIWidget, etc.
static const int DEFAULT_FONT_SIZE = 12;

/// \brief Upper limit of exact-width integer types
#if defined( INT32_MAX )

  /// \note As per /usr/include/stdint.h under OS X v10.9.x "Mavericks".
  static const int MAX_INT = INT32_MAX;
#endif

/// \brief Alignment types.
///
/// \remarks See also, nom::Anchor enumeration.
///
/// \note Borrowed from [maelstrom's screenlib](https://hg.libsdl.org/Maelstrom/)
enum Alignment: uint32
{
  NONE = 0x0,
  X_LEFT = 0x01,
  X_CENTER = 0x02,
  X_RIGHT = 0x4,

  /// \remarks Horizontal
  X_MASK = ( X_LEFT | X_CENTER | X_RIGHT ),

  Y_TOP = 0x10,
  Y_CENTER = 0x20,
  Y_BOTTOM = 0x40,

  /// \remarks Vertical
  Y_MASK = ( Y_TOP | Y_CENTER | Y_BOTTOM )
};

/// \note Borrowed from [maelstrom's screenlib](https://hg.libsdl.org/Maelstrom/)
enum Anchor: uint32
{
  None = NONE,                          // 0
  Left = X_LEFT,                        // 1
  Center = X_CENTER,                    // 2
  Right = X_RIGHT,                      // 4

  TopLeft = Y_TOP | X_LEFT,             // Hex: 0x11, Dec: 17
  TopCenter = Y_TOP | X_CENTER,         // Hex: 0x12, Dec: 18
  TopRight = Y_TOP | X_RIGHT,           // Hex: 0x14, Dec: 20

  MiddleLeft = Y_CENTER | X_LEFT,       // Hex: 0x21, Dec: 33
  MiddleCenter = Y_CENTER | X_CENTER,   // Hex: 0x22, Dec: 34
  MiddleRight = Y_CENTER | X_RIGHT,     // Hex: 0x24, Dec: 36

  BottomLeft = Y_BOTTOM | X_LEFT,       // Hex: 0x41, Dec: 65
  BottomCenter = Y_BOTTOM | X_CENTER,   // Hex: 0x42, Dec: 66
  BottomRight = Y_BOTTOM | X_RIGHT      // Hex: 0x44, Dec: 68
};

typedef std::vector<std::string> StringList;

} // namespace nom

/// Ensure our data types have the right sizes using C++11 compile-time asserts.
static_assert ( sizeof ( nom::uint8 ) == 1, "nom::uint8" );
static_assert ( sizeof ( nom::int8 ) == 1, "nom::int8" );

static_assert ( sizeof ( nom::uint16 ) == 2, "nom::uint16" );
static_assert ( sizeof ( nom::int16 ) == 2, "nom::int16" );

static_assert ( sizeof ( nom::uint32 ) == 4, "nom::uint32" );
static_assert ( sizeof ( nom::int32 ) == 4, "nom::int32" );

static_assert ( sizeof ( nom::uint64 ) == 8, "nom::uint64" );
static_assert ( sizeof ( nom::int64 ) == 8, "nom::int64" );

static_assert ( sizeof ( nom::uchar ) == 1, "nom::uchar" );

// Blindly assumes we are on either a 64-bit or 32-bit platform.
#if defined( NOM_PLATFORM_ARCH_X86_64 )
  static_assert( sizeof ( nom::ulong ) == 8, "nom::ulong" );
  static_assert( sizeof ( nom::size_type ) == 8, "nom::size_type" );
#else // #elif defined( NOM_PLATFORM_ARCH_X86_86 )
  static_assert( sizeof ( nom::ulong ) == 4, "nom::ulong" );
  static_assert( sizeof ( nom::size_type ) == 4, "nom::size_type" );
#endif

// Blindly assumes we are on either a 64-bit or 32-bit platform.
#if defined( NOM_PLATFORM_ARCH_X86_64 )
  static_assert( sizeof(nom::int_ptr) == 8, "nom::int_ptr" );
  static_assert( sizeof(nom::uint_ptr) == 8, "nom::uint_ptr" );
  static_assert( sizeof ( nom::int32_ptr ) == ( sizeof(long) ), "nom::int32_ptr" );
  static_assert( sizeof ( nom::uint32_ptr ) == ( sizeof(nom::ulong) ), "nom::uint32_ptr" );
#else // #elif defined(NOM_PLATFORM_ARCH_X86)
  static_assert( sizeof(nom::int_ptr) == 4, "nom::int_ptr" );
  static_assert( sizeof(nom::uint_ptr) == 4, "nom::uint_ptr" );
  static_assert( sizeof( nom::int32_ptr ) == ( sizeof( long ) ), "nom::int32_ptr" );
  static_assert( sizeof( nom::uint32_ptr ) == ( sizeof( nom::ulong ) ), "nom::uint32_ptr" );
#endif

/// Additional type definitions

const nom::sint NOM_EXIT_FAILURE = 1; // EXIT_FAILURE from cstdlib headers
const nom::sint NOM_EXIT_SUCCESS = 0; // EXIT_SUCCESS from cstdlib headers

//#if defined(HAVE_SDL2)
const nom::sint SDL_SUCCESS = 0; // Non-error return value for SDL2 API
//#endif

#endif // include guard defined
<|endoftext|>


<commit_before>#ifndef STATE_MACHINE_HPP
#define STATE_MACHINE_HPP

#include <cstdint>
#include <functional>
#include <iostream>
#include <limits>
#include <stdexcept>
#include <unordered_map>
#include <vector>

#include "common.hpp"

template <class Identifier, class Packet> class StateMachine {
public:
	struct State;
	class FunIface;

	using stateFun = std::function<void(State &, Packet *, FunIface &)>;
	using ConnectionID = typename Identifier::ConnectionID;
	using Hasher = typename Identifier::Hasher;

	static constexpr auto StateIDInvalid = std::numeric_limits<StateID>::max();

	struct State {
	public:
		void *stateData;
		StateID state;

		State(StateID state, void *stateData) : stateData(stateData), state(state) {};
		State(const State &s) : stateData(s.stateData), state(s.state) {};

		void transition(StateID newState) { state = newState; }
	};

	class FunIface {
	private:
		StateMachine<Identifier, Packet> *sm;

	public:
		FunIface(StateMachine<Identifier, Packet> *sm) : sm(sm){};

		void addPktToFree(Packet *p) { sm->pktsToFree.push_back(p); }

		void addPktToSend(Packet *p) { sm->pktsToSend.push_back(p); }

		Packet *getPkt() {
			if (sm->pktsToFree.size() != 0) {
				Packet *ret = sm->pktsToFree.back();
				sm->pktsToFree.pop_back();
				return ret;
			} else if (sm->getPkt) {
				D(sm->getPktCBCounter++;)
				return sm->getPkt();
			} else {
				throw std::runtime_error(
					"StateMachine::SMFunIface::getPkt no function registered");
			}
		}

		void setTimeout() {
			throw new std::runtime_error(
				"StateMachine::FunIface::setTimeout not implemented");
		}
	};

private:
	std::unordered_map<ConnectionID, State, Hasher> stateTable;

	std::unordered_map<StateID, stateFun> functions;

	Identifier identifier;

	StateID startStateID;
	StateID endStateID;

	std::function<Packet &()> getPktCB;
	D(unsigned int getPktCBCounter = 0;)

	FunIface funIface;

	std::vector<Packet *> pktsToFree;
	std::vector<Packet *> pktsToSend;

	auto findState(ConnectionID id) {
	findStateLoop:
		auto stateIt = stateTable.find(id);
		if (stateIt == stateTable.end()) {
			// Add new state
			D(std::cout << "Adding new state" << std::endl;)
			State s(startStateID, nullptr);
			stateTable.insert({id, s});
			goto findStateLoop;
		} else {
			D(std::cout << "State found" << std::endl;)
		}
		return stateIt;
	};

	void runPkt(Packet *pktIn) {
		ConnectionID identity = identifier.identify(pktIn);

		auto stateIt = findState(identity);

		// TODO unregister timeout, if one exists

		auto sfIt = functions.find(stateIt->second.state);
		if (sfIt == functions.end()) {
			throw std::runtime_error("StateMachine::runPkt() No such function found");
		}

		D(std::cout << "Running Function" << std::endl;)
		(sfIt->second)(stateIt->second, pktIn, funIface);

		if (stateIt->second.state == endStateID) {
			D(std::cout << "Reached endStateID - deleting connection" << std::endl;)
			removeState(identity);
		}
	}

public:
	StateMachine() : startStateID(0), endStateID(StateIDInvalid), funIface(this){};

	size_t getStateTableSize() { return stateTable.size(); };

	void registerFunction(StateID id, stateFun function) { functions.insert({id, function}); }

	void registerEndStateID(StateID endStateID) { this->endStateID = endStateID; }
	void registerStartStateID(StateID startStateID) { this->startStateID = startStateID; }

	void registerGetPktCB(std::function<Packet &()> fun) { getPktCB = fun; }

	void removeState(ConnectionID id) { stateTable.erase(id); }

	void addState(ConnectionID id, State st) {
		stateTable.insert({id, st});
		auto stateIt = findState(id);

		auto sfIt = functions.find(stateIt->second.state);
		if (sfIt == functions.end()) {
			throw std::runtime_error("StateMachine::addState() No such function found");
		}

		D(std::cout << "Running Function" << std::endl;)
		(sfIt->second)(stateIt->second, nullptr, funIface);

		if (stateIt->second.state == endStateID) {
			D(std::cout << "Reached endStateID - deleting connection" << std::endl;)
			removeState(id);
		}
	}

	void runPktBatch(std::vector<Packet *> &pktsIn, std::vector<Packet *> &pktsSend,
		std::vector<Packet *> &pktsFree) {
		for (auto pkt : pktsIn) {
			runPkt(pkt);
		}
#ifdef DEBUG
		// putting it all in D() and using assert would have been better...
		// for some reason that didn't work...
		if ((pktsToFree.size() + pktsToSend.size()) != (getPktCBCounter + pktsIn.size())) {
			std::cout << "pktsToFree: " << pktsToFree.size() << std::endl;
			std::cout << "pktsToSend: " << pktsToSend.size() << std::endl;
			std::cout << "pktsIn: " << pktsIn.size() << std::endl;
			std::cout << "getPktCBCounter: " << getPktCBCounter << std::endl;

			throw new std::runtime_error(
				"StateMachine::runPktBatch() some packets were are not in send/free vector");
		}
		getPktCBCounter = 0;
#endif
		pktsSend.clear();
		pktsFree.clear();
		std::swap(pktsSend, pktsToSend);
		std::swap(pktsFree, pktsToFree);
		pktsToSend.clear();
		pktsToFree.clear();
	}
};

#endif /* STATE_MACHINE_HPP */
<commit_msg>fix getPkt() in StateMachine<commit_after>#ifndef STATE_MACHINE_HPP
#define STATE_MACHINE_HPP

#include <cstdint>
#include <functional>
#include <iostream>
#include <limits>
#include <stdexcept>
#include <unordered_map>
#include <vector>

#include "common.hpp"

template <class Identifier, class Packet> class StateMachine {
public:
	struct State;
	class FunIface;

	using stateFun = std::function<void(State &, Packet *, FunIface &)>;
	using ConnectionID = typename Identifier::ConnectionID;
	using Hasher = typename Identifier::Hasher;

	static constexpr auto StateIDInvalid = std::numeric_limits<StateID>::max();

	struct State {
	public:
		void *stateData;
		StateID state;

		State(StateID state, void *stateData) : stateData(stateData), state(state) {};
		State(const State &s) : stateData(s.stateData), state(s.state) {};

		void transition(StateID newState) { state = newState; }
	};

	class FunIface {
	private:
		StateMachine<Identifier, Packet> *sm;

	public:
		FunIface(StateMachine<Identifier, Packet> *sm) : sm(sm){};

		void addPktToFree(Packet *p) { sm->pktsToFree.push_back(p); }

		void addPktToSend(Packet *p) { sm->pktsToSend.push_back(p); }

		Packet *getPkt() {
			if (sm->pktsToFree.size() != 0) {
				Packet *ret = sm->pktsToFree.back();
				sm->pktsToFree.pop_back();
				return ret;
			} else if (sm->getPktCB) {
				D(sm->getPktCBCounter++;)
				return sm->getPktCB();
			} else {
				throw std::runtime_error(
					"StateMachine::SMFunIface::getPkt no function registered");
			}
		}

		void setTimeout() {
			throw new std::runtime_error(
				"StateMachine::FunIface::setTimeout not implemented");
		}
	};

private:
	std::unordered_map<ConnectionID, State, Hasher> stateTable;

	std::unordered_map<StateID, stateFun> functions;

	Identifier identifier;

	StateID startStateID;
	StateID endStateID;

	std::function<Packet *()> getPktCB;
	D(unsigned int getPktCBCounter = 0;)

	FunIface funIface;

	std::vector<Packet *> pktsToFree;
	std::vector<Packet *> pktsToSend;

	auto findState(ConnectionID id) {
	findStateLoop:
		auto stateIt = stateTable.find(id);
		if (stateIt == stateTable.end()) {
			// Add new state
			D(std::cout << "Adding new state" << std::endl;)
			State s(startStateID, nullptr);
			stateTable.insert({id, s});
			goto findStateLoop;
		} else {
			D(std::cout << "State found" << std::endl;)
		}
		return stateIt;
	};

	void runPkt(Packet *pktIn) {
		ConnectionID identity = identifier.identify(pktIn);

		auto stateIt = findState(identity);

		// TODO unregister timeout, if one exists

		auto sfIt = functions.find(stateIt->second.state);
		if (sfIt == functions.end()) {
			throw std::runtime_error("StateMachine::runPkt() No such function found");
		}

		D(std::cout << "Running Function" << std::endl;)
		(sfIt->second)(stateIt->second, pktIn, funIface);

		if (stateIt->second.state == endStateID) {
			D(std::cout << "Reached endStateID - deleting connection" << std::endl;)
			removeState(identity);
		}
	}

public:
	StateMachine() : startStateID(0), endStateID(StateIDInvalid), funIface(this){};

	size_t getStateTableSize() { return stateTable.size(); };

	void registerFunction(StateID id, stateFun function) { functions.insert({id, function}); }

	void registerEndStateID(StateID endStateID) { this->endStateID = endStateID; }
	void registerStartStateID(StateID startStateID) { this->startStateID = startStateID; }

	void registerGetPktCB(std::function<Packet *()> fun) { getPktCB = fun; }

	void removeState(ConnectionID id) { stateTable.erase(id); }

	void addState(ConnectionID id, State st) {
		stateTable.insert({id, st});
		auto stateIt = findState(id);

		auto sfIt = functions.find(stateIt->second.state);
		if (sfIt == functions.end()) {
			throw std::runtime_error("StateMachine::addState() No such function found");
		}

		D(std::cout << "Running Function" << std::endl;)
		(sfIt->second)(stateIt->second, nullptr, funIface);

		if (stateIt->second.state == endStateID) {
			D(std::cout << "Reached endStateID - deleting connection" << std::endl;)
			removeState(id);
		}
	}

	void runPktBatch(std::vector<Packet *> &pktsIn, std::vector<Packet *> &pktsSend,
		std::vector<Packet *> &pktsFree) {
		for (auto pkt : pktsIn) {
			runPkt(pkt);
		}
#ifdef DEBUG
		// putting it all in D() and using assert would have been better...
		// for some reason that didn't work...
		if ((pktsToFree.size() + pktsToSend.size()) != (getPktCBCounter + pktsIn.size())) {
			std::cout << "pktsToFree: " << pktsToFree.size() << std::endl;
			std::cout << "pktsToSend: " << pktsToSend.size() << std::endl;
			std::cout << "pktsIn: " << pktsIn.size() << std::endl;
			std::cout << "getPktCBCounter: " << getPktCBCounter << std::endl;

			throw new std::runtime_error(
				"StateMachine::runPktBatch() some packets were are not in send/free vector");
		}
		getPktCBCounter = 0;
#endif
		pktsSend.clear();
		pktsFree.clear();
		std::swap(pktsSend, pktsToSend);
		std::swap(pktsFree, pktsToFree);
		pktsToSend.clear();
		pktsToFree.clear();
	}
};

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


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_SVL_POOLITEM_HXX
#define INCLUDED_SVL_POOLITEM_HXX

#include <svl/svldllapi.h>
#include <com/sun/star/uno/Any.hxx>

#include <sal/config.h>
#include <tools/rtti.hxx>
#include <limits.h>
#include <tools/solar.h>
#include <tools/debug.hxx>
#include <svl/hint.hxx>

typedef long SfxArgumentError;

class SbxVariable;
class SbxObject;
class SvStream;
class Color;
class IntlWrapper;

namespace com { namespace sun { namespace star { namespace uno { class Any; } } } }

static const sal_uInt32 SFX_ITEMS_DIRECT=   0xffffffff;
static const sal_uInt32 SFX_ITEMS_NULL=     0xfffffff0;  // instead StoreSurrogate
static const sal_uInt32 SFX_ITEMS_DEFAULT=  0xfffffffe;

#define SFX_ITEMS_POOLDEFAULT               0xffff
#define SFX_ITEMS_STATICDEFAULT             0xfffe
#define SFX_ITEMS_DELETEONIDLE              0xfffd

#define SFX_ITEMS_OLD_MAXREF                0xffef
#define SFX_ITEMS_MAXREF                    0xfffffffe
#define SFX_ITEMS_SPECIAL                   0xffffffff

#define CONVERT_TWIPS                       0x80    //Uno-Konvertierung fuer Massangaben (fuer MemberId)

// UNO3 shortcuts

// warning, if there is no boolean inside the any this will always return the value false
inline bool Any2Bool( const ::com::sun::star::uno::Any&rValue )
{
    bool nValue = false;
    if( rValue.hasValue() )
    {
        if( rValue.getValueType() == ::getCppuBooleanType() )
        {
            nValue = *(sal_Bool*)rValue.getValue();
        }
        else
        {
            sal_Int32 nNum = 0;
            if( rValue >>= nNum )
                nValue = nNum != 0;
        }
    }

    return nValue;
}

inline ::com::sun::star::uno::Any Bool2Any( bool bValue )
{
    return ::com::sun::star::uno::Any( &bValue, ::getCppuBooleanType() );
}

//! Notloesung!!!
enum SfxFieldUnit
{
    SFX_FUNIT_NONE, SFX_FUNIT_MM, SFX_FUNIT_CM, SFX_FUNIT_M, SFX_FUNIT_KM,
    SFX_FUNIT_TWIP, SFX_FUNIT_POINT, SFX_FUNIT_PICA,
    SFX_FUNIT_INCH, SFX_FUNIT_FOOT, SFX_FUNIT_MILE, SFX_FUNIT_CHAR, SFX_FUNIT_LINE, SFX_FUNIT_CUSTOM
};

enum SfxMapUnit
{
    SFX_MAPUNIT_100TH_MM,
    SFX_MAPUNIT_10TH_MM,
    SFX_MAPUNIT_MM,
    SFX_MAPUNIT_CM,
    SFX_MAPUNIT_1000TH_INCH,
    SFX_MAPUNIT_100TH_INCH,
    SFX_MAPUNIT_10TH_INCH,
    SFX_MAPUNIT_INCH,
    SFX_MAPUNIT_POINT,
    SFX_MAPUNIT_TWIP,
    SFX_MAPUNIT_PIXEL,
    SFX_MAPUNIT_SYSFONT,
    SFX_MAPUNIT_APPFONT,
    SFX_MAPUNIT_RELATIVE,
    SFX_MAPUNIT_ABSOLUTE
};

enum SfxItemPresentation

/*  [Beschreibung]

    Die Werte dieses Enums bezeichnen den Grad der textuellen
    Presentation eines Items nach Aufruf der virtuellen Methode
    <SfxPoolItem::GetPresentation()const>.
*/

{
    SFX_ITEM_PRESENTATION_NONE,
    SFX_ITEM_PRESENTATION_NAMELESS,
    SFX_ITEM_PRESENTATION_COMPLETE
};

typedef sal_uInt16 SfxItemState;

#define SFX_ITEM_UNKNOWN    0x0000

#define SFX_ITEM_DISABLED   0x0001
#define SFX_ITEM_READONLY   0x0002

#define SFX_ITEM_DONTCARE   0x0010
#define SFX_ITEM_DEFAULT    0x0020
#define SFX_ITEM_SET        0x0030

// old stuff - dont use!!!
#define SFX_ITEM_AVAILABLE  SFX_ITEM_DEFAULT
#define SFX_ITEM_OFF        SFX_ITEM_DEFAULT
#define SFX_ITEM_ON         SFX_ITEM_SET

class SvXMLUnitConverter;
class SfxItemPool;
class SfxItemSet;

class SVL_DLLPUBLIC SfxPoolItem
{
friend class SfxItemPool;
friend class SfxItemDesruptor_Impl;
friend class SfxItemPoolCache;
friend class SfxItemSet;
friend class SfxVoidItem;

    sal_uLong   m_nRefCount;
    sal_uInt16  m_nWhich;
    sal_uInt16  m_nKind;

private:
    inline void              SetRefCount( sal_uLong n );
    inline void              SetKind( sal_uInt16 n );
public:
    inline sal_uLong         AddRef( sal_uLong n = 1 ) const;
private:
    inline sal_uLong         ReleaseRef( sal_uLong n = 1 ) const;
    SVL_DLLPRIVATE long      Delete_Impl(void*);

protected:
                             explicit SfxPoolItem( sal_uInt16 nWhich = 0 );
                             SfxPoolItem( const SfxPoolItem& );

public:
                             TYPEINFO();
    virtual                  ~SfxPoolItem();

    void                     SetWhich( sal_uInt16 nId ) { m_nWhich = nId; }
    sal_uInt16               Which() const { return m_nWhich; }
    virtual bool             operator==( const SfxPoolItem& ) const = 0;
    bool                     operator!=( const SfxPoolItem& rItem ) const
                             { return !(*this == rItem); }
    virtual int              Compare( const SfxPoolItem &rWith ) const;
    virtual int              Compare( const SfxPoolItem &rWith, const IntlWrapper& rIntlWrapper ) const;

    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePresentation,
                                    SfxMapUnit eCoreMetric,
                                    SfxMapUnit ePresentationMetric,
                                    OUString &rText,
                                    const IntlWrapper * pIntlWrapper = 0 ) const;

    virtual sal_uInt16       GetVersion( sal_uInt16 nFileFormatVersion ) const;
    virtual bool             ScaleMetrics( long lMult, long lDiv );
    virtual bool             HasMetrics() const;

    virtual bool             QueryValue( com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId = 0 ) const;
    virtual bool             PutValue( const com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId = 0 );

    virtual SfxPoolItem*     Create( SvStream &, sal_uInt16 nItemVersion ) const;
    virtual SvStream&        Store( SvStream &, sal_uInt16 nItemVersion ) const;
    virtual SfxPoolItem*     Clone( SfxItemPool *pPool = 0 ) const = 0;

    sal_uLong                GetRefCount() const { return m_nRefCount; }
    inline sal_uInt16        GetKind() const { return m_nKind; }

    /** Read in a Unicode string from a streamed byte string representation.

        @param rStream  Some (input) stream.  Its Stream/TargetCharSets must
        be set to correct values!

        @return  On success, returns the reconstructed Unicode string.
     */
    static OUString readByteString(SvStream & rStream);

    /** Write a byte string representation of a Unicode string into a stream.

        @param rStream  Some (output) stream.  Its Stream/TargetCharSets must
        be set to correct values!

        @param rString  Some Unicode string.
     */
    static void writeByteString(SvStream & rStream,
                                const OUString& rString);

    /** Read in a Unicode string from either a streamed Unicode or byte string
        representation.

        @param rStream  Some (input) stream.  If bUnicode is false, its
        Stream/TargetCharSets must be set to correct values!

        @param bUnicode  Whether to read in a stream Unicode (true) or byte
        string (false) representation.

        @return          On success, returns the reconstructed Unicode string.
     */
    static OUString readUnicodeString(SvStream & rStream, bool bUnicode);

    /** Write a Unicode string representation of a Unicode string into a
        stream.

        @param rStream  Some (output) stream.

        @param rString  Some Unicode string.
     */
    static void writeUnicodeString(SvStream & rStream,
                                   const OUString& rString);

private:
    SfxPoolItem&             operator=( const SfxPoolItem& );    // not implemented!!
};

inline void SfxPoolItem::SetRefCount( sal_uLong n )
{
    m_nRefCount = n;
    m_nKind = 0;
}

inline void SfxPoolItem::SetKind( sal_uInt16 n )
{
    m_nRefCount = SFX_ITEMS_SPECIAL;
    m_nKind = n;
}

inline sal_uLong SfxPoolItem::AddRef( sal_uLong n ) const
{
    DBG_ASSERT(m_nRefCount <= SFX_ITEMS_MAXREF, "AddRef with non-Pool-Item");
    DBG_ASSERT(ULONG_MAX - m_nRefCount > n, "AddRef: refcount overflow");
    return (const_cast<SfxPoolItem *>(this)->m_nRefCount += n);
}

inline sal_uLong SfxPoolItem::ReleaseRef( sal_uLong n ) const
{
    DBG_ASSERT(m_nRefCount <= SFX_ITEMS_MAXREF, "AddRef with non-Pool-Item");
    DBG_ASSERT(m_nRefCount >= n, "AddRef: refcount underflow");
    const_cast<SfxPoolItem *>(this)->m_nRefCount -= n;
    return m_nRefCount;
}

inline bool IsPoolDefaultItem(const SfxPoolItem *pItem )
{
    return pItem && pItem->GetKind() == SFX_ITEMS_POOLDEFAULT;
}

inline bool IsStaticDefaultItem(const SfxPoolItem *pItem )
{
    return pItem && pItem->GetKind() == SFX_ITEMS_STATICDEFAULT;
}

inline bool IsDefaultItem( const SfxPoolItem *pItem )
{
    return pItem && pItem->GetKind() >= SFX_ITEMS_STATICDEFAULT;
}

inline bool IsPooledItem( const SfxPoolItem *pItem )
{
    return pItem && pItem->GetRefCount() > 0 && pItem->GetRefCount() <= SFX_ITEMS_MAXREF;
}

inline bool IsInvalidItem(const SfxPoolItem *pItem)
{
    return pItem == (SfxPoolItem *)-1;
}

class SVL_DLLPUBLIC SfxVoidItem: public SfxPoolItem
{
    SfxVoidItem & operator=( const SfxVoidItem& ); // not implemented.
public:
                            TYPEINFO_OVERRIDE();
                            explicit SfxVoidItem( sal_uInt16 nWhich );
                            SfxVoidItem( sal_uInt16 nWhich, SvStream & );
                            SfxVoidItem( const SfxVoidItem& );
                            virtual ~SfxVoidItem();

    virtual bool            operator==( const SfxPoolItem& ) const SAL_OVERRIDE;

    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                    SfxMapUnit eCoreMetric,
                                    SfxMapUnit ePresMetric,
                                    OUString &rText,
                                    const IntlWrapper * = 0 ) const SAL_OVERRIDE;

    // create a copy of itself
    virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const SAL_OVERRIDE;
            void            SetWhich(sal_uInt16 nWh) { m_nWhich = nWh; }
};

class SVL_DLLPUBLIC SfxSetItem: public SfxPoolItem
{
    SfxItemSet              *pSet;

    SfxSetItem & operator=( const SfxSetItem& ); // not implemented.

public:
                            TYPEINFO_OVERRIDE();
                            SfxSetItem( sal_uInt16 nWhich, SfxItemSet *pSet );
                            SfxSetItem( sal_uInt16 nWhich, const SfxItemSet &rSet );
                            SfxSetItem( const SfxSetItem&, SfxItemPool *pPool = 0 );
                            virtual ~SfxSetItem();

    virtual bool            operator==( const SfxPoolItem& ) const SAL_OVERRIDE;

    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                    SfxMapUnit eCoreMetric,
                                    SfxMapUnit ePresMetric,
                                    OUString &rText,
                                    const IntlWrapper * = 0 ) const SAL_OVERRIDE;

    // create a copy of itself
    virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const SAL_OVERRIDE = 0;
    virtual SfxPoolItem*    Create(SvStream &, sal_uInt16 nVersion) const SAL_OVERRIDE = 0;
    virtual SvStream&       Store(SvStream &, sal_uInt16 nVer) const SAL_OVERRIDE;

    const SfxItemSet&       GetItemSet() const
                            { return *pSet; }
    SfxItemSet&             GetItemSet()
                            { return *pSet; }
};

// Handle class for PoolItems

class SVL_DLLPUBLIC SfxItemHandle
{
    sal_uInt16      *pRef;
    SfxPoolItem     *pItem;
public:
    explicit SfxItemHandle( SfxPoolItem& );
    SfxItemHandle( const SfxItemHandle& );
    ~SfxItemHandle();

    const SfxItemHandle &operator=(const SfxItemHandle &);
    const SfxPoolItem &GetItem() const { return *pItem; }
};

DECL_PTRHINT(SVL_DLLPUBLIC, SfxPoolItemHint, SfxPoolItem);

#endif // INCLUDED_SVL_POOLITEM_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>remove unused SfxPoolItem::Delete_Impl method<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */
#ifndef INCLUDED_SVL_POOLITEM_HXX
#define INCLUDED_SVL_POOLITEM_HXX

#include <svl/svldllapi.h>
#include <com/sun/star/uno/Any.hxx>

#include <sal/config.h>
#include <tools/rtti.hxx>
#include <limits.h>
#include <tools/solar.h>
#include <tools/debug.hxx>
#include <svl/hint.hxx>

typedef long SfxArgumentError;

class SbxVariable;
class SbxObject;
class SvStream;
class Color;
class IntlWrapper;

namespace com { namespace sun { namespace star { namespace uno { class Any; } } } }

static const sal_uInt32 SFX_ITEMS_DIRECT=   0xffffffff;
static const sal_uInt32 SFX_ITEMS_NULL=     0xfffffff0;  // instead StoreSurrogate
static const sal_uInt32 SFX_ITEMS_DEFAULT=  0xfffffffe;

#define SFX_ITEMS_POOLDEFAULT               0xffff
#define SFX_ITEMS_STATICDEFAULT             0xfffe
#define SFX_ITEMS_DELETEONIDLE              0xfffd

#define SFX_ITEMS_OLD_MAXREF                0xffef
#define SFX_ITEMS_MAXREF                    0xfffffffe
#define SFX_ITEMS_SPECIAL                   0xffffffff

#define CONVERT_TWIPS                       0x80    //Uno-Konvertierung fuer Massangaben (fuer MemberId)

// UNO3 shortcuts

// warning, if there is no boolean inside the any this will always return the value false
inline bool Any2Bool( const ::com::sun::star::uno::Any&rValue )
{
    bool nValue = false;
    if( rValue.hasValue() )
    {
        if( rValue.getValueType() == ::getCppuBooleanType() )
        {
            nValue = *(sal_Bool*)rValue.getValue();
        }
        else
        {
            sal_Int32 nNum = 0;
            if( rValue >>= nNum )
                nValue = nNum != 0;
        }
    }

    return nValue;
}

inline ::com::sun::star::uno::Any Bool2Any( bool bValue )
{
    return ::com::sun::star::uno::Any( &bValue, ::getCppuBooleanType() );
}

//! Notloesung!!!
enum SfxFieldUnit
{
    SFX_FUNIT_NONE, SFX_FUNIT_MM, SFX_FUNIT_CM, SFX_FUNIT_M, SFX_FUNIT_KM,
    SFX_FUNIT_TWIP, SFX_FUNIT_POINT, SFX_FUNIT_PICA,
    SFX_FUNIT_INCH, SFX_FUNIT_FOOT, SFX_FUNIT_MILE, SFX_FUNIT_CHAR, SFX_FUNIT_LINE, SFX_FUNIT_CUSTOM
};

enum SfxMapUnit
{
    SFX_MAPUNIT_100TH_MM,
    SFX_MAPUNIT_10TH_MM,
    SFX_MAPUNIT_MM,
    SFX_MAPUNIT_CM,
    SFX_MAPUNIT_1000TH_INCH,
    SFX_MAPUNIT_100TH_INCH,
    SFX_MAPUNIT_10TH_INCH,
    SFX_MAPUNIT_INCH,
    SFX_MAPUNIT_POINT,
    SFX_MAPUNIT_TWIP,
    SFX_MAPUNIT_PIXEL,
    SFX_MAPUNIT_SYSFONT,
    SFX_MAPUNIT_APPFONT,
    SFX_MAPUNIT_RELATIVE,
    SFX_MAPUNIT_ABSOLUTE
};

enum SfxItemPresentation

/*  [Beschreibung]

    Die Werte dieses Enums bezeichnen den Grad der textuellen
    Presentation eines Items nach Aufruf der virtuellen Methode
    <SfxPoolItem::GetPresentation()const>.
*/

{
    SFX_ITEM_PRESENTATION_NONE,
    SFX_ITEM_PRESENTATION_NAMELESS,
    SFX_ITEM_PRESENTATION_COMPLETE
};

typedef sal_uInt16 SfxItemState;

#define SFX_ITEM_UNKNOWN    0x0000

#define SFX_ITEM_DISABLED   0x0001
#define SFX_ITEM_READONLY   0x0002

#define SFX_ITEM_DONTCARE   0x0010
#define SFX_ITEM_DEFAULT    0x0020
#define SFX_ITEM_SET        0x0030

// old stuff - dont use!!!
#define SFX_ITEM_AVAILABLE  SFX_ITEM_DEFAULT
#define SFX_ITEM_OFF        SFX_ITEM_DEFAULT
#define SFX_ITEM_ON         SFX_ITEM_SET

class SvXMLUnitConverter;
class SfxItemPool;
class SfxItemSet;

class SVL_DLLPUBLIC SfxPoolItem
{
friend class SfxItemPool;
friend class SfxItemDesruptor_Impl;
friend class SfxItemPoolCache;
friend class SfxItemSet;
friend class SfxVoidItem;

    sal_uLong   m_nRefCount;
    sal_uInt16  m_nWhich;
    sal_uInt16  m_nKind;

private:
    inline void              SetRefCount( sal_uLong n );
    inline void              SetKind( sal_uInt16 n );
public:
    inline sal_uLong         AddRef( sal_uLong n = 1 ) const;
private:
    inline sal_uLong         ReleaseRef( sal_uLong n = 1 ) const;

protected:
                             explicit SfxPoolItem( sal_uInt16 nWhich = 0 );
                             SfxPoolItem( const SfxPoolItem& );

public:
                             TYPEINFO();
    virtual                  ~SfxPoolItem();

    void                     SetWhich( sal_uInt16 nId ) { m_nWhich = nId; }
    sal_uInt16               Which() const { return m_nWhich; }
    virtual bool             operator==( const SfxPoolItem& ) const = 0;
    bool                     operator!=( const SfxPoolItem& rItem ) const
                             { return !(*this == rItem); }
    virtual int              Compare( const SfxPoolItem &rWith ) const;
    virtual int              Compare( const SfxPoolItem &rWith, const IntlWrapper& rIntlWrapper ) const;

    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePresentation,
                                    SfxMapUnit eCoreMetric,
                                    SfxMapUnit ePresentationMetric,
                                    OUString &rText,
                                    const IntlWrapper * pIntlWrapper = 0 ) const;

    virtual sal_uInt16       GetVersion( sal_uInt16 nFileFormatVersion ) const;
    virtual bool             ScaleMetrics( long lMult, long lDiv );
    virtual bool             HasMetrics() const;

    virtual bool             QueryValue( com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId = 0 ) const;
    virtual bool             PutValue( const com::sun::star::uno::Any& rVal, sal_uInt8 nMemberId = 0 );

    virtual SfxPoolItem*     Create( SvStream &, sal_uInt16 nItemVersion ) const;
    virtual SvStream&        Store( SvStream &, sal_uInt16 nItemVersion ) const;
    virtual SfxPoolItem*     Clone( SfxItemPool *pPool = 0 ) const = 0;

    sal_uLong                GetRefCount() const { return m_nRefCount; }
    inline sal_uInt16        GetKind() const { return m_nKind; }

    /** Read in a Unicode string from a streamed byte string representation.

        @param rStream  Some (input) stream.  Its Stream/TargetCharSets must
        be set to correct values!

        @return  On success, returns the reconstructed Unicode string.
     */
    static OUString readByteString(SvStream & rStream);

    /** Write a byte string representation of a Unicode string into a stream.

        @param rStream  Some (output) stream.  Its Stream/TargetCharSets must
        be set to correct values!

        @param rString  Some Unicode string.
     */
    static void writeByteString(SvStream & rStream,
                                const OUString& rString);

    /** Read in a Unicode string from either a streamed Unicode or byte string
        representation.

        @param rStream  Some (input) stream.  If bUnicode is false, its
        Stream/TargetCharSets must be set to correct values!

        @param bUnicode  Whether to read in a stream Unicode (true) or byte
        string (false) representation.

        @return          On success, returns the reconstructed Unicode string.
     */
    static OUString readUnicodeString(SvStream & rStream, bool bUnicode);

    /** Write a Unicode string representation of a Unicode string into a
        stream.

        @param rStream  Some (output) stream.

        @param rString  Some Unicode string.
     */
    static void writeUnicodeString(SvStream & rStream,
                                   const OUString& rString);

private:
    SfxPoolItem&             operator=( const SfxPoolItem& );    // not implemented!!
};

inline void SfxPoolItem::SetRefCount( sal_uLong n )
{
    m_nRefCount = n;
    m_nKind = 0;
}

inline void SfxPoolItem::SetKind( sal_uInt16 n )
{
    m_nRefCount = SFX_ITEMS_SPECIAL;
    m_nKind = n;
}

inline sal_uLong SfxPoolItem::AddRef( sal_uLong n ) const
{
    DBG_ASSERT(m_nRefCount <= SFX_ITEMS_MAXREF, "AddRef with non-Pool-Item");
    DBG_ASSERT(ULONG_MAX - m_nRefCount > n, "AddRef: refcount overflow");
    return (const_cast<SfxPoolItem *>(this)->m_nRefCount += n);
}

inline sal_uLong SfxPoolItem::ReleaseRef( sal_uLong n ) const
{
    DBG_ASSERT(m_nRefCount <= SFX_ITEMS_MAXREF, "AddRef with non-Pool-Item");
    DBG_ASSERT(m_nRefCount >= n, "AddRef: refcount underflow");
    const_cast<SfxPoolItem *>(this)->m_nRefCount -= n;
    return m_nRefCount;
}

inline bool IsPoolDefaultItem(const SfxPoolItem *pItem )
{
    return pItem && pItem->GetKind() == SFX_ITEMS_POOLDEFAULT;
}

inline bool IsStaticDefaultItem(const SfxPoolItem *pItem )
{
    return pItem && pItem->GetKind() == SFX_ITEMS_STATICDEFAULT;
}

inline bool IsDefaultItem( const SfxPoolItem *pItem )
{
    return pItem && pItem->GetKind() >= SFX_ITEMS_STATICDEFAULT;
}

inline bool IsPooledItem( const SfxPoolItem *pItem )
{
    return pItem && pItem->GetRefCount() > 0 && pItem->GetRefCount() <= SFX_ITEMS_MAXREF;
}

inline bool IsInvalidItem(const SfxPoolItem *pItem)
{
    return pItem == (SfxPoolItem *)-1;
}

class SVL_DLLPUBLIC SfxVoidItem: public SfxPoolItem
{
    SfxVoidItem & operator=( const SfxVoidItem& ); // not implemented.
public:
                            TYPEINFO_OVERRIDE();
                            explicit SfxVoidItem( sal_uInt16 nWhich );
                            SfxVoidItem( sal_uInt16 nWhich, SvStream & );
                            SfxVoidItem( const SfxVoidItem& );
                            virtual ~SfxVoidItem();

    virtual bool            operator==( const SfxPoolItem& ) const SAL_OVERRIDE;

    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                    SfxMapUnit eCoreMetric,
                                    SfxMapUnit ePresMetric,
                                    OUString &rText,
                                    const IntlWrapper * = 0 ) const SAL_OVERRIDE;

    // create a copy of itself
    virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const SAL_OVERRIDE;
            void            SetWhich(sal_uInt16 nWh) { m_nWhich = nWh; }
};

class SVL_DLLPUBLIC SfxSetItem: public SfxPoolItem
{
    SfxItemSet              *pSet;

    SfxSetItem & operator=( const SfxSetItem& ); // not implemented.

public:
                            TYPEINFO_OVERRIDE();
                            SfxSetItem( sal_uInt16 nWhich, SfxItemSet *pSet );
                            SfxSetItem( sal_uInt16 nWhich, const SfxItemSet &rSet );
                            SfxSetItem( const SfxSetItem&, SfxItemPool *pPool = 0 );
                            virtual ~SfxSetItem();

    virtual bool            operator==( const SfxPoolItem& ) const SAL_OVERRIDE;

    virtual SfxItemPresentation GetPresentation( SfxItemPresentation ePres,
                                    SfxMapUnit eCoreMetric,
                                    SfxMapUnit ePresMetric,
                                    OUString &rText,
                                    const IntlWrapper * = 0 ) const SAL_OVERRIDE;

    // create a copy of itself
    virtual SfxPoolItem*    Clone( SfxItemPool *pPool = 0 ) const SAL_OVERRIDE = 0;
    virtual SfxPoolItem*    Create(SvStream &, sal_uInt16 nVersion) const SAL_OVERRIDE = 0;
    virtual SvStream&       Store(SvStream &, sal_uInt16 nVer) const SAL_OVERRIDE;

    const SfxItemSet&       GetItemSet() const
                            { return *pSet; }
    SfxItemSet&             GetItemSet()
                            { return *pSet; }
};

// Handle class for PoolItems

class SVL_DLLPUBLIC SfxItemHandle
{
    sal_uInt16      *pRef;
    SfxPoolItem     *pItem;
public:
    explicit SfxItemHandle( SfxPoolItem& );
    SfxItemHandle( const SfxItemHandle& );
    ~SfxItemHandle();

    const SfxItemHandle &operator=(const SfxItemHandle &);
    const SfxPoolItem &GetItem() const { return *pItem; }
};

DECL_PTRHINT(SVL_DLLPUBLIC, SfxPoolItemHint, SfxPoolItem);

#endif // INCLUDED_SVL_POOLITEM_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef TAC_ARGUMENT_H
#define TAC_ARGUMENT_H

#include <memory>

#include <boost/variant/variant.hpp>

namespace eddic {

class Variable;

namespace tac {

typedef boost::variant<
        std::shared_ptr<Variable>,
        int
    > Argument;

} //end of tac

} //end of eddic

#endif
<commit_msg>Allow string labels as a valid argument<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#ifndef TAC_ARGUMENT_H
#define TAC_ARGUMENT_H

#include <memory>
#include <string>

#include <boost/variant/variant.hpp>

namespace eddic {

class Variable;

namespace tac {

typedef boost::variant<
        std::shared_ptr<Variable>,  //A symbol
        int,                        //An immediate int value
        std::string                 //An immediate string value : A label
    > Argument;

} //end of tac

} //end of eddic

#endif
<|endoftext|>