<commit_before>#include "common.th"
#include "vga.th"

#define THRESHOLD 64

// The operations later only work if INSET_{ROW,COL}S end up to be a power of 2
#define OFFSET_ROWS 4
#define OFFSET_COLS 8

#define INSET_ROWS (ROWS - (OFFSET_ROWS * 2))
#define INSET_COLS (COLS - (OFFSET_COLS * 2))

_start:
    bare_metal_init()   // TODO this shouldn't be necessary
    prologue

    call(init_display)
    call(disable_cursor)

    // m is generation
    m <- 0

    // i is global video base
    i <- VGA_BASE
    // g is global flip buffer
    g <- rel(databuf)
    // h is global flip buffer bit index
    h <- 0

    c <- i
    d <- 0xa // in our font, a 50% greyscale
    call(blank_area)

    call(randomise_board)
    call(flip)

forever:
    m -> [0x100]

    call(compute)
    call(flip)

    m <- m + 1
    goto(forever)

blank_area:
    pushall(j,n)
    j <- COLS
    j <- j * ROWS
blank_area_loop:
    j <- j - 1
    d -> [c + j]
    n <- j > 0
    jnzrel(n,blank_area_loop)
    popall_ret(j,n)

randomise_board:
    pushall(j,k,c,d,l,n)
    c <- [rel(seed)]
    call(srand)
    j <- (INSET_ROWS - 1)
randomise_board_rows:
    k <- (INSET_COLS - 1)
randomise_board_cols:
    call(rand)
    b <- b >> 23

    l <- b >= THRESHOLD

    b <- j * INSET_COLS + k
    l -> [b + g] // write to buf0

    k <- k - 1
    n <- k >= 0
    jnzrel(n,randomise_board_cols)
    j <- j - 1
    n <- j >= 0
    jnzrel(n,randomise_board_rows)
    popall_ret(j,k,c,d,l,n)

flip:
    pushall(j,k,n)
    j <- (INSET_ROWS - 1)
flip_rows:
    k <- (INSET_COLS - 1)
flip_cols:
    b <- j * INSET_COLS + k
    b <- [b + g] // read from buf0

    b <- b @ h

    n <- 'o' &  b
    b <- ' ' &~ b
    n <- b | n
    c <- j
    d <- k
    call(get_real_offset)
    n -> [b + i] // write to display

    k <- k - 1
    n <- k >= 0
    jnzrel(n,flip_cols)
    j <- j - 1
    n <- j >= 0
    jnzrel(n,flip_rows)

    h <- h ^ 1
    popall_ret(j,k,n)

compute:
    pushall(c,d,e,f,j,k,l)
    j <- (INSET_ROWS - 1)
compute_rows:
    k <- (INSET_COLS - 1)
compute_cols:

    c <- j
    d <- k
    call(get_neighbour_count)
    e <- b

    b <- j * INSET_COLS + k
    f <- [b + g] // read from buf1
    // E is neighbour count, F is current state
    c <- h ^ 1
    n <- f @ c
    n <- - n
    // N is 1 if alive
    e <- e | n // tricky
    e <- e == 3
    n <- 1 << h
    e <- e & n
    f <- f &~ n
    f <- f |  e
    f -> [b + g] // write to buf0

    k <- k - 1
    n <- k >= 0
    jnzrel(n,compute_cols)
    j <- j - 1
    n <- j >= 0
    jnzrel(n,compute_rows)
    popall_ret(c,d,e,f,j,k,l)

get_neighbour_count:
    pushall(e,f,j,k,l,m,n)
    m <- 0
    j <- c
    k <- d

    e <- -1
neighbour_loop_rows:
    f <- -1
neighbour_loop_cols:
    // essentially doing `(a + 31) % 32` to get `a - 1` safely
    c <- j + e + INSET_ROWS ; c <- c & (INSET_ROWS - 1)
    d <- k + f + INSET_COLS ; d <- d & (INSET_COLS - 1)

    b <- c * INSET_COLS + d
    l <- [b + g]
    n <- e | f
    n <- n == 0
    // skip case where e == f == 0 (self)

    c <- h ^ 1
    l <- l @ c ; l <- l &~ n

    m <- m - l

    f <- f + 1
    n <- f <= 1
    jnzrel(n,neighbour_loop_cols)
    e <- e + 1
    n <- e <= 1
    jnzrel(n,neighbour_loop_rows)

    b <- m
    popall_ret(e,f,j,k,l,m,n)

get_real_offset:
    b <- c + OFFSET_ROWS
    b <- b * COLS + d
    b <- b + OFFSET_COLS
    ret

seed: .word 0x99999999

<commit_msg>Inline get_real_offset in conway<commit_after>#include "common.th"
#include "vga.th"

#define THRESHOLD 64

// The operations later only work if INSET_{ROW,COL}S end up to be a power of 2
#define OFFSET_ROWS 4
#define OFFSET_COLS 8

#define INSET_ROWS (ROWS - (OFFSET_ROWS * 2))
#define INSET_COLS (COLS - (OFFSET_COLS * 2))

_start:
    bare_metal_init()   // TODO this shouldn't be necessary
    prologue

    call(init_display)
    call(disable_cursor)

    // m is generation
    m <- 0

    // i is global video base
    i <- VGA_BASE
    // g is global flip buffer
    g <- rel(databuf)
    // h is global flip buffer bit index
    h <- 0

    c <- i
    d <- 0xa // in our font, a 50% greyscale
    call(blank_area)

    call(randomise_board)
    call(flip)

forever:
    m -> [0x100]

    call(compute)
    call(flip)

    m <- m + 1
    goto(forever)

blank_area:
    pushall(j,n)
    j <- COLS
    j <- j * ROWS
blank_area_loop:
    j <- j - 1
    d -> [c + j]
    n <- j > 0
    jnzrel(n,blank_area_loop)
    popall_ret(j,n)

randomise_board:
    pushall(j,k,c,d,l,n)
    c <- [rel(seed)]
    call(srand)
    j <- (INSET_ROWS - 1)
randomise_board_rows:
    k <- (INSET_COLS - 1)
randomise_board_cols:
    call(rand)
    b <- b >> 23

    l <- b >= THRESHOLD

    b <- j * INSET_COLS + k
    l -> [b + g] // write to buf0

    k <- k - 1
    n <- k >= 0
    jnzrel(n,randomise_board_cols)
    j <- j - 1
    n <- j >= 0
    jnzrel(n,randomise_board_rows)
    popall_ret(j,k,c,d,l,n)

flip:
    pushall(j,k,n)
    j <- (INSET_ROWS - 1)
flip_rows:
    k <- (INSET_COLS - 1)
flip_cols:
    b <- j * INSET_COLS + k
    b <- [b + g] // read from buf0

    b <- b @ h

    n <- 'o' &  b
    b <- ' ' &~ b
    n <- b | n

    // convert from inset coordinates to full coordinates
    b <- j + OFFSET_ROWS
    b <- b * COLS + k
    b <- b + OFFSET_COLS
    n -> [b + i] // write to display

    k <- k - 1
    n <- k >= 0
    jnzrel(n,flip_cols)
    j <- j - 1
    n <- j >= 0
    jnzrel(n,flip_rows)

    h <- h ^ 1
    popall_ret(j,k,n)

compute:
    pushall(c,d,e,f,j,k,l)
    j <- (INSET_ROWS - 1)
compute_rows:
    k <- (INSET_COLS - 1)
compute_cols:

    c <- j
    d <- k
    call(get_neighbour_count)
    e <- b

    b <- j * INSET_COLS + k
    f <- [b + g] // read from buf1
    // E is neighbour count, F is current state
    c <- h ^ 1
    n <- f @ c
    n <- - n
    // N is 1 if alive
    e <- e | n // tricky
    e <- e == 3
    n <- 1 << h
    e <- e & n
    f <- f &~ n
    f <- f |  e
    f -> [b + g] // write to buf0

    k <- k - 1
    n <- k >= 0
    jnzrel(n,compute_cols)
    j <- j - 1
    n <- j >= 0
    jnzrel(n,compute_rows)
    popall_ret(c,d,e,f,j,k,l)

get_neighbour_count:
    pushall(e,f,j,k,l,m,n)
    m <- 0
    j <- c
    k <- d

    e <- -1
neighbour_loop_rows:
    f <- -1
neighbour_loop_cols:
    // essentially doing `(a + 31) % 32` to get `a - 1` safely
    c <- j + e + INSET_ROWS ; c <- c & (INSET_ROWS - 1)
    d <- k + f + INSET_COLS ; d <- d & (INSET_COLS - 1)

    b <- c * INSET_COLS + d
    l <- [b + g]
    n <- e | f
    n <- n == 0
    // skip case where e == f == 0 (self)

    c <- h ^ 1
    l <- l @ c ; l <- l &~ n

    m <- m - l

    f <- f + 1
    n <- f <= 1
    jnzrel(n,neighbour_loop_cols)
    e <- e + 1
    n <- e <= 1
    jnzrel(n,neighbour_loop_rows)

    b <- m
    popall_ret(e,f,j,k,l,m,n)

seed: .word 0x99999999

<|endoftext|>


<commit_before>#ifndef ___INANITY_SCRIPT_NP_VALUES_IPP___
#define ___INANITY_SCRIPT_NP_VALUES_IPP___

#include "values.hpp"
#include "Any.hpp"
#include "State.hpp"
#include "../../platform/NpapiPlugin.hpp"
#include "../../Exception.hpp"

BEGIN_INANITY_NP

/*
NPVariants sent as argument to 'From' methods
are not referenced/dereferenced.
Returned NPVariant from 'To' methods should be
released with NPN_ReleaseVariantValue.
*/

template <>
struct Value<bool>
{
	typedef bool ValueType;

	static inline bool From(NPVariant value)
	{
		if(NPVARIANT_IS_VOID(value) || NPVARIANT_IS_NULL(value))
			return false;
		if(NPVARIANT_IS_BOOLEAN(value))
			return NPVARIANT_TO_BOOLEAN(value);
		if(NPVARIANT_IS_INT32(value))
			return !!NPVARIANT_TO_INT32(value);
		if(NPVARIANT_IS_DOUBLE(value))
			return !!NPVARIANT_TO_DOUBLE(value);
		if(NPVARIANT_IS_STRING(value))
			return !!NPVARIANT_TO_STRING(value).UTF8Length;
		if(NPVARIANT_IS_OBJECT(value))
			return !!NPVARIANT_TO_OBJECT(value);
		return false;
	}

	static inline NPVariant To(bool value)
	{
		NPVariant variant;
		BOOLEAN_TO_NPVARIANT(value, variant);
		return variant;
	}
};

template <>
struct Value<int>
{
	typedef int ValueType;

	static inline int From(NPVariant value)
	{
		if(NPVARIANT_IS_BOOLEAN(value))
			return (int)NPVARIANT_TO_BOOLEAN(value);
		if(NPVARIANT_IS_INT32(value))
			return (int)NPVARIANT_TO_INT32(value);
		if(NPVARIANT_IS_DOUBLE(value))
			return (int)NPVARIANT_TO_DOUBLE(value);
		return 0;
	}

	static inline NPVariant To(int value)
	{
		NPVariant variant;
		INT32_TO_NPVARIANT(value, variant);
		return variant;
	}
};

template <>
struct Value<long>
{
	typedef long ValueType;

	static inline long From(NPVariant value)
	{
		if(NPVARIANT_IS_BOOLEAN(value))
			return (long)NPVARIANT_TO_BOOLEAN(value);
		if(NPVARIANT_IS_INT32(value))
			return (long)NPVARIANT_TO_INT32(value);
		if(NPVARIANT_IS_DOUBLE(value))
			return (long)NPVARIANT_TO_DOUBLE(value);
		return 0;
	}

	static inline NPVariant To(long value)
	{
		NPVariant variant;
		INT32_TO_NPVARIANT(value, variant);
		return variant;
	}
};

template <>
struct Value<double>
{
	typedef double ValueType;

