<commit_before>/*
  +----------------------------------------------------------------------+
  | Swoole                                                               |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.0 of the Apache license,    |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.apache.org/licenses/LICENSE-2.0.html                      |
  | If you did not receive a copy of the Apache2.0 license and are unable|
  | to obtain it through the world-wide-web, please send a note to       |
  | license@swoole.com so we can mail you a copy immediately.            |
  +----------------------------------------------------------------------+
  | Author: Xinyu Zhu  <xyzhu1120@gmail.com>                             |
  |         shiguangqi <shiguangqi2008@gmail.com>                        |
  +----------------------------------------------------------------------+
 */

#include "php_swoole.h"

#ifdef SW_COROUTINE
#include "swoole_coroutine.h"

#define TASK_SLOT \
    ((int)((ZEND_MM_ALIGNED_SIZE(sizeof(coro_task)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval))))
#define SWCC(x) sw_current_context->x

coro_global COROG;

#if PHP_VERSION_ID >= 70200
static inline void sw_vm_stack_init(void)
{
    uint32_t size = COROG.stack_size;
    zend_vm_stack page = (zend_vm_stack) emalloc(size);

    page->top = ZEND_VM_STACK_ELEMENTS(page);
    page->end = (zval*) ((char*) page + size);
    page->prev = NULL;

    EG(vm_stack) = page;
    EG(vm_stack)->top++;
    EG(vm_stack_top) = EG(vm_stack)->top;
    EG(vm_stack_end) = EG(vm_stack)->end;
}
#else
#define sw_vm_stack_init zend_vm_stack_init
#endif

static sw_inline void php_coro_save_vm_stack(coro_task *task)
{
    task->execute_data = EG(current_execute_data);
    task->vm_stack = EG(vm_stack);
    task->vm_stack_top = EG(vm_stack_top);
    task->vm_stack_end = EG(vm_stack_end);
    SW_SAVE_EG_SCOPE(task->scope);
}

static sw_inline coro_task* php_coro_get_current_task()
{
    coro_task *task = (coro_task *) coroutine_get_current_task();
    if (!task)
    {
        task = &COROG.task;
    }
    php_coro_save_vm_stack(task);
    return task;
}

static sw_inline void php_coro_restore_vm_stack(coro_task *task)
{
    EG(current_execute_data) = task->execute_data;
    EG(vm_stack) = task->vm_stack;
    EG(vm_stack_top) = task->vm_stack_top;
    EG(vm_stack_end) = task->vm_stack_end;
    SW_SET_EG_SCOPE(task->scope);
}

/**
 * The meaning of the task argument in coro switch functions
 *
 * create: origin_task
 * yield: current_task
 * resume: target_task
 * close: current_task
 *
 */

static sw_inline void php_coro_save_og(coro_task *task)
{
    task->output_ptr = (zend_output_globals *) emalloc(sizeof(zend_output_globals));
    memcpy(task->output_ptr, SWOG, sizeof(zend_output_globals));
    php_output_activate();
}

static sw_inline void php_coro_restore_og(coro_task *task)
{
    memcpy(SWOG, task->output_ptr, sizeof(zend_output_globals));
    efree(task->output_ptr);
    task->output_ptr = NULL;
}

static sw_inline void php_coro_og_create(coro_task *task)
{
    if (OG(handlers).elements)
    {
        php_coro_save_og(task);
    }
    else
    {
        task->output_ptr = NULL;
    }
}

static sw_inline void php_coro_og_yield(coro_task *task)
{
    if (OG(handlers).elements)
    {
        php_coro_save_og(task);
    }
    else
    {
        task->output_ptr = NULL;
    }
    if (task->origin_task->output_ptr)
    {
        php_coro_restore_og(task->origin_task);
    }
}

static sw_inline void php_coro_og_resume(coro_task *task)
{
    if (OG(handlers).elements)
    {
        php_coro_save_og(task->origin_task);
    }
    else
    {
        task->origin_task->output_ptr = NULL;
    }
    if (task->output_ptr)
    {
        php_coro_restore_og(task);
    }
}

static sw_inline void php_coro_og_close(coro_task *task)
{
    if (OG(handlers).elements)
    {
        if (OG(active))
        {
            php_output_end_all();
        }
        php_output_deactivate();
        php_output_activate();
    }
    if (task->output_ptr)
    {
        efree(task->output_ptr);
        task->output_ptr = nullptr;
    }
}

void coro_init(void)
{
    COROG.max_coro_num = DEFAULT_MAX_CORO_NUM;
    COROG.stack_size = DEFAULT_STACK_SIZE;
    coroutine_set_onYield(internal_coro_yield);
    coroutine_set_onResume(internal_coro_resume);
    coroutine_set_onClose(sw_coro_close);
}

static void php_coro_create(void *arg)
{
    php_args *php_arg = (php_args *) arg;
    zend_fcall_info_cache *fci_cache = php_arg->fci_cache;
    zval **argv = php_arg->argv;
    int argc = php_arg->argc;
    zval *retval = php_arg->retval;
    coro_task *origin_task = php_arg->origin_task;

    int cid = coroutine_get_current_cid();
    int i;
    zend_function *func;
    coro_task *task;

    func = fci_cache->function_handler;
    sw_vm_stack_init();
    zend_execute_data *call = (zend_execute_data *) (EG(vm_stack_top));

    task = (coro_task *) EG(vm_stack_top);
    EG(vm_stack_top) = (zval *) ((char *) call + TASK_SLOT * sizeof(zval));

    call = zend_vm_stack_push_call_frame(
        ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED,
        func, argc,
        fci_cache->called_scope, fci_cache->object
    );

    SW_SET_EG_SCOPE(func->common.scope);
    SW_SAVE_EG_SCOPE(task->scope);

    for (i = 0; i < argc; ++i)
    {
        zval *target;
        target = ZEND_CALL_ARG(call, i + 1);
        ZVAL_COPY(target, argv[i]);
    }
    call->symbol_table = NULL;

    // EG(current_execute_data) = NULL; // for backtrace
    if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE))
    {
        uint32_t call_info;
        GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
        call_info = ZEND_CALL_CLOSURE;
        ZEND_ADD_CALL_FLAG(call, call_info);
    }
    zend_init_execute_data(call, &func->op_array, retval);

#ifdef SW_LOG_TRACE_OPEN
    task->cid = cid;
#endif
    task->execute_data = call;
    task->vm_stack = EG(vm_stack);
    task->vm_stack_top = EG(vm_stack_top);
    task->vm_stack_end = EG(vm_stack_end);
    task->origin_task = origin_task;
    task->output_ptr = nullptr;
    task->co = coroutine_get_by_id(cid);
    coroutine_set_task(task->co, (void *) task);

    if (SwooleG.hooks[SW_GLOBAL_HOOK_ON_CORO_START])
    {
        swoole_call_hook(SW_GLOBAL_HOOK_ON_CORO_START, task);
    }
    swTraceLog(SW_TRACE_COROUTINE, "Create coro id: %d, origin cid: %d, coro total count: %d, heap size: %zu", cid, task->origin_task->cid, COROG.coro_num, zend_memory_usage(0));

    php_coro_og_create(origin_task);
    EG(current_execute_data) = task->execute_data;
    zend_execute_ex(EG(current_execute_data));

    if (EG(exception))
    {
        zend_exception_error(EG(exception), E_ERROR);
    }
}

static sw_inline void php_coro_yield(coro_task *task)
{
    swTraceLog(SW_TRACE_COROUTINE,"php_coro_yield from cid=%d to cid=%d", task->cid, task->origin_task->cid);
    php_coro_save_vm_stack(task);
    php_coro_restore_vm_stack(task->origin_task);
    php_coro_og_yield(task);
}

static sw_inline void php_coro_resume(coro_task *task)
{
    task->origin_task = php_coro_get_current_task();
    php_coro_restore_vm_stack(task);
    php_coro_og_resume(task);
    swTraceLog(SW_TRACE_COROUTINE,"php_coro_resume from cid=%d to cid=%d", task->origin_task->cid, task->cid);
}

static sw_inline void php_coro_close(coro_task *task)
{
    php_coro_og_close(task);
    php_coro_yield(task);
}

void internal_coro_resume(void *arg)
{
    coro_task *task = (coro_task *) arg;
    php_coro_resume(task);
}

void internal_coro_yield(void *arg)
{
    coro_task *task = (coro_task *) arg;
    php_coro_yield(task);
}

void coro_check(void)
{
    if (unlikely(!sw_coro_is_in()))
    {
        swoole_php_fatal_error(E_ERROR, "must be called in the coroutine.");
    }
}

void coro_destroy(void)
{
}

void sw_coro_check_bind(const char *name, int bind_cid)
{
    if (unlikely(bind_cid > 0))
    {
        swString *buffer = SwooleTG.buffer_stack;
        sw_get_debug_print_backtrace(buffer, DEBUG_BACKTRACE_IGNORE_ARGS, 3);
        swoole_error_log(
            SW_LOG_ERROR, SW_ERROR_CO_HAS_BEEN_BOUND,
            "%s has already been bound to another coroutine #%d, "
            "reading or writing of the same socket in multiple coroutines at the same time is not allowed.\n"
            "%.*s", name, bind_cid, (int) buffer->length, buffer->str
        );
        exit(255);
    }
}

int sw_coro_create(zend_fcall_info_cache *fci_cache, zval **argv, int argc, zval *retval)
{
    if (unlikely(COROG.active == 0))
    {
        if (zend_get_module_started("xdebug") == SUCCESS)
        {
            swWarn("xdebug do not support coroutine, please notice that it lead to coredump.");
        }
        COROG.active = 1;
    }
    if (unlikely(COROG.coro_num >= COROG.max_coro_num) )
    {
        swWarn("exceed max number of coro_num %d, max_coro_num:%d", COROG.coro_num, COROG.max_coro_num);
        return CORO_LIMIT;
    }

    if (++COROG.coro_num > COROG.peak_coro_num)
    {
        COROG.peak_coro_num = COROG.coro_num;
    }

    php_args php_args;
    php_args.fci_cache = fci_cache;
    php_args.argv = argv;
    php_args.argc = argc;
    php_args.retval = retval;
    php_args.origin_task = php_coro_get_current_task();

    int cid = coroutine_create(php_coro_create, (void*) &php_args);
    if (unlikely(cid <= 0))
    {
        COROG.coro_num--;
    }
    return cid;
}

void sw_coro_save(zval *return_value, php_context *sw_current_context)
{
    SWCC(current_coro_return_value_ptr) = return_value;
    SWCC(current_execute_data) = EG(current_execute_data);
    SWCC(current_vm_stack) = EG(vm_stack);
    SWCC(current_vm_stack_top) = EG(vm_stack_top);
    SWCC(current_vm_stack_end) = EG(vm_stack_end);
    SWCC(current_task) = (coro_task *) coroutine_get_current_task();
}

void sw_coro_yield()
{
    if (unlikely(!sw_coro_is_in()))
    {
        swoole_php_fatal_error(E_ERROR, "must be called in the coroutine.");
    }
    coro_task *task = (coro_task *) coroutine_get_current_task();
    php_coro_yield(task);
    coroutine_yield_naked(task->co);
}

int sw_coro_resume(php_context *sw_current_context, zval *retval, zval *coro_retval)
{
    coro_task *task = SWCC(current_task);
    php_coro_resume(task);
    if (EG(current_execute_data)->prev_execute_data->opline->result_type != IS_UNUSED && retval)
    {
        ZVAL_COPY(SWCC(current_coro_return_value_ptr), retval);
    }

    coroutine_resume_naked(task->co);

    if (unlikely(EG(exception)))
    {
        if (retval)
        {
            zval_ptr_dtor(retval);
        }
        zend_exception_error(EG(exception), E_ERROR);
    }
    return CORO_END;
}

