<commit_before>#include "LLVM_Headers.h"
#include "CodeGen_X86.h"
#include "IROperator.h"
#include <iostream>
#include "buffer_t.h"
#include "IRPrinter.h"
#include "IRMatch.h"
#include "Log.h"
#include "Util.h"
#include "Var.h"
#include "Param.h"
#include "integer_division_table.h"

namespace Halide {
namespace Internal {

using std::vector;
using std::string;
using std::map;
using std::pair;
using std::stack;

using namespace llvm;

CodeGen_Posix::CodeGen_Posix() :
    CodeGen(),

    // Vector types. These need an LLVMContext before they can be initialized.
    i8x8(NULL),
    i8x16(NULL),
    i8x32(NULL),
    i16x4(NULL),
    i16x8(NULL),
    i16x16(NULL),
    i32x2(NULL),
    i32x4(NULL),
    i32x8(NULL),
    i64x2(NULL),
    i64x4(NULL),
    f32x2(NULL),
    f32x4(NULL),
    f32x8(NULL),
    f64x2(NULL),
    f64x4(NULL),

    // Wildcards for pattern matching
    wild_i8x8(Variable::make(Int(8, 8), "*")),
    wild_i16x4(Variable::make(Int(16, 4), "*")),
    wild_i32x2(Variable::make(Int(32, 2), "*")),

    wild_u8x8(Variable::make(UInt(8, 8), "*")),
    wild_u16x4(Variable::make(UInt(16, 4), "*")),
    wild_u32x2(Variable::make(UInt(32, 2), "*")),

    wild_i8x16(Variable::make(Int(8, 16), "*")),
    wild_i16x8(Variable::make(Int(16, 8), "*")),
    wild_i32x4(Variable::make(Int(32, 4), "*")),
    wild_i64x2(Variable::make(Int(64, 2), "*")),

    wild_u8x16(Variable::make(UInt(8, 16), "*")),
    wild_u16x8(Variable::make(UInt(16, 8), "*")),
    wild_u32x4(Variable::make(UInt(32, 4), "*")),
    wild_u64x2(Variable::make(UInt(64, 2), "*")),

    wild_i8x32(Variable::make(Int(8, 32), "*")),
    wild_i16x16(Variable::make(Int(16, 16), "*")),
    wild_i32x8(Variable::make(Int(32, 8), "*")),
    wild_i64x4(Variable::make(Int(64, 4), "*")),

    wild_u8x32(Variable::make(UInt(8, 32), "*")),
    wild_u16x16(Variable::make(UInt(16, 16), "*")),
    wild_u32x8(Variable::make(UInt(32, 8), "*")),
    wild_u64x4(Variable::make(UInt(64, 4), "*")),

    wild_f32x2(Variable::make(Float(32, 2), "*")),

    wild_f32x4(Variable::make(Float(32, 4), "*")),
    wild_f64x2(Variable::make(Float(64, 2), "*")),

    wild_f32x8(Variable::make(Float(32, 8), "*")),
    wild_f64x4(Variable::make(Float(64, 4), "*")),

    // Bounds of types
    min_i8(Int(8).min()),
    max_i8(Int(8).max()),
    max_u8(UInt(8).max()),

    min_i16(Int(16).min()),
    max_i16(Int(16).max()),
    max_u16(UInt(16).max()),

    min_i32(Int(32).min()),
    max_i32(Int(32).max()),
    max_u32(UInt(32).max()),

    min_i64(Int(64).min()),
    max_i64(Int(64).max()),
    max_u64(UInt(64).max()),

    min_f32(Float(32).min()),
    max_f32(Float(32).max()),

    min_f64(Float(64).min()),
    max_f64(Float(64).max()) {

}

void CodeGen_Posix::init_module() {
    CodeGen::init_module();

    i8x8 = VectorType::get(i8, 8);
    i8x16 = VectorType::get(i8, 16);
    i8x32 = VectorType::get(i8, 32);
    i16x4 = VectorType::get(i16, 4);
    i16x8 = VectorType::get(i16, 8);
    i16x16 = VectorType::get(i16, 16);
    i32x2 = VectorType::get(i32, 2);
    i32x4 = VectorType::get(i32, 4);
    i32x8 = VectorType::get(i32, 8);
    i64x2 = VectorType::get(i64, 2);
    i64x4 = VectorType::get(i64, 4);
    f32x2 = VectorType::get(f32, 2);
    f32x4 = VectorType::get(f32, 4);
    f32x8 = VectorType::get(f32, 8);
    f64x2 = VectorType::get(f64, 2);
    f64x4 = VectorType::get(f64, 4);
}

Value *CodeGen_Posix::save_stack() {
    llvm::Function *stacksave =
        llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::stacksave);
    return builder->CreateCall(stacksave);
}

void CodeGen_Posix::restore_stack(llvm::Value *saved_stack) {
    llvm::Function *stackrestore =
        llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::stackrestore);
    builder->CreateCall(stackrestore, saved_stack);
}

CodeGen_Posix::Allocation CodeGen_Posix::create_allocation(const std::string &name, Type type, Expr size) {

    Allocation allocation;

    int bytes_per_element = type.bits / 8;
    if (const IntImm *int_size = size.as<IntImm>()) {
        allocation.stack_size = int_size->value * bytes_per_element;

        // Round up to nearest multiple of 32.
        allocation.stack_size = ((allocation.stack_size + 31)/32)*32;

        // If it's more than 8k, put it on the heap.
        if (allocation.stack_size > 8*1024) {
            allocation.stack_size = 0;
        }
    } else {
        allocation.stack_size = 0;
    }

    llvm::Type *llvm_type = llvm_type_of(type);

    if (allocation.stack_size) {
        // First, try to reuse an existing free block using a best-fit
        // algorithm. Note that we don't actually need to fit, because
        // it's possible to go back to the original alloca and
        // increase its size.
        int best_fit = -1;
        int best_waste = 0;
        for (size_t i = 0; i < free_stack_blocks.size(); i++) {
            int waste = free_stack_blocks[i].stack_size - allocation.stack_size;
            if (waste < 0) waste = -waste;
            if (i == 0 || waste <= best_waste) {
                best_fit = (int)i;
                best_waste = waste;
            }
        }

        if (best_fit >= 0) {

            // Grab the old allocation and remove it from the free blocks list
            Allocation old_alloc = free_stack_blocks[best_fit];
            free_stack_blocks[best_fit] = free_stack_blocks[free_stack_blocks.size()-1];
            free_stack_blocks.pop_back();

            if (old_alloc.stack_size < allocation.stack_size) {
                log(2) << "Allocation of " << name << " reusing an old smaller allocation\n";
                // We need to go back in time and rewrite the original
                // alloca to be slightly larger so we can fit this one
                // into the same space.
                Value *size = ConstantInt::get(i32, allocation.stack_size/32);
                // Insert the new version just before the old version
                string old_name = old_alloc.alloca_inst->getName();
                AllocaInst *new_alloca = new AllocaInst(i32x8, size, old_name + "_" + name, old_alloc.alloca_inst);
                // Replace all uses of the old version with the new version
                old_alloc.alloca_inst->replaceAllUsesWith(new_alloca);
                // Delete the old version
                old_alloc.alloca_inst->eraseFromParent();
                // For future rewrites to this alloca, we want to rewrite the new version
                allocation.alloca_inst = new_alloca;

            } else {
                log(2) << "Allocation of " << name << " reusing an old larger allocation\n";
                allocation.alloca_inst = old_alloc.alloca_inst;
                allocation.stack_size = old_alloc.stack_size;
            }

            // No need to restore the stack if we're reusing an old allocation
            allocation.saved_stack = NULL;

            // The new allocation uses the same pointer and the same alloca instruction
            allocation.ptr = old_alloc.ptr;

        } else {
            // Do a new 32-byte aligned alloca
            allocation.saved_stack = save_stack();
            Value *size = ConstantInt::get(i32, allocation.stack_size/32);
            allocation.alloca_inst = builder->CreateAlloca(i32x8, size, name);
            allocation.ptr = builder->CreatePointerCast(allocation.alloca_inst, llvm_type->getPointerTo());
        }
    } else {
        allocation.saved_stack = NULL;
        allocation.alloca_inst = NULL;
        Value *llvm_size = codegen(size * bytes_per_element);

        // call malloc
        llvm::Function *malloc_fn = module->getFunction("halide_malloc");
        malloc_fn->setDoesNotAlias(0);
        assert(malloc_fn && "Could not find halide_malloc in module");

        llvm_size = builder->CreateIntCast(llvm_size, malloc_fn->arg_begin()->getType(), false);

        log(4) << "Creating call to halide_malloc\n";
        CallInst *call = builder->CreateCall(malloc_fn, llvm_size);
        allocation.ptr = call;
    }

    // Push the allocation base pointer onto the symbol table
    log(3) << "Pushing allocation called " << name << ".host onto the symbol table\n";

    allocations.push(name, allocation);
    sym_push(name + ".host", allocation.ptr);

    return allocation;
}

void CodeGen_Posix::free_allocation(const std::string &name) {
    Allocation alloc = allocations.get(name);

    if (alloc.stack_size) {
        log(2) << "Moving allocation " << name << " onto the free stack blocks list\n";
        // Mark this block as free, but don't restore the stack yet
        free_stack_blocks.push_back(alloc);
    } else {
        // Call free
        llvm::Function *free_fn = module->getFunction("halide_free");
        assert(free_fn && "Could not find halide_free in module");
        log(4) << "Creating call to halide_free\n";
        builder->CreateCall(free_fn, alloc.ptr);
    }

    sym_pop(name + ".host");
    allocations.pop(name);
}