	static inline double From(NPVariant value)
	{
		if(NPVARIANT_IS_BOOLEAN(value))
			return (double)NPVARIANT_TO_BOOLEAN(value);
		if(NPVARIANT_IS_INT32(value))
			return (double)NPVARIANT_TO_INT32(value);
		if(NPVARIANT_IS_DOUBLE(value))
			return (double)NPVARIANT_TO_DOUBLE(value);
		return 0;
	}

	static inline NPVariant To(double value)
	{
		NPVariant variant;
		DOUBLE_TO_NPVARIANT(value, variant);
		return variant;
	}
};

template <>
struct Value<float>
{
	typedef float ValueType;

	static inline float From(NPVariant value)
	{
		if(NPVARIANT_IS_BOOLEAN(value))
			return (float)NPVARIANT_TO_BOOLEAN(value);
		if(NPVARIANT_IS_INT32(value))
			return (float)NPVARIANT_TO_INT32(value);
		if(NPVARIANT_IS_DOUBLE(value))
			return (float)NPVARIANT_TO_DOUBLE(value);
		return 0;
	}

	static inline NPVariant To(float value)
	{
		NPVariant variant;
		DOUBLE_TO_NPVARIANT((double)value, variant);
		return variant;
	}
};

template <>
struct Value<unsigned int>
{
	typedef unsigned int ValueType;

	static inline unsigned int From(NPVariant value)
	{
		return (unsigned int)Value<double>::From(value);
	}

	static inline NPVariant To(unsigned int value)
	{
		return Value<double>::To((double)value);
	}
};

template <>
struct Value<unsigned long>
{
	typedef unsigned long ValueType;

	static inline unsigned long From(NPVariant value)
	{
		return (unsigned long)Value<double>::From(value);
	}

	static inline NPVariant To(unsigned long value)
	{
		return Value<double>::To((double)value);
	}
};

template <>
struct Value<long long>
{
	typedef long long ValueType;

	static inline long long From(NPVariant value)
	{
		return (long long)Value<double>::From(value);
	}

	static inline NPVariant To(long long value)
	{
		return Value<double>::To((double)value);
	}
};

template <>
struct Value<unsigned long long>
{
	typedef unsigned long long ValueType;

	static inline unsigned long long From(NPVariant value)
	{
		return (unsigned long long)Value<double>::From(value);
	}

	static inline NPVariant To(unsigned long long value)
	{
		return Value<double>::To((double)value);
	}
};

template <>
struct Value<String>
{
	typedef String ValueType;

	static inline String From(NPVariant value)
	{
		if(NPVARIANT_IS_STRING(value))
		{
			const NPString& str = NPVARIANT_TO_STRING(value);
			return String(str.UTF8Characters, str.UTF8Length);
		}
		return String();
	}

	static inline NPVariant To(const String& value)
	{
		char* mem = (char*)Platform::NpapiPlugin::browserFuncs.memalloc(value.length() + 1);
		memcpy(mem, value.c_str(), value.length() + 1);
		NPVariant variant;
		STRINGN_TO_NPVARIANT(mem, value.length(), variant);
		return variant;
	}
};

template <>
struct Value<const char*>
{
	typedef String ValueType;

	static inline String From(NPVariant value)
	{
		return Value<String>::From(value);
	}

	static inline NPVariant To(const char* value)
	{
		int length = strlen(value);
		char* mem = (char*)Platform::NpapiPlugin::browserFuncs.memalloc(length + 1);
		memcpy(mem, value, length + 1);
		NPVariant variant;
		STRINGN_TO_NPVARIANT(mem, length, variant);
		return variant;
	}
};

template <>
struct Value<const String&>
{
	typedef String ValueType;

	static inline String From(NPVariant value)
	{
		return Value<String>::From(value);
	}
};

template <>
struct Value<ptr<Script::Any> >
{
	typedef ptr<Script::Any> ValueType;

	static inline ptr<Script::Any> From(NPVariant value)
	{
		if(NPVARIANT_IS_STRING(value))
		{
			// copy string
			NPString string = NPVARIANT_TO_STRING(value);
			char* mem = (char*)Platform::NpapiPlugin::browserFuncs.memalloc(string.UTF8Length);
			memcpy(mem, string.UTF8Characters, string.UTF8Length);
			STRINGN_TO_NPVARIANT(mem, string.UTF8Length, value);
		}
		return State::GetCurrent()->CreateAny(value);
	}

	static inline NPVariant To(ptr<Script::Any> value)
	{
		return fast_cast<Any*>(&*value)->GetVariant();
	}
};

template <typename ObjectType>
struct Value<ptr<ObjectType> >
{
	typedef ptr<ObjectType> ValueType;

	static inline ptr<ObjectType> From(NPVariant value)
	{
		// if it's null
		if(NPVARIANT_IS_NULL(value))
			return nullptr;

		// get target class
		MetaProvider::ClassBase* targetClass = Meta::MetaOf<MetaProvider, ObjectType>();

		// it should be an object
		if(!NPVARIANT_IS_OBJECT(value))
			THROW(String("Can't get ") + targetClass->GetFullName() + " from non-object");

		NPObject* npObject = NPVARIANT_TO_OBJECT(value);

		// object should be of registered class
		State* state = State::GetCurrent();
		if(!state->CheckClass(npObject->_class))
			THROW(String("Can't get ") + targetClass->GetFullName() + " from object of non-Inanity class");

		// get object wrapper
		NPObjectWrapper* objectWrapper = static_cast<NPObjectWrapper*>(npObject);

		// check if object was reclaimed
		if(!objectWrapper->object)
			THROW("Object was reclaimed");

		// get class meta
		MetaProvider::ClassBase* classMeta = objectWrapper->GetClassWrapper()->classMeta;

		// check that object can cast to requested type
		if(!classMeta->CanCastTo(Meta::MetaOf<MetaProvider, ObjectType>()))
			THROW(String("Can't cast ") + classMeta->GetFullName() + " to " + targetClass->GetFullName());

		// do cast and return
		return objectWrapper->object.FastCast<ObjectType>();
	}

	static inline NPVariant To(ptr<ObjectType> value)
	{
		if(value)
			return State::GetCurrent()->ConvertObject(
				Meta::MetaOf<MetaProvider, ObjectType>(),
				static_cast<RefCounted*>(&*value));
		else
		{
			NPVariant variant;
			NULL_TO_NPVARIANT(variant);
			return variant;
		}
	}
};

template <typename T>
struct Value
{
	typedef T ValueType;

	static inline T From(NPVariant value)
	{
		return ConvertFromScript<T>(State::GetCurrent()->CreateAny(value));
	}

	static inline NPVariant To(const T& value)
	{
		return fast_cast<Any*>(&*ConvertToScript<T>(State::GetCurrent(), value))->GetVariant();
	}
};

END_INANITY_NP

#endif
<commit_msg>add missing variant of Script::Np::Value for const valuetypes by ref<commit_after>#ifndef ___INANITY_SCRIPT_NP_VALUES_IPP___
#define ___INANITY_SCRIPT_NP_VALUES_IPP___

#include "values.hpp"
#include "Any.hpp"
#include "State.hpp"
#include "../../platform/NpapiPlugin.hpp"
#include "../../Exception.hpp"

BEGIN_INANITY_NP

/*
NPVariants sent as argument to 'From' methods
are not referenced/dereferenced.
Returned NPVariant from 'To' methods should be
released with NPN_ReleaseVariantValue.
*/

template <>
struct Value<bool>
{
	typedef bool ValueType;

	static inline bool From(NPVariant value)
	{
		if(NPVARIANT_IS_VOID(value) || NPVARIANT_IS_NULL(value))
			return false;
		if(NPVARIANT_IS_BOOLEAN(value))
			return NPVARIANT_TO_BOOLEAN(value);
		if(NPVARIANT_IS_INT32(value))
			return !!NPVARIANT_TO_INT32(value);
		if(NPVARIANT_IS_DOUBLE(value))
			return !!NPVARIANT_TO_DOUBLE(value);
		if(NPVARIANT_IS_STRING(value))
			return !!NPVARIANT_TO_STRING(value).UTF8Length;
		if(NPVARIANT_IS_OBJECT(value))
			return !!NPVARIANT_TO_OBJECT(value);
		return false;
	}

	static inline NPVariant To(bool value)
	{
		NPVariant variant;
		BOOLEAN_TO_NPVARIANT(value, variant);
		return variant;
	}
};

template <>
struct Value<int>
{
	typedef int ValueType;

	static inline int From(NPVariant value)
	{
		if(NPVARIANT_IS_BOOLEAN(value))
			return (int)NPVARIANT_TO_BOOLEAN(value);
		if(NPVARIANT_IS_INT32(value))
			return (int)NPVARIANT_TO_INT32(value);
		if(NPVARIANT_IS_DOUBLE(value))
			return (int)NPVARIANT_TO_DOUBLE(value);
		return 0;
	}

	static inline NPVariant To(int value)
	{
		NPVariant variant;
		INT32_TO_NPVARIANT(value, variant);
		return variant;
	}
};

template <>
struct Value<long>
{
	typedef long ValueType;

	static inline long From(NPVariant value)
	{
		if(NPVARIANT_IS_BOOLEAN(value))
			return (long)NPVARIANT_TO_BOOLEAN(value);
		if(NPVARIANT_IS_INT32(value))
			return (long)NPVARIANT_TO_INT32(value);
		if(NPVARIANT_IS_DOUBLE(value))
			return (long)NPVARIANT_TO_DOUBLE(value);
		return 0;
	}

	static inline NPVariant To(long value)
	{
		NPVariant variant;
		INT32_TO_NPVARIANT(value, variant);
		return variant;
	}
};

template <>
struct Value<double>
{
	typedef double ValueType;

	static inline double From(NPVariant value)
	{
		if(NPVARIANT_IS_BOOLEAN(value))
			return (double)NPVARIANT_TO_BOOLEAN(value);
		if(NPVARIANT_IS_INT32(value))
			return (double)NPVARIANT_TO_INT32(value);
		if(NPVARIANT_IS_DOUBLE(value))
			return (double)NPVARIANT_TO_DOUBLE(value);
		return 0;
	}

	static inline NPVariant To(double value)
	{
		NPVariant variant;
		DOUBLE_TO_NPVARIANT(value, variant);
		return variant;
	}
};

template <>
struct Value<float>
{
	typedef float ValueType;

	static inline float From(NPVariant value)
	{
		if(NPVARIANT_IS_BOOLEAN(value))
			return (float)NPVARIANT_TO_BOOLEAN(value);
		if(NPVARIANT_IS_INT32(value))
			return (float)NPVARIANT_TO_INT32(value);
		if(NPVARIANT_IS_DOUBLE(value))
			return (float)NPVARIANT_TO_DOUBLE(value);
		return 0;
	}

	static inline NPVariant To(float value)
	{
		NPVariant variant;
		DOUBLE_TO_NPVARIANT((double)value, variant);
		return variant;
	}
};

template <>
struct Value<unsigned int>
{
	typedef unsigned int ValueType;

	static inline unsigned int From(NPVariant value)
	{
		return (unsigned int)Value<double>::From(value);
	}

	static inline NPVariant To(unsigned int value)
	{
		return Value<double>::To((double)value);
	}
};

template <>
struct Value<unsigned long>
{
	typedef unsigned long ValueType;

	static inline unsigned long From(NPVariant value)
	{
		return (unsigned long)Value<double>::From(value);
	}

	static inline NPVariant To(unsigned long value)
	{
		return Value<double>::To((double)value);
	}
};

template <>
struct Value<long long>
{
	typedef long long ValueType;

	static inline long long From(NPVariant value)
	{
		return (long long)Value<double>::From(value);
	}

	static inline NPVariant To(long long value)
	{
		return Value<double>::To((double)value);
	}
};

template <>
struct Value<unsigned long long>
{
	typedef unsigned long long ValueType;

	static inline unsigned long long From(NPVariant value)
	{
		return (unsigned long long)Value<double>::From(value);
	}

	static inline NPVariant To(unsigned long long value)
	{
		return Value<double>::To((double)value);
	}
};