void sw_coro_close()
{
    coro_task *task = (coro_task *) coroutine_get_current_task();

    if (SwooleG.hooks[SW_GLOBAL_HOOK_ON_CORO_STOP])
    {
        swoole_call_hook(SW_GLOBAL_HOOK_ON_CORO_STOP, task);
    }

    php_coro_close(task);
    efree(task->vm_stack);
    COROG.coro_num--;

    swTraceLog(SW_TRACE_COROUTINE, "coro close cid=%d and %d remained. usage size: %zu. malloc size: %zu", task->cid, COROG.coro_num, zend_memory_usage(0), zend_memory_usage(1));
}

int sw_get_current_cid()
{
    if (unlikely(COROG.active == 0))
    {
        return -1;
    }
    else
    {
        return coroutine_get_current_cid();
    }
}

void sw_coro_set_stack_size(int stack_size)
{
    coroutine_set_stack_size(stack_size);
}

#endif
<commit_msg>update coro<commit_after>/*
  +----------------------------------------------------------------------+
  | Swoole                                                               |
  +----------------------------------------------------------------------+
  | This source file is subject to version 2.0 of the Apache license,    |
  | that is bundled with this package in the file LICENSE, and is        |
  | available through the world-wide-web at the following url:           |
  | http://www.apache.org/licenses/LICENSE-2.0.html                      |
  | If you did not receive a copy of the Apache2.0 license and are unable|
  | to obtain it through the world-wide-web, please send a note to       |
  | license@swoole.com so we can mail you a copy immediately.            |
  +----------------------------------------------------------------------+
  | Author: Xinyu Zhu  <xyzhu1120@gmail.com>                             |
  |         shiguangqi <shiguangqi2008@gmail.com>                        |
  +----------------------------------------------------------------------+
 */

#include "php_swoole.h"

#ifdef SW_COROUTINE
#include "swoole_coroutine.h"

#define TASK_SLOT \
    ((int)((ZEND_MM_ALIGNED_SIZE(sizeof(coro_task)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval))))
#define SWCC(x) sw_current_context->x

coro_global COROG;

#if PHP_VERSION_ID >= 70200
static inline void sw_vm_stack_init(void)
{
    uint32_t size = COROG.stack_size;
    zend_vm_stack page = (zend_vm_stack) emalloc(size);

    page->top = ZEND_VM_STACK_ELEMENTS(page);
    page->end = (zval*) ((char*) page + size);
    page->prev = NULL;

    EG(vm_stack) = page;
    EG(vm_stack)->top++;
    EG(vm_stack_top) = EG(vm_stack)->top;
    EG(vm_stack_end) = EG(vm_stack)->end;
}
#else
#define sw_vm_stack_init zend_vm_stack_init
#endif

static void sw_vm_stack_destroy(zend_vm_stack stack)
{
    while (stack != NULL) {
        zend_vm_stack p = stack->prev;
        efree(stack);
        stack = p;
    }
}

static sw_inline void php_coro_save_vm_stack(coro_task *task)
{
    task->execute_data = EG(current_execute_data);
    task->vm_stack = EG(vm_stack);
    task->vm_stack_top = EG(vm_stack_top);
    task->vm_stack_end = EG(vm_stack_end);
    SW_SAVE_EG_SCOPE(task->scope);
}

static sw_inline coro_task* php_coro_get_current_task()
{
    coro_task *task = (coro_task *) coroutine_get_current_task();
    if (!task)
    {
        task = &COROG.task;
    }
    php_coro_save_vm_stack(task);
    return task;
}

static sw_inline void php_coro_restore_vm_stack(coro_task *task)
{
    EG(current_execute_data) = task->execute_data;
    EG(vm_stack) = task->vm_stack;
    EG(vm_stack_top) = task->vm_stack_top;
    EG(vm_stack_end) = task->vm_stack_end;
    SW_SET_EG_SCOPE(task->scope);
}

/**
 * The meaning of the task argument in coro switch functions
 *
 * create: origin_task
 * yield: current_task
 * resume: target_task
 * close: current_task
 *
 */

static sw_inline void php_coro_save_og(coro_task *task)
{
    task->output_ptr = (zend_output_globals *) emalloc(sizeof(zend_output_globals));
    memcpy(task->output_ptr, SWOG, sizeof(zend_output_globals));
    php_output_activate();
}

static sw_inline void php_coro_restore_og(coro_task *task)
{
    memcpy(SWOG, task->output_ptr, sizeof(zend_output_globals));
    efree(task->output_ptr);
    task->output_ptr = NULL;
}

static sw_inline void php_coro_og_create(coro_task *task)
{
    if (OG(handlers).elements)
    {
        php_coro_save_og(task);
    }
    else
    {
        task->output_ptr = NULL;
    }
}

static sw_inline void php_coro_og_yield(coro_task *task)
{
    if (OG(handlers).elements)
    {
        php_coro_save_og(task);
    }
    else
    {
        task->output_ptr = NULL;
    }
    if (task->origin_task->output_ptr)
    {
        php_coro_restore_og(task->origin_task);
    }
}

static sw_inline void php_coro_og_resume(coro_task *task)
{
    if (OG(handlers).elements)
    {
        php_coro_save_og(task->origin_task);
    }
    else
    {
        task->origin_task->output_ptr = NULL;
    }
    if (task->output_ptr)
    {
        php_coro_restore_og(task);
    }
}

static sw_inline void php_coro_og_close(coro_task *task)
{
    if (OG(handlers).elements)
    {
        if (OG(active))
        {
            php_output_end_all();
        }
        php_output_deactivate();
        php_output_activate();
    }
    if (task->output_ptr)
    {
        efree(task->output_ptr);
        task->output_ptr = nullptr;
    }
}

void coro_init(void)
{
    COROG.max_coro_num = DEFAULT_MAX_CORO_NUM;
    COROG.stack_size = DEFAULT_STACK_SIZE;
    coroutine_set_onYield(internal_coro_yield);
    coroutine_set_onResume(internal_coro_resume);
    coroutine_set_onClose(sw_coro_close);
}

static void php_coro_create(void *arg)
{
    php_args *php_arg = (php_args *) arg;
    zend_fcall_info_cache *fci_cache = php_arg->fci_cache;
    zval **argv = php_arg->argv;
    int argc = php_arg->argc;
    zval *retval = php_arg->retval;
    coro_task *origin_task = php_arg->origin_task;

    int cid = coroutine_get_current_cid();
    int i;
    zend_function *func;
    coro_task *task;

    func = fci_cache->function_handler;
    sw_vm_stack_init();
    zend_execute_data *call = (zend_execute_data *) (EG(vm_stack_top));

    task = (coro_task *) EG(vm_stack_top);
    EG(vm_stack_top) = (zval *) ((char *) call + TASK_SLOT * sizeof(zval));

    call = zend_vm_stack_push_call_frame(
        ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED,
        func, argc,
        fci_cache->called_scope, fci_cache->object
    );

    SW_SET_EG_SCOPE(func->common.scope);
    SW_SAVE_EG_SCOPE(task->scope);

    for (i = 0; i < argc; ++i)
    {
        zval *target;
        target = ZEND_CALL_ARG(call, i + 1);
        ZVAL_COPY(target, argv[i]);
    }
    call->symbol_table = NULL;

    // EG(current_execute_data) = NULL; // for backtrace
    if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE))
    {
        uint32_t call_info;
        GC_ADDREF(ZEND_CLOSURE_OBJECT(func));
        call_info = ZEND_CALL_CLOSURE;
        ZEND_ADD_CALL_FLAG(call, call_info);
    }
    zend_init_execute_data(call, &func->op_array, retval);

#ifdef SW_LOG_TRACE_OPEN
    task->cid = cid;
#endif
    task->execute_data = call;
    task->vm_stack = EG(vm_stack);
    task->vm_stack_top = EG(vm_stack_top);
    task->vm_stack_end = EG(vm_stack_end);
    task->origin_task = origin_task;
    task->output_ptr = nullptr;
    task->co = coroutine_get_by_id(cid);
    coroutine_set_task(task->co, (void *) task);

    if (SwooleG.hooks[SW_GLOBAL_HOOK_ON_CORO_START])
    {
        swoole_call_hook(SW_GLOBAL_HOOK_ON_CORO_START, task);
    }
    swTraceLog(SW_TRACE_COROUTINE, "Create coro id: %d, origin cid: %d, coro total count: %d, heap size: %zu", cid, task->origin_task->cid, COROG.coro_num, zend_memory_usage(0));

    php_coro_og_create(origin_task);
    EG(current_execute_data) = task->execute_data;
    zend_execute_ex(EG(current_execute_data));

    if (EG(exception))
    {
        zend_exception_error(EG(exception), E_ERROR);
    }
}

static sw_inline void php_coro_yield(coro_task *task)
{
    swTraceLog(SW_TRACE_COROUTINE,"php_coro_yield from cid=%d to cid=%d", task->cid, task->origin_task->cid);
    php_coro_save_vm_stack(task);
    php_coro_restore_vm_stack(task->origin_task);
    php_coro_og_yield(task);
}

static sw_inline void php_coro_resume(coro_task *task)
{
    task->origin_task = php_coro_get_current_task();
    php_coro_restore_vm_stack(task);
    php_coro_og_resume(task);
    swTraceLog(SW_TRACE_COROUTINE,"php_coro_resume from cid=%d to cid=%d", task->origin_task->cid, task->cid);
}

static sw_inline void php_coro_close(coro_task *task)
{
    php_coro_og_close(task);
    php_coro_yield(task);
}

void internal_coro_resume(void *arg)
{
    coro_task *task = (coro_task *) arg;
    php_coro_resume(task);
}

void internal_coro_yield(void *arg)
{
    coro_task *task = (coro_task *) arg;
    php_coro_yield(task);
}

void coro_check(void)
{
    if (unlikely(!sw_coro_is_in()))
    {
        swoole_php_fatal_error(E_ERROR, "must be called in the coroutine.");
    }
}

void coro_destroy(void)
{
}

void sw_coro_check_bind(const char *name, int bind_cid)
{
    if (unlikely(bind_cid > 0))
    {
        swString *buffer = SwooleTG.buffer_stack;
        sw_get_debug_print_backtrace(buffer, DEBUG_BACKTRACE_IGNORE_ARGS, 3);
        swoole_error_log(
            SW_LOG_ERROR, SW_ERROR_CO_HAS_BEEN_BOUND,
            "%s has already been bound to another coroutine #%d, "
            "reading or writing of the same socket in multiple coroutines at the same time is not allowed.\n"
            "%.*s", name, bind_cid, (int) buffer->length, buffer->str
        );
        exit(255);
    }
}

int sw_coro_create(zend_fcall_info_cache *fci_cache, zval **argv, int argc, zval *retval)
{
    if (unlikely(COROG.active == 0))
    {
        if (zend_get_module_started("xdebug") == SUCCESS)
        {
            swWarn("xdebug do not support coroutine, please notice that it lead to coredump.");
        }
        COROG.active = 1;
    }
    if (unlikely(COROG.coro_num >= COROG.max_coro_num) )
    {
        swWarn("exceed max number of coro_num %d, max_coro_num:%d", COROG.coro_num, COROG.max_coro_num);
        return CORO_LIMIT;
    }

    if (++COROG.coro_num > COROG.peak_coro_num)
    {
        COROG.peak_coro_num = COROG.coro_num;
    }

    php_args php_args;
    php_args.fci_cache = fci_cache;
    php_args.argv = argv;
    php_args.argc = argc;
    php_args.retval = retval;
    php_args.origin_task = php_coro_get_current_task();

    int cid = coroutine_create(php_coro_create, (void*) &php_args);
    if (unlikely(cid <= 0))
    {
        COROG.coro_num--;
    }
    return cid;
}