void CodeGen_Posix::destroy_allocation(Allocation alloc) {

    if (alloc.saved_stack) {
        // We should be in the free blocks list
        bool found = false;
        for (size_t i = 0; !found && i < free_stack_blocks.size(); i++) {
            if (free_stack_blocks[i].ptr == alloc.ptr) {
                free_stack_blocks[i] = free_stack_blocks[free_stack_blocks.size()-1];
                free_stack_blocks.pop_back();
                found = true;
            }
        }
        assert(found && "Stack allocation should have been in the free blocks list");

        restore_stack(alloc.saved_stack);
    }

}

void CodeGen_Posix::visit(const Allocate *alloc) {

    Allocation allocation = create_allocation(alloc->name, alloc->type, alloc->size);

    codegen(alloc->body);

    // Should have been freed
    assert(!sym_exists(alloc->name + ".host"));
    assert(!allocations.contains(alloc->name));

    log(2) << "Destroying allocation " << alloc->name << "\n";
    destroy_allocation(allocation);
}

void CodeGen_Posix::visit(const Free *stmt) {
    free_allocation(stmt->name);
}

void CodeGen_Posix::prepare_for_early_exit() {
    // We've jumped to a code path that will be called just before
    // bailing out. Free everything outstanding.
    for (map<string, stack<Allocation> >::const_iterator iter = allocations.get_table().begin();
         iter != allocations.get_table().end(); ++iter) {
        string name = iter->first;
        std::vector<Allocation> stash;
        while (allocations.contains(name)) {
            stash.push_back(allocations.get(name));
            free_allocation(name);
        }

        // Restore all the allocations before we jump back to the main
        // code path.
        for (size_t i = stash.size(); i > 0; i--) {
            allocations.push(name, stash[i-1]);
            sym_push(name + ".host", stash[i-1].ptr);
        }
    }
}

}}
<commit_msg>Reusing old stack space was buggy :(<commit_after>#include "LLVM_Headers.h"
#include "CodeGen_X86.h"
#include "IROperator.h"
#include <iostream>
#include "buffer_t.h"
#include "IRPrinter.h"
#include "IRMatch.h"
#include "Log.h"
#include "Util.h"
#include "Var.h"
#include "Param.h"
#include "integer_division_table.h"

namespace Halide {
namespace Internal {

using std::vector;
using std::string;
using std::map;
using std::pair;
using std::stack;

using namespace llvm;

CodeGen_Posix::CodeGen_Posix() :
    CodeGen(),

    // Vector types. These need an LLVMContext before they can be initialized.
    i8x8(NULL),
    i8x16(NULL),
    i8x32(NULL),
    i16x4(NULL),
    i16x8(NULL),
    i16x16(NULL),
    i32x2(NULL),
    i32x4(NULL),
    i32x8(NULL),
    i64x2(NULL),
    i64x4(NULL),
    f32x2(NULL),
    f32x4(NULL),
    f32x8(NULL),
    f64x2(NULL),
    f64x4(NULL),

    // Wildcards for pattern matching
    wild_i8x8(Variable::make(Int(8, 8), "*")),
    wild_i16x4(Variable::make(Int(16, 4), "*")),
    wild_i32x2(Variable::make(Int(32, 2), "*")),

    wild_u8x8(Variable::make(UInt(8, 8), "*")),
    wild_u16x4(Variable::make(UInt(16, 4), "*")),
    wild_u32x2(Variable::make(UInt(32, 2), "*")),

    wild_i8x16(Variable::make(Int(8, 16), "*")),
    wild_i16x8(Variable::make(Int(16, 8), "*")),
    wild_i32x4(Variable::make(Int(32, 4), "*")),
    wild_i64x2(Variable::make(Int(64, 2), "*")),

    wild_u8x16(Variable::make(UInt(8, 16), "*")),
    wild_u16x8(Variable::make(UInt(16, 8), "*")),
    wild_u32x4(Variable::make(UInt(32, 4), "*")),
    wild_u64x2(Variable::make(UInt(64, 2), "*")),

    wild_i8x32(Variable::make(Int(8, 32), "*")),
    wild_i16x16(Variable::make(Int(16, 16), "*")),
    wild_i32x8(Variable::make(Int(32, 8), "*")),
    wild_i64x4(Variable::make(Int(64, 4), "*")),

    wild_u8x32(Variable::make(UInt(8, 32), "*")),
    wild_u16x16(Variable::make(UInt(16, 16), "*")),
    wild_u32x8(Variable::make(UInt(32, 8), "*")),
    wild_u64x4(Variable::make(UInt(64, 4), "*")),

    wild_f32x2(Variable::make(Float(32, 2), "*")),

    wild_f32x4(Variable::make(Float(32, 4), "*")),
    wild_f64x2(Variable::make(Float(64, 2), "*")),

    wild_f32x8(Variable::make(Float(32, 8), "*")),
    wild_f64x4(Variable::make(Float(64, 4), "*")),

    // Bounds of types
    min_i8(Int(8).min()),
    max_i8(Int(8).max()),
    max_u8(UInt(8).max()),

    min_i16(Int(16).min()),
    max_i16(Int(16).max()),
    max_u16(UInt(16).max()),

    min_i32(Int(32).min()),
    max_i32(Int(32).max()),
    max_u32(UInt(32).max()),

    min_i64(Int(64).min()),
    max_i64(Int(64).max()),
    max_u64(UInt(64).max()),

    min_f32(Float(32).min()),
    max_f32(Float(32).max()),

    min_f64(Float(64).min()),
    max_f64(Float(64).max()) {

}

void CodeGen_Posix::init_module() {
    CodeGen::init_module();

    i8x8 = VectorType::get(i8, 8);
    i8x16 = VectorType::get(i8, 16);
    i8x32 = VectorType::get(i8, 32);
    i16x4 = VectorType::get(i16, 4);
    i16x8 = VectorType::get(i16, 8);
    i16x16 = VectorType::get(i16, 16);
    i32x2 = VectorType::get(i32, 2);
    i32x4 = VectorType::get(i32, 4);
    i32x8 = VectorType::get(i32, 8);
    i64x2 = VectorType::get(i64, 2);
    i64x4 = VectorType::get(i64, 4);
    f32x2 = VectorType::get(f32, 2);
    f32x4 = VectorType::get(f32, 4);
    f32x8 = VectorType::get(f32, 8);
    f64x2 = VectorType::get(f64, 2);
    f64x4 = VectorType::get(f64, 4);
}

Value *CodeGen_Posix::save_stack() {
    llvm::Function *stacksave =
        llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::stacksave);
    return builder->CreateCall(stacksave);
}

void CodeGen_Posix::restore_stack(llvm::Value *saved_stack) {
    llvm::Function *stackrestore =
        llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::stackrestore);
    builder->CreateCall(stackrestore, saved_stack);
}

CodeGen_Posix::Allocation CodeGen_Posix::create_allocation(const std::string &name, Type type, Expr size) {

    Allocation allocation;

    int bytes_per_element = type.bits / 8;
    if (const IntImm *int_size = size.as<IntImm>()) {
        allocation.stack_size = int_size->value * bytes_per_element;

        // Round up to nearest multiple of 32.
        allocation.stack_size = ((allocation.stack_size + 31)/32)*32;

        // If it's more than 8k, put it on the heap.
        if (allocation.stack_size > 8*1024) {
            allocation.stack_size = 0;
        }
    } else {
        allocation.stack_size = 0;
    }

    llvm::Type *llvm_type = llvm_type_of(type);

    if (allocation.stack_size) {
        // First, try to reuse an existing free block using a best-fit
        // algorithm. Note that we don't actually need to fit, because
        // it's possible to go back to the original alloca and
        // increase its size.
        int best_fit = -1;
        int best_waste = 0;
        for (size_t i = 0; i < free_stack_blocks.size(); i++) {
            int waste = free_stack_blocks[i].stack_size - allocation.stack_size;
            if (waste < 0) waste = -waste;
            if (i == 0 || waste <= best_waste) {
                best_fit = (int)i;
                best_waste = waste;
            }
        }

        // Seems to be buggy. Disabled for now.
        if (best_fit >= 0 && false) {

            // Grab the old allocation and remove it from the free blocks list
            Allocation old_alloc = free_stack_blocks[best_fit];
            free_stack_blocks[best_fit] = free_stack_blocks[free_stack_blocks.size()-1];
            free_stack_blocks.pop_back();

            if (old_alloc.stack_size < allocation.stack_size) {
                log(2) << "Allocation of " << name << " reusing an old smaller allocation\n";
                // We need to go back in time and rewrite the original
                // alloca to be slightly larger so we can fit this one
                // into the same space.
                Value *size = ConstantInt::get(i32, allocation.stack_size/32);
                // Insert the new version just before the old version
                string old_name = old_alloc.alloca_inst->getName();
                AllocaInst *new_alloca = new AllocaInst(i32x8, size, old_name + "_" + name, old_alloc.alloca_inst);
                // Replace all uses of the old version with the new version
                old_alloc.alloca_inst->replaceAllUsesWith(new_alloca);
                // Delete the old version
                old_alloc.alloca_inst->eraseFromParent();
                // For future rewrites to this alloca, we want to rewrite the new version
                allocation.alloca_inst = new_alloca;

            } else {
                log(2) << "Allocation of " << name << " reusing an old larger allocation\n";
                allocation.alloca_inst = old_alloc.alloca_inst;
                allocation.stack_size = old_alloc.stack_size;
            }

            // No need to restore the stack if we're reusing an old allocation
            allocation.saved_stack = NULL;

            // The new allocation uses the same pointer and the same alloca instruction
            allocation.ptr = old_alloc.ptr;

        } else {
            // Do a new 32-byte aligned alloca
            allocation.saved_stack = save_stack();
            Value *size = ConstantInt::get(i32, allocation.stack_size/32);
            allocation.alloca_inst = builder->CreateAlloca(i32x8, size, name);
            allocation.ptr = builder->CreatePointerCast(allocation.alloca_inst, llvm_type->getPointerTo());
        }
    } else {
        allocation.saved_stack = NULL;
        allocation.alloca_inst = NULL;
        Value *llvm_size = codegen(size * bytes_per_element);

        // call malloc
        llvm::Function *malloc_fn = module->getFunction("halide_malloc");
        malloc_fn->setDoesNotAlias(0);
        assert(malloc_fn && "Could not find halide_malloc in module");

        llvm_size = builder->CreateIntCast(llvm_size, malloc_fn->arg_begin()->getType(), false);

        log(4) << "Creating call to halide_malloc\n";
        CallInst *call = builder->CreateCall(malloc_fn, llvm_size);
        allocation.ptr = call;
    }

    // Push the allocation base pointer onto the symbol table
    log(3) << "Pushing allocation called " << name << ".host onto the symbol table\n";

    allocations.push(name, allocation);
    sym_push(name + ".host", allocation.ptr);

    return allocation;
}

void CodeGen_Posix::free_allocation(const std::string &name) {
    Allocation alloc = allocations.get(name);

    if (alloc.stack_size) {
        log(2) << "Moving allocation " << name << " onto the free stack blocks list\n";
        // Mark this block as free, but don't restore the stack yet
        free_stack_blocks.push_back(alloc);
    } else {
        // Call free
        llvm::Function *free_fn = module->getFunction("halide_free");
        assert(free_fn && "Could not find halide_free in module");
        log(4) << "Creating call to halide_free\n";
        builder->CreateCall(free_fn, alloc.ptr);
    }

    sym_pop(name + ".host");
    allocations.pop(name);
}

void CodeGen_Posix::destroy_allocation(Allocation alloc) {

    if (alloc.saved_stack) {
        // We should be in the free blocks list
        bool found = false;
        for (size_t i = 0; !found && i < free_stack_blocks.size(); i++) {
            if (free_stack_blocks[i].ptr == alloc.ptr) {
                free_stack_blocks[i] = free_stack_blocks[free_stack_blocks.size()-1];
                free_stack_blocks.pop_back();
                found = true;
            }
        }
        assert(found && "Stack allocation should have been in the free blocks list");

        restore_stack(alloc.saved_stack);
    }

}

void CodeGen_Posix::visit(const Allocate *alloc) {

    Allocation allocation = create_allocation(alloc->name, alloc->type, alloc->size);

    codegen(alloc->body);

    // Should have been freed
    assert(!sym_exists(alloc->name + ".host"));
    assert(!allocations.contains(alloc->name));

    log(2) << "Destroying allocation " << alloc->name << "\n";
    destroy_allocation(allocation);
}

void CodeGen_Posix::visit(const Free *stmt) {
    free_allocation(stmt->name);
}

void CodeGen_Posix::prepare_for_early_exit() {
    // We've jumped to a code path that will be called just before
    // bailing out. Free everything outstanding.
    for (map<string, stack<Allocation> >::const_iterator iter = allocations.get_table().begin();
         iter != allocations.get_table().end(); ++iter) {
        string name = iter->first;
        std::vector<Allocation> stash;
        while (allocations.contains(name)) {
            stash.push_back(allocations.get(name));
            free_allocation(name);
        }

        // Restore all the allocations before we jump back to the main
        // code path.
        for (size_t i = stash.size(); i > 0; i--) {
            allocations.push(name, stash[i-1]);
            sym_push(name + ".host", stash[i-1].ptr);
        }
    }
}

}}
<|endoftext|>