template <>
struct Value<String>
{
	typedef String ValueType;

	static inline String From(NPVariant value)
	{
		if(NPVARIANT_IS_STRING(value))
		{
			const NPString& str = NPVARIANT_TO_STRING(value);
			return String(str.UTF8Characters, str.UTF8Length);
		}
		return String();
	}

	static inline NPVariant To(const String& value)
	{
		char* mem = (char*)Platform::NpapiPlugin::browserFuncs.memalloc(value.length() + 1);
		memcpy(mem, value.c_str(), value.length() + 1);
		NPVariant variant;
		STRINGN_TO_NPVARIANT(mem, value.length(), variant);
		return variant;
	}
};

template <>
struct Value<const char*>
{
	typedef String ValueType;

	static inline String From(NPVariant value)
	{
		return Value<String>::From(value);
	}

	static inline NPVariant To(const char* value)
	{
		int length = strlen(value);
		char* mem = (char*)Platform::NpapiPlugin::browserFuncs.memalloc(length + 1);
		memcpy(mem, value, length + 1);
		NPVariant variant;
		STRINGN_TO_NPVARIANT(mem, length, variant);
		return variant;
	}
};

template <>
struct Value<const String&>
{
	typedef String ValueType;

	static inline String From(NPVariant value)
	{
		return Value<String>::From(value);
	}
};

template <>
struct Value<ptr<Script::Any> >
{
	typedef ptr<Script::Any> ValueType;

	static inline ptr<Script::Any> From(NPVariant value)
	{
		if(NPVARIANT_IS_STRING(value))
		{
			// copy string
			NPString string = NPVARIANT_TO_STRING(value);
			char* mem = (char*)Platform::NpapiPlugin::browserFuncs.memalloc(string.UTF8Length);
			memcpy(mem, string.UTF8Characters, string.UTF8Length);
			STRINGN_TO_NPVARIANT(mem, string.UTF8Length, value);
		}
		return State::GetCurrent()->CreateAny(value);
	}

	static inline NPVariant To(ptr<Script::Any> value)
	{
		return fast_cast<Any*>(&*value)->GetVariant();
	}
};

template <typename ObjectType>
struct Value<ptr<ObjectType> >
{
	typedef ptr<ObjectType> ValueType;

	static inline ptr<ObjectType> From(NPVariant value)
	{
		// if it's null
		if(NPVARIANT_IS_NULL(value))
			return nullptr;

		// get target class
		MetaProvider::ClassBase* targetClass = Meta::MetaOf<MetaProvider, ObjectType>();

		// it should be an object
		if(!NPVARIANT_IS_OBJECT(value))
			THROW(String("Can't get ") + targetClass->GetFullName() + " from non-object");

		NPObject* npObject = NPVARIANT_TO_OBJECT(value);

		// object should be of registered class
		State* state = State::GetCurrent();
		if(!state->CheckClass(npObject->_class))
			THROW(String("Can't get ") + targetClass->GetFullName() + " from object of non-Inanity class");

		// get object wrapper
		NPObjectWrapper* objectWrapper = static_cast<NPObjectWrapper*>(npObject);

		// check if object was reclaimed
		if(!objectWrapper->object)
			THROW("Object was reclaimed");

		// get class meta
		MetaProvider::ClassBase* classMeta = objectWrapper->GetClassWrapper()->classMeta;

		// check that object can cast to requested type
		if(!classMeta->CanCastTo(Meta::MetaOf<MetaProvider, ObjectType>()))
			THROW(String("Can't cast ") + classMeta->GetFullName() + " to " + targetClass->GetFullName());

		// do cast and return
		return objectWrapper->object.FastCast<ObjectType>();
	}

	static inline NPVariant To(ptr<ObjectType> value)
	{
		if(value)
			return State::GetCurrent()->ConvertObject(
				Meta::MetaOf<MetaProvider, ObjectType>(),
				static_cast<RefCounted*>(&*value));
		else
		{
			NPVariant variant;
			NULL_TO_NPVARIANT(variant);
			return variant;
		}
	}
};

template <typename T>
struct Value
{
	typedef T ValueType;

	static inline T From(NPVariant value)
	{
		return ConvertFromScript<T>(State::GetCurrent()->CreateAny(value));
	}

	static inline NPVariant To(const T& value)
	{
		return fast_cast<Any*>(&*ConvertToScript<T>(State::GetCurrent(), value))->GetVariant();
	}
};

template <typename T>
struct Value<const T&>
{
	typedef T ValueType;

	static inline T From(NPVariant value)
	{
		return ConvertFromScript<T>(State::GetCurrent()->CreateAny(value));
	}

	static inline NPVariant To(const T& value)
	{
		return fast_cast<Any*>(&*ConvertToScript<T>(State::GetCurrent(), value))->GetVariant();
	}
};

END_INANITY_NP

#endif
<|endoftext|>


<commit_before><commit_msg>bugfix<commit_after><|endoftext|>


<commit_before>/** @file
    @brief Implementation

    @date 2014

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>

*/

// Copyright 2014 Sensics, Inc.
//
// Licensed 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
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef __ANDROID__
#define OSVR_DEV_VERBOSE_DISABLE
#endif

// Internal Includes
#include <osvr/PluginHost/RegistrationContext.h>
#include <osvr/PluginHost/SearchPath.h>
#include <osvr/PluginHost/PathConfig.h>
#include "PluginSpecificRegistrationContextImpl.h"
#include <osvr/Util/Verbosity.h>
#include <osvr/Util/Log.h>

// Library/third-party includes
#include <libfunctionality/LoadPlugin.h>
#include <boost/filesystem.hpp>
#include <boost/noncopyable.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/algorithm/string/predicate.hpp>

// Standard includes
#include <algorithm>
#include <iterator>

namespace osvr {
namespace pluginhost {
    static const auto PLUGIN_HOST_LOGGER_NAME = "PluginHost";
    namespace fs = boost::filesystem;

    struct RegistrationContext::Impl : private boost::noncopyable {
        /// constructor - creates and caches the plugin search path
        Impl() : pluginPaths(pluginhost::getPluginSearchPath()) {}

        const std::vector<std::string> pluginPaths;
    };

    RegistrationContext::RegistrationContext()
        : m_impl(new Impl),
          m_logger(util::log::make_logger(PLUGIN_HOST_LOGGER_NAME)) {}

    RegistrationContext::~RegistrationContext() {
        // Reset the plugins in reverse order.
        for (auto &ptr : m_regMap | boost::adaptors::map_values |
                             boost::adaptors::reversed) {
            ptr.reset();
        }
    }

    template <typename MapType>
    static inline bool isPluginLoaded(MapType const &regMap,
                                      std::string const &pluginName) {
        return (regMap.find(pluginName) != end(regMap));
    }

    static inline bool tryLoadingPlugin(libfunc::PluginHandle &plugin,
                                        std::string const &name,
                                        OSVR_PluginRegContext ctx,
                                        bool shouldRethrow = false) {
        auto log = util::log::make_logger(PLUGIN_HOST_LOGGER_NAME);
        log->debug() << "Trying to load a plugin with the name " << name;
        try {
            plugin = libfunc::loadPluginByName(name, ctx);
            return true;
        } catch (std::runtime_error const &e) {
            log->debug() << "Failed: " << e.what();
            if (shouldRethrow) {
                throw;
            }
            return false;
        } catch (...) {
            throw;
        }
    }

    void RegistrationContext::loadPlugin(std::string const &pluginName) {
        if (isPluginLoaded(m_regMap, pluginName)) {
            throw std::runtime_error("Already loaded a plugin named " +
                                     pluginName);
        }

        PluginRegPtr pluginReg(
            PluginSpecificRegistrationContext::create(pluginName));
        pluginReg->setParent(*this);

        bool success = false;
        libfunc::PluginHandle plugin;
        auto ctx = pluginReg->extractOpaquePointer();

        const std::string pluginPathName =
            pluginhost::findPlugin(m_impl->pluginPaths, pluginName);
        if (pluginPathName.empty()) {
            // was the plugin pre-loaded or statically linked? Try loading
            // it by name.
            success = tryLoadingPlugin(plugin, pluginName, ctx);
            if (!success) {
                throw std::runtime_error("Could not find plugin named " +
                                         pluginName);
            }
        }

        if (!success) {
            const auto pluginPathNameNoExt =
                (fs::path(pluginPathName).parent_path() /
                 fs::path(pluginPathName).stem())
                    .generic_string();

            success = tryLoadingPlugin(plugin, pluginPathName, ctx) ||
                      tryLoadingPlugin(plugin, pluginPathNameNoExt, ctx, true);
            if (!success) {
                throw std::runtime_error(
                    "Unusual error occurred trying to load plugin named " +
                    pluginName);
            }
        }
        pluginReg->takePluginHandle(plugin);
        adoptPluginRegistrationContext(pluginReg);
    }

    void RegistrationContext::loadPlugins() {
        // Build a list of all the plugins we can find
        auto pluginPathNames = pluginhost::getAllFilesWithExt(
            m_impl->pluginPaths, OSVR_PLUGIN_EXTENSION);

        // Load all of the non-.manualload plugins
        for (const auto &plugin : pluginPathNames) {
            m_logger->debug() << "Examining plugin '" << plugin << "'...";
            const auto pluginBaseName =
                fs::path(plugin).filename().stem().generic_string();
            if (boost::iends_with(pluginBaseName, OSVR_PLUGIN_IGNORE_SUFFIX)) {
                m_logger->debug() << "Ignoring manual-load plugin: "
                                  << pluginBaseName;
                continue;
            }

            try {
                loadPlugin(pluginBaseName);
                m_logger->info() << "Successfully loaded plugin: "
                                 << pluginBaseName;
            } catch (const std::exception &e) {
                m_logger->warn() << "Failed to load plugin " << pluginBaseName
                                 << ": " << e.what();
            } catch (...) {
                m_logger->warn() << "Failed to load plugin " << pluginBaseName
                                 << ": Unknown error.";
            }
        }
    }

    void RegistrationContext::adoptPluginRegistrationContext(PluginRegPtr ctx) {
        /// This set parent might be a duplicate, but won't be if the plugin reg
        /// ctx is not created by loadPlugin above.
        ctx->setParent(*this);

        m_regMap.insert(std::make_pair(ctx->getName(), ctx));
    }

    void RegistrationContext::triggerHardwareDetect() {
        for (auto &pluginPtr : m_regMap | boost::adaptors::map_values) {
            pluginPtr->triggerHardwareDetectCallbacks();
        }
    }

    void
    RegistrationContext::instantiateDriver(const std::string &pluginName,
                                           const std::string &driverName,
                                           const std::string &params) const {
        auto pluginIt = m_regMap.find(pluginName);
        if (pluginIt == end(m_regMap)) {
            throw std::runtime_error("Could not find plugin named " +
                                     pluginName);
        }
        pluginIt->second->instantiateDriver(driverName, params);
    }

    util::AnyMap &RegistrationContext::data() { return m_data; }

    util::AnyMap const &RegistrationContext::data() const { return m_data; }
} // namespace pluginhost
} // namespace osvr
<commit_msg>Change the message severity of the pluginhost message that makes its way to the console by default<commit_after>/** @file
    @brief Implementation

    @date 2014

    @author
    Sensics, Inc.
    <http://sensics.com/osvr>

*/

// Copyright 2014 Sensics, Inc.
//
// Licensed 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
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef __ANDROID__
#define OSVR_DEV_VERBOSE_DISABLE
#endif

// Internal Includes
#include <osvr/PluginHost/RegistrationContext.h>
#include <osvr/PluginHost/SearchPath.h>
#include <osvr/PluginHost/PathConfig.h>
#include "PluginSpecificRegistrationContextImpl.h"
#include <osvr/Util/Verbosity.h>
#include <osvr/Util/Log.h>

// Library/third-party includes
#include <libfunctionality/LoadPlugin.h>
#include <boost/filesystem.hpp>
#include <boost/noncopyable.hpp>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/adaptor/reversed.hpp>
#include <boost/algorithm/string/predicate.hpp>