void sw_coro_save(zval *return_value, php_context *sw_current_context)
{
    SWCC(current_coro_return_value_ptr) = return_value;
    SWCC(current_execute_data) = EG(current_execute_data);
    SWCC(current_vm_stack) = EG(vm_stack);
    SWCC(current_vm_stack_top) = EG(vm_stack_top);
    SWCC(current_vm_stack_end) = EG(vm_stack_end);
    SWCC(current_task) = (coro_task *) coroutine_get_current_task();
}

void sw_coro_yield()
{
    if (unlikely(!sw_coro_is_in()))
    {
        swoole_php_fatal_error(E_ERROR, "must be called in the coroutine.");
    }
    coro_task *task = (coro_task *) coroutine_get_current_task();
    php_coro_yield(task);
    coroutine_yield_naked(task->co);
}

int sw_coro_resume(php_context *sw_current_context, zval *retval, zval *coro_retval)
{
    coro_task *task = SWCC(current_task);
    php_coro_resume(task);
    if (EG(current_execute_data)->prev_execute_data->opline->result_type != IS_UNUSED && retval)
    {
        ZVAL_COPY(SWCC(current_coro_return_value_ptr), retval);
    }

    coroutine_resume_naked(task->co);

    if (unlikely(EG(exception)))
    {
        if (retval)
        {
            zval_ptr_dtor(retval);
        }
        zend_exception_error(EG(exception), E_ERROR);
    }
    return CORO_END;
}

void sw_coro_close()
{
    coro_task *task = (coro_task *) coroutine_get_current_task();

    if (SwooleG.hooks[SW_GLOBAL_HOOK_ON_CORO_STOP])
    {
        swoole_call_hook(SW_GLOBAL_HOOK_ON_CORO_STOP, task);
    }

    php_coro_close(task);
    sw_vm_stack_destroy(task->vm_stack);
    COROG.coro_num--;

    swTraceLog(SW_TRACE_COROUTINE, "coro close cid=%d and %d remained. usage size: %zu. malloc size: %zu", task->cid, COROG.coro_num, zend_memory_usage(0), zend_memory_usage(1));
}

int sw_get_current_cid()
{
    if (unlikely(COROG.active == 0))
    {
        return -1;
    }
    else
    {
        return coroutine_get_current_cid();
    }
}

void sw_coro_set_stack_size(int stack_size)
{
    coroutine_set_stack_size(stack_size);
}

#endif
<|endoftext|>


<commit_before>#include <dsa/requester.h>

int main() {
  App app;

  client;

  requester = client->session()->requester();

  stream = requester.subscribe("/abc", func);
  stream.close();
}

void callback(ValueUpdate, ResponseStatus)<commit_msg>fix compilation error<commit_after>#include <dsa/requester.h>

int main() {
#if 0
  App app;

  client;

  requester = client->session()->requester();

  stream = requester.subscribe("/abc", func);
  stream.close();
#endif
}

// void callback(ValueUpdate, ResponseStatus);
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>

#include <opencv2/core/core.hpp>
#include <opencv2/core/opengl_interop.hpp>
#include <opencv2/gpu/gpu.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/contrib/contrib.hpp>

int main(int argc, const char* argv[])
{
    if (argc != 2)
        return -1;

    const std::string fname(argv[1]);

    cv::namedWindow("CPU", cv::WINDOW_NORMAL);
    cv::namedWindow("GPU", cv::WINDOW_OPENGL);
    cv::gpu::setGlDevice();

    cv::Mat frame;
    cv::VideoCapture reader(fname);

    cv::gpu::GpuMat d_frame;
    cv::gpu::VideoReader_GPU d_reader(fname);
    d_reader.dumpFormat(std::cout);

    cv::TickMeter tm;
    std::vector<double> cpu_times;
    std::vector<double> gpu_times;

    for (;;)
    {
        tm.reset(); tm.start();
        if (!reader.read(frame))
            break;
        tm.stop();
        cpu_times.push_back(tm.getTimeMilli());

        tm.reset(); tm.start();
        if (!d_reader.read(d_frame))
            break;
        tm.stop();
        gpu_times.push_back(tm.getTimeMilli());

        cv::imshow("CPU", frame);
        cv::imshow("GPU", frame);

        if (cv::waitKey(3) > 0)
            break;
    }

    if (!cpu_times.empty() && !gpu_times.empty())
    {
        std::cout << std::endl << "Results:" << std::endl;

        std::sort(cpu_times.begin(), cpu_times.end());
        std::sort(gpu_times.begin(), gpu_times.end());

        double cpu_avg = std::accumulate(cpu_times.begin(), cpu_times.end(), 0.0) / cpu_times.size();
        double gpu_avg = std::accumulate(gpu_times.begin(), gpu_times.end(), 0.0) / gpu_times.size();

        std::cout << "CPU : Avg : " << cpu_avg << " ms FPS : " << 1000.0 / cpu_avg << std::endl;
        std::cout << "GPU : Avg : " << gpu_avg << " ms FPS : " << 1000.0 / gpu_avg << std::endl;
    }

    return 0;
}
<commit_msg>minor fix in gpu video_writer sample<commit_after>#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <numeric>

#include <opencv2/core/core.hpp>
#include <opencv2/core/opengl_interop.hpp>
#include <opencv2/gpu/gpu.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/contrib/contrib.hpp>

int main(int argc, const char* argv[])
{
    if (argc != 2)
        return -1;

    const std::string fname(argv[1]);

    cv::namedWindow("CPU", cv::WINDOW_NORMAL);
    cv::namedWindow("GPU", cv::WINDOW_OPENGL);
    cv::gpu::setGlDevice();

    cv::Mat frame;
    cv::VideoCapture reader(fname);

    cv::gpu::GpuMat d_frame;
    cv::gpu::VideoReader_GPU d_reader(fname);
    d_reader.dumpFormat(std::cout);

    cv::TickMeter tm;
    std::vector<double> cpu_times;
    std::vector<double> gpu_times;

    for (;;)
    {
        tm.reset(); tm.start();
        if (!reader.read(frame))
            break;
        tm.stop();
        cpu_times.push_back(tm.getTimeMilli());

        tm.reset(); tm.start();
        if (!d_reader.read(d_frame))
            break;
        tm.stop();
        gpu_times.push_back(tm.getTimeMilli());

        cv::imshow("CPU", frame);
        cv::imshow("GPU", d_frame);

        if (cv::waitKey(3) > 0)
            break;
    }

    if (!cpu_times.empty() && !gpu_times.empty())
    {
        std::cout << std::endl << "Results:" << std::endl;

        std::sort(cpu_times.begin(), cpu_times.end());
        std::sort(gpu_times.begin(), gpu_times.end());

        double cpu_avg = std::accumulate(cpu_times.begin(), cpu_times.end(), 0.0) / cpu_times.size();
        double gpu_avg = std::accumulate(gpu_times.begin(), gpu_times.end(), 0.0) / gpu_times.size();

        std::cout << "CPU : Avg : " << cpu_avg << " ms FPS : " << 1000.0 / cpu_avg << std::endl;
        std::cout << "GPU : Avg : " << gpu_avg << " ms FPS : " << 1000.0 / gpu_avg << std::endl;
    }

    return 0;
}
<|endoftext|>


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

#ifndef _DIF_HXX
#define _DIF_HXX

#ifndef _TOOLS_DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif

#ifndef _LIST_HXX //autogen
#include <tools/list.hxx>
#endif

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef SC_SCGLOB_HXX
#include "global.hxx"
#endif

class SvStream;
class SvNumberFormatter;
class ScDocument;
class ScPatternAttr;

extern const sal_Unicode pKeyTABLE[];
extern const sal_Unicode pKeyVECTORS[];
extern const sal_Unicode pKeyTUPLES[];
extern const sal_Unicode pKeyDATA[];
extern const sal_Unicode pKeyBOT[];
extern const sal_Unicode pKeyEOD[];
extern const sal_Unicode pKeyTRUE[];
extern const sal_Unicode pKeyFALSE[];
extern const sal_Unicode pKeyNA[];
extern const sal_Unicode pKeyV[];
extern const sal_Unicode pKey1_0[];

enum TOPIC
{
    T_UNKNOWN,
    T_TABLE, T_VECTORS, T_TUPLES, T_DATA, T_LABEL, T_COMMENT, T_SIZE,
    T_PERIODICITY, T_MAJORSTART, T_MINORSTART, T_TRUELENGTH, T_UINITS,
    T_DISPLAYUNITS,
    T_END
};

enum DATASET { D_BOT, D_EOD, D_NUMERIC, D_STRING, D_UNKNOWN, D_SYNT_ERROR };

class DifParser
{
public:
    String              aData;
    double              fVal;
    UINT32              nVector;
    UINT32              nVal;
    UINT32              nNumFormat;
    CharSet             eCharSet;
private:
    SvNumberFormatter*  pNumFormatter;
    SvStream&           rIn;
    BOOL                bPlain;

    static inline BOOL  IsBOT( const sal_Unicode* pRef );
    static inline BOOL  IsEOD( const sal_Unicode* pRef );
    static inline BOOL  Is1_0( const sal_Unicode* pRef );
public:
                        DifParser( SvStream&, const UINT32 nOption, ScDocument&, CharSet );

    TOPIC               GetNextTopic( void );

    DATASET             GetNextDataset( void );

    const sal_Unicode*  ScanIntVal( const sal_Unicode* pStart, UINT32& rRet );
    BOOL                ScanFloatVal( const sal_Unicode* pStart );

    inline BOOL         IsNumber( const sal_Unicode cChar );
    inline BOOL         IsNumberEnding( const sal_Unicode cChar );

    static inline BOOL  IsV( const sal_Unicode* pRef );

    inline BOOL         IsPlain( void ) const;
};

inline BOOL DifParser::IsBOT( const sal_Unicode* pRef )
{
    return  (   pRef[ 0 ] == pKeyBOT[0] &&
                pRef[ 1 ] == pKeyBOT[1] &&
                pRef[ 2 ] == pKeyBOT[2] &&
                pRef[ 3 ] == pKeyBOT[3] );
}

inline BOOL DifParser::IsEOD( const sal_Unicode* pRef )
{
    return  (   pRef[ 0 ] == pKeyEOD[0] &&
                pRef[ 1 ] == pKeyEOD[1] &&
                pRef[ 2 ] == pKeyEOD[2] &&
                pRef[ 3 ] == pKeyEOD[3] );
}

inline BOOL DifParser::Is1_0( const sal_Unicode* pRef )
{
    return  (   pRef[ 0 ] == pKey1_0[0] &&
                pRef[ 1 ] == pKey1_0[1] &&
                pRef[ 2 ] == pKey1_0[2] &&
                pRef[ 3 ] == pKey1_0[3] );
}

inline BOOL DifParser::IsV( const sal_Unicode* pRef )
{
    return  (   pRef[ 0 ] == pKeyV[0] &&
                pRef[ 1 ] == pKeyV[1]   );
}

inline BOOL DifParser::IsNumber( const sal_Unicode cChar )
{
    return ( cChar >= '0' && cChar <= '9' );
}

inline BOOL DifParser::IsNumberEnding( const sal_Unicode cChar )
{
    return ( cChar == 0x00 );
}

inline BOOL DifParser::IsPlain( void ) const
{
    return bPlain;
}

class DifAttrCache;
class ScPatternAttr;

class DifColumn : private List
{
private:
    friend DifAttrCache;
    struct ENTRY
    {
        UINT32          nNumFormat;

        UINT16          nStart;
        UINT16          nEnd;
    };

    ENTRY*              pAkt;

    inline              DifColumn( void );
                        ~DifColumn();
    void                SetLogical( UINT16 nRow );
    void                SetNumFormat( UINT16 nRow, const UINT32 nNumFormat );
    void                NewEntry( const UINT16 nPos, const UINT32 nNumFormat );
    void                Apply( ScDocument&, const UINT16 nCol, const UINT16 nTab, const ScPatternAttr& );
    void                Apply( ScDocument &rDoc, const UINT16 nCol, const UINT16 nTab );
public:     // geht niemanden etwas an...
};