<commit_before><commit_msg>Prevent warning on Mac about uninitialized variable by initializing the variable in the failure case.<commit_after><|endoftext|>


<commit_before>// @(#)root/test:$Name:  $:$Id: Hello.cxx,v 1.3 2000/12/21 09:20:29 brun Exp $
// Author: Valeriy Onuchin & Fons Rademakers   04/10/98

///////////////////////////////////////////////////////////////////
//  Animated Text with cool wave effect.
//
//  ROOT implementation of the hello world example borrowed
//  from the Qt hello world example.
//
//  To run this example do the following:
//  $ root
//  root [0] gSystem.Load("Hello")
//  root [1] Hello h
//  <enjoy>
//  root [2] .q
//
//  Other ROOT fun examples: Tetris, Aclock ...
//
//  Begin_Html
//
//  End_Html
//
///////////////////////////////////////////////////////////////////

#include <TROOT.h>
#include <TSystem.h>
#include "Hello.h"

ClassImp(Hello)

TChar::TChar(char ch, Coord_t x, Coord_t y) : TText(x, y, "")
{
   // Create single character text.

   char *tmp;
   tmp = (char*)GetTitle();
   tmp[0] = ch;
   SetTitle(tmp);
}

Float_t TChar::GetWidth()
{
   // Return character width

   UInt_t w,h;

   if (!TVirtualPad::Pad()) return 0;

   Float_t wh = (Float_t)gPad->XtoPixel(gPad->GetX2());
   gVirtualX->GetTextExtent(w, h, (char*)GetTitle());
   return  w/wh;
}

Hello::Hello(const char *text) : TTimer(40, kTRUE)
{
   // Hello constructor

   TChar *ch;
   fI = 0;
   fList = new TList();

   if (!TVirtualPad::Pad())
      fPad = new TCanvas("Hello:canvas","ROOT says Hello!",200,200,400,200);
   else
      fPad = (TPad*)gPad;

   while(text[fI]) {               // create  list of characters
      ch = new TChar(text[fI]);
      ch->SetTextFont(71);         // times-bold-r-normal
      ch->SetTextSize(0.3);
      ch->Modify();
      fI++;
      fList->Add(ch);
   }

   SetBit(kCanDelete);
   Draw();                         // append this to current pad
   Paint();                        // calculate new coordinates of chars and paint it
   gSystem->AddTimer(this);        // start timer= start animation
}

Hello::~Hello()
{
   // Clean up hello.

   fList->Delete();
   delete fList;
}

void Hello::ExecuteEvent(Int_t event, Int_t, Int_t)
{
   // Actions when mouse clicked.

   if (event == kButton1Up) {
      TTimer::Remove();
   }
}

Float_t Hello::GetWidth()
{
   // Return text width

   TChar *ch;
   TIter nextin(fList);
   Float_t width = 0;

   while ((ch = (TChar*)nextin()))
      width = width + ch->GetWidth();

   return width;
}

void Hello::Paint(Option_t *)
{
   // Paint text

   static int sin_tbl[16] = {
        0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38
   };

   TChar *ch;
   TIter nextin(fList);
   Float_t width = GetWidth();

   Coord_t xnext = (1-width)/2.;    // draw text in the center of the pad
   Coord_t y;
   Coord_t y0 = 0.5;

   fI = (fI+1) & 15;
   int i = 0;

   while ((ch = (TChar*)nextin())) {
      int i16 = (fI+i) & 15;
      y = y0 - (Coord_t)sin_tbl[i16]/1500.;   // sin-wave coordinates
      ch->SetY(y);
      ch->SetX(xnext);
      ch->SetTextColor(i16+200);              // let's use x3d colors
      i++;
      xnext = xnext + ch->GetWidth();         // x position of next character
      ch->Paint("");                          // paint character
   }
}

Bool_t Hello::Notify()
{
   // Actions after timer time-out

   fPad->Modified();
   fPad->Update();
   TTimer::Reset();
   return kFALSE;
}
<commit_msg>Fix in TChar::GetWidth to take into account teh new TText::GetTextExtent<commit_after>// @(#)root/test:$Name:  $:$Id: Hello.cxx,v 1.4 2001/01/09 08:06:07 brun Exp $
// Author: Valeriy Onuchin & Fons Rademakers   04/10/98

///////////////////////////////////////////////////////////////////
//  Animated Text with cool wave effect.
//
//  ROOT implementation of the hello world example borrowed
//  from the Qt hello world example.
//
//  To run this example do the following:
//  $ root
//  root [0] gSystem.Load("Hello")
//  root [1] Hello h
//  <enjoy>
//  root [2] .q
//
//  Other ROOT fun examples: Tetris, Aclock ...
//
//  Begin_Html
//
//  End_Html
//
///////////////////////////////////////////////////////////////////

#include <TROOT.h>
#include <TSystem.h>
#include "Hello.h"

ClassImp(Hello)