// Standard includes
#include <algorithm>
#include <iterator>

namespace osvr {
namespace pluginhost {
    static const auto PLUGIN_HOST_LOGGER_NAME = "PluginHost";
    namespace fs = boost::filesystem;

    struct RegistrationContext::Impl : private boost::noncopyable {
        /// constructor - creates and caches the plugin search path
        Impl() : pluginPaths(pluginhost::getPluginSearchPath()) {}

        const std::vector<std::string> pluginPaths;
    };

    RegistrationContext::RegistrationContext()
        : m_impl(new Impl),
          m_logger(util::log::make_logger(PLUGIN_HOST_LOGGER_NAME)) {}

    RegistrationContext::~RegistrationContext() {
        // Reset the plugins in reverse order.
        for (auto &ptr : m_regMap | boost::adaptors::map_values |
                             boost::adaptors::reversed) {
            ptr.reset();
        }
    }

    template <typename MapType>
    static inline bool isPluginLoaded(MapType const &regMap,
                                      std::string const &pluginName) {
        return (regMap.find(pluginName) != end(regMap));
    }

    static inline bool tryLoadingPlugin(libfunc::PluginHandle &plugin,
                                        std::string const &name,
                                        OSVR_PluginRegContext ctx,
                                        bool shouldRethrow = false) {
        auto log = util::log::make_logger(PLUGIN_HOST_LOGGER_NAME);
        log->debug() << "Trying to load a plugin with the name " << name;
        try {
            plugin = libfunc::loadPluginByName(name, ctx);
            return true;
        } catch (std::runtime_error const &e) {
            log->debug() << "Failed: " << e.what();
            if (shouldRethrow) {
                throw;
            }
            return false;
        } catch (...) {
            throw;
        }
    }

    void RegistrationContext::loadPlugin(std::string const &pluginName) {
        if (isPluginLoaded(m_regMap, pluginName)) {
            throw std::runtime_error("Already loaded a plugin named " +
                                     pluginName);
        }

        PluginRegPtr pluginReg(
            PluginSpecificRegistrationContext::create(pluginName));
        pluginReg->setParent(*this);

        bool success = false;
        libfunc::PluginHandle plugin;
        auto ctx = pluginReg->extractOpaquePointer();

        const std::string pluginPathName =
            pluginhost::findPlugin(m_impl->pluginPaths, pluginName);
        if (pluginPathName.empty()) {
            // was the plugin pre-loaded or statically linked? Try loading
            // it by name.
            success = tryLoadingPlugin(plugin, pluginName, ctx);
            if (!success) {
                throw std::runtime_error("Could not find plugin named " +
                                         pluginName);
            }
        }

        if (!success) {
            const auto pluginPathNameNoExt =
                (fs::path(pluginPathName).parent_path() /
                 fs::path(pluginPathName).stem())
                    .generic_string();

            success = tryLoadingPlugin(plugin, pluginPathName, ctx) ||
                      tryLoadingPlugin(plugin, pluginPathNameNoExt, ctx, true);
            if (!success) {
                throw std::runtime_error(
                    "Unusual error occurred trying to load plugin named " +
                    pluginName);
            }
        }
        pluginReg->takePluginHandle(plugin);
        adoptPluginRegistrationContext(pluginReg);
    }

    void RegistrationContext::loadPlugins() {
        // Build a list of all the plugins we can find
        auto pluginPathNames = pluginhost::getAllFilesWithExt(
            m_impl->pluginPaths, OSVR_PLUGIN_EXTENSION);

        // Load all of the non-.manualload plugins
        for (const auto &plugin : pluginPathNames) {
            m_logger->debug() << "Examining plugin '" << plugin << "'...";
            const auto pluginBaseName =
                fs::path(plugin).filename().stem().generic_string();
            if (boost::iends_with(pluginBaseName, OSVR_PLUGIN_IGNORE_SUFFIX)) {
                m_logger->debug() << "Ignoring manual-load plugin: "
                                  << pluginBaseName;
                continue;
            }

            try {
                loadPlugin(pluginBaseName);
                m_logger->debug() << "Successfully loaded plugin: "
                                 << pluginBaseName;
            } catch (const std::exception &e) {
                m_logger->warn() << "Failed to load plugin " << pluginBaseName
                                 << ": " << e.what();
            } catch (...) {
                m_logger->warn() << "Failed to load plugin " << pluginBaseName
                                 << ": Unknown error.";
            }
        }
    }

    void RegistrationContext::adoptPluginRegistrationContext(PluginRegPtr ctx) {
        /// This set parent might be a duplicate, but won't be if the plugin reg
        /// ctx is not created by loadPlugin above.
        ctx->setParent(*this);

        m_regMap.insert(std::make_pair(ctx->getName(), ctx));
    }

    void RegistrationContext::triggerHardwareDetect() {
        for (auto &pluginPtr : m_regMap | boost::adaptors::map_values) {
            pluginPtr->triggerHardwareDetectCallbacks();
        }
    }

    void
    RegistrationContext::instantiateDriver(const std::string &pluginName,
                                           const std::string &driverName,
                                           const std::string &params) const {
        auto pluginIt = m_regMap.find(pluginName);
        if (pluginIt == end(m_regMap)) {
            throw std::runtime_error("Could not find plugin named " +
                                     pluginName);
        }
        pluginIt->second->instantiateDriver(driverName, params);
    }

    util::AnyMap &RegistrationContext::data() { return m_data; }

    util::AnyMap const &RegistrationContext::data() const { return m_data; }
} // namespace pluginhost
} // namespace osvr
<|endoftext|>


<commit_before>#include "SynthGrid.h"
#include "SDL.h"
#include "ISynth.h"
#include "Renderer.h"
#include "ModularSynth.h"
#include "SynthModule.h"
#include "ModuleSelector.h"
#include "Color.h"
#include <cstdlib>
#include <cstdio>
#include <cmath>

SynthGrid::SynthGrid(EditorState& editorState, ISynth& synth)
	:Editor(editorState, true), mSynth(synth), mMode(IDLE), mSelectedModule(-1)
{
	mModuleSelector = new ModuleSelector(editorState);
}

void SynthGrid::drawWire(Renderer& renderer, int x1, int y1, int x2, int y2, const Color& color) const
{
	const int spacing = 4;
	int dx = x1 - x2, dy = y1 - y2;
	int d = sqrt(dx * dx + dy * dy) / spacing;

	if (d == 0)
		return;

	int px = x1, py = y1;

	for (int i = 1 ; i <= d ; ++i)
	{
		int x = (x2 - x1) * i / d + x1;
		int y = (y2 - y1) * i / d + y1 + sin((float)i/d * M_PI) * d * 2;

		renderer.renderLine(px, py, x, y + 1, Color(0,0,0));
		renderer.renderLine(px, py, x, y, color);

		px = x;
		py = y;
	}
}

void SynthGrid::startMove(int module)
{
	const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));

	// Don't start moving from empty slot

	if (modularSynth.getModule(module) == NULL)
		return;

	mMode = MOVING_MODULE;
	mFromModule = module;
}

void SynthGrid::endMove(int targetModule)
{
	if (mMode != MOVING_MODULE)
		return;

	mMode = IDLE;

	ModularSynth& modularSynth = static_cast<ModularSynth&>(mSynth.getOscillator(0));

	modularSynth.swapModules(mFromModule, targetModule);
}

void SynthGrid::startConnect(int fromModule, int toModule, int fromOutput, int toInput)
{
	mMode = CONNECTING_MODULE;
	mFromModule = fromModule;
	mToModule = toModule;
	mFromOutput = fromOutput;
	mToInput = toInput;
}

void SynthGrid::endConnect(int module, int connector)
{
	if (mMode != CONNECTING_MODULE)
		return;

	mMode = IDLE;

	if (mFromModule != -1)
	{
		mToModule = module;
		mToInput = connector;
	}
	else
	{
		mFromModule = module;
		mFromOutput = connector;
	}
}

SDL_Rect SynthGrid::getConnectorArea(int moduleIndex, int type, int connectorIndex, const SDL_Rect& parent) const
{
	const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));
	const SynthModule* module = modularSynth.getModule(moduleIndex);
	const int connectorSize = 8;

	SDL_Rect area = {0,0,connectorSize,connectorSize};

	if (module)
	{
		SDL_Rect moduleArea = getModuleArea(moduleIndex, parent);
		int c;

		if (type == 0)
			c = module->getNumInputs();
		else
			c = module->getNumOutputs();

		area.x = moduleArea.x + moduleArea.w / 2 + (connectorIndex - c / 2) * moduleArea.w / c;
		area.y = moduleArea.y;

		if (type == 1)
			area.y += moduleArea.h - area.h;
	}

	return area;
}

SDL_Rect SynthGrid::getModuleArea(int index, const SDL_Rect& parent) const
{
	SDL_Rect area = {0, 0, parent.w / gridWidth, parent.h / gridHeight};

	area.x = parent.x + area.w * (index % gridWidth);
	area.y = parent.y + area.h * (index / gridHeight);

	return area;
}

bool SynthGrid::pickModule(int x, int y, const SDL_Rect& area, int& moduleOut, bool includeEmpty)
{
	const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));

	for (int index = 0 ; index < ModularSynth::maxModules ; ++index)
	{
		const SynthModule *module = modularSynth.getModule(index);

		if (includeEmpty || module != NULL)
		{
			SDL_Rect moduleArea = getModuleArea(index, area);
			SDL_Point point = {x,y};

			if (pointInRect(point, moduleArea))
			{
				moduleOut = index;
				return true;
			}
		}
	}

	return false;
}

bool SynthGrid::pickConnector(int x, int y, const SDL_Rect& area, int& moduleOut, int& connectorType, int& connector)
{
	if (!pickModule(x, y, area, moduleOut))
		return false;

	const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));
	const SynthModule *module = modularSynth.getModule(moduleOut);
	SDL_Point point = {x,y};

	for (connectorType = 0 ; connectorType <= 1 ; connectorType++)
	{
		int c;

		if (connectorType == 0)
			c = module->getNumInputs();
		else
			c = module->getNumOutputs();

		for (int i = 0 ; i < c ; ++i)
		{
			if (pointInRect(point, getConnectorArea(moduleOut, connectorType, i, area)))
			{
				connector = i;
				return true;
			}
		}
	}

	return false;
}

void SynthGrid::onDraw(Renderer& renderer, const SDL_Rect& area)
{
	setDirty(false);
	renderer.clearRect(area, Color(0,0,0));

	const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));

	for (int index = 0 ; index < ModularSynth::maxModules ; ++index)
	{
		const SynthModule *module = modularSynth.getModule(index);

		if (module != NULL)
		{
			SDL_Rect moduleArea = getModuleArea(index, area);
			renderer.drawRect(moduleArea, mSelectedModule == index ? Color(255,0,0) : Color(255,255,255));

			SDL_Rect textArea = {moduleArea.x + 2, moduleArea.y + moduleArea.h / 2 - 4, 100, 100};

			renderer.renderText(textArea, Color(255,255,255), module->getName());

			for (int connectorType = 0 ; connectorType <= 1 ; connectorType++)
			{
				int c;

				if (connectorType == 0)
					c = module->getNumInputs();
				else
					c = module->getNumOutputs();

				for (int i = 0 ; i < c ; ++i)
				{
					renderer.drawRect(getConnectorArea(index, connectorType, i, area), Color(255,255,0));
				}
			}
		}
	}

	for (int i = 0 ; i < modularSynth.getNumConnections() ; ++i)
	{
		const SynthConnection& connection = modularSynth.getConnection(i);
		SDL_Rect fromModuleArea = getConnectorArea(connection.fromModule, 1, connection.fromOutput, area);
		SDL_Rect toModuleArea = getConnectorArea(connection.toModule, 0, connection.toInput, area);
		drawWire(renderer, fromModuleArea.x, fromModuleArea.y, toModuleArea.x, toModuleArea.y, Color(255,0,0));
	}

	if (mMode == CONNECTING_MODULE)
	{
		SDL_Rect moduleArea;
		if (mFromModule != -1)
		{
			moduleArea = getConnectorArea(mFromModule, 1, mFromOutput, area);
		}
		else
		{
			moduleArea = getConnectorArea(mToModule, 0, mToInput, area);
		}

		drawWire(renderer, mMouseX, mMouseY, moduleArea.x, moduleArea.y, Color(255, 0,0));
	}
}