inline DifColumn::DifColumn( void )
{
    pAkt = NULL;
}

class DifAttrCache
{
private:
    DifColumn**         ppCols;
    BOOL                bPlain;
public:
                        DifAttrCache( const BOOL bPlain );
                        ~DifAttrCache();
    inline void         SetLogical( const UINT16 nCol, const UINT16 nRow );
    void                SetNumFormat( const UINT16 nCol, const UINT16 nRow, const UINT32 nNumFormat );
    void                Apply( ScDocument&, UINT16 nTab );
};

inline void DifAttrCache::SetLogical( const UINT16 nCol, const UINT16 nRow )
{
    DBG_ASSERT( nCol <= MAXCOL, "-DifAttrCache::SetLogical(): Col zu gross!" );
    DBG_ASSERT( bPlain, "*DifAttrCache::SetLogical(): muss Plain sein!" );

    if( !ppCols[ nCol ] )
        ppCols[ nCol ] = new DifColumn;
    ppCols[ nCol ]->SetLogical( nRow );
}

#endif

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

#ifndef _DIF_HXX
#define _DIF_HXX

#ifndef _TOOLS_DEBUG_HXX //autogen
#include <tools/debug.hxx>
#endif

#ifndef _LIST_HXX //autogen
#include <tools/list.hxx>
#endif

#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif

#ifndef SC_SCGLOB_HXX
#include "global.hxx"
#endif

class SvStream;
class SvNumberFormatter;
class ScDocument;
class ScPatternAttr;

extern const sal_Unicode pKeyTABLE[];
extern const sal_Unicode pKeyVECTORS[];
extern const sal_Unicode pKeyTUPLES[];
extern const sal_Unicode pKeyDATA[];
extern const sal_Unicode pKeyBOT[];
extern const sal_Unicode pKeyEOD[];
extern const sal_Unicode pKeyTRUE[];
extern const sal_Unicode pKeyFALSE[];
extern const sal_Unicode pKeyNA[];
extern const sal_Unicode pKeyV[];
extern const sal_Unicode pKey1_0[];

enum TOPIC
{
    T_UNKNOWN,
    T_TABLE, T_VECTORS, T_TUPLES, T_DATA, T_LABEL, T_COMMENT, T_SIZE,
    T_PERIODICITY, T_MAJORSTART, T_MINORSTART, T_TRUELENGTH, T_UINITS,
    T_DISPLAYUNITS,
    T_END
};

enum DATASET { D_BOT, D_EOD, D_NUMERIC, D_STRING, D_UNKNOWN, D_SYNT_ERROR };

class DifParser
{
public:
    String              aData;
    double              fVal;
    UINT32              nVector;
    UINT32              nVal;
    UINT32              nNumFormat;
    CharSet             eCharSet;
private:
    SvNumberFormatter*  pNumFormatter;
    SvStream&           rIn;
    BOOL                bPlain;

    static inline BOOL  IsBOT( const sal_Unicode* pRef );
    static inline BOOL  IsEOD( const sal_Unicode* pRef );
    static inline BOOL  Is1_0( const sal_Unicode* pRef );
public:
                        DifParser( SvStream&, const UINT32 nOption, ScDocument&, CharSet );

    TOPIC               GetNextTopic( void );

    DATASET             GetNextDataset( void );

    const sal_Unicode*  ScanIntVal( const sal_Unicode* pStart, UINT32& rRet );
    BOOL                ScanFloatVal( const sal_Unicode* pStart );

    inline BOOL         IsNumber( const sal_Unicode cChar );
    inline BOOL         IsNumberEnding( const sal_Unicode cChar );

    static inline BOOL  IsV( const sal_Unicode* pRef );

    inline BOOL         IsPlain( void ) const;
};

inline BOOL DifParser::IsBOT( const sal_Unicode* pRef )
{
    return  (   pRef[ 0 ] == pKeyBOT[0] &&
                pRef[ 1 ] == pKeyBOT[1] &&
                pRef[ 2 ] == pKeyBOT[2] &&
                pRef[ 3 ] == pKeyBOT[3] );
}

inline BOOL DifParser::IsEOD( const sal_Unicode* pRef )
{
    return  (   pRef[ 0 ] == pKeyEOD[0] &&
                pRef[ 1 ] == pKeyEOD[1] &&
                pRef[ 2 ] == pKeyEOD[2] &&
                pRef[ 3 ] == pKeyEOD[3] );
}

inline BOOL DifParser::Is1_0( const sal_Unicode* pRef )
{
    return  (   pRef[ 0 ] == pKey1_0[0] &&
                pRef[ 1 ] == pKey1_0[1] &&
                pRef[ 2 ] == pKey1_0[2] &&
                pRef[ 3 ] == pKey1_0[3] );
}

inline BOOL DifParser::IsV( const sal_Unicode* pRef )
{
    return  (   pRef[ 0 ] == pKeyV[0] &&
                pRef[ 1 ] == pKeyV[1]   );
}

inline BOOL DifParser::IsNumber( const sal_Unicode cChar )
{
    return ( cChar >= '0' && cChar <= '9' );
}

inline BOOL DifParser::IsNumberEnding( const sal_Unicode cChar )
{
    return ( cChar == 0x00 );
}

inline BOOL DifParser::IsPlain( void ) const
{
    return bPlain;
}

class DifAttrCache;
class ScPatternAttr;

class DifColumn : private List
{
private:
    friend class DifAttrCache;
    struct ENTRY
    {
        UINT32          nNumFormat;

        UINT16          nStart;
        UINT16          nEnd;
    };

    ENTRY*              pAkt;

    inline              DifColumn( void );
                        ~DifColumn();
    void                SetLogical( UINT16 nRow );
    void                SetNumFormat( UINT16 nRow, const UINT32 nNumFormat );
    void                NewEntry( const UINT16 nPos, const UINT32 nNumFormat );
    void                Apply( ScDocument&, const UINT16 nCol, const UINT16 nTab, const ScPatternAttr& );
    void                Apply( ScDocument &rDoc, const UINT16 nCol, const UINT16 nTab );
public:     // geht niemanden etwas an...
};

inline DifColumn::DifColumn( void )
{
    pAkt = NULL;
}

class DifAttrCache
{
private:
    DifColumn**         ppCols;
    BOOL                bPlain;
public:
                        DifAttrCache( const BOOL bPlain );
                        ~DifAttrCache();
    inline void         SetLogical( const UINT16 nCol, const UINT16 nRow );
    void                SetNumFormat( const UINT16 nCol, const UINT16 nRow, const UINT32 nNumFormat );
    void                Apply( ScDocument&, UINT16 nTab );
};

inline void DifAttrCache::SetLogical( const UINT16 nCol, const UINT16 nRow )
{
    DBG_ASSERT( nCol <= MAXCOL, "-DifAttrCache::SetLogical(): Col zu gross!" );
    DBG_ASSERT( bPlain, "*DifAttrCache::SetLogical(): muss Plain sein!" );

    if( !ppCols[ nCol ] )
        ppCols[ nCol ] = new DifColumn;
    ppCols[ nCol ]->SetLogical( nRow );
}

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cbutton.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 21:13:59 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

//------------------------------------------------------------------

#ifndef SC_CBUTTON_HXX
#define SC_CBUTTON_HXX

#ifndef _GEN_HXX //autogen
#include <tools/gen.hxx>
#endif

#ifndef _TOOLS_COLOR_HXX
#include <tools/color.hxx>
#endif

class Window;

//==================================================================

class ScDDComboBoxButton
{
public:
            ScDDComboBoxButton( Window* pOutputDevice );
            ~ScDDComboBoxButton();

    void    Draw( const Point&  rAt,
                  const Size&   rSize,
                  BOOL          bState,
                  BOOL          bBtnIn = FALSE );

    void    Draw( const Point&  rAt,
                  BOOL          bState,
                  BOOL          bBtnIn = FALSE )
                { Draw( rAt, aBtnSize, bState, bBtnIn ); }

    void    Draw( BOOL          bState,
                  BOOL          bBtnIn = FALSE )
                { Draw( aBtnPos, aBtnSize, bState, bBtnIn ); }

    void    SetOptSizePixel();

    void    SetPosPixel( const Point& rNewPos )  { aBtnPos = rNewPos; }
    Point   GetPosPixel() const                  { return aBtnPos; }

    void    SetSizePixel( const Size& rNewSize ) { aBtnSize = rNewSize; }
    Size    GetSizePixel() const                 { return aBtnSize; }

private:
    void    ImpDrawArrow( const Rectangle&  rRect,
                          BOOL              bState );

protected:
    Window* pOut;
    Point   aBtnPos;
    Size    aBtnSize;
};

#endif // SC_CBUTTON_HXX

<commit_msg>INTEGRATION: CWS aw046 (1.4.384); FILE MERGED 2007/02/22 17:56:07 nn 1.4.384.1: #i74768# use variable pContentDev to draw content in ScGridWindow::Draw<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cbutton.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2007-06-26 11:50:17 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

//------------------------------------------------------------------

#ifndef SC_CBUTTON_HXX
#define SC_CBUTTON_HXX

#ifndef _GEN_HXX //autogen
#include <tools/gen.hxx>
#endif

#ifndef _TOOLS_COLOR_HXX
#include <tools/color.hxx>
#endif

class OutputDevice;

//==================================================================

class ScDDComboBoxButton
{
public:
            ScDDComboBoxButton( OutputDevice* pOutputDevice );
            ~ScDDComboBoxButton();

    void    SetOutputDevice( OutputDevice* pOutputDevice );

    void    Draw( const Point&  rAt,
                  const Size&   rSize,
                  BOOL          bState,
                  BOOL          bBtnIn = FALSE );

    void    Draw( const Point&  rAt,
                  BOOL          bState,
                  BOOL          bBtnIn = FALSE )
                { Draw( rAt, aBtnSize, bState, bBtnIn ); }

    void    Draw( BOOL          bState,
                  BOOL          bBtnIn = FALSE )
                { Draw( aBtnPos, aBtnSize, bState, bBtnIn ); }

    void    SetOptSizePixel();

    void    SetPosPixel( const Point& rNewPos )  { aBtnPos = rNewPos; }
    Point   GetPosPixel() const                  { return aBtnPos; }

    void    SetSizePixel( const Size& rNewSize ) { aBtnSize = rNewSize; }
    Size    GetSizePixel() const                 { return aBtnSize; }

private:
    void    ImpDrawArrow( const Rectangle&  rRect,
                          BOOL              bState );

protected:
    OutputDevice* pOut;
    Point   aBtnPos;
    Size    aBtnSize;
};

#endif // SC_CBUTTON_HXX

<|endoftext|>


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

#ifndef SC_HDRCONT_HXX
#define SC_HDRCONT_HXX

#ifndef _WINDOW_HXX //autogen
#include <vcl/window.hxx>
#endif
#ifndef _SELENG_HXX //autogen
#include <vcl/seleng.hxx>
#endif
#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif

// ---------------------------------------------------------------------------

#define HDR_HORIZONTAL      0
#define HDR_VERTICAL        1

#define HDR_SIZE_OPTIMUM    0xFFFF

                                    // Groesse des Sliders
#define HDR_SLIDERSIZE      2

class ScHeaderControl : public Window
{
private:
    SelectionEngine*    pSelEngine;
    Font                aNormFont;
    Font                aBoldFont;
    BOOL                bBoldSet;

    USHORT          nFlags;
    BOOL            bVertical;              // Vertikal = Zeilenheader

    long            nWidth;
    long            nSmallWidth;
    long            nBigWidth;

    SCCOLROW        nSize;