TChar::TChar(char ch, Coord_t x, Coord_t y) : TText(x, y, "")
{
   // Create single character text.

   char *tmp;
   tmp = (char*)GetTitle();
   tmp[0] = ch;
   SetTitle(tmp);
}

Float_t TChar::GetWidth()
{
   // Return character width

   UInt_t w,h;

   if (!TVirtualPad::Pad()) return 0;

   Float_t wh = (Float_t)gPad->XtoAbsPixel(gPad->GetX2());
   GetTextExtent(w, h, (char*)GetTitle());
   return  w/wh;
}

Hello::Hello(const char *text) : TTimer(40, kTRUE)
{
   // Hello constructor

   TChar *ch;
   fI = 0;
   fList = new TList();

   if (!TVirtualPad::Pad())
      fPad = new TCanvas("Hello:canvas","ROOT says Hello!",200,200,400,200);
   else
      fPad = (TPad*)gPad;

   while(text[fI]) {               // create  list of characters
      ch = new TChar(text[fI]);
      ch->SetTextFont(72);         // times-bold-r-normal
      ch->SetTextSize(0.3);
      ch->Modify();
      fI++;
      fList->Add(ch);
   }

   SetBit(kCanDelete);
   Draw();                         // append this to current pad
   Paint();                        // calculate new coordinates of chars and paint it
   gSystem->AddTimer(this);        // start timer= start animation
}

Hello::~Hello()
{
   // Clean up hello.

   fList->Delete();
   delete fList;
}

void Hello::ExecuteEvent(Int_t event, Int_t, Int_t)
{
   // Actions when mouse clicked.

   if (event == kButton1Up) {
      TTimer::Remove();
   }
}

Float_t Hello::GetWidth()
{
   // Return text width

   TChar *ch;
   TIter nextin(fList);
   Float_t width = 0;

   while ((ch = (TChar*)nextin()))
      width = width + ch->GetWidth();

   return width;
}

void Hello::Paint(Option_t *)
{
   // Paint text

   static int sin_tbl[16] = {
        0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38
   };

   TChar *ch;
   TIter nextin(fList);
   Float_t width = GetWidth();

   Coord_t xnext = (1-width)/2.;    // draw text in the center of the pad
   Coord_t y;
   Coord_t y0 = 0.5;

   fI = (fI+1) & 15;
   int i = 0;

   while ((ch = (TChar*)nextin())) {
      int i16 = (fI+i) & 15;
      y = y0 - (Coord_t)sin_tbl[i16]/1500.;   // sin-wave coordinates
      ch->SetY(y);
      ch->SetX(xnext);
      ch->SetTextColor(i16+200);              // let's use x3d colors
      i++;
      xnext = xnext + ch->GetWidth();         // x position of next character
      ch->Paint("");                          // paint character
   }
}

Bool_t Hello::Notify()
{
   // Actions after timer time-out

   fPad->Modified();
   fPad->Update();
   TTimer::Reset();
   return kFALSE;
}
<|endoftext|>


<commit_before>///
/// @file   P2_xa.cpp
/// @brief  Test the 2nd partial sieve function P2(x, a)
///         that counts the numbers <= x that have exactly
///         2 prime factors each exceeding the a-th prime.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount-internal.hpp>
#include <generate.hpp>
#include <imath.hpp>

#include <stdint.h>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <random>

using namespace std;
using namespace primecount;

void check(bool OK)
{
  cout << "   " << (OK ? "OK" : "ERROR") << "\n";
  if (!OK)
    exit(1);
}

int main()
{
  random_device rd;
  mt19937 gen(rd());
  uniform_int_distribution<int> dist(10000, 20000);

  int64_t x = dist(gen);
  auto primes = generate_primes<int64_t>(x);

  for (int a = 1; primes[a] <= isqrt(x); a++)
  {
    int64_t p2 = 0;

    for (size_t b = a + 1; b < primes.size(); b++)
      for (size_t c = b; c < primes.size(); c++)
        if (primes[b] * primes[c] <= x)
          p2++;

    cout << "P2(" << x << ", " << a << ") = " << p2;
    check(p2 == P2(x, primes[a], 1));
  }

  cout << endl;
  cout << "All tests passed successfully!" << endl;

  return 0;
}
<commit_msg>Increase test range<commit_after>///
/// @file   P2_xa.cpp
/// @brief  Test the 2nd partial sieve function P2(x, a)
///         that counts the numbers <= x that have exactly
///         2 prime factors each exceeding the a-th prime.
///
/// Copyright (C) 2017 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primecount-internal.hpp>
#include <generate.hpp>
#include <imath.hpp>

#include <stdint.h>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <random>

using namespace std;
using namespace primecount;

void check(bool OK)
{
  cout << "   " << (OK ? "OK" : "ERROR") << "\n";
  if (!OK)
    exit(1);
}

int main()
{
  random_device rd;
  mt19937 gen(rd());
  uniform_int_distribution<int> dist(50000, 70000);

  int64_t x = dist(gen);
  auto primes = generate_primes<int64_t>(x);

  for (int a = 1; primes[a] <= isqrt(x); a++)
  {
    int64_t p2 = 0;

    for (size_t b = a + 1; b < primes.size(); b++)
      for (size_t c = b; c < primes.size(); c++)
        if (primes[b] * primes[c] <= x)
          p2++;

    cout << "P2(" << x << ", " << a << ") = " << p2;
    check(p2 == P2(x, primes[a], 1));
  }

  cout << endl;
  cout << "All tests passed successfully!" << endl;

  return 0;
}
<|endoftext|>


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

#ifndef AST_MEMBER_DECLARATION_H
#define AST_MEMBER_DECLARATION_H

#include <boost/fusion/include/adapt_struct.hpp>

#include "ast/Deferred.hpp"
#include "ast/Position.hpp"

namespace eddic {

class Context;

namespace ast {

/*!
 * \class ASTMemberDeclaration
 * \brief The AST node for a declaration of a member variable.
 * Should only be used from the Deferred version (eddic::ast::MemberDeclaration).
 */
struct ASTMemberDeclaration {
    std::shared_ptr<Context> context;

    Position position;
    std::string type;
    std::string name;

    mutable long references;
    ASTMemberDeclaration() : references(0) {}
};

/*!
 * \typedef MemberDeclaration
 * \brief The AST node for a declaration of a member variable.
 */
typedef Deferred<ASTMemberDeclaration> MemberDeclaration;

} //end of ast

} //end of eddic

//Adapt the struct for the AST
BOOST_FUSION_ADAPT_STRUCT(
    eddic::ast::MemberDeclaration,
    (eddic::ast::Position, Content->position)
    (std::string, Content->type)
    (std::string, Content->name)
)

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

#ifndef AST_MEMBER_DECLARATION_H
#define AST_MEMBER_DECLARATION_H

#include <boost/fusion/include/adapt_struct.hpp>

#include "ast/Deferred.hpp"
#include "ast/Position.hpp"

namespace eddic {

class Context;

namespace ast {

/*!
 * \class ASTMemberDeclaration
 * \brief The AST node for a declaration of a member variable.
 * Should only be used from the Deferred version (eddic::ast::MemberDeclaration).
 */
struct ASTMemberDeclaration {
    Position position;
    std::string type;
    std::string name;

    mutable long references = 0;
};

/*!
 * \typedef MemberDeclaration
 * \brief The AST node for a declaration of a member variable.
 */
typedef Deferred<ASTMemberDeclaration> MemberDeclaration;

} //end of ast

} //end of eddic

//Adapt the struct for the AST
BOOST_FUSION_ADAPT_STRUCT(
    eddic::ast::MemberDeclaration,
    (eddic::ast::Position, Content->position)
    (std::string, Content->type)
    (std::string, Content->name)
)

#endif
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Declarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsgparticlegroup_p.h"

/*!
    \qmlclass ParticleGroup QSGParticleGroup
    \inqmlmodule QtQuick.Particles 2
    \brief ParticleGroup elements allow you to set attributes on a logical particle group.

    This element allows you to set timed transitions on particle groups.

    You can also use this element to group particle system elements related to the logical
    particle group. Emitters, Affectors and Painters set as direct children of a ParticleGroup
    will automatically apply to that logical particle group. TrailEmitters will automatically follow
    the group.

    If a ParticleGroup element is not defined for a group, the group will function normally as if
    none of the transition properties were set.
*/
/*!
    \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::system
    This is the system which will contain the group.

    If the ParticleGroup is a direct child of a ParticleSystem, it will automatically be associated with it.
*/
/*!
    \qmlproperty string QtQuick.Particles2::ParticleGroup::name
    This is the name of the particle group, and how it is generally referred to by other elements.

    If elements refer to a name which does not have an explicit ParticleGroup created, it will
    work normally (with no transitions specified for the group). If you do not need to assign
    duration based transitions to a group, you do not need to create a ParticleGroup with that name (although you may).
*/
/*!
    \qmlproperty int QtQuick.Particles2::ParticleGroup::duration
    The time in milliseconds before the group will attempt to transition.

*/
/*!
    \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::durationVariation
    The maximum number of milliseconds that the duration of the transition cycle varies per particle in the group.

    Default value is zero.
*/
/*!
    \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::to
    The weighted list of transitions valid for this group.

    If the chosen transition stays in this group, another duration (+/- up to durationVariation)
    milliseconds will occur before another transition is attempted.
*/

QSGParticleGroup::QSGParticleGroup(QObject* parent)
    : QSGStochasticState(parent)
{

}