bool SynthGrid::onEvent(SDL_Event& event)
{
	if (mModal != NULL)
	{
		setDirty(true);
		return mModal->onEvent(event);
	}

	if (event.type == SDL_MOUSEBUTTONDOWN)
	{
		// Editor base class should probably do this when clicked
		setFocus(this);

		mMouseX = event.button.x;
		mMouseY = event.button.y;

		int moduleOut, connectorType, connector;

		switch (event.button.button)
		{
			case SDL_BUTTON_LEFT:

				// Left button starts module connection mode or module move mode
				// depending on if the user clicks the connector or just the module
				// area.

				if (pickConnector(event.button.x, event.button.y, mThisArea, moduleOut, connectorType, connector))
				{
					ModularSynth& modularSynth = static_cast<ModularSynth&>(mSynth.getOscillator(0));

					if (mMode == CONNECTING_MODULE)
					{
						if ((connectorType == 0 && mToModule == -1) || (connectorType == 1 && mToModule != -1))
						{
							endConnect(moduleOut, connector);
							modularSynth.connectModules(mFromModule, mToModule, mFromOutput, mToInput);
							mSelectedModule = -1;
						}
					}
					else if (mMode == IDLE)
					{
						if (connectorType == 0)
						{
							startConnect(-1, moduleOut, -1, connector);
							modularSynth.detachConnection(moduleOut, 0, connector);
							mSelectedModule = moduleOut;
						}
						else
						{
							startConnect(moduleOut, -1, connector, -1);
							modularSynth.detachConnection(moduleOut, 1, connector);
							mSelectedModule = moduleOut;
						}
					}
				}
				else if (pickModule(event.button.x, event.button.y, mThisArea, moduleOut, true))
				{
					if (mMode == IDLE)
					{
						const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));
						if (modularSynth.getModule(moduleOut) != NULL)
						{
							startMove(moduleOut);
						}
						else
						{
							showNewModuleDialog();
						}

						mSelectedModule = moduleOut;
					}
					else if (mMode == MOVING_MODULE)
					{
						endMove(moduleOut);
						mSelectedModule = -1;
					}

				}

				break;

			case SDL_BUTTON_RIGHT:
				if (mMode == CONNECTING_MODULE || mMode == MOVING_MODULE)
				{
					// Abort connecting/moving
					mMode = IDLE;
				}
				else if (pickModule(event.button.x, event.button.y, mThisArea, moduleOut, true))
				{
					ModularSynth& modularSynth = static_cast<ModularSynth&>(mSynth.getOscillator(0));
					modularSynth.removeModule(moduleOut);
				}

				break;
		}

		return true;
	}

	if (event.type == SDL_MOUSEMOTION)
	{
		mMouseX = event.motion.x;
		mMouseY = event.motion.y;

		if (mMode == CONNECTING_MODULE)
			setDirty(true);
	}

	return false;
}

void SynthGrid::showNewModuleDialog()
{
	setModal(mModuleSelector);
	setFocus(mModuleSelector);
}

void SynthGrid::onFileSelectorEvent(const Editor& moduleSelector, bool accept)
{
	if (accept)
	{
		ModularSynth& modularSynth = static_cast<ModularSynth&>(mSynth.getOscillator(0));
		modularSynth.addModule(mSelectedModule, static_cast<const ModuleSelector&>(moduleSelector).getSelectedModuleId());
	}

	setModal(NULL);
}<commit_msg>Wire coordinate fine tuning<commit_after>#include "SynthGrid.h"
#include "SDL.h"
#include "ISynth.h"
#include "Renderer.h"
#include "ModularSynth.h"
#include "SynthModule.h"
#include "ModuleSelector.h"
#include "Color.h"
#include <cstdlib>
#include <cstdio>
#include <cmath>

SynthGrid::SynthGrid(EditorState& editorState, ISynth& synth)
	:Editor(editorState, true), mSynth(synth), mMode(IDLE), mSelectedModule(-1)
{
	mModuleSelector = new ModuleSelector(editorState);
}

void SynthGrid::drawWire(Renderer& renderer, int x1, int y1, int x2, int y2, const Color& color) const
{
	const int spacing = 8;
	int dx = x1 - x2, dy = y1 - y2;
	int d = sqrt(dx * dx + dy * dy) / spacing;

	if (d == 0)
		return;

	int px = x1, py = y1;

	for (int i = 1 ; i <= d ; ++i)
	{
		int x = (x2 - x1) * i / d + x1;
		int y = (y2 - y1) * i / d + y1 + sin((float)i/d * M_PI) * 16;

		renderer.renderLine(px, py, x, y + 1, Color(0,0,0));
		renderer.renderLine(px, py, x, y, color);

		px = x;
		py = y;
	}
}

void SynthGrid::startMove(int module)
{
	const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));

	// Don't start moving from empty slot

	if (modularSynth.getModule(module) == NULL)
		return;

	mMode = MOVING_MODULE;
	mFromModule = module;
}

void SynthGrid::endMove(int targetModule)
{
	if (mMode != MOVING_MODULE)
		return;

	mMode = IDLE;

	ModularSynth& modularSynth = static_cast<ModularSynth&>(mSynth.getOscillator(0));

	modularSynth.swapModules(mFromModule, targetModule);
}

void SynthGrid::startConnect(int fromModule, int toModule, int fromOutput, int toInput)
{
	mMode = CONNECTING_MODULE;
	mFromModule = fromModule;
	mToModule = toModule;
	mFromOutput = fromOutput;
	mToInput = toInput;
}

void SynthGrid::endConnect(int module, int connector)
{
	if (mMode != CONNECTING_MODULE)
		return;

	mMode = IDLE;

	if (mFromModule != -1)
	{
		mToModule = module;
		mToInput = connector;
	}
	else
	{
		mFromModule = module;
		mFromOutput = connector;
	}
}

SDL_Rect SynthGrid::getConnectorArea(int moduleIndex, int type, int connectorIndex, const SDL_Rect& parent) const
{
	const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));
	const SynthModule* module = modularSynth.getModule(moduleIndex);
	const int connectorSize = 8;

	SDL_Rect area = {0,0,connectorSize,connectorSize};

	if (module)
	{
		SDL_Rect moduleArea = getModuleArea(moduleIndex, parent);
		int c;

		if (type == 0)
			c = module->getNumInputs();
		else
			c = module->getNumOutputs();

		area.x = moduleArea.x + moduleArea.w / 2 + (connectorIndex - c / 2) * moduleArea.w / c - connectorSize / 2;
		area.y = moduleArea.y;

		if (type == 1)
			area.y += moduleArea.h - area.h - 2;
		else
			area.y += 2;
	}

	return area;
}

SDL_Rect SynthGrid::getModuleArea(int index, const SDL_Rect& parent) const
{
	SDL_Rect area = {0, 0, parent.w / gridWidth, parent.h / gridHeight};

	area.x = parent.x + area.w * (index % gridWidth);
	area.y = parent.y + area.h * (index / gridHeight);

	return area;
}

bool SynthGrid::pickModule(int x, int y, const SDL_Rect& area, int& moduleOut, bool includeEmpty)
{
	const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));

	for (int index = 0 ; index < ModularSynth::maxModules ; ++index)
	{
		const SynthModule *module = modularSynth.getModule(index);

		if (includeEmpty || module != NULL)
		{
			SDL_Rect moduleArea = getModuleArea(index, area);
			SDL_Point point = {x,y};

			if (pointInRect(point, moduleArea))
			{
				moduleOut = index;
				return true;
			}
		}
	}

	return false;
}

bool SynthGrid::pickConnector(int x, int y, const SDL_Rect& area, int& moduleOut, int& connectorType, int& connector)
{
	if (!pickModule(x, y, area, moduleOut))
		return false;

	const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));
	const SynthModule *module = modularSynth.getModule(moduleOut);
	SDL_Point point = {x,y};

	for (connectorType = 0 ; connectorType <= 1 ; connectorType++)
	{
		int c;

		if (connectorType == 0)
			c = module->getNumInputs();
		else
			c = module->getNumOutputs();

		for (int i = 0 ; i < c ; ++i)
		{
			if (pointInRect(point, getConnectorArea(moduleOut, connectorType, i, area)))
			{
				connector = i;
				return true;
			}
		}
	}

	return false;
}

void SynthGrid::onDraw(Renderer& renderer, const SDL_Rect& area)
{
	setDirty(false);
	renderer.clearRect(area, Color(0,0,0));

	const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));

	for (int index = 0 ; index < ModularSynth::maxModules ; ++index)
	{
		const SynthModule *module = modularSynth.getModule(index);

		if (module != NULL)
		{
			SDL_Rect moduleArea = getModuleArea(index, area);
			renderer.drawRect(moduleArea, mSelectedModule == index ? Color(255,0,0) : Color(255,255,255));

			SDL_Rect textArea = {moduleArea.x + 2, moduleArea.y + moduleArea.h / 2 - 4, 100, 100};

			renderer.renderText(textArea, Color(255,255,255), module->getName());

			for (int connectorType = 0 ; connectorType <= 1 ; connectorType++)
			{
				int c;

				if (connectorType == 0)
					c = module->getNumInputs();
				else
					c = module->getNumOutputs();

				for (int i = 0 ; i < c ; ++i)
				{
					renderer.drawRect(getConnectorArea(index, connectorType, i, area), Color(255,255,0));
				}
			}
		}
	}

	for (int i = 0 ; i < modularSynth.getNumConnections() ; ++i)
	{
		const SynthConnection& connection = modularSynth.getConnection(i);
		SDL_Rect fromModuleArea = getConnectorArea(connection.fromModule, 1, connection.fromOutput, area);
		SDL_Rect toModuleArea = getConnectorArea(connection.toModule, 0, connection.toInput, area);
		drawWire(renderer, fromModuleArea.x + fromModuleArea.w / 2, fromModuleArea.y + fromModuleArea.h / 2, toModuleArea.x + toModuleArea.w / 2, toModuleArea.y + toModuleArea.h / 2, Color(255,0,0));
	}

	if (mMode == CONNECTING_MODULE)
	{
		SDL_Rect moduleArea;
		if (mFromModule != -1)
		{
			moduleArea = getConnectorArea(mFromModule, 1, mFromOutput, area);
		}
		else
		{
			moduleArea = getConnectorArea(mToModule, 0, mToInput, area);
		}

		drawWire(renderer, mMouseX, mMouseY, moduleArea.x, moduleArea.y, Color(255, 0,0));
	}
}