    SCCOLROW        nMarkStart;
    SCCOLROW        nMarkEnd;
    BOOL            bMarkRange;

    BOOL            bDragging;              // Groessen aendern
    SCCOLROW        nDragNo;
    long            nDragStart;
    long            nDragPos;
    BOOL            bDragMoved;

    BOOL            bIgnoreMove;

    long            GetScrPos( SCCOLROW nEntryNo );
    SCCOLROW        GetMousePos( const MouseEvent& rMEvt, BOOL& rBorder );

    void            ShowDragHelp();

    void            DoPaint( SCCOLROW nStart, SCCOLROW nEnd );

protected:
                    //  von Window ueberladen

    virtual void    Paint( const Rectangle& rRect );

    virtual void    MouseMove( const MouseEvent& rMEvt );
    virtual void    MouseButtonUp( const MouseEvent& rMEvt );
    virtual void    MouseButtonDown( const MouseEvent& rMEvt );
    virtual void    Tracking( const TrackingEvent& rTEvt );

    virtual void    RequestHelp( const HelpEvent& rHEvt );

                    //  neue Methoden

    virtual SCCOLROW    GetPos() = 0;                               // aktuelle Position (Scrolling)
    virtual USHORT  GetEntrySize( SCCOLROW nEntryNo ) = 0;      // Breite / Hoehe (Pixel)
    virtual String  GetEntryText( SCCOLROW nEntryNo ) = 0;

    virtual SCCOLROW GetHiddenCount( SCCOLROW nEntryNo );
    virtual BOOL    IsLayoutRTL();
    virtual BOOL    IsMirrored();

    virtual void    SetEntrySize( SCCOLROW nPos, USHORT nNewWidth ) = 0;
    virtual void    HideEntries( SCCOLROW nStart, SCCOLROW nEnd ) = 0;

    virtual void    SetMarking( BOOL bSet );
    virtual void    SelectWindow();
    virtual BOOL    IsDisabled();
    virtual BOOL    ResizeAllowed();
    virtual String  GetDragHelp( long nVal );

    virtual void    DrawInvert( long nDragPos );
    virtual void    Command( const CommandEvent& rCEvt );

public:
            ScHeaderControl( Window* pParent, SelectionEngine* pSelectionEngine,
                                SCCOLROW nNewSize, USHORT nNewFlags );
            ~ScHeaderControl();

    void    SetIgnoreMove(BOOL bSet)            { bIgnoreMove = bSet; }

    void    StopMarking();

    void    SetMark( BOOL bNewSet, SCCOLROW nNewStart, SCCOLROW nNewEnd );

    long    GetWidth() const                    { return nWidth; }
    long    GetSmallWidth() const               { return nSmallWidth; }
    long    GetBigWidth() const                 { return nBigWidth; }
    void    SetWidth( long nNew );
};

#endif

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

#ifndef SC_HDRCONT_HXX
#define SC_HDRCONT_HXX

#ifndef _WINDOW_HXX //autogen
#include <vcl/window.hxx>
#endif
#ifndef _SELENG_HXX //autogen
#include <vcl/seleng.hxx>
#endif
#ifndef SC_ADDRESS_HXX
#include "address.hxx"
#endif

// ---------------------------------------------------------------------------

#define HDR_HORIZONTAL      0
#define HDR_VERTICAL        1

#define HDR_SIZE_OPTIMUM    0xFFFF

                                    // Groesse des Sliders
#define HDR_SLIDERSIZE      2

class ScHeaderControl : public Window
{
private:
    SelectionEngine*    pSelEngine;
    Font                aNormFont;
    Font                aBoldFont;
    BOOL                bBoldSet;

    USHORT          nFlags;
    BOOL            bVertical;              // Vertikal = Zeilenheader

    long            nWidth;
    long            nSmallWidth;
    long            nBigWidth;

    SCCOLROW        nSize;

    SCCOLROW        nMarkStart;
    SCCOLROW        nMarkEnd;
    BOOL            bMarkRange;

    BOOL            bDragging;              // Groessen aendern
    SCCOLROW        nDragNo;
    long            nDragStart;
    long            nDragPos;
    BOOL            bDragMoved;

    BOOL            bIgnoreMove;

    long            GetScrPos( SCCOLROW nEntryNo );
    SCCOLROW        GetMousePos( const MouseEvent& rMEvt, BOOL& rBorder );

    void            ShowDragHelp();

    void            DoPaint( SCCOLROW nStart, SCCOLROW nEnd );

protected:
                    //  von Window ueberladen

    virtual void    Paint( const Rectangle& rRect );

    virtual void    MouseMove( const MouseEvent& rMEvt );
    virtual void    MouseButtonUp( const MouseEvent& rMEvt );
    virtual void    MouseButtonDown( const MouseEvent& rMEvt );
    virtual void    Tracking( const TrackingEvent& rTEvt );

    virtual void    RequestHelp( const HelpEvent& rHEvt );

                    //  neue Methoden

    virtual SCCOLROW    GetPos() = 0;                               // aktuelle Position (Scrolling)
    virtual USHORT  GetEntrySize( SCCOLROW nEntryNo ) = 0;      // Breite / Hoehe (Pixel)
    virtual String  GetEntryText( SCCOLROW nEntryNo ) = 0;

    virtual SCCOLROW GetHiddenCount( SCCOLROW nEntryNo );
    virtual BOOL    IsLayoutRTL();
    virtual BOOL    IsMirrored();

    virtual void    SetEntrySize( SCCOLROW nPos, USHORT nNewWidth ) = 0;
    virtual void    HideEntries( SCCOLROW nStart, SCCOLROW nEnd ) = 0;

    virtual void    SetMarking( BOOL bSet );
    virtual void    SelectWindow();
    virtual BOOL    IsDisabled();
    virtual BOOL    ResizeAllowed();
    virtual String  GetDragHelp( long nVal );

    virtual void    DrawInvert( long nDragPos );
    virtual void    Command( const CommandEvent& rCEvt );

public:
            ScHeaderControl( Window* pParent, SelectionEngine* pSelectionEngine,
                                SCCOLROW nNewSize, USHORT nNewFlags );
            ~ScHeaderControl();

    void    SetIgnoreMove(BOOL bSet)            { bIgnoreMove = bSet; }

    void    StopMarking();

    void    SetMark( BOOL bNewSet, SCCOLROW nNewStart, SCCOLROW nNewEnd );

    long    GetWidth() const                    { return nWidth; }
    long    GetSmallWidth() const               { return nSmallWidth; }
    long    GetBigWidth() const                 { return nBigWidth; }
    void    SetWidth( long nNew );
};

#endif

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sizedev.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 21:50:46 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SC_SIZEDEV_HXX
#define SC_SIZEDEV_HXX

#ifndef _SV_MAPMOD_HXX
#include <vcl/mapmod.hxx>
#endif

class OutputDevice;
class ScDocShell;

class ScSizeDeviceProvider
{
    OutputDevice*   pDevice;
    BOOL            bOwner;
    double          nPPTX;
    double          nPPTY;
    MapMode         aOldMapMode;

public:
                ScSizeDeviceProvider( ScDocShell* pDocSh );
                ~ScSizeDeviceProvider();

    OutputDevice*   GetDevice() const   { return pDevice; }
    double          GetPPTX() const     { return nPPTX; }
    double          GetPPTY() const     { return nPPTY; }
    BOOL            IsPrinter() const   { return !bOwner; }
};

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.3.700); FILE MERGED 2008/04/01 15:31:00 thb 1.3.700.2: #i85898# Stripping all external header guards 2008/03/31 17:15:48 rt 1.3.700.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: sizedev.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SC_SIZEDEV_HXX
#define SC_SIZEDEV_HXX

#include <vcl/mapmod.hxx>

class OutputDevice;
class ScDocShell;

class ScSizeDeviceProvider
{
    OutputDevice*   pDevice;
    BOOL            bOwner;
    double          nPPTX;
    double          nPPTY;
    MapMode         aOldMapMode;

public:
                ScSizeDeviceProvider( ScDocShell* pDocSh );
                ~ScSizeDeviceProvider();

    OutputDevice*   GetDevice() const   { return pDevice; }
    double          GetPPTX() const     { return nPPTX; }
    double          GetPPTY() const     { return nPPTY; }
    BOOL            IsPrinter() const   { return !bOwner; }
};

#endif

<|endoftext|>


<commit_before>/*!
 *  @author Richard Everhart
 *  @date   July 2017
 *
 *  Declarations and template definitions for all tsty library
 *  functions
!*/

#ifndef TSTY_HPP__
#define TSTY_HPP__

#include <type_traits>
#include <string>

namespace tsty {

//! Rudimentary structure for storing RGB color values.
struct Rgb {
    unsigned char r = 0, g = 0, b = 0;

    //! Constructor for initializing r, g, b values from a hexadecimal
    explicit Rgb(unsigned int hex);

    /*!
     *  Method for acquiring a hexadecimal representation of the rgb color
     *  data.
     *
     *  @return An unsigned integer that is the hexadecimal representation
    !*/
    unsigned int hex();
};
typedef Rgb rgb;

//! Enum containing flags representing various ANSI-Supported text emphasis
enum Emphasis {
    NORMAL          = 0x000001,
    BOLD            = 0x000002,
    FAINT           = 0x000004,
    ITALIC          = 0x000008,
    UNDERLINE       = 0x000010,
    SLOW_BLINK      = 0x000020,
    FAST_BLINK      = 0x000040,
    NEGATIVE        = 0x000080,
    CONCEAL         = 0x000100,
    CROSS_OUT       = 0x000200,
    FRAKTUR         = 0x000400,
    NO_BOLD         = 0x000800,
    NO_COLOR        = 0x001000,
    NO_ITALIC       = 0x002000,
    NO_UNDERLINE    = 0x004000,
    POSITIVE        = 0x008000,
    REVEAL          = 0x010000,
    NO_CROSS_OUT    = 0x020000,
    FRAME           = 0x040000,
    ENCIRCLE        = 0x080000,
    OVERLINE        = 0x100000,
    NO_FRAME        = 0x200000,
    NO_OVERLINE     = 0x400000
};
typedef Emphasis emphasis;

/*!
 *  Sets the current emphasis of all subsequent outputted text to correspond to
 *  the emphasis specified by flags.
 *
 *  Example usage:
 *  @code
 *      emphasis(ITALIC | NEGATIVE | FRAME);
 *  @endcode
 *
 *  @param flags    A bit flag specifying the emphasis
!*/
void emphasis_on(unsigned int flags);

/*!
 *  Sets the current emphasis of all subsequent outputted text to correspond to
 *  the emphasis specified by a variadic list of elements n.
 *
 *  Example usage:
 *  @code
 *      emphasis(ITALIC, NEGATIVE, FRAME);
 *  @endcode
 *
 *  @param n    A variadic list specifying the emphasis
!*/
void emphasis_on(Emphasis n...);

//! Turns off any emphasis that may have been set previously using
void emphasis_off();

/*!
 *  Returns a string representing an ANSI escape sequence that may be printed
 *  in the future to set the emphasis.
 *
 *  Example usage:
 *  @code
 *      std::string str = ansi_emphasis(ITALIC | BOLD);
 *      std::cout << str << "Styled text!" << std::endl;
 *  @endcode
 *
 *  @param flags    A bit flag specifying the emphasis
 *
 *  @return A string representing an ANSI escape sequence that may be pinted in
 *          the future to set the emphasis.
!*/
std::string ansi_emphasis(unsigned int flags);

/*!
 *  Returns a string representing an ANSI escape sequence that may be printed
 *  in the future to set the emphasis.
 *
 *  Example usage:
 *  @code
 *      std::string str = ansi_emphasis(ITALIC, BOLD);
 *      std::cout << str << "Styled text!" << std::endl;
 *  @endcode
 *
 *  @param n    A variadic list specifying the emphasis
 *
 *  @return A string representing an ANSI escape sequence that may be pinted in
 *          the future to set the emphasis.
!*/
std::string ansi_emphasis(Emphasis n...);

}