void delayedRedirect(QDeclarativeListProperty<QObject> *prop, QObject *value)
{
    QSGParticleGroup* pg = qobject_cast<QSGParticleGroup*>(prop->object);
    if (pg)
        pg->delayRedirect(value);
}

QDeclarativeListProperty<QObject> QSGParticleGroup::particleChildren()
{
    QSGParticleSystem* system = qobject_cast<QSGParticleSystem*>(parent());
    if (system)
        return QDeclarativeListProperty<QObject>(this, 0, &QSGParticleSystem::statePropertyRedirect);
    else
        return QDeclarativeListProperty<QObject>(this, 0, &delayedRedirect);
}

void QSGParticleGroup::setSystem(QSGParticleSystem* arg)
{
    if (m_system != arg) {
        m_system = arg;
        m_system->registerParticleGroup(this);
        performDelayedRedirects();
        emit systemChanged(arg);
    }
}

void QSGParticleGroup::delayRedirect(QObject *obj)
{
    m_delayedRedirects << obj;
}

void QSGParticleGroup::performDelayedRedirects()
{
    if (!m_system)
        return;
    foreach (QObject* obj, m_delayedRedirects)
        m_system->stateRedirect(this, m_system, obj);

    m_delayedRedirects.clear();
}

void QSGParticleGroup::componentComplete(){
    if (!m_system && qobject_cast<QSGParticleSystem*>(parent()))
        setSystem(qobject_cast<QSGParticleSystem*>(parent()));
}
<commit_msg>Zero-initialize QSGParticleGroup::m_system.<commit_after>/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Declarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qsgparticlegroup_p.h"

/*!
    \qmlclass ParticleGroup QSGParticleGroup
    \inqmlmodule QtQuick.Particles 2
    \brief ParticleGroup elements allow you to set attributes on a logical particle group.

    This element allows you to set timed transitions on particle groups.

    You can also use this element to group particle system elements related to the logical
    particle group. Emitters, Affectors and Painters set as direct children of a ParticleGroup
    will automatically apply to that logical particle group. TrailEmitters will automatically follow
    the group.

    If a ParticleGroup element is not defined for a group, the group will function normally as if
    none of the transition properties were set.
*/
/*!
    \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::system
    This is the system which will contain the group.

    If the ParticleGroup is a direct child of a ParticleSystem, it will automatically be associated with it.
*/
/*!
    \qmlproperty string QtQuick.Particles2::ParticleGroup::name
    This is the name of the particle group, and how it is generally referred to by other elements.

    If elements refer to a name which does not have an explicit ParticleGroup created, it will
    work normally (with no transitions specified for the group). If you do not need to assign
    duration based transitions to a group, you do not need to create a ParticleGroup with that name (although you may).
*/
/*!
    \qmlproperty int QtQuick.Particles2::ParticleGroup::duration
    The time in milliseconds before the group will attempt to transition.

*/
/*!
    \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::durationVariation
    The maximum number of milliseconds that the duration of the transition cycle varies per particle in the group.

    Default value is zero.
*/
/*!
    \qmlproperty ParticleSystem QtQuick.Particles2::ParticleGroup::to
    The weighted list of transitions valid for this group.

    If the chosen transition stays in this group, another duration (+/- up to durationVariation)
    milliseconds will occur before another transition is attempted.
*/

QSGParticleGroup::QSGParticleGroup(QObject* parent)
    : QSGStochasticState(parent)
    , m_system(0)
{

}

void delayedRedirect(QDeclarativeListProperty<QObject> *prop, QObject *value)
{
    QSGParticleGroup* pg = qobject_cast<QSGParticleGroup*>(prop->object);
    if (pg)
        pg->delayRedirect(value);
}

QDeclarativeListProperty<QObject> QSGParticleGroup::particleChildren()
{
    QSGParticleSystem* system = qobject_cast<QSGParticleSystem*>(parent());
    if (system)
        return QDeclarativeListProperty<QObject>(this, 0, &QSGParticleSystem::statePropertyRedirect);
    else
        return QDeclarativeListProperty<QObject>(this, 0, &delayedRedirect);
}

void QSGParticleGroup::setSystem(QSGParticleSystem* arg)
{
    if (m_system != arg) {
        m_system = arg;
        m_system->registerParticleGroup(this);
        performDelayedRedirects();
        emit systemChanged(arg);
    }
}

void QSGParticleGroup::delayRedirect(QObject *obj)
{
    m_delayedRedirects << obj;
}

void QSGParticleGroup::performDelayedRedirects()
{
    if (!m_system)
        return;
    foreach (QObject* obj, m_delayedRedirects)
        m_system->stateRedirect(this, m_system, obj);

    m_delayedRedirects.clear();
}

void QSGParticleGroup::componentComplete(){
    if (!m_system && qobject_cast<QSGParticleSystem*>(parent()))
        setSystem(qobject_cast<QSGParticleSystem*>(parent()));
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qmltypenamescriptclass_p.h"
#include <private/qmlengine_p.h>
#include <private/qmltypenamecache_p.h>

QT_BEGIN_NAMESPACE

struct TypeNameData : public QScriptDeclarativeClass::Object {
    TypeNameData(QObject *o, QmlType *t) : object(o), type(t), typeNamespace(0) {}
    TypeNameData(QObject *o, QmlTypeNameCache *n) : object(o), type(0), typeNamespace(n) {
        if (typeNamespace) typeNamespace->addref();
    }
    ~TypeNameData() {
        if (typeNamespace) typeNamespace->release();
    }

    QObject *object;
    QmlType *type;
    QmlTypeNameCache *typeNamespace;
};

QmlTypeNameScriptClass::QmlTypeNameScriptClass(QmlEngine *bindEngine)
: QScriptDeclarativeClass(QmlEnginePrivate::getScriptEngine(bindEngine)),
  engine(bindEngine), object(0), type(0)
{
}

QmlTypeNameScriptClass::~QmlTypeNameScriptClass()
{
}

QScriptValue QmlTypeNameScriptClass::newObject(QObject *object, QmlType *type)
{
    QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);

    return QScriptDeclarativeClass::newObject(scriptEngine, this, new TypeNameData(object, type));
}

QScriptValue QmlTypeNameScriptClass::newObject(QObject *object, QmlTypeNameCache *ns)
{
    QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);

    return QScriptDeclarativeClass::newObject(scriptEngine, this, new TypeNameData(object, ns));
}

QScriptClass::QueryFlags
QmlTypeNameScriptClass::queryProperty(Object *obj, const Identifier &name,
                                      QScriptClass::QueryFlags flags)
{
    Q_UNUSED(flags);

    TypeNameData *data = (TypeNameData *)obj;

    object = 0;
    type = 0;
    QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);

    if (data->typeNamespace) {

        QmlTypeNameCache::Data *d = data->typeNamespace->data(name);
        if (d && d->type) {
            type = d->type;
            return QScriptClass::HandlesReadAccess;
        } else {
            return 0;
        }

    } else {
        Q_ASSERT(data->type);

        QString strName = toString(name);

        if (strName.at(0).isUpper()) {
            // Must be an enum
            // ### Optimize
            const char *enumName = strName.toUtf8().constData();
            const QMetaObject *metaObject = data->type->baseMetaObject();
            for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
                QMetaEnum e = metaObject->enumerator(ii);
                int value = e.keyToValue(enumName);
                if (value != -1) {
                    enumValue = value;
                    return QScriptClass::HandlesReadAccess;
                }
            }
            return 0;
        } else {
            // Must be an attached property
            object = qmlAttachedPropertiesObjectById(data->type->index(), data->object);
            if (!object) return 0;
            return ep->objectClass->queryProperty(object, name, flags);
        }
    }
}

QScriptValue QmlTypeNameScriptClass::property(Object *obj, const Identifier &name)
{
    QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
    if (type) {
        return newObject(object, type);
    } else if (object) {
        return ep->objectClass->property(((TypeNameData *)obj)->object, name);
    } else {
        return QScriptValue(enumValue);
    }
}

void QmlTypeNameScriptClass::setProperty(Object *o, const Identifier &n, const QScriptValue &v)
{
    Q_ASSERT(object);
    Q_ASSERT(!type);

    QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
    ep->objectClass->setProperty(((TypeNameData *)o)->object, n, v);
}

QT_END_NAMESPACE

<commit_msg>Crash<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qmltypenamescriptclass_p.h"
#include <private/qmlengine_p.h>
#include <private/qmltypenamecache_p.h>

QT_BEGIN_NAMESPACE

struct TypeNameData : public QScriptDeclarativeClass::Object {
    TypeNameData(QObject *o, QmlType *t) : object(o), type(t), typeNamespace(0) {}
    TypeNameData(QObject *o, QmlTypeNameCache *n) : object(o), type(0), typeNamespace(n) {
        if (typeNamespace) typeNamespace->addref();
    }
    ~TypeNameData() {
        if (typeNamespace) typeNamespace->release();
    }

    QObject *object;
    QmlType *type;
    QmlTypeNameCache *typeNamespace;
};

QmlTypeNameScriptClass::QmlTypeNameScriptClass(QmlEngine *bindEngine)
: QScriptDeclarativeClass(QmlEnginePrivate::getScriptEngine(bindEngine)),
  engine(bindEngine), object(0), type(0)
{
}