bool SynthGrid::onEvent(SDL_Event& event)
{
	if (mModal != NULL)
	{
		setDirty(true);
		return mModal->onEvent(event);
	}

	if (event.type == SDL_MOUSEBUTTONDOWN)
	{
		// Editor base class should probably do this when clicked
		setFocus(this);

		mMouseX = event.button.x;
		mMouseY = event.button.y;

		int moduleOut, connectorType, connector;

		switch (event.button.button)
		{
			case SDL_BUTTON_LEFT:

				// Left button starts module connection mode or module move mode
				// depending on if the user clicks the connector or just the module
				// area.

				if (pickConnector(event.button.x, event.button.y, mThisArea, moduleOut, connectorType, connector))
				{
					ModularSynth& modularSynth = static_cast<ModularSynth&>(mSynth.getOscillator(0));

					if (mMode == CONNECTING_MODULE)
					{
						if ((connectorType == 0 && mToModule == -1) || (connectorType == 1 && mToModule != -1))
						{
							endConnect(moduleOut, connector);
							modularSynth.connectModules(mFromModule, mToModule, mFromOutput, mToInput);
							mSelectedModule = -1;
						}
					}
					else if (mMode == IDLE)
					{
						if (connectorType == 0)
						{
							startConnect(-1, moduleOut, -1, connector);
							modularSynth.detachConnection(moduleOut, 0, connector);
							mSelectedModule = moduleOut;
						}
						else
						{
							startConnect(moduleOut, -1, connector, -1);
							modularSynth.detachConnection(moduleOut, 1, connector);
							mSelectedModule = moduleOut;
						}
					}
				}
				else if (pickModule(event.button.x, event.button.y, mThisArea, moduleOut, true))
				{
					if (mMode == IDLE)
					{
						const ModularSynth& modularSynth = static_cast<const ModularSynth&>(mSynth.getOscillator(0));
						if (modularSynth.getModule(moduleOut) != NULL)
						{
							startMove(moduleOut);
						}
						else
						{
							showNewModuleDialog();
						}

						mSelectedModule = moduleOut;
					}
					else if (mMode == MOVING_MODULE)
					{
						endMove(moduleOut);
						mSelectedModule = -1;
					}

				}

				break;

			case SDL_BUTTON_RIGHT:
				if (mMode == CONNECTING_MODULE || mMode == MOVING_MODULE)
				{
					// Abort connecting/moving
					mMode = IDLE;
				}
				else if (pickModule(event.button.x, event.button.y, mThisArea, moduleOut, true))
				{
					ModularSynth& modularSynth = static_cast<ModularSynth&>(mSynth.getOscillator(0));
					modularSynth.removeModule(moduleOut);
				}

				break;
		}

		return true;
	}

	if (event.type == SDL_MOUSEMOTION)
	{
		mMouseX = event.motion.x;
		mMouseY = event.motion.y;

		if (mMode == CONNECTING_MODULE)
			setDirty(true);
	}

	return false;
}

void SynthGrid::showNewModuleDialog()
{
	setModal(mModuleSelector);
	setFocus(mModuleSelector);
}

void SynthGrid::onFileSelectorEvent(const Editor& moduleSelector, bool accept)
{
	if (accept)
	{
		ModularSynth& modularSynth = static_cast<ModularSynth&>(mSynth.getOscillator(0));
		modularSynth.addModule(mSelectedModule, static_cast<const ModuleSelector&>(moduleSelector).getSelectedModuleId());
	}

	setModal(NULL);
}<|endoftext|>


<commit_before><commit_msg>small bug fix<commit_after><|endoftext|>


<commit_before>//
// General:
//      This file is pary of .NET Bridge
//
// Copyright:
//      2010 Jonathan Shore
//	2017 Jonathan Shore and Contributors
//
// License:
//      Licensed 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
//
//      Unless required by applicable law or agreed to in writing, software
//      distributed under the License is distributed on an "AS IS" BASIS,
//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//      See the License for the specific language governing permissions and
//      limitations under the License.
//

// [[Rcpp::depends(BH)]]

#include <Rcpp.h>
#include <cstdlib>
#include "CLRObjectRef.hpp"
#include "CLRApi.hpp"

using namespace std;

//
// GC Handle
//
struct CLRObjectGC
{
    CLRObjectGC(int objectId, CLRApi* api) : ObjectId(objectId), API(api) {}

    int      ObjectId;
    CLRApi*  API;
};

// release object handle
static void ObjectFinalizer (SEXP sptr)
{
     if (TYPEOF(sptr) != EXTPTRSXP)
         throw std::runtime_error ("bad finalizer pointer sent in rDotNet gc()");

     // retrieve .NET GC handle (not really a pointer)
     CLRObjectGC* xgc = (CLRObjectGC*)((void*)R_ExternalPtrAddr (sptr));

     // inform API that object done
     xgc->API->release (xgc->ObjectId);
     delete xgc;
}

// R value associated with this message
RValue CLRObjectRef::rvalue()
{
    return _object;
}

// serialize object to stream
void CLRObjectRef::serialize (BufferedSocketWriter& stream)
{
    CLRMessage::serialize (stream);

    List list(_object);
    SEXP eId = list.attr("ObjectId");
    if (Rf_isNull(eId))
        throw std::runtime_error ("CLRMessage: object reference missing object ID");

    stream.write_int32 (Rcpp::as<int>(eId));
    stream.write_byte(0);
}

// deserialize object from stream
void CLRObjectRef::deserialize (BufferedSocketReader& stream)
{
    List vobj;
    vobj.attr("class") = "rDotNet";

    // object ID
    int objectId = stream.read_int32();
    vobj.attr("ObjectId") = objectId;

    // class name
    if (stream.read_byte() != 0)
        vobj.attr("Classname") = stream.read_string();

    // setup garbage collection
    CLRObjectGC* gc = new CLRObjectGC(objectId, _api);
    SEXP xgc = PROTECT(R_MakeExternalPtr((void*)gc, R_NilValue, R_NilValue));
    vobj.attr("gc") = xgc;

    R_RegisterCFinalizerEx(xgc, ObjectFinalizer, Rboolean::TRUE);

    _object = RValue(Rcpp::wrap(vobj));
    UNPROTECT(1);
}

<commit_msg>fixed RBoolean problem seen on windows<commit_after>//
// General:
//      This file is pary of .NET Bridge
//
// Copyright:
//      2010 Jonathan Shore
//	2017 Jonathan Shore and Contributors
//
// License:
//      Licensed 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
//
//      Unless required by applicable law or agreed to in writing, software
//      distributed under the License is distributed on an "AS IS" BASIS,
//      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//      See the License for the specific language governing permissions and
//      limitations under the License.
//

// [[Rcpp::depends(BH)]]

#include <Rcpp.h>
#include <cstdlib>
#include "CLRObjectRef.hpp"
#include "CLRApi.hpp"

#undef TRUE
#undef FALSE

using namespace std;

//
// GC Handle
//
struct CLRObjectGC
{
    CLRObjectGC(int objectId, CLRApi* api) : ObjectId(objectId), API(api) {}

    int      ObjectId;
    CLRApi*  API;
};

// release object handle
static void ObjectFinalizer (SEXP sptr)
{
     if (TYPEOF(sptr) != EXTPTRSXP)
         throw std::runtime_error ("bad finalizer pointer sent in rDotNet gc()");

     // retrieve .NET GC handle (not really a pointer)
     CLRObjectGC* xgc = (CLRObjectGC*)((void*)R_ExternalPtrAddr (sptr));

     // inform API that object done
     xgc->API->release (xgc->ObjectId);
     delete xgc;
}

// R value associated with this message
RValue CLRObjectRef::rvalue()
{
    return _object;
}

// serialize object to stream
void CLRObjectRef::serialize (BufferedSocketWriter& stream)
{
    CLRMessage::serialize (stream);

    List list(_object);
    SEXP eId = list.attr("ObjectId");
    if (Rf_isNull(eId))
        throw std::runtime_error ("CLRMessage: object reference missing object ID");

    stream.write_int32 (Rcpp::as<int>(eId));
    stream.write_byte(0);
}

// deserialize object from stream
void CLRObjectRef::deserialize (BufferedSocketReader& stream)
{
    List vobj;
    vobj.attr("class") = "rDotNet";

    // object ID
    int objectId = stream.read_int32();
    vobj.attr("ObjectId") = objectId;

    // class name
    if (stream.read_byte() != 0)
        vobj.attr("Classname") = stream.read_string();

    // setup garbage collection
    CLRObjectGC* gc = new CLRObjectGC(objectId, _api);
    SEXP xgc = PROTECT(R_MakeExternalPtr((void*)gc, R_NilValue, R_NilValue));
    vobj.attr("gc") = xgc;

    R_RegisterCFinalizerEx(xgc, ObjectFinalizer, Rboolean::TRUE);

    _object = RValue(Rcpp::wrap(vobj));
    UNPROTECT(1);
}

<|endoftext|>


<commit_before>/*
*
COPYRIGHT AND LICENSE

Copyright (c) 2011 The Regents of the University of California.
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.

3. All advertising materials mentioning features or use of this
software must display the following acknowledgement: This product
includes software developed by the San Diego Supercomputer Center.

4. Neither the names of the Centers nor the names of the contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS
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.
*
*
* Based on the notes by Prof. Ramon Arrowsmith(ramon.arrowsmith@asu.edu)
* Authors: Han S Kim (hskim@cs.ucsd.edu), Sriram Krishnan (sriram@sdsc.edu)
*
*/

#include "GridFile.h"
#include <float.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

GridFile::GridFile(int id, char *_fname, int _size_x, int _size_y)
{
    boost::iostreams::mapped_file mf;
    size_t n = 0;

    ID = id;
    strncpy(fname, _fname, sizeof(fname));
    size_x = _size_x;
    size_y = _size_y;
    inMemory = false;
 }

GridFile::~GridFile()
{
    if(inMemory == true){
        mf.close();
        inMemory = false;
        interp = NULL;
    }

    unlink(fname);

    //cout << "file closed: " << ID << endl;
}

int GridFile::getId()
{
    return ID;
}

// memory map
int GridFile::map()
{
    boost::iostreams::mapped_file_params params;
    params.path = fname;
    params.new_file_size = sizeof(GridPoint) * size_x * size_y;
    params.mode = boost::iostreams::mapped_file::readwrite;

    try {
        mf.open(params);
        interp = (GridPoint *) mf.data();
    }
    catch(std::exception& e) {
        fprintf(stderr, "mmap error %d(%s) \n", errno, strerror(errno));
        return -1;
    }
    inMemory = true;

    // initialize every point in the file
    GridPoint init_value = {DBL_MAX, -DBL_MAX, 0, 0, 0, 0, 0, 0};
    for(int i = 0; i < size_x * size_y; i++)
        memcpy(interp + sizeof(GridPoint)*i, &init_value, sizeof(GridPoint));
    cout << ID << ". file size: " << params.new_file_size << endl;

    return 0;
}

int GridFile::unmap()
{
    // have to delete previous information??
    // have to overwrite

    // we can track the changes but that scheme requires memory usage.
    // But our main goal is to fully utilize memory.

    if(interp != NULL)
    {
        mf.close();
	    inMemory = false;
	    interp = NULL;
    }

    return 0;
}

bool GridFile::isInMemory()
{
    return inMemory;
}

unsigned int GridFile::getMemSize()
{
    return size_x * size_y * sizeof(GridPoint);
}
<commit_msg>Storing memory-mapping options in the correct struct member.<commit_after>/*
*
COPYRIGHT AND LICENSE

Copyright (c) 2011 The Regents of the University of California.
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.

3. All advertising materials mentioning features or use of this
software must display the following acknowledgement: This product
includes software developed by the San Diego Supercomputer Center.

4. Neither the names of the Centers nor the names of the contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS
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.
*
*
* Based on the notes by Prof. Ramon Arrowsmith(ramon.arrowsmith@asu.edu)
* Authors: Han S Kim (hskim@cs.ucsd.edu), Sriram Krishnan (sriram@sdsc.edu)
*
*/

#include "GridFile.h"
#include <float.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

GridFile::GridFile(int id, char *_fname, int _size_x, int _size_y)
{
    boost::iostreams::mapped_file mf;
    size_t n = 0;

    ID = id;
    strncpy(fname, _fname, sizeof(fname));
    size_x = _size_x;
    size_y = _size_y;
    inMemory = false;
 }

GridFile::~GridFile()
{
    if(inMemory == true){
        mf.close();
        inMemory = false;
        interp = NULL;
    }

    unlink(fname);

    //cout << "file closed: " << ID << endl;
}

int GridFile::getId()
{
    return ID;
}

// memory map
int GridFile::map()
{
    boost::iostreams::mapped_file_params params;
    params.path = fname;
    params.new_file_size = sizeof(GridPoint) * size_x * size_y;
    params.flags = boost::iostreams::mapped_file::readwrite;

    try {
        mf.open(params);
        interp = (GridPoint *) mf.data();
    }
    catch(std::exception& e) {
        fprintf(stderr, "mmap error %d(%s) \n", errno, strerror(errno));
        return -1;
    }
    inMemory = true;

    // initialize every point in the file
    GridPoint init_value = {DBL_MAX, -DBL_MAX, 0, 0, 0, 0, 0, 0};
    for(int i = 0; i < size_x * size_y; i++)
        memcpy(interp + sizeof(GridPoint)*i, &init_value, sizeof(GridPoint));
    cout << ID << ". file size: " << params.new_file_size << endl;

    return 0;
}