#endif
<commit_msg>Added color_on(), color_off() and ansi_color() function declarations.<commit_after>/*!
 *  @author Richard Everhart
 *  @date   July 2017
 *
 *  Declarations and template definitions for all tsty library
 *  functions
!*/

#ifndef TSTY_HPP__
#define TSTY_HPP__

#include <type_traits>
#include <string>

namespace tsty {

//! Rudimentary structure for storing RGB color values.
struct Rgb {
    unsigned char r = 0, g = 0, b = 0;

    //! Constructor for initializing r, g, b values from a hexadecimal
    explicit Rgb(unsigned int hex);

    /*!
     *  Method for acquiring a hexadecimal representation of the rgb color
     *  data.
     *
     *  @return An unsigned integer that is the hexadecimal representation
    !*/
    unsigned int hex();
};
typedef Rgb rgb;

//! Enum containing flags representing various ANSI-Supported text emphasis
enum Emphasis {
    NORMAL          = 0x000001,
    BOLD            = 0x000002,
    FAINT           = 0x000004,
    ITALIC          = 0x000008,
    UNDERLINE       = 0x000010,
    SLOW_BLINK      = 0x000020,
    FAST_BLINK      = 0x000040,
    NEGATIVE        = 0x000080,
    CONCEAL         = 0x000100,
    CROSS_OUT       = 0x000200,
    FRAKTUR         = 0x000400,
    NO_BOLD         = 0x000800,
    NO_COLOR        = 0x001000,
    NO_ITALIC       = 0x002000,
    NO_UNDERLINE    = 0x004000,
    POSITIVE        = 0x008000,
    REVEAL          = 0x010000,
    NO_CROSS_OUT    = 0x020000,
    FRAME           = 0x040000,
    ENCIRCLE        = 0x080000,
    OVERLINE        = 0x100000,
    NO_FRAME        = 0x200000,
    NO_OVERLINE     = 0x400000
};
typedef Emphasis emphasis;

/*!
 *  Sets the current emphasis of all subsequent outputted text to correspond to
 *  the emphasis specified by flags.
 *
 *  Example usage:
 *  @code
 *      emphasis(ITALIC | NEGATIVE | FRAME);
 *  @endcode
 *
 *  @param flags    A bit flag specifying the emphasis
!*/
void emphasis_on(unsigned int flags);

/*!
 *  Sets the current emphasis of all subsequent outputted text to correspond to
 *  the emphasis specified by a variadic list of elements n.
 *
 *  Example usage:
 *  @code
 *      emphasis(ITALIC, NEGATIVE, FRAME);
 *  @endcode
 *
 *  @param n    A variadic list specifying the emphasis
!*/
void emphasis_on(Emphasis n...);

//! Turns off any emphasis that may have been set previously
void emphasis_off();

/*!
 *  Returns a string representing an ANSI escape sequence that may be printed
 *  in the future to set the emphasis.
 *
 *  Example usage:
 *  @code
 *      std::string str = ansi_emphasis(ITALIC | BOLD);
 *      std::cout << str << "Styled text!" << std::endl;
 *  @endcode
 *
 *  @param flags    A bit flag specifying the emphasis
 *
 *  @return A string representing an ANSI escape sequence that may be pinted in
 *          the future to set the text emphasis.
!*/
std::string ansi_emphasis(unsigned int flags);

/*!
 *  Returns a string representing an ANSI escape sequence that may be printed
 *  in the future to set the emphasis.
 *
 *  Example usage:
 *  @code
 *      std::string str = ansi_emphasis(ITALIC, BOLD);
 *      std::cout << str << "Styled text!" << std::endl;
 *  @endcode
 *
 *  @param n    A variadic list specifying the emphasis
 *
 *  @return A string representing an ANSI escape sequence that may be printed
 *          in the future to set the text emphasis.
!*/
std::string ansi_emphasis(Emphasis n...);

/*!
 *  Sets the background and foreground colors of all subsequent outputted text
 *  to correspond to the values specified by fg and bg, respectively.
 *
 *  Example usage:
 *  @code
 *      color_on(rgb(127, 127, 255), rgb(255, 127, 127);
 *  @endcode
 *
 *  @param fg   A rgb color value specifying the desired foreground color
 *  @param bg   A rgb color value specifying the desired background color
!*/
void color_on(rgb fg, rgb bg);

//! Turns off any color that may have been set previously
void color_off();

/*!
 *  Returns a string representing an ANSI escape sequence that may be printed
 *  in the future to set the text color.
 *
 *  Example usage:
 *  @code
 *      std::string str = ansi_color(rgb(0, 0, 0), rgb(255, 255, 255));
 *      std::cout << str << "Black text on a white background!" << std::endl;
 *  @endcode
 *
 *  @param fg   A rgb color value specifying the desired foreground color
 *  @param bg   A rgb color value specifying the desired background color
 *
 *  @return A string representing an ANSI escape sequence that may be printed
 *          in the future to set the text color.
!*/
ansi_color(rgb fg, rgb bg);

}

#endif
<|endoftext|>


<commit_before>#include "fencemodel.h"

using namespace troen;

FenceModel::FenceModel(FenceController* fenceController)
{
	m_fenceController = fenceController;
	m_rigidBodies = std::vector<std::shared_ptr<btRigidBody>>();
}

void FenceModel::addFencePart(btVector3 a, btVector3 b)
{
	btVector3 fenceVector = b - a;

	// TODO: convert to shared_ptr
	btBoxShape *boxShape = new btBoxShape(btVector3(1, fenceVector.length() / 2, getFenceHeight() / 2));

	const btVector3 up = btVector3(0, 0, 1);
	const btVector3 forward = btVector3(0, 1, 0);
	const btScalar angle = fenceVector.angle(forward);

	btQuaternion rotationQuat;
	if (angle > 0) {
		btVector3 axis = fenceVector.cross(-forward).normalized();
		rotationQuat = btQuaternion(axis, angle);
	}
	btDefaultMotionState *fenceMotionState = new btDefaultMotionState(btTransform(rotationQuat, (a + b) / 2 + btVector3(0, 0, getFenceHeight() / 2)));

	const btScalar mass = 0;
	const btVector3 fenceInertia(0, 0, 0);

	btRigidBody::btRigidBodyConstructionInfo m_fenceRigidBodyCI(mass, fenceMotionState, boxShape, fenceInertia);

	std::shared_ptr<btRigidBody> fenceRigidBody = std::make_shared<btRigidBody>(m_fenceRigidBodyCI);

	m_rigidBodies.push_back(fenceRigidBody);
}

btRigidBody* FenceModel::getLastPart() {
	return m_rigidBodies.back().get();
}

void FenceModel::addFenceMarker(btVector3 a)
{
	// TODO: convert to shared_ptr
	btBoxShape *boxShape = new btBoxShape(btVector3(0.5, 0.5, getFenceHeight() / 2));

	btDefaultMotionState *fenceMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), a + btVector3(0, 0, getFenceHeight() / 4)));

	// set mass to zero so that we get a static rigidBody (is this enough?)
	btScalar mass = 0;
	btVector3 fenceInertia(0, 0, 0);
	// boxShape->calculateLocalInertia(mass, fenceInertia);www

	btRigidBody::btRigidBodyConstructionInfo m_fenceRigidBodyCI(mass, fenceMotionState, boxShape, fenceInertia);

	std::shared_ptr<btRigidBody> fenceRigidBody = std::make_shared<btRigidBody>(m_fenceRigidBodyCI);

	m_rigidBodies.push_back(fenceRigidBody);
}

float FenceModel::getFenceHeight()
{
	return 20;
}<commit_msg>fixes collision with fence sound, two lines of code got lost in merge<commit_after>#include "fencemodel.h"

using namespace troen;

FenceModel::FenceModel(FenceController* fenceController)
{
	m_fenceController = fenceController;
	m_rigidBodies = std::vector<std::shared_ptr<btRigidBody>>();
}

void FenceModel::addFencePart(btVector3 a, btVector3 b)
{
	btVector3 fenceVector = b - a;

	// TODO: convert to shared_ptr
	btBoxShape *boxShape = new btBoxShape(btVector3(1, fenceVector.length() / 2, getFenceHeight() / 2));

	const btVector3 up = btVector3(0, 0, 1);
	const btVector3 forward = btVector3(0, 1, 0);
	const btScalar angle = fenceVector.angle(forward);

	btQuaternion rotationQuat;
	if (angle > 0) {
		btVector3 axis = fenceVector.cross(-forward).normalized();
		rotationQuat = btQuaternion(axis, angle);
	}
	btDefaultMotionState *fenceMotionState = new btDefaultMotionState(btTransform(rotationQuat, (a + b) / 2 + btVector3(0, 0, getFenceHeight() / 2)));

	const btScalar mass = 0;
	const btVector3 fenceInertia(0, 0, 0);

	btRigidBody::btRigidBodyConstructionInfo m_fenceRigidBodyCI(mass, fenceMotionState, boxShape, fenceInertia);

	std::shared_ptr<btRigidBody> fenceRigidBody = std::make_shared<btRigidBody>(m_fenceRigidBodyCI);
	fenceRigidBody->setUserPointer(m_fenceController);

	m_rigidBodies.push_back(fenceRigidBody);
}

btRigidBody* FenceModel::getLastPart() {
	return m_rigidBodies.back().get();
}

void FenceModel::addFenceMarker(btVector3 a)
{
	// TODO: convert to shared_ptr
	btBoxShape *boxShape = new btBoxShape(btVector3(0.5, 0.5, getFenceHeight() / 2));

	btDefaultMotionState *fenceMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), a + btVector3(0, 0, getFenceHeight() / 4)));

	// set mass to zero so that we get a static rigidBody (is this enough?)
	btScalar mass = 0;
	btVector3 fenceInertia(0, 0, 0);
	// boxShape->calculateLocalInertia(mass, fenceInertia);www

	btRigidBody::btRigidBodyConstructionInfo m_fenceRigidBodyCI(mass, fenceMotionState, boxShape, fenceInertia);

	std::shared_ptr<btRigidBody> fenceRigidBody = std::make_shared<btRigidBody>(m_fenceRigidBodyCI);
	fenceRigidBody->setUserPointer(m_fenceController);

	m_rigidBodies.push_back(fenceRigidBody);
}

float FenceModel::getFenceHeight()
{
	return 20;
}<|endoftext|>


<commit_before>#include "picasso.h"

// !! Taken from ctrulib !!
u32 f32tof24(float vf)
{
	if (!vf) return 0;

	union { float f; u32 v; } q;
	q.f=vf;

	u8 s = q.v>>31;
	u32 exp = ((q.v>>23) & 0xFF) - 0x40;
	u32 man = (q.v>>7) & 0xFFFF;

	if (exp >= 0)
		return man | (exp<<16) | (s<<23);
	else
		return s<<23;
}

#ifdef WIN32
static inline void FixMinGWPath(char* buf)
{
	if (buf && *buf == '/')
	{
		buf[0] = buf[1];
		buf[1] = ':';
	}
}
#endif

int usage(const char* prog)
{
	fprintf(stderr,
		"Usage:\n\n"
		"%s shbinFile vshFile [hFile]\n", prog);
	return 0;
}