QmlTypeNameScriptClass::~QmlTypeNameScriptClass()
{
}

QScriptValue QmlTypeNameScriptClass::newObject(QObject *object, QmlType *type)
{
    QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);

    return QScriptDeclarativeClass::newObject(scriptEngine, this, new TypeNameData(object, type));
}

QScriptValue QmlTypeNameScriptClass::newObject(QObject *object, QmlTypeNameCache *ns)
{
    QScriptEngine *scriptEngine = QmlEnginePrivate::getScriptEngine(engine);

    return QScriptDeclarativeClass::newObject(scriptEngine, this, new TypeNameData(object, ns));
}

QScriptClass::QueryFlags
QmlTypeNameScriptClass::queryProperty(Object *obj, const Identifier &name,
                                      QScriptClass::QueryFlags flags)
{
    Q_UNUSED(flags);

    TypeNameData *data = (TypeNameData *)obj;

    object = 0;
    type = 0;
    QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);

    if (data->typeNamespace) {

        QmlTypeNameCache::Data *d = data->typeNamespace->data(name);
        if (d && d->type) {
            type = d->type;
            return QScriptClass::HandlesReadAccess;
        } else {
            return 0;
        }

    } else {
        Q_ASSERT(data->type);

        QString strName = toString(name);

        if (strName.at(0).isUpper()) {
            // Must be an enum
            // ### Optimize
            const char *enumName = strName.toUtf8().constData();
            const QMetaObject *metaObject = data->type->baseMetaObject();
            for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
                QMetaEnum e = metaObject->enumerator(ii);
                int value = e.keyToValue(enumName);
                if (value != -1) {
                    enumValue = value;
                    return QScriptClass::HandlesReadAccess;
                }
            }
            return 0;
        } else if (data->object) {
            // Must be an attached property
            object = qmlAttachedPropertiesObjectById(data->type->index(), data->object);
            if (!object) return 0;
            return ep->objectClass->queryProperty(object, name, flags);
        }
    }

    return 0;
}

QScriptValue QmlTypeNameScriptClass::property(Object *obj, const Identifier &name)
{
    QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
    if (type) {
        return newObject(object, type);
    } else if (object) {
        return ep->objectClass->property(((TypeNameData *)obj)->object, name);
    } else {
        return QScriptValue(enumValue);
    }
}

void QmlTypeNameScriptClass::setProperty(Object *o, const Identifier &n, const QScriptValue &v)
{
    Q_ASSERT(object);
    Q_ASSERT(!type);

    QmlEnginePrivate *ep = QmlEnginePrivate::get(engine);
    ep->objectClass->setProperty(((TypeNameData *)o)->object, n, v);
}

QT_END_NAMESPACE

<|endoftext|>