int GridFile::unmap()
{
    // have to delete previous information??
    // have to overwrite

    // we can track the changes but that scheme requires memory usage.
    // But our main goal is to fully utilize memory.

    if(interp != NULL)
    {
        mf.close();
	    inMemory = false;
	    interp = NULL;
    }

    return 0;
}

bool GridFile::isInMemory()
{
    return inMemory;
}

unsigned int GridFile::getMemSize()
{
    return size_x * size_y * sizeof(GridPoint);
}
<|endoftext|>


<commit_before>//#include <boost/noncopyable.hpp>
//#include <boost/python.hpp>

//class pyinit: boost::noncopyable {
//    public:
//        pyinit(int initsigs = 1) {
//            assert(initsigs == 0 || initsigs == 1);
//            Py_InitializeEx(initsigs);
//        }
//        ~pyinit(){};
//
//        bool isInitialized() {
//            return Py_IsInitialized();
//        }
//        const char* version() {
//            return Py_GetVersion();
//        }
//};
//
//int main() {
//    pyinit pinit;
//
//    python::list l;
//    l.append("edony");
//    l.append(12);
//
//    cout << len(l) << endl;
//}
//#cat test.cpp
#include <boost/lexical_cast.hpp>
#include <iostream>

int main()
{
    using boost::lexical_cast;
    int a= lexical_cast<int>("123456");
    double b = lexical_cast<double>("123.456");
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    return 0;
}
<commit_msg>test boost python<commit_after>#include <boost/noncopyable.hpp>
#include <boost/python.hpp>
#include <iostream>

using namespace std;
using namespace boost;

class pyinit: boost::noncopyable {
    public:
        pyinit(int initsigs = 1) {
            assert(initsigs == 0 || initsigs == 1);
            Py_InitializeEx(initsigs);
        }
        ~pyinit(){};

        bool isInitialized() {
            return Py_IsInitialized();
        }
        const char* version() {
            return Py_GetVersion();
        }
};

int main() {
    pyinit pinit;

    boost::python::list l;
    l.append("edony");
    l.append(12);

    cout << boost::python::len(l) << endl;
}
//#cat test.cpp
//#include <boost/lexical_cast.hpp>
//#include <iostream>
//
//int main()
//{
//    using boost::lexical_cast;
//    int a= lexical_cast<int>("123456");
//    double b = lexical_cast<double>("123.456");
//    std::cout << a << std::endl;
//    std::cout << b << std::endl;
//    return 0;
//}
<|endoftext|>


<commit_before>#include "cellmlplugin.h"
#include "coreutils.h"

#include "CellMLBootstrap.hpp"
#include "IfaceCellML_APISPEC.hxx"
#include "cellml-api-cxx-support.hpp"

#include <QDebug>
#include <QDir>
#include <QUrl>

namespace OpenCOR {
namespace CellML {

PLUGININFO_FUNC CellMLPluginInfo()
{
    Descriptions descriptions;

    descriptions.insert("en", "A plugin to use the CellML API");
    descriptions.insert("fr", "Une extension pour utiliser l'API CellML");

    return PluginInfo(PluginInfo::V001,
                      PluginInfo::General,
                      PluginInfo::Api,
                      false,
                      QStringList(),
                      descriptions);
}

Q_EXPORT_PLUGIN2(CellML, CellMLPlugin)

void CellMLPlugin::initialize()
{
    // Fetch a bootstrap object

    RETURN_INTO_OBJREF(cbs, iface::cellml_api::CellMLBootstrap,
                       CreateCellMLBootstrap());

    // Retrieve the model loader

    RETURN_INTO_OBJREF(ml, iface::cellml_api::DOMModelLoader,
                       cbs->modelLoader());

    // Load our test CellML model and return its cmeta:id
    // Note: we do this within a try...catch statement since we might get an
    //       exception...

    QString testCellmlModelFileName = QDir::tempPath()+QDir::separator()+"test_cellml_model.cellml";

    Core::saveResourceAs(":test_cellml_model", testCellmlModelFileName);

    try {
        RETURN_INTO_OBJREF(model, iface::cellml_api::Model,
                           ml->loadFromURL(QUrl::fromLocalFile(testCellmlModelFileName).toString().toStdWString().c_str()));
        RETURN_INTO_WSTRING(cmid, model->cmetaId());

        qDebug("The model's cmeta:id is '%s'.", QString::fromStdWString(cmid).toLatin1().constData());
    } catch (iface::cellml_api::CellMLException& e) {
        RETURN_INTO_WSTRING(msg, ml->lastErrorMessage());

        qDebug("An error occurred while loading the mode: %s.", QString::fromStdWString(msg).toLatin1().constData());
    }

    QFile::remove(testCellmlModelFileName);
}

QList<FileType> CellMLPlugin::fileTypes() const
{
    // Return the CellML file type that the CellML plugin supports

    return QList<FileType>() << FileType(qobject_cast<FileInterface *>(this),
                                         CellmlMimeType, "cellml");
}

QString CellMLPlugin::fileTypeDescription(const QString &mMimeType) const
{
    // Return the description for the requested Mime type, that is as long as it
    // is for the CellML Mime type

    if (!mMimeType.compare(CellmlMimeType))
        return tr("CellML File");
    else
        // Not a Mime type that we can recognise, so...

        return FileInterface::fileTypeDescription(mMimeType);
}

} }
<commit_msg>Minor refactoring.<commit_after>#include "cellmlplugin.h"
#include "coreutils.h"

#include "CellMLBootstrap.hpp"
#include "IfaceCellML_APISPEC.hxx"
#include "cellml-api-cxx-support.hpp"

#include <QDebug>
#include <QDir>
#include <QUrl>

namespace OpenCOR {
namespace CellML {

PLUGININFO_FUNC CellMLPluginInfo()
{
    Descriptions descriptions;

    descriptions.insert("en", "A plugin to use the CellML API");
    descriptions.insert("fr", "Une extension pour utiliser l'API CellML");

    return PluginInfo(PluginInfo::V001,
                      PluginInfo::General,
                      PluginInfo::Api,
                      false,
                      QStringList(),
                      descriptions);
}

Q_EXPORT_PLUGIN2(CellML, CellMLPlugin)

void CellMLPlugin::initialize()
{
    // Fetch a bootstrap object

    RETURN_INTO_OBJREF(cbs, iface::cellml_api::CellMLBootstrap,
                       CreateCellMLBootstrap());

    // Retrieve the model loader

    RETURN_INTO_OBJREF(ml, iface::cellml_api::DOMModelLoader,
                       cbs->modelLoader());

    // Load our test CellML model and return its cmeta:id
    // Note: we do this within a try...catch statement since we might get an
    //       exception...

    QString testCellmlModelFileName = QDir::tempPath()+QDir::separator()+"test_cellml_model.cellml";

    Core::saveResourceAs(":test_cellml_model", testCellmlModelFileName);

    try {
        qDebug("Loading the CellML model...");

        RETURN_INTO_OBJREF(model, iface::cellml_api::Model,
                           ml->loadFromURL(QUrl::fromLocalFile(testCellmlModelFileName).toString().toStdWString().c_str()));

        qDebug("Retrieving the CellML model's cmeta:id...");

        RETURN_INTO_WSTRING(cmid, model->cmetaId());

        qDebug("    ---> %s", QString::fromStdWString(cmid).toLatin1().constData());

        qDebug("All done...");
    } catch (iface::cellml_api::CellMLException& e) {
        RETURN_INTO_WSTRING(msg, ml->lastErrorMessage());

        qDebug("ERROR: %s.", QString::fromStdWString(msg).toLatin1().constData());
    }

    QFile::remove(testCellmlModelFileName);
}

QList<FileType> CellMLPlugin::fileTypes() const
{
    // Return the CellML file type that the CellML plugin supports

    return QList<FileType>() << FileType(qobject_cast<FileInterface *>(this),
                                         CellmlMimeType, "cellml");
}

QString CellMLPlugin::fileTypeDescription(const QString &mMimeType) const
{
    // Return the description for the requested Mime type, that is as long as it
    // is for the CellML Mime type

    if (!mMimeType.compare(CellmlMimeType))
        return tr("CellML File");
    else
        // Not a Mime type that we can recognise, so...

        return FileInterface::fileTypeDescription(mMimeType);
}

} }
<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Kirsten Weber

#ifndef DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH
#define DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH

#include <memory>
#include <type_traits>

#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>

#include <dune/grid/io/file/vtk.hh>

#include <dune/stuff/la/container/interfaces.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/common/memory.hh>

#include <dune/gdt/spaces/interface.hh>

#include "local.hh"

namespace Dune {
namespace GDT {

template <class SpaceImp, class VectorImp>
class ConstDiscreteFunction
    : public Stuff::LocalizableFunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                                 SpaceImp::dimDomain, typename SpaceImp::RangeFieldType,
                                                 SpaceImp::dimRange, SpaceImp::dimRangeCols>
{
  static_assert(is_space<SpaceImp>::value, "SpaceImp has to be derived from SpaceInterface!");
  static_assert(Stuff::LA::is_vector<VectorImp>::value, "VectorImp has to be derived from Stuff::LA::VectorInterface!");
  static_assert(std::is_same<typename SpaceImp::RangeFieldType, typename VectorImp::ScalarType>::value,
                "Types do not match!");
  typedef Stuff::LocalizableFunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                              SpaceImp::dimDomain, typename SpaceImp::RangeFieldType,
                                              SpaceImp::dimRange, SpaceImp::dimRangeCols> BaseType;
  typedef ConstDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef SpaceImp SpaceType;
  typedef VectorImp VectorType;
  typedef typename BaseType::EntityType EntityType;
  typedef typename BaseType::LocalfunctionType LocalfunctionType;

  typedef ConstLocalDiscreteFunction<SpaceType, VectorType> ConstLocalDiscreteFunctionType;

  ConstDiscreteFunction(const SpaceType& sp, const VectorType& vec, const std::string nm = "gdt.constdiscretefunction")
    : space_(sp)
    , vector_(vec)
    , name_(nm)
  {
    assert(vector_.size() == space_->mapper().size() && "Given vector has wrong size!");
  }

  ConstDiscreteFunction(const ThisType& other)
    : space_(other.space())
    , vector_(other.vector_)
    , name_(other.name_)
  {
  }

  ConstDiscreteFunction(ThisType&& source)
    : space_(source.space())
    , vector_(source.vector_)
    , name_(source.name_)
  {
  }

  virtual ~ConstDiscreteFunction()
  {
  }

  ThisType& operator=(const ThisType& other) = delete;

  virtual ThisType* copy() const override
  {
    return new ThisType(*this);
  }

  virtual std::string name() const override
  {
    return name_;
  }

  const SpaceType& space() const
  {
    return *space_;
  }

  const VectorType& vector() const
  {
    return vector_;
  }

  std::unique_ptr<ConstLocalDiscreteFunctionType> local_discrete_function(const EntityType& entity) const
  {
    assert(space_->grid_view().indexSet().contains(entity));
    return DSC::make_unique<ConstLocalDiscreteFunctionType>(*space_, vector_, entity);
  }

  virtual std::unique_ptr<LocalfunctionType> local_function(const EntityType& entity) const override
  {
    return local_discrete_function(entity);
  }

  void visualize(const std::string filename, const bool subsampling = (SpaceType::polOrder > 1),
                 VTK::OutputType vtk_output_type = VTK::appendedraw) const
  {
    BaseType::template visualize<typename SpaceType::GridViewType>(
        space().grid_view(), filename, subsampling, vtk_output_type);
  }

  bool dofs_valid() const
  {
    return vector().valid();
  }

protected:
  const DS::PerThreadValue<SpaceType> space_;

private:
  const VectorType& vector_;
  const std::string name_;
}; // class ConstDiscreteFunction

template <class SpaceImp, class VectorImp>
class DiscreteFunction : Stuff::Common::StorageProvider<VectorImp>, public ConstDiscreteFunction<SpaceImp, VectorImp>
{
  typedef Stuff::Common::StorageProvider<VectorImp> VectorProviderBaseType;
  typedef ConstDiscreteFunction<SpaceImp, VectorImp> BaseType;
  typedef DiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef typename BaseType::SpaceType SpaceType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::EntityType EntityType;
  typedef typename BaseType::LocalfunctionType LocalfunctionType;