int main(int argc, char* argv[])
{
	if (argc < 3 || argc > 4)
		return usage(argv[0]);

	char* shbinFile = argv[1];
	char* vshFile = argv[2];
	char* hFile = argc > 3 ? argv[3] : NULL;

#ifdef WIN32
	FixMinGWPath(shbinFile);
	FixMinGWPath(vshFile);
	FixMinGWPath(hFile);
#endif

	char* sourceCode = StringFromFile(vshFile);
	if (!sourceCode)
	{
		fprintf(stderr, "Cannot open input file!\n");
		return 1;
	}

	int rc = AssembleString(sourceCode, vshFile);
	free(sourceCode);
	if (rc != 0)
		return rc;

	procTableIter mainIt = g_procTable.find("main");
	if (mainIt == g_procTable.end())
	{
		fprintf(stderr, "Error: main proc not defined\n");
		return 1;
	}

	FileClass f(shbinFile, "wb");

	if (f.openerror())
	{
		fprintf(stderr, "Can't open output file!");
		return 1;
	}

	f.WriteWord(0x424C5644); // DVLB
	f.WriteWord(1); // 1 DVLE
	f.WriteWord(3*4 + 0x28); // offset to DVLE

	u32 dvlpStart = f.Tell();
	u32 shaderSize = g_outputBuf.size();
	u32 paramStart = 0x28 + 0x40;

	f.WriteWord(0x504C5644); // DVLP
	f.WriteWord(0); // version
	f.WriteWord(paramStart); // offset to shader binary blob
	f.WriteWord(shaderSize); // size of shader binary blob
	paramStart += shaderSize*4;
	f.WriteWord(paramStart); // offset to opdesc table
	f.WriteWord(g_opdescCount); // number of opdescs
	paramStart += g_opdescCount*8;
	f.WriteWord(paramStart); // offset to symtable (TODO)
	f.WriteWord(0); // ????
	f.WriteWord(0); // ????
	f.WriteWord(0); // ????

	u32 dvleStart = f.Tell();
	paramStart -= dvleStart - dvlpStart;

	f.WriteWord(0x454C5644); // DVLE
	f.WriteHword(0); // padding?
	f.WriteHword(0); // Vertex shader
	f.WriteWord(mainIt->second.first); // offset to main
	f.WriteWord(mainIt->second.first+mainIt->second.second); // offset to end of main
	f.WriteWord(0); // ???
	f.WriteWord(0); // ???
	f.WriteWord(paramStart); // offset to constant table
	f.WriteWord(g_constantCount); // size of constant table
	paramStart += g_constantCount*0x14;
	f.WriteWord(paramStart); // offset to label table (TODO)
	f.WriteWord(0); // size of label table (TODO)
	f.WriteWord(paramStart); // offset to output table
	f.WriteWord(g_outputCount); // size of output table
	paramStart += g_outputCount*8;
	f.WriteWord(paramStart); // offset to uniform table
	f.WriteWord(g_uniformCount); // size of uniform table
	paramStart += g_uniformCount*8;
	f.WriteWord(paramStart); // offset to symbol table
	u32 temp = f.Tell();
	f.WriteWord(0); // size of symbol table

	// Write program
	//for (u32 p : g_outputBuf)
	for (outputBufIter it = g_outputBuf.begin(); it != g_outputBuf.end(); ++it)
		f.WriteWord(*it);

	// Write opdescs
	for (int i = 0; i < g_opdescCount; i ++)
	{
		f.WriteWord(g_opdescTable[i]);
		f.WriteWord(0x0000000F); // unknown
	}

	// Write constants
	for (int i = 0; i < g_constantCount; i ++)
	{
		Constant& ct = g_constantTable[i];
		f.WriteHword(0);
		f.WriteByte(ct.regId-0x20);
		f.WriteByte(0);
		for (int j = 0; j < 4; j ++)
			f.WriteWord(f32tof24(ct.param[j]));
	}

	// Write outputs
	for (int i = 0; i < g_outputCount; i ++)
		f.WriteDword(g_outputTable[i]);

	// Write uniforms
	size_t sp = 0;
	for (int i = 0; i < g_uniformCount; i ++)
	{
		Uniform& u = g_uniformTable[i];
		size_t l = strlen(u.name)+1;
		f.WriteWord(sp); sp += l;
		f.WriteHword(u.pos-0x20);
		f.WriteHword(u.pos+u.size-1-0x20);
	}

	// Write size of symbol table
	u32 temp2 = f.Tell();
	f.Seek(temp, SEEK_SET);
	f.WriteWord(sp);
	f.Seek(temp2, SEEK_SET);

	// Write symbols
	for (int i = 0; i < g_uniformCount; i ++)
	{
		const char* u = g_uniformTable[i].name;
		size_t l = strlen(u)+1;
		f.WriteRaw(u, l);
	}

	if (hFile)
	{
		FILE* f2 = fopen(hFile, "w");
		if (!f2)
		{
			fprintf(stderr, "Can't open header file!\n");
			return 1;
		}

		fprintf(f2, "// Generated by picasso\n");
		fprintf(f2, "#pragma once\n");
		for (int i = 0; i < g_uniformCount; i ++)
		{
			Uniform& u = g_uniformTable[i];
			fprintf(f2, "#define SHADER_UREG_%s 0x%02X\n", u.name, u.pos-0x20);
			fprintf(f2, "#define SHADER_ULEN_%s %d\n", u.name, u.size);
		}

		fclose(f2);
	}

	return 0;
}
<commit_msg>Correct uniform handling value [pointed out by smea]<commit_after>#include "picasso.h"

// !! Taken from ctrulib !!
u32 f32tof24(float vf)
{
	if (!vf) return 0;

	union { float f; u32 v; } q;
	q.f=vf;

	u8 s = q.v>>31;
	u32 exp = ((q.v>>23) & 0xFF) - 0x40;
	u32 man = (q.v>>7) & 0xFFFF;

	if (exp >= 0)
		return man | (exp<<16) | (s<<23);
	else
		return s<<23;
}

#ifdef WIN32
static inline void FixMinGWPath(char* buf)
{
	if (buf && *buf == '/')
	{
		buf[0] = buf[1];
		buf[1] = ':';
	}
}
#endif

int usage(const char* prog)
{
	fprintf(stderr,
		"Usage:\n\n"
		"%s shbinFile vshFile [hFile]\n", prog);
	return 0;
}

int main(int argc, char* argv[])
{
	if (argc < 3 || argc > 4)
		return usage(argv[0]);

	char* shbinFile = argv[1];
	char* vshFile = argv[2];
	char* hFile = argc > 3 ? argv[3] : NULL;

#ifdef WIN32
	FixMinGWPath(shbinFile);
	FixMinGWPath(vshFile);
	FixMinGWPath(hFile);
#endif

	char* sourceCode = StringFromFile(vshFile);
	if (!sourceCode)
	{
		fprintf(stderr, "Cannot open input file!\n");
		return 1;
	}

	int rc = AssembleString(sourceCode, vshFile);
	free(sourceCode);
	if (rc != 0)
		return rc;

	procTableIter mainIt = g_procTable.find("main");
	if (mainIt == g_procTable.end())
	{
		fprintf(stderr, "Error: main proc not defined\n");
		return 1;
	}

	FileClass f(shbinFile, "wb");

	if (f.openerror())
	{
		fprintf(stderr, "Can't open output file!");
		return 1;
	}

	f.WriteWord(0x424C5644); // DVLB
	f.WriteWord(1); // 1 DVLE
	f.WriteWord(3*4 + 0x28); // offset to DVLE

	u32 dvlpStart = f.Tell();
	u32 shaderSize = g_outputBuf.size();
	u32 paramStart = 0x28 + 0x40;

	f.WriteWord(0x504C5644); // DVLP
	f.WriteWord(0); // version
	f.WriteWord(paramStart); // offset to shader binary blob
	f.WriteWord(shaderSize); // size of shader binary blob
	paramStart += shaderSize*4;
	f.WriteWord(paramStart); // offset to opdesc table
	f.WriteWord(g_opdescCount); // number of opdescs
	paramStart += g_opdescCount*8;
	f.WriteWord(paramStart); // offset to symtable (TODO)
	f.WriteWord(0); // ????
	f.WriteWord(0); // ????
	f.WriteWord(0); // ????

	u32 dvleStart = f.Tell();
	paramStart -= dvleStart - dvlpStart;

	f.WriteWord(0x454C5644); // DVLE
	f.WriteHword(0); // padding?
	f.WriteHword(0); // Vertex shader
	f.WriteWord(mainIt->second.first); // offset to main
	f.WriteWord(mainIt->second.first+mainIt->second.second); // offset to end of main
	f.WriteWord(0); // ???
	f.WriteWord(0); // ???
	f.WriteWord(paramStart); // offset to constant table
	f.WriteWord(g_constantCount); // size of constant table
	paramStart += g_constantCount*0x14;
	f.WriteWord(paramStart); // offset to label table (TODO)
	f.WriteWord(0); // size of label table (TODO)
	f.WriteWord(paramStart); // offset to output table
	f.WriteWord(g_outputCount); // size of output table
	paramStart += g_outputCount*8;
	f.WriteWord(paramStart); // offset to uniform table
	f.WriteWord(g_uniformCount); // size of uniform table
	paramStart += g_uniformCount*8;
	f.WriteWord(paramStart); // offset to symbol table
	u32 temp = f.Tell();
	f.WriteWord(0); // size of symbol table

	// Write program
	//for (u32 p : g_outputBuf)
	for (outputBufIter it = g_outputBuf.begin(); it != g_outputBuf.end(); ++it)
		f.WriteWord(*it);

	// Write opdescs
	for (int i = 0; i < g_opdescCount; i ++)
	{
		f.WriteWord(g_opdescTable[i]);
		f.WriteWord(0x0000000F); // unknown
	}

	// Write constants
	for (int i = 0; i < g_constantCount; i ++)
	{
		Constant& ct = g_constantTable[i];
		f.WriteHword(0);
		f.WriteByte(ct.regId-0x20);
		f.WriteByte(0);
		for (int j = 0; j < 4; j ++)
			f.WriteWord(f32tof24(ct.param[j]));
	}

	// Write outputs
	for (int i = 0; i < g_outputCount; i ++)
		f.WriteDword(g_outputTable[i]);

	// Write uniforms
	size_t sp = 0;
	for (int i = 0; i < g_uniformCount; i ++)
	{
		Uniform& u = g_uniformTable[i];
		size_t l = strlen(u.name)+1;
		f.WriteWord(sp); sp += l;
		f.WriteHword(u.pos-0x10);
		f.WriteHword(u.pos+u.size-1-0x10);
	}

	// Write size of symbol table
	u32 temp2 = f.Tell();
	f.Seek(temp, SEEK_SET);
	f.WriteWord(sp);
	f.Seek(temp2, SEEK_SET);

	// Write symbols
	for (int i = 0; i < g_uniformCount; i ++)
	{
		const char* u = g_uniformTable[i].name;
		size_t l = strlen(u)+1;
		f.WriteRaw(u, l);
	}

	if (hFile)
	{
		FILE* f2 = fopen(hFile, "w");
		if (!f2)
		{
			fprintf(stderr, "Can't open header file!\n");
			return 1;
		}

		fprintf(f2, "// Generated by picasso\n");
		fprintf(f2, "#pragma once\n");
		for (int i = 0; i < g_uniformCount; i ++)
		{
			Uniform& u = g_uniformTable[i];
			fprintf(f2, "#define SHADER_UREG_%s 0x%02X\n", u.name, u.pos-0x20);
			fprintf(f2, "#define SHADER_ULEN_%s %d\n", u.name, u.size);
		}

		fclose(f2);
	}

	return 0;
}
<|endoftext|>


<commit_before>//@	{"targets":[{"name":"type.hpp","type":"include"}]}

#ifndef TEMPLE_TYPE_HPP
#define TEMPLE_TYPE_HPP

#include "error.hpp"
#include <cassert>
#include <type_traits>