<commit_before>/*

    ofxTableGestures (formerly OF-TangibleFramework)
    Developed for Taller de Sistemes Interactius I
    Universitat Pompeu Fabra

    Copyright (c) 2010 Daniel Gallardo Grassot <daniel.gallardo@upf.edu>

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

#include <fstream>
#include "TableApp.hpp"
#include "GraphicDispatcher.hpp"
#include "Renderer_plane.hpp"
#include "Renderer_to_texture.hpp"
#include "ofxGlobalConfig.hpp"
#include "CollisionHelper.h"

#define WIDTH_STEP 0.005
#define ANGLE_STEP 1
#define DISTORTION_PATH "calibration.conf"

float TableApp::height = 0;
float TableApp::width = 0;

TableApp::TableApp():
//    calibration_enabled(false),
    calibration_mode(0),
    show_help(false),
    show_info(false),
    hide_cursor(true),
    #ifdef SIMULATOR
    simulator(new simulator::Simulator()),
    is_simulating(false),
    #endif
    squaredInterface(ofxGlobalConfig::getRef("GLOBAL:SQUAREDINTERFACE",1)),
    matrix_updated(false)
{
    if(ofxGlobalConfig::getRef("GLOBAL:RENDERTOTEXTURE",0)) renderer = new Renderer_to_texture();
    else renderer = new Renderer_plane();

    renderer->LoadDistortion();
    show_grid = false;

    ofAddListener(ofEvents.update,this,&TableApp::update);
    ofAddListener(ofEvents.keyPressed,this,&TableApp::keyPressed);
    ofAddListener(ofEvents.keyReleased,this,&TableApp::keyReleased);
    ofAddListener(ofEvents.mouseDragged,this,&TableApp::mouseDragged);
    ofAddListener(ofEvents.mousePressed,this,&TableApp::mousePressed);
    ofAddListener(ofEvents.mouseReleased,this,&TableApp::mouseReleased);
    ofAddListener(ofEvents.windowResized,this,&TableApp::windowResized);

    Figures::CollisionHelper::ignore_transformation_matrix.SetIdentity();
}

TableApp::~TableApp(){
    #ifdef SIMULATOR
    delete simulator;
    #endif
    delete renderer;
    delete grid;

    ofRemoveListener(ofEvents.update,this,&TableApp::update);
    ofRemoveListener(ofEvents.keyPressed,this,&TableApp::keyPressed);
    ofRemoveListener(ofEvents.keyReleased,this,&TableApp::keyReleased);
    ofRemoveListener(ofEvents.mouseDragged,this,&TableApp::mouseDragged);
    ofRemoveListener(ofEvents.mousePressed,this,&TableApp::mousePressed);
    ofRemoveListener(ofEvents.mouseReleased,this,&TableApp::mouseReleased);
    ofRemoveListener(ofEvents.windowResized,this,&TableApp::windowResized);

}

int TableApp::GetSquareSide(){
    if(ofGetWidth() > ofGetHeight())return ofGetHeight();
    else return ofGetWidth();
}

//--------------------------------------------------------------
void TableApp::setup(){
    grid = new Grid(6,6);
    full=false;
    ofSetFrameRate(60);
    ///starts the tuioinput thread
    //tuio::tuioinput::Instance().init();
    ofSetWindowTitle("Table APP    press 'h' to show help content");
    ofBackground(0, 0, 0);
    ofHideCursor();
}

//--------------------------------------------------------------
void TableApp::update(ofEventArgs & args){
    ///Update input events, it says to all input gestures to process the gesture stack.
    //tuio::tuioAreaDelivery::Instance().processTevents();
    ///Update graphic data, with this command all update methods from all 'Graphics' are launched
    GraphicDispatcher::Instance().Update();
    ///Update simulator objects
    #ifdef SIMULATOR
    if(is_simulating) simulator->Update();
    #endif
}

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

void TableApp::DrawInfo()
{
    if(show_info)
    {
        glPushMatrix();
        glTranslatef(50.0f,50.0f,0.0f);
        ofSetColor(0x00FF00);
        std::stringstream msg;
        msg << ofGetWidth() << "X" << ofGetHeight() << "@" <<  (int)ofGetFrameRate() << "fps" << std::endl;
        if(renderer->IsEnabled())
            msg << "Distortion enabled" << std::endl;
        else
            msg << "Distortion disabled" << std::endl;
        msg << "Calibration data:" << std::endl;
        msg << renderer->ToString();
        ofDrawBitmapString(msg.str(), 0, 0);
        glPopMatrix();
    }
}

void TableApp::DrawHelp()
{
    if(show_help)
    {
        glPushMatrix();
        glTranslatef(50.0f,200.0f,0.0f);
        ofSetColor(0x00FF00);
        std::stringstream msg;
        msg << "h - help content." << std::endl;
        msg << "i - shows graphic information content." << std::endl;
        msg << "f - toggle fullscreen." << std::endl;
        msg << "m - shows/hides cursor pointer." << std::endl;
        msg << "d - enable/disable distortion." << std::endl;
        msg << "c - calibration mode." << std::endl;
        msg << "Under calibration mode:" << std::endl;
        msg << "  r - reset calibration values." << std::endl;
        msg << "  l - load calibration file." << std::endl;
        msg << "  return  - toggle calibration parameter." << std::endl;
        msg << "  cursors - Changes the selected parameter." << std::endl;
        #ifdef SIMULATOR
        msg << "s - enable simulator." << std::endl;
        msg << "Under simulator mode:" << std::endl;
        msg << "  r - reset." << std::endl;
        msg << "  a - hold." << std::endl;
        msg << "  z - select." << std::endl;
        #endif
        ofDrawBitmapString(msg.str(), 0, 0);
        glPopMatrix();
    }
}

void TableApp::draw(){
    ofPushMatrix();
    #ifdef SIMULATOR
    if(is_simulating) ofScale(0.91f,0.91f,1.0f);
    #endif

    renderer->Start();
    ofPushMatrix();
    int shortside = min(ofGetWidth(),ofGetHeight());
    if(squaredInterface)
    {
        //if the surface is squared we center the drawing  plane
        glTranslatef((ofGetWidth()-shortside)/2.0,(ofGetHeight()-shortside)/2.0,0);
        TableApp::height = 1;
        TableApp::width = 1;
    }
    else
    {
        TableApp::height = float(ofGetHeight())/float(shortside);
        TableApp::width = float(ofGetWidth())/float(shortside);
    }
    glScalef(shortside,shortside,1);

    if(!matrix_updated)
    {
        matrix_updated = true;
        glGetDoublev(GL_MODELVIEW_MATRIX,Figures::CollisionHelper::ignore_transformation_matrix.data);
        Figures::CollisionHelper::ignore_transformation_matrix = Figures::CollisionHelper::ignore_transformation_matrix.GetInverse();
    }
    ///Draws all 'Graphics'
    glDisable(GL_DEPTH_TEST);
    ofPushMatrix();
    GraphicDispatcher::Instance().Draw();
    ofPopMatrix();
    glEnable(GL_DEPTH_TEST);

    ofPopMatrix();
    grid->Draw(show_grid,calibration_mode);
    renderer->End();
    ///Draws Info & help
    DrawInfo();
    DrawHelp();
    ofPopMatrix();
    #ifdef SIMULATOR
    if(is_simulating) simulator->Draw();
    #endif
}

//--------------------------------------------------------------
void TableApp::keyPressed(ofKeyEventArgs & event){
    int key = event.key;
    #ifdef SIMULATOR
    switch(key)
    {
        case 'a':
            simulator->Hold(true);
        break;
        case 'z':
            simulator->Select(true);
        break;
        default:
            KeyPressed(key);
        break;
    }
    #endif
}

//--------------------------------------------------------------
void TableApp::keyReleased(ofKeyEventArgs & event){
    int key = event.key;
    switch(key)
    {
        default:
            KeyReleased(key);
        break;
        #ifdef SIMULATOR
        case 'a':
            simulator->Hold(false);
        break;
        case 'z':
            simulator->Select(false);
        break;
        #endif
        case 'f':
            ofToggleFullscreen();
		break;
		case 'c':
            if(renderer->IsEnabled()){
                renderer->SaveDistortion();
            }
            show_grid = !show_grid;
        break;
        case OF_KEY_RETURN:
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid) calibration_mode ++;
            if(calibration_mode > 3) calibration_mode = 0;
        break;
        case OF_KEY_UP:
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid)
            {
                switch(calibration_mode)
                {
                    case 0:renderer->center_y--;break;
                    case 1:renderer->height_offset+=WIDTH_STEP;break;
                    case 2:renderer->angle+=ANGLE_STEP;break;
                    case 3:renderer->angle_h+=ANGLE_STEP;break;
                }
            }
        break;
        case OF_KEY_DOWN:
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid)
            {
                switch(calibration_mode)
                {
                    case 0:renderer->center_y++;break;
                    case 1:renderer->height_offset-=WIDTH_STEP;break;
                    case 2:renderer->angle-=ANGLE_STEP;break;
                    case 3:renderer->angle_h-=ANGLE_STEP;break;
                }
            }
        break;
        case OF_KEY_RIGHT:
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid)
            {
                switch(calibration_mode)
                {
                    case 0:renderer->center_x++;break;
                    case 1:renderer->width_offset+=WIDTH_STEP;break;
                    case 2:renderer->angle+=ANGLE_STEP;break;
                    case 3:renderer->angle_w+=ANGLE_STEP;break;
                }
            }
        break;
        case OF_KEY_LEFT:
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid)
            {
                switch(calibration_mode)
                {
                    case 0:renderer->center_x--;break;
                    case 1:renderer->width_offset-=WIDTH_STEP;break;
                    case 2:renderer->angle-=ANGLE_STEP;break;
                    case 3:renderer->angle_w-=ANGLE_STEP;break;
                }
            }
        break;
        case 'i':
            show_info = !show_info;
        break;
        case 'm':
            if(hide_cursor)
            {
                hide_cursor=false;
                ofShowCursor();
            }else{
                hide_cursor=true;
                ofHideCursor();
            }
        break;
        case 'r':
            if(renderer->IsEnabled() && show_grid)
                renderer->LoadDefaultValues();
            #ifdef SIMULATOR
                if(is_simulating)
                    simulator->Reset();
            #endif
        break;
        case 'l':
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid)
                renderer->LoadDistortion();
        break;
        case 'h':
            show_help = !show_help;
        break;
        case 'd':
            #ifdef SIMULATOR
            if(!is_simulating)
            {
            #endif
            if(renderer->IsEnabled()) renderer->Disable();
            else renderer->Enable();
            #ifdef SIMULATOR
            }
            #endif
        break;
        case 's':
            #ifdef SIMULATOR
                if(is_simulating){
                    ///restore distorsion
                    ///restore cursor
                    if(was_distorsion_enabled) renderer->Enable();
                    else renderer->Disable();
                    if(was_cursor_hide){
                        hide_cursor=true;
                        ofHideCursor();
                    }
                    is_simulating=false;
                    simulator->Reset();
                }
                else{
                    was_distorsion_enabled = renderer->IsEnabled();
                    was_cursor_hide = hide_cursor;
                    renderer->Disable();
                    hide_cursor=false;
                    ofShowCursor();
                    is_simulating=true;
                }
                matrix_updated = false;
            #endif
        break;
        case 'b':
            Figures::CollisionHelper::debug_graphics = !Figures::CollisionHelper::debug_graphics;
        break;
    }
}

//--------------------------------------------------------------
void TableApp::windowResized(ofResizeEventArgs & event){
    int w = event.width;
    int h = event.height;
    #ifdef SIMULATOR
    if(is_simulating) simulator->windowResized(w,h);
    #endif
    grid->Resize();
    ///calls resize method of all 'Graphics' when nedded.
    GraphicDispatcher::Instance().Resize(w,h);
}

//--------------------------------------------------------------
void TableApp::mouseDragged(ofMouseEventArgs & event){
    #ifdef SIMULATOR
    if(is_simulating) simulator->mouseDragged(event.x,event.y,event.button);
    #endif
}

//--------------------------------------------------------------
void TableApp::mousePressed(ofMouseEventArgs & event){
    #ifdef SIMULATOR
    if(is_simulating) simulator->mousePressed(event.x,event.y,event.button);
    #endif
}

//--------------------------------------------------------------
void TableApp::mouseReleased(ofMouseEventArgs & event){
    #ifdef SIMULATOR
    if(is_simulating) simulator->mouseReleased(event.x,event.y,event.button);
    #endif
}

<commit_msg>bugfix: Figure's global matrix not updated when resizing<commit_after>/*

    ofxTableGestures (formerly OF-TangibleFramework)
    Developed for Taller de Sistemes Interactius I
    Universitat Pompeu Fabra

    Copyright (c) 2010 Daniel Gallardo Grassot <daniel.gallardo@upf.edu>

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

#include <fstream>
#include "TableApp.hpp"
#include "GraphicDispatcher.hpp"
#include "Renderer_plane.hpp"
#include "Renderer_to_texture.hpp"
#include "ofxGlobalConfig.hpp"
#include "CollisionHelper.h"

#define WIDTH_STEP 0.005
#define ANGLE_STEP 1
#define DISTORTION_PATH "calibration.conf"

float TableApp::height = 0;
float TableApp::width = 0;

TableApp::TableApp():
//    calibration_enabled(false),
    calibration_mode(0),
    show_help(false),
    show_info(false),
    hide_cursor(true),
    #ifdef SIMULATOR
    simulator(new simulator::Simulator()),
    is_simulating(false),
    #endif
    squaredInterface(ofxGlobalConfig::getRef("GLOBAL:SQUAREDINTERFACE",1)),
    matrix_updated(false)
{
    if(ofxGlobalConfig::getRef("GLOBAL:RENDERTOTEXTURE",0)) renderer = new Renderer_to_texture();
    else renderer = new Renderer_plane();

    renderer->LoadDistortion();
    show_grid = false;

    ofAddListener(ofEvents.update,this,&TableApp::update);
    ofAddListener(ofEvents.keyPressed,this,&TableApp::keyPressed);
    ofAddListener(ofEvents.keyReleased,this,&TableApp::keyReleased);
    ofAddListener(ofEvents.mouseDragged,this,&TableApp::mouseDragged);
    ofAddListener(ofEvents.mousePressed,this,&TableApp::mousePressed);
    ofAddListener(ofEvents.mouseReleased,this,&TableApp::mouseReleased);
    ofAddListener(ofEvents.windowResized,this,&TableApp::windowResized);

    Figures::CollisionHelper::ignore_transformation_matrix.SetIdentity();
}

TableApp::~TableApp(){
    #ifdef SIMULATOR
    delete simulator;
    #endif
    delete renderer;
    delete grid;

    ofRemoveListener(ofEvents.update,this,&TableApp::update);
    ofRemoveListener(ofEvents.keyPressed,this,&TableApp::keyPressed);
    ofRemoveListener(ofEvents.keyReleased,this,&TableApp::keyReleased);
    ofRemoveListener(ofEvents.mouseDragged,this,&TableApp::mouseDragged);
    ofRemoveListener(ofEvents.mousePressed,this,&TableApp::mousePressed);
    ofRemoveListener(ofEvents.mouseReleased,this,&TableApp::mouseReleased);
    ofRemoveListener(ofEvents.windowResized,this,&TableApp::windowResized);

}

int TableApp::GetSquareSide(){
    if(ofGetWidth() > ofGetHeight())return ofGetHeight();
    else return ofGetWidth();
}

//--------------------------------------------------------------
void TableApp::setup(){
    grid = new Grid(6,6);
    full=false;
    ofSetFrameRate(60);
    ///starts the tuioinput thread
    //tuio::tuioinput::Instance().init();
    ofSetWindowTitle("Table APP    press 'h' to show help content");
    ofBackground(0, 0, 0);
    ofHideCursor();
}

//--------------------------------------------------------------
void TableApp::update(ofEventArgs & args){
    ///Update input events, it says to all input gestures to process the gesture stack.
    //tuio::tuioAreaDelivery::Instance().processTevents();
    ///Update graphic data, with this command all update methods from all 'Graphics' are launched
    GraphicDispatcher::Instance().Update();
    ///Update simulator objects
    #ifdef SIMULATOR
    if(is_simulating) simulator->Update();
    #endif
}

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

void TableApp::DrawInfo()
{
    if(show_info)
    {
        glPushMatrix();
        glTranslatef(50.0f,50.0f,0.0f);
        ofSetColor(0x00FF00);
        std::stringstream msg;
        msg << ofGetWidth() << "X" << ofGetHeight() << "@" <<  (int)ofGetFrameRate() << "fps" << std::endl;
        if(renderer->IsEnabled())
            msg << "Distortion enabled" << std::endl;
        else
            msg << "Distortion disabled" << std::endl;
        msg << "Calibration data:" << std::endl;
        msg << renderer->ToString();
        ofDrawBitmapString(msg.str(), 0, 0);
        glPopMatrix();
    }
}

void TableApp::DrawHelp()
{
    if(show_help)
    {
        glPushMatrix();
        glTranslatef(50.0f,200.0f,0.0f);
        ofSetColor(0x00FF00);
        std::stringstream msg;
        msg << "h - help content." << std::endl;
        msg << "i - shows graphic information content." << std::endl;
        msg << "f - toggle fullscreen." << std::endl;
        msg << "m - shows/hides cursor pointer." << std::endl;
        msg << "d - enable/disable distortion." << std::endl;
        msg << "c - calibration mode." << std::endl;
        msg << "Under calibration mode:" << std::endl;
        msg << "  r - reset calibration values." << std::endl;
        msg << "  l - load calibration file." << std::endl;
        msg << "  return  - toggle calibration parameter." << std::endl;
        msg << "  cursors - Changes the selected parameter." << std::endl;
        #ifdef SIMULATOR
        msg << "s - enable simulator." << std::endl;
        msg << "Under simulator mode:" << std::endl;
        msg << "  r - reset." << std::endl;
        msg << "  a - hold." << std::endl;
        msg << "  z - select." << std::endl;
        #endif
        ofDrawBitmapString(msg.str(), 0, 0);
        glPopMatrix();
    }
}

void TableApp::draw(){
    ofPushMatrix();
    #ifdef SIMULATOR
    if(is_simulating) ofScale(0.91f,0.91f,1.0f);
    #endif

    renderer->Start();
    ofPushMatrix();
    int shortside = min(ofGetWidth(),ofGetHeight());
    if(squaredInterface)
    {
        //if the surface is squared we center the drawing  plane
        glTranslatef((ofGetWidth()-shortside)/2.0,(ofGetHeight()-shortside)/2.0,0);
        TableApp::height = 1;
        TableApp::width = 1;
    }
    else
    {
        TableApp::height = float(ofGetHeight())/float(shortside);
        TableApp::width = float(ofGetWidth())/float(shortside);
    }
    glScalef(shortside,shortside,1);

    if(!matrix_updated)
    {
        matrix_updated = true;
        glGetDoublev(GL_MODELVIEW_MATRIX,Figures::CollisionHelper::ignore_transformation_matrix.data);
        Figures::CollisionHelper::ignore_transformation_matrix = Figures::CollisionHelper::ignore_transformation_matrix.GetInverse();
    }
    ///Draws all 'Graphics'
    glDisable(GL_DEPTH_TEST);
    ofPushMatrix();
    GraphicDispatcher::Instance().Draw();
    ofPopMatrix();
    glEnable(GL_DEPTH_TEST);

    ofPopMatrix();
    grid->Draw(show_grid,calibration_mode);
    renderer->End();
    ///Draws Info & help
    DrawInfo();
    DrawHelp();
    ofPopMatrix();
    #ifdef SIMULATOR
    if(is_simulating) simulator->Draw();
    #endif
}

//--------------------------------------------------------------
void TableApp::keyPressed(ofKeyEventArgs & event){
    int key = event.key;
    #ifdef SIMULATOR
    switch(key)
    {
        case 'a':
            simulator->Hold(true);
        break;
        case 'z':
            simulator->Select(true);
        break;
        default:
            KeyPressed(key);
        break;
    }
    #endif
}

//--------------------------------------------------------------
void TableApp::keyReleased(ofKeyEventArgs & event){
    int key = event.key;
    switch(key)
    {
        default:
            KeyReleased(key);
        break;
        #ifdef SIMULATOR
        case 'a':
            simulator->Hold(false);
        break;
        case 'z':
            simulator->Select(false);
        break;
        #endif
        case 'f':
            ofToggleFullscreen();
		break;
		case 'c':
            if(renderer->IsEnabled()){
                renderer->SaveDistortion();
            }
            show_grid = !show_grid;
        break;
        case OF_KEY_RETURN:
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid) calibration_mode ++;
            if(calibration_mode > 3) calibration_mode = 0;
        break;
        case OF_KEY_UP:
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid)
            {
                switch(calibration_mode)
                {
                    case 0:renderer->center_y--;break;
                    case 1:renderer->height_offset+=WIDTH_STEP;break;
                    case 2:renderer->angle+=ANGLE_STEP;break;
                    case 3:renderer->angle_h+=ANGLE_STEP;break;
                }
            }
        break;
        case OF_KEY_DOWN:
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid)
            {
                switch(calibration_mode)
                {
                    case 0:renderer->center_y++;break;
                    case 1:renderer->height_offset-=WIDTH_STEP;break;
                    case 2:renderer->angle-=ANGLE_STEP;break;
                    case 3:renderer->angle_h-=ANGLE_STEP;break;
                }
            }
        break;
        case OF_KEY_RIGHT:
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid)
            {
                switch(calibration_mode)
                {
                    case 0:renderer->center_x++;break;
                    case 1:renderer->width_offset+=WIDTH_STEP;break;
                    case 2:renderer->angle+=ANGLE_STEP;break;
                    case 3:renderer->angle_w+=ANGLE_STEP;break;
                }
            }
        break;
        case OF_KEY_LEFT:
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid)
            {
                switch(calibration_mode)
                {
                    case 0:renderer->center_x--;break;
                    case 1:renderer->width_offset-=WIDTH_STEP;break;
                    case 2:renderer->angle-=ANGLE_STEP;break;
                    case 3:renderer->angle_w-=ANGLE_STEP;break;
                }
            }
        break;
        case 'i':
            show_info = !show_info;
        break;
        case 'm':
            if(hide_cursor)
            {
                hide_cursor=false;
                ofShowCursor();
            }else{
                hide_cursor=true;
                ofHideCursor();
            }
        break;
        case 'r':
            if(renderer->IsEnabled() && show_grid)
                renderer->LoadDefaultValues();
            #ifdef SIMULATOR
                if(is_simulating)
                    simulator->Reset();
            #endif
        break;
        case 'l':
            #ifdef SIMULATOR
            if(!is_simulating)
            #endif
            if(renderer->IsEnabled() && show_grid)
                renderer->LoadDistortion();
        break;
        case 'h':
            show_help = !show_help;
        break;
        case 'd':
            #ifdef SIMULATOR
            if(!is_simulating)
            {
            #endif
            if(renderer->IsEnabled()) renderer->Disable();
            else renderer->Enable();
            #ifdef SIMULATOR
            }
            #endif
        break;
        case 's':
            #ifdef SIMULATOR
                if(is_simulating){
                    ///restore distorsion
                    ///restore cursor
                    if(was_distorsion_enabled) renderer->Enable();
                    else renderer->Disable();
                    if(was_cursor_hide){
                        hide_cursor=true;
                        ofHideCursor();
                    }
                    is_simulating=false;
                    simulator->Reset();
                }
                else{
                    was_distorsion_enabled = renderer->IsEnabled();
                    was_cursor_hide = hide_cursor;
                    renderer->Disable();
                    hide_cursor=false;
                    ofShowCursor();
                    is_simulating=true;
                }
                matrix_updated = false;
            #endif
        break;
        case 'b':
            Figures::CollisionHelper::debug_graphics = !Figures::CollisionHelper::debug_graphics;
        break;
    }
}

//--------------------------------------------------------------
void TableApp::windowResized(ofResizeEventArgs & event){
    int w = event.width;
    int h = event.height;
    #ifdef SIMULATOR
    if(is_simulating) simulator->windowResized(w,h);
    #endif
    grid->Resize();
    ///calls resize method of all 'Graphics' when nedded.
    GraphicDispatcher::Instance().Resize(w,h);
    matrix_updated = false;
}

//--------------------------------------------------------------
void TableApp::mouseDragged(ofMouseEventArgs & event){
    #ifdef SIMULATOR
    if(is_simulating) simulator->mouseDragged(event.x,event.y,event.button);
    #endif
}

//--------------------------------------------------------------
void TableApp::mousePressed(ofMouseEventArgs & event){
    #ifdef SIMULATOR
    if(is_simulating) simulator->mousePressed(event.x,event.y,event.button);
    #endif
}

//--------------------------------------------------------------
void TableApp::mouseReleased(ofMouseEventArgs & event){
    #ifdef SIMULATOR
    if(is_simulating) simulator->mouseReleased(event.x,event.y,event.button);
    #endif
}

<|endoftext|>