  typedef LocalDiscreteFunction<SpaceType, VectorType> LocalDiscreteFunctionType;

  DiscreteFunction(const SpaceType& sp, VectorType& vec, const std::string nm = "gdt.discretefunction")
    : VectorProviderBaseType(vec)
    , BaseType(sp, VectorProviderBaseType::storage_access(), nm)
  {
  }

  DiscreteFunction(const SpaceType& sp, VectorType&& vec, const std::string nm = "gdt.discretefunction")
    : VectorProviderBaseType(vec)
    , BaseType(sp, VectorProviderBaseType::storage_access(), nm)
  {
  }

  DiscreteFunction(const SpaceType& sp, const std::string nm = "gdt.discretefunction")
    : VectorProviderBaseType(new VectorType(sp.mapper().size()))
    , BaseType(sp, VectorProviderBaseType::storage_access(), nm)
  {
  }

  // manual copy ctor needed bc. of the storage provider
  DiscreteFunction(const ThisType& other)
    : VectorProviderBaseType(new VectorType(other.vector()))
    , BaseType(other.space(), VectorProviderBaseType::storage_access(), other.name())
  {
  }

  // manual move ctor needed bc. of the storage provider
  DiscreteFunction(ThisType&& source)
    : VectorProviderBaseType(new VectorType(source.vector()))
    , BaseType(source.space(), VectorProviderBaseType::storage_access(), source.name())
  {
  }

  virtual ~DiscreteFunction()
  {
  }

  ThisType& operator=(const ThisType& other) = delete;

  virtual ThisType* copy() const override
  {
    return new ThisType(*this);
  }

  using BaseType::vector;

  VectorType& vector()
  {
    return this->storage_access();
  }

  using BaseType::local_discrete_function;

  std::unique_ptr<LocalDiscreteFunctionType> local_discrete_function(const EntityType& entity)
  {
    assert(space_->grid_view().indexSet().contains(entity));
    return DSC::make_unique<LocalDiscreteFunctionType>(*space_, this->storage_access(), entity);
  }

private:
  using BaseType::space_;
}; // class DiscreteFunction

template <class SpaceType, class VectorType>
ConstDiscreteFunction<SpaceType, VectorType>
make_const_discrete_function(const SpaceType& space, const VectorType& vector,
                             const std::string nm = "gdt.constdiscretefunction")
{
  return ConstDiscreteFunction<SpaceType, VectorType>(space, vector, nm);
}

template <class SpaceType, class VectorType>
DiscreteFunction<SpaceType, VectorType> make_discrete_function(const SpaceType& space, VectorType& vector,
                                                               const std::string nm = "gdt.discretefunction")
{
  return DiscreteFunction<SpaceType, VectorType>(space, vector, nm);
}

template <class VectorType, class SpaceType>
DiscreteFunction<SpaceType, VectorType> make_discrete_function(const SpaceType& space,
                                                               const std::string nm = "gdt.discretefunction")
{
  return DiscreteFunction<SpaceType, VectorType>(space, nm);
}

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH
<commit_msg>[discretefunction.default] add is_{const_,}discrete_function<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Kirsten Weber

#ifndef DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH
#define DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH

#include <memory>
#include <type_traits>

#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>

#include <dune/grid/io/file/vtk.hh>

#include <dune/stuff/la/container/interfaces.hh>
#include <dune/stuff/functions/interfaces.hh>
#include <dune/stuff/common/memory.hh>

#include <dune/gdt/spaces/interface.hh>

#include "local.hh"

namespace Dune {
namespace GDT {

template <class SpaceImp, class VectorImp>
class ConstDiscreteFunction
    : public Stuff::LocalizableFunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                                 SpaceImp::dimDomain, typename SpaceImp::RangeFieldType,
                                                 SpaceImp::dimRange, SpaceImp::dimRangeCols>
{
  static_assert(is_space<SpaceImp>::value, "SpaceImp has to be derived from SpaceInterface!");
  static_assert(Stuff::LA::is_vector<VectorImp>::value, "VectorImp has to be derived from Stuff::LA::VectorInterface!");
  static_assert(std::is_same<typename SpaceImp::RangeFieldType, typename VectorImp::ScalarType>::value,
                "Types do not match!");
  typedef Stuff::LocalizableFunctionInterface<typename SpaceImp::EntityType, typename SpaceImp::DomainFieldType,
                                              SpaceImp::dimDomain, typename SpaceImp::RangeFieldType,
                                              SpaceImp::dimRange, SpaceImp::dimRangeCols> BaseType;
  typedef ConstDiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef SpaceImp SpaceType;
  typedef VectorImp VectorType;
  typedef typename BaseType::EntityType EntityType;
  typedef typename BaseType::LocalfunctionType LocalfunctionType;

  typedef ConstLocalDiscreteFunction<SpaceType, VectorType> ConstLocalDiscreteFunctionType;

  ConstDiscreteFunction(const SpaceType& sp, const VectorType& vec, const std::string nm = "gdt.constdiscretefunction")
    : space_(sp)
    , vector_(vec)
    , name_(nm)
  {
    assert(vector_.size() == space_->mapper().size() && "Given vector has wrong size!");
  }

  ConstDiscreteFunction(const ThisType& other)
    : space_(other.space())
    , vector_(other.vector_)
    , name_(other.name_)
  {
  }

  ConstDiscreteFunction(ThisType&& source)
    : space_(source.space())
    , vector_(source.vector_)
    , name_(source.name_)
  {
  }

  virtual ~ConstDiscreteFunction()
  {
  }

  ThisType& operator=(const ThisType& other) = delete;

  virtual ThisType* copy() const override
  {
    return new ThisType(*this);
  }

  virtual std::string name() const override
  {
    return name_;
  }

  const SpaceType& space() const
  {
    return *space_;
  }

  const VectorType& vector() const
  {
    return vector_;
  }

  std::unique_ptr<ConstLocalDiscreteFunctionType> local_discrete_function(const EntityType& entity) const
  {
    assert(space_->grid_view().indexSet().contains(entity));
    return DSC::make_unique<ConstLocalDiscreteFunctionType>(*space_, vector_, entity);
  }

  virtual std::unique_ptr<LocalfunctionType> local_function(const EntityType& entity) const override
  {
    return local_discrete_function(entity);
  }

  void visualize(const std::string filename, const bool subsampling = (SpaceType::polOrder > 1),
                 VTK::OutputType vtk_output_type = VTK::appendedraw) const
  {
    BaseType::template visualize<typename SpaceType::GridViewType>(
        space().grid_view(), filename, subsampling, vtk_output_type);
  }

  bool dofs_valid() const
  {
    return vector().valid();
  }

protected:
  const DS::PerThreadValue<SpaceType> space_;

private:
  const VectorType& vector_;
  const std::string name_;
}; // class ConstDiscreteFunction

template <class SpaceImp, class VectorImp>
class DiscreteFunction : Stuff::Common::StorageProvider<VectorImp>, public ConstDiscreteFunction<SpaceImp, VectorImp>
{
  typedef Stuff::Common::StorageProvider<VectorImp> VectorProviderBaseType;
  typedef ConstDiscreteFunction<SpaceImp, VectorImp> BaseType;
  typedef DiscreteFunction<SpaceImp, VectorImp> ThisType;

public:
  typedef typename BaseType::SpaceType SpaceType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::EntityType EntityType;
  typedef typename BaseType::LocalfunctionType LocalfunctionType;

  typedef LocalDiscreteFunction<SpaceType, VectorType> LocalDiscreteFunctionType;

  DiscreteFunction(const SpaceType& sp, VectorType& vec, const std::string nm = "gdt.discretefunction")
    : VectorProviderBaseType(vec)
    , BaseType(sp, VectorProviderBaseType::storage_access(), nm)
  {
  }

  DiscreteFunction(const SpaceType& sp, VectorType&& vec, const std::string nm = "gdt.discretefunction")
    : VectorProviderBaseType(vec)
    , BaseType(sp, VectorProviderBaseType::storage_access(), nm)
  {
  }

  DiscreteFunction(const SpaceType& sp, const std::string nm = "gdt.discretefunction")
    : VectorProviderBaseType(new VectorType(sp.mapper().size()))
    , BaseType(sp, VectorProviderBaseType::storage_access(), nm)
  {
  }

  // manual copy ctor needed bc. of the storage provider
  DiscreteFunction(const ThisType& other)
    : VectorProviderBaseType(new VectorType(other.vector()))
    , BaseType(other.space(), VectorProviderBaseType::storage_access(), other.name())
  {
  }

  // manual move ctor needed bc. of the storage provider
  DiscreteFunction(ThisType&& source)
    : VectorProviderBaseType(new VectorType(source.vector()))
    , BaseType(source.space(), VectorProviderBaseType::storage_access(), source.name())
  {
  }

  virtual ~DiscreteFunction()
  {
  }

  ThisType& operator=(const ThisType& other) = delete;

  virtual ThisType* copy() const override
  {
    return new ThisType(*this);
  }

  using BaseType::vector;

  VectorType& vector()
  {
    return this->storage_access();
  }

  using BaseType::local_discrete_function;

  std::unique_ptr<LocalDiscreteFunctionType> local_discrete_function(const EntityType& entity)
  {
    assert(space_->grid_view().indexSet().contains(entity));
    return DSC::make_unique<LocalDiscreteFunctionType>(*space_, this->storage_access(), entity);
  }

private:
  using BaseType::space_;
}; // class DiscreteFunction

template <class SpaceType, class VectorType>
ConstDiscreteFunction<SpaceType, VectorType>
make_const_discrete_function(const SpaceType& space, const VectorType& vector,
                             const std::string nm = "gdt.constdiscretefunction")
{
  return ConstDiscreteFunction<SpaceType, VectorType>(space, vector, nm);
}

template <class SpaceType, class VectorType>
DiscreteFunction<SpaceType, VectorType> make_discrete_function(const SpaceType& space, VectorType& vector,
                                                               const std::string nm = "gdt.discretefunction")
{
  return DiscreteFunction<SpaceType, VectorType>(space, vector, nm);
}

template <class VectorType, class SpaceType>
DiscreteFunction<SpaceType, VectorType> make_discrete_function(const SpaceType& space,
                                                               const std::string nm = "gdt.discretefunction")
{
  return DiscreteFunction<SpaceType, VectorType>(space, nm);
}

namespace internal {

template <class D>
struct is_const_discrete_function_helper
{
  DSC_has_typedef_initialize_once(SpaceType) DSC_has_typedef_initialize_once(VectorType)

      static const bool is_candidate = DSC_has_typedef(SpaceType)<D>::value && DSC_has_typedef(SpaceType)<D>::value;
};

} // namespace internal

template <class D, bool candidate = internal::is_const_discrete_function_helper<D>::is_candidate>
struct is_const_discrete_function
    : public std::is_base_of<ConstDiscreteFunction<typename D::SpaceType, typename D::VectorType>, D>
{
};

template <class D>
struct is_const_discrete_function<D, false> : public std::false_type
{
};

template <class D, bool candidate = internal::is_const_discrete_function_helper<D>::is_candidate>
struct is_discrete_function : public std::is_base_of<DiscreteFunction<typename D::SpaceType, typename D::VectorType>, D>
{
};

template <class D>
struct is_discrete_function<D, false> : public std::false_type
{
};

} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_DISCRETEFUNCTION_DEFAULT_HH
<|endoftext|>


<commit_before><commit_msg>fix: Json output causes segfault<commit_after><|endoftext|>