namespace Temple
	{
	enum class Type:int
		{
		 I8=0,I8_ARRAY
		,I16,I16_ARRAY
		,I32,I32_ARRAY
		,I64,I64_ARRAY
		,FLOAT,FLOAT_ARRAY
		,DOUBLE,DOUBLE_ARRAY
		,STRING,STRING_ARRAY
		,COMPOUND,COMPOUND_ARRAY
		};

	inline constexpr Type arraySet(Type t)
		{return static_cast<Type>(static_cast<int>(t) | 1);}

	inline constexpr Type arrayUnset(Type t)
		{return static_cast<Type>(static_cast<int>(t)&( ~1));}

	inline constexpr Type next(Type t)
		{return static_cast<Type>(static_cast<int>(t) + 1);}

	inline constexpr Type step(Type t,int x)
		{return static_cast<Type>(static_cast<int>(t) + x);}

	inline constexpr Type previous(Type t)
		{return static_cast<Type>(static_cast<int>(t) - 1);}

	template<Type t,class StorageModel>
	struct TypeGet:private TypeGet<arrayUnset(t),StorageModel>
		{
		typedef typename TypeGet<arrayUnset(t),StorageModel>::type BaseType;
		static constexpr auto id=t;
		typedef typename StorageModel::template ArrayType<BaseType> type;
		};

	template<class StorageModel>
	struct TypeGet<Type::I8,StorageModel>
		{
		static constexpr auto id=Type::I8;
		typedef int8_t type;
		};

	template<class StorageModel>
	struct TypeGet<Type::I16,StorageModel>
		{
		static constexpr auto id=Type::I16;
		typedef int8_t type;
		};

	template<class StorageModel>
	struct TypeGet<Type::I32,StorageModel>
		{
		static constexpr auto id=Type::I32;
		typedef int32_t type;
		};

	template<class StorageModel>
	struct TypeGet<Type::I64,StorageModel>
		{
		static constexpr auto id=Type::I64;
		typedef int64_t type;
		};

	template<class StorageModel>
	struct TypeGet<Type::FLOAT,StorageModel>
		{
		static constexpr auto id=Type::FLOAT;
		typedef float type;
		};

	template<class StorageModel>
	struct TypeGet<Type::DOUBLE,StorageModel>
		{
		static constexpr auto id=Type::DOUBLE;
		typedef double type;
		};

	template<class StorageModel>
	struct TypeGet<Type::STRING,StorageModel>
		{
		static constexpr auto id=Type::STRING;
		typedef typename StorageModel::StringType type;
		};

	template<class StorageModel>
	struct TypeGet<Type::COMPOUND,StorageModel>
		{
		static constexpr auto id=Type::COMPOUND;
		typedef void type;
		};

	template<Type t,int x,Type t_end,class StorageModel,bool cont>
	struct TypeProcess
		{
		template<class Callback,class ExceptionHandler>
		static void doIt(Type type,Callback& cb,ExceptionHandler& eh)
			{
			if(t==type)
				{
				cb(TypeGet<t,StorageModel>{});
				}
			else
				{
				static constexpr auto t_next=step(t,x);
				static constexpr bool cont_next=static_cast<int>(t_next) <= static_cast<int>(t_end);
				TypeProcess<t_next,x,t_end,StorageModel,cont_next>::doIt(type,cb,eh);
				}
			}
		};

	template<Type t,int x,Type t_end,class StorageModel>
	struct TypeProcess<t,x,t_end,StorageModel,0>
		{
		template<class Callback,class ExceptionHandler>
		static void doIt(Type type,Callback& cb,ExceptionHandler& eh)
			{eh.raise(Error("Internal error: Type not found."));}
		};

	template<class StorageModel,Type start,int x,Type end,class Callback,class ExceptionHandler>
	inline void for_type(Type type,Callback&& cb,ExceptionHandler& eh)
		{TypeProcess<start,x,end,StorageModel,1>::doIt(type,cb,eh);}

	template<class StringType,class ExceptionHandler>
	inline Type type(const StringType& str,ExceptionHandler& eh)
		{
		if(str=="s")
			{return Type::STRING;}
		if(str=="i8")
			{return Type::I8;}
		if(str=="i16")
			{return Type::I16;}
		if(str=="i32")
			{return Type::I32;}
		if(str=="i64")
			{return Type::I64;}
		if(str=="f")
			{return Type::FLOAT;}
		if(str=="d")
			{return Type::DOUBLE;}
		if(str=="")
			{return Type::COMPOUND;}
		eh.raise(Error("The type identifier ",str.c_str()," does not correspond to a known type."));
		return Type::COMPOUND;
		}

	inline const char* type(Type type)
		{
		switch(arrayUnset(type))
			{
			case Type::I8:
				return "i8";
			case Type::I16:
				return "i16";
			case Type::I32:
				return "i32";
			case Type::I64:
				return "i64";
			case Type::FLOAT:
				return "f";
			case Type::DOUBLE:
				return "d";
			case Type::STRING:
				return "s";
			case Type::COMPOUND:
				return "";
			default:
				assert(1!=1);
				return nullptr;
			}
		assert(1!=1);
		return nullptr;
		}
	}

#endif
<commit_msg>Inverse type map<commit_after>//@	{"targets":[{"name":"type.hpp","type":"include"}]}

#ifndef TEMPLE_TYPE_HPP
#define TEMPLE_TYPE_HPP

#include "error.hpp"
//#include "stringconst.hpp"
#include <cassert>
#include <type_traits>

namespace Temple
	{
	enum class Type:int
		{
		 I8=0,I8_ARRAY
		,I16,I16_ARRAY
		,I32,I32_ARRAY
		,I64,I64_ARRAY
		,FLOAT,FLOAT_ARRAY
		,DOUBLE,DOUBLE_ARRAY
		,STRING,STRING_ARRAY
		,COMPOUND,COMPOUND_ARRAY
		};

	inline constexpr Type arraySet(Type t)
		{return static_cast<Type>(static_cast<int>(t) | 1);}

	inline constexpr Type arrayUnset(Type t)
		{return static_cast<Type>(static_cast<int>(t)&( ~1));}

	inline constexpr Type next(Type t)
		{return static_cast<Type>(static_cast<int>(t) + 1);}

	inline constexpr Type step(Type t,int x)
		{return static_cast<Type>(static_cast<int>(t) + x);}

	inline constexpr Type previous(Type t)
		{return static_cast<Type>(static_cast<int>(t) - 1);}

	template<Type t,class StorageModel>
	struct TypeGet:private TypeGet<arrayUnset(t),StorageModel>
		{
		typedef typename TypeGet<arrayUnset(t),StorageModel>::type BaseType;
		static constexpr auto id=t;
		typedef typename StorageModel::template ArrayType<BaseType> type;

/*		static constexpr auto name_buffer=concat(TypeGet<arrayUnset(t),StorageModel>::name," array");
		static constexpr const char* name=name_buffer.begin();*/
		};

	template<class T,class StorageModel>
	struct IdGet
		{
		static constexpr auto id=arraySet(IdGet<typename T::value_type,StorageModel>::id);
		typedef T type;
		};

	template<class StorageModel>
	struct TypeGet<Type::I8,StorageModel>
		{
		static constexpr auto id=Type::I8;
		typedef int8_t type;
		};

	template<class StorageModel>
	struct IdGet<int8_t,StorageModel>
		{
		static constexpr auto id=Type::I8;
		typedef int8_t type;
		};

	template<class StorageModel>
	struct TypeGet<Type::I16,StorageModel>
		{
		static constexpr auto id=Type::I16;
		typedef int8_t type;
		};

	template<class StorageModel>
	struct IdGet<int16_t,StorageModel>
		{
		static constexpr auto id=Type::I16;
		typedef int16_t type;
		};

	template<class StorageModel>
	struct TypeGet<Type::I32,StorageModel>
		{
		static constexpr auto id=Type::I32;
		typedef int32_t type;
		};

	template<class StorageModel>
	struct IdGet<int32_t,StorageModel>
		{
		static constexpr auto id=Type::I32;
		typedef int32_t type;
		};

	template<class StorageModel>
	struct TypeGet<Type::I64,StorageModel>
		{
		static constexpr auto id=Type::I64;
		typedef int64_t type;
		};

	template<class StorageModel>
	struct IdGet<int64_t,StorageModel>
		{
		static constexpr auto id=Type::I64;
		typedef int64_t type;
		};

	template<class StorageModel>
	struct TypeGet<Type::FLOAT,StorageModel>
		{
		static constexpr auto id=Type::FLOAT;
		typedef float type;
		};

	template<class StorageModel>
	struct IdGet<float,StorageModel>
		{
		static constexpr auto id=Type::FLOAT;
		typedef float type;
		};

	template<class StorageModel>
	struct TypeGet<Type::DOUBLE,StorageModel>
		{
		static constexpr auto id=Type::DOUBLE;
		typedef double type;
		};

	template<class StorageModel>
	struct IdGet<double,StorageModel>
		{
		static constexpr auto id=Type::DOUBLE;
		typedef double type;
		};

	template<class StorageModel>
	struct TypeGet<Type::STRING,StorageModel>
		{
		static constexpr auto id=Type::STRING;
		typedef typename StorageModel::StringType type;
		};

	template<class StorageModel>
	struct IdGet<typename StorageModel::StringType,StorageModel>
		{
		static constexpr auto id=Type::STRING;
		typedef typename StorageModel::StringType type;
		};

	template<class StorageModel>
	struct TypeGet<Type::COMPOUND,StorageModel>
		{
		static constexpr auto id=Type::COMPOUND;
		typedef void type;
		};

	template<Type t,int x,Type t_end,class StorageModel,bool cont>
	struct TypeProcess
		{
		template<class Callback,class ExceptionHandler>
		static void doIt(Type type,Callback& cb,ExceptionHandler& eh)
			{
			if(t==type)
				{
				cb(TypeGet<t,StorageModel>{});
				}
			else
				{
				static constexpr auto t_next=step(t,x);
				static constexpr bool cont_next=static_cast<int>(t_next) <= static_cast<int>(t_end);
				TypeProcess<t_next,x,t_end,StorageModel,cont_next>::doIt(type,cb,eh);
				}
			}
		};

	template<Type t,int x,Type t_end,class StorageModel>
	struct TypeProcess<t,x,t_end,StorageModel,0>
		{
		template<class Callback,class ExceptionHandler>
		static void doIt(Type type,Callback& cb,ExceptionHandler& eh)
			{eh.raise(Error("Internal error: Type not found."));}
		};

	template<class StorageModel,Type start,int x,Type end,class Callback,class ExceptionHandler>
	inline void for_type(Type type,Callback&& cb,ExceptionHandler& eh)
		{TypeProcess<start,x,end,StorageModel,1>::doIt(type,cb,eh);}

	template<class StringType,class ExceptionHandler>
	inline Type type(const StringType& str,ExceptionHandler& eh)
		{
		if(str=="s")
			{return Type::STRING;}
		if(str=="i8")
			{return Type::I8;}
		if(str=="i16")
			{return Type::I16;}
		if(str=="i32")
			{return Type::I32;}
		if(str=="i64")
			{return Type::I64;}
		if(str=="f")
			{return Type::FLOAT;}
		if(str=="d")
			{return Type::DOUBLE;}
		if(str=="")
			{return Type::COMPOUND;}
		eh.raise(Error("The type identifier ",str.c_str()," does not correspond to a known type."));
		return Type::COMPOUND;
		}

	inline const char* type(Type type)
		{
		switch(arrayUnset(type))
			{
			case Type::I8:
				return "i8";
			case Type::I16:
				return "i16";
			case Type::I32:
				return "i32";
			case Type::I64:
				return "i64";
			case Type::FLOAT:
				return "f";
			case Type::DOUBLE:
				return "d";
			case Type::STRING:
				return "s";
			case Type::COMPOUND:
				return "";
			default:
				assert(1!=1);
				return nullptr;
			}
		assert(1!=1);
		return nullptr;
		}
	}

#endif
<|endoftext|>