<commit_before>// Copyright (c) 2014, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: yanshiguang02@baidu.com

#include <gflags/gflags.h>

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unistd.h>
#include <stdlib.h>

#include "common/timer.h"
#include "sdk/bfs.h"

DECLARE_string(flagfile);
DECLARE_string(nameserver);
DECLARE_string(nameserver_port);

void print_usage() {
    printf("Use:\nbfs_client <commond> path\n");
    printf("\t commond:\n");
    printf("\t    ls <path> : list the directory\n");
    printf("\t    cat <path> : cat the file\n");
    printf("\t    mkdir <path> : make director\n");
    printf("\t    mv <srcpath> <destpath> : rename director or file\n");
    printf("\t    touchz <path> : create a new file\n");
    printf("\t    rm <path> : remove a file\n");
    printf("\t    get <bfsfile> <localfile> : copy file to local\n");
    printf("\t    put <localfile> <bfsfile> : copy file from local to bfs\n");
    printf("\t    append <localfile> <bfsfile> : append localfile to bfsfile\n");
    printf("\t    rmdir <path> : remove empty directory\n");
    printf("\t    rmr <path> : remove directory recursively\n");
    printf("\t    change_replica_num <bfsfile> <num>: change replica num of <bfsfile> to <num>\n");
    printf("\t    dus <path> : count disk usage for path\n");
}

int BfsMkdir(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    bool ret = fs->CreateDirectory(argv[0]);
    if (!ret) {
        fprintf(stderr, "Create dir %s fail\n", argv[0]);
        return 1;
    }
    return 0;
}

int BfsRename(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    bool ret = fs->Rename(argv[0], argv[1]);
    if (!ret) {
        fprintf(stderr, "Rename %s to %s fail\n", argv[0], argv[1]);
        return 1;
    }
    return 0;
}

int BfsCat(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    for (int i = 0; i < argc; i++) {
        bfs::File* file;
        if (!fs->OpenFile(argv[i], O_RDONLY, &file)) {
            fprintf(stderr, "Can't Open bfs file %s\n", argv[0]);
            return 1;
        }
        char buf[10240];
        int64_t bytes = 0;
        int64_t len = 0;
        while (1) {
            len = file->Read(buf, sizeof(buf));
            if (len <= 0) {
                break;
            }
            bytes += len;
            write(1, buf, len);
        }
        delete file;
    }
    return 0;
}

int BfsGet(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    bfs::File* file;
    if (!fs->OpenFile(argv[0], O_RDONLY, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[0]);
        return 1;
    }

    FILE* fp = fopen(argv[1], "wb");
    if (fp == NULL) {
        fprintf(stderr, "Open local file %s fail\n", argv[1]);
        delete file;
        return -1;
    }
    char buf[10240];
    int64_t bytes = 0;
    int64_t len = 0;
    while (1) {
        len = file->Read(buf, sizeof(buf));
        if (len <= 0) {
            break;
        }
        bytes += len;
        fwrite(buf, len, 1, fp);
    }
    printf("Read %ld bytes from %s\n", bytes, argv[1]);
    delete file;
    return 0;
}

int BfsPut(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 4) {
        print_usage();
        return 0;
    }
    common::timer::AutoTimer at(0, "BfsPut", argv[3]);
    FILE* fp = fopen(argv[2], "rb");
    if (fp == NULL) {
        fprintf(stderr, "Can't open local file %s\n", argv[2]);
        return 1;
    }

    bfs::File* file;
    if (!fs->OpenFile(argv[3], O_WRONLY, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[3]);
        return 1;
    }
    char buf[1024];
    int64_t len = 0;
    int64_t bytes = 0;
    while ( (bytes = fread(buf, 1, sizeof(buf), fp)) > 0) {
        int64_t write_bytes = file->Write(buf, bytes);
        if (write_bytes < bytes) {
            fprintf(stderr, "Write fail: [%s:%ld]\n", argv[3], len);
            return 1;
        }
        len += bytes;
    }
    if (!fs->CloseFile(file)) {
        fprintf(stderr, "close fail: %s\n", argv[3]);
        return 1;
    }
    delete file;
    printf("Put file to bfs %s %ld bytes\n", argv[3], len);
    return 0;
}

int64_t BfsDuRecursive(bfs::FS* fs, const std::string& path) {
    int64_t ret = 0;
    bfs::BfsFileInfo* files = NULL;
    int num = 0;
    fs->ListDirectory(path.c_str(), &files, &num);
    for (int i = 0; i < num; i++) {
        int32_t type = files[i].mode;
        if (type & (1<<9)) {
            ret += BfsDuRecursive(fs, files[i].name);
            continue;
        }
        bfs::BfsFileInfo fileinfo;
        if (fs->Stat(files[i].name, &fileinfo)) {
            ret += fileinfo.size;
            printf("%s\t %ld\n", files[i].name, fileinfo.size);
        }
    }
    delete files;
    return ret;
}

int BfsDus(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 1) {
        print_usage();
        return 1;
    }
    int64_t du = BfsDuRecursive(fs, argv[0]);
    printf("Total:\t%ld\n", du);
    return 0;
}

int BfsList(bfs::FS* fs, int argc, char* argv[]) {
    std::string path("/");
    if (argc == 3) {
        path = argv[2];
    }
    bfs::BfsFileInfo* files = NULL;
    int num;
    fs->ListDirectory(path.c_str(), &files, &num);
    printf("Found %d items\n", num);
    for (int i = 0; i < num; i++) {
        int32_t type = files[i].mode;
        char statbuf[16] = "drwxrwxrwx";
        for (int j = 0; j < 10; j++) {
            if ((type & (1<<(9-j))) == 0) {
                statbuf[j] = '-';
            }
        }
        char timestr[64];
        struct tm stm;
        time_t ctime = files[i].ctime;
        localtime_r(&ctime, &stm);
        snprintf(timestr, sizeof(timestr), "%4d-%02d-%02d %2d:%02d",
            stm.tm_year+1900, stm.tm_mon+1, stm.tm_mday, stm.tm_hour, stm.tm_min);
        printf("%s\t%s  %s\n", statbuf, timestr, files[i].name);
    }
    delete files;
    return 0;
}

int BfsAppend(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 4) {
        print_usage();
        return 0;
    }
    common::timer::AutoTimer at(0, "BfsAppend", argv[3]);
    FILE* fp = fopen(argv[2], "rb");
    if (fp == NULL) {
        fprintf(stderr, "Can't open local file %s\n", argv[2]);
        return 1;
    }

    bfs::File* file;
    if (!fs->OpenFile(argv[3], O_APPEND, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[3]);
        return 1;
    }
    char buf[1024];
    int64_t len = 0;
    int64_t bytes = 0;
    while ( (bytes = fread(buf, 1, sizeof(buf), fp)) > 0) {
        int64_t write_bytes = file->Write(buf, bytes);
        if (write_bytes < bytes) {
            fprintf(stderr, "Append fail: [%s:%ld]\n", argv[3], len);
            return 1;
        }
        len += bytes;
    }
    if (!fs->CloseFile(file)) {
        fprintf(stderr, "close fail: %s\n", argv[3]);
        return 1;
    }
    delete file;
    printf("Append to bfs %s %ld bytes\n", argv[3], len);
    return 0;
}

int BfsRmdir(bfs::FS* fs, int argc, char* argv[], bool recursive) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    bool ret = fs->DeleteDirectory(argv[0], recursive);
    if (!ret) {
        fprintf(stderr, "Remove dir %s fail\n", argv[0]);
        return 1;
    }
    return 0;
}

int BfsChangeReplicaNum(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    char* file_name = argv[0];
    int32_t replica_num = atoi(argv[1]);
    bool ret = fs->ChangeReplicaNum(file_name, replica_num);
    if (!ret) {
        fprintf(stderr, "Change %s replica num to %d fail\n", file_name, replica_num);
        return 1;
    }
    return 0;
}

/// bfs client main
int main(int argc, char* argv[]) {
    FLAGS_flagfile = "./bfs.flag";
    ::google::ParseCommandLineFlags(&argc, &argv, false);

    if (argc < 2) {
        print_usage();
        return 0;
    }

    bfs::FS* fs;
    std::string ns_address = FLAGS_nameserver + ":" + FLAGS_nameserver_port;
    if (!bfs::FS::OpenFileSystem(ns_address.c_str(), &fs)) {
        fprintf(stderr, "Open filesytem %s fail\n", ns_address.c_str());
        return 1;
    }

    int ret = 1;
    if (strcmp(argv[1], "touchz") == 0) {
        if (argc != 3) {
            print_usage();
            return ret;
        }
        bfs::File* file;
        if (!fs->OpenFile(argv[2], O_WRONLY, &file)) {
            fprintf(stderr, "Open %s fail\n", argv[2]);
        } else {
            ret = 0;
        }
    } else if (strcmp(argv[1], "rm") == 0) {
        if (argc != 3) {
            print_usage();
            return ret;
        }
        if (fs->DeleteFile(argv[2])) {
            printf("%s Removed\n", argv[2]);
            ret = 0;
        } else {
            fprintf(stderr, "Remove file fail: %s\n", argv[2]);
        }
    } else if (strcmp(argv[1], "mkdir") == 0) {
        ret = BfsMkdir(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "mv") == 0) {
        ret = BfsRename(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "put") == 0) {
        ret = BfsPut(fs, argc, argv);
    } else if (strcmp(argv[1], "get") == 0 ) {
        ret = BfsGet(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "cat") == 0) {
        ret = BfsCat(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "ls") == 0) {
        ret = BfsList(fs, argc, argv);
    } else if (strcmp(argv[1], "append") == 0) {
        ret = BfsAppend(fs, argc, argv);
    } else if (strcmp(argv[1], "rmdir") == 0) {
        ret = BfsRmdir(fs, argc - 2, argv + 2, false);
    } else if (strcmp(argv[1], "rmr") == 0) {
        ret = BfsRmdir(fs, argc - 2, argv + 2, true);
    } else if (strcmp(argv[1], "change_replica_num") == 0) {
        ret = BfsChangeReplicaNum(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "dus") == 0) {
        ret = BfsDus(fs, argc - 2, argv + 2);
    } else {
        fprintf(stderr, "Unknow common: %s\n", argv[1]);
    }
    return ret;
}

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
<commit_msg>Add dus for bfs_client<commit_after>// Copyright (c) 2014, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: yanshiguang02@baidu.com

#include <gflags/gflags.h>

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unistd.h>
#include <stdlib.h>

#include "common/timer.h"
#include "sdk/bfs.h"

DECLARE_string(flagfile);
DECLARE_string(nameserver);
DECLARE_string(nameserver_port);

void print_usage() {
    printf("Use:\nbfs_client <commond> path\n");
    printf("\t commond:\n");
    printf("\t    ls <path> : list the directory\n");
    printf("\t    cat <path> : cat the file\n");
    printf("\t    mkdir <path> : make director\n");
    printf("\t    mv <srcpath> <destpath> : rename director or file\n");
    printf("\t    touchz <path> : create a new file\n");
    printf("\t    rm <path> : remove a file\n");
    printf("\t    get <bfsfile> <localfile> : copy file to local\n");
    printf("\t    put <localfile> <bfsfile> : copy file from local to bfs\n");
    printf("\t    append <localfile> <bfsfile> : append localfile to bfsfile\n");
    printf("\t    rmdir <path> : remove empty directory\n");
    printf("\t    rmr <path> : remove directory recursively\n");
    printf("\t    change_replica_num <bfsfile> <num>: change replica num of <bfsfile> to <num>\n");
    printf("\t    du <path> : count disk usage for path\n");
}

int BfsMkdir(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    bool ret = fs->CreateDirectory(argv[0]);
    if (!ret) {
        fprintf(stderr, "Create dir %s fail\n", argv[0]);
        return 1;
    }
    return 0;
}

int BfsRename(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    bool ret = fs->Rename(argv[0], argv[1]);
    if (!ret) {
        fprintf(stderr, "Rename %s to %s fail\n", argv[0], argv[1]);
        return 1;
    }
    return 0;
}

int BfsCat(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    for (int i = 0; i < argc; i++) {
        bfs::File* file;
        if (!fs->OpenFile(argv[i], O_RDONLY, &file)) {
            fprintf(stderr, "Can't Open bfs file %s\n", argv[0]);
            return 1;
        }
        char buf[10240];
        int64_t bytes = 0;
        int64_t len = 0;
        while (1) {
            len = file->Read(buf, sizeof(buf));
            if (len <= 0) {
                break;
            }
            bytes += len;
            write(1, buf, len);
        }
        delete file;
    }
    return 0;
}

int BfsGet(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    bfs::File* file;
    if (!fs->OpenFile(argv[0], O_RDONLY, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[0]);
        return 1;
    }

    FILE* fp = fopen(argv[1], "wb");
    if (fp == NULL) {
        fprintf(stderr, "Open local file %s fail\n", argv[1]);
        delete file;
        return -1;
    }
    char buf[10240];
    int64_t bytes = 0;
    int64_t len = 0;
    while (1) {
        len = file->Read(buf, sizeof(buf));
        if (len <= 0) {
            break;
        }
        bytes += len;
        fwrite(buf, len, 1, fp);
    }
    printf("Read %ld bytes from %s\n", bytes, argv[1]);
    delete file;
    return 0;
}

int BfsPut(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 4) {
        print_usage();
        return 0;
    }
    common::timer::AutoTimer at(0, "BfsPut", argv[3]);
    FILE* fp = fopen(argv[2], "rb");
    if (fp == NULL) {
        fprintf(stderr, "Can't open local file %s\n", argv[2]);
        return 1;
    }

    bfs::File* file;
    if (!fs->OpenFile(argv[3], O_WRONLY, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[3]);
        return 1;
    }
    char buf[1024];
    int64_t len = 0;
    int64_t bytes = 0;
    while ( (bytes = fread(buf, 1, sizeof(buf), fp)) > 0) {
        int64_t write_bytes = file->Write(buf, bytes);
        if (write_bytes < bytes) {
            fprintf(stderr, "Write fail: [%s:%ld]\n", argv[3], len);
            return 1;
        }
        len += bytes;
    }
    if (!fs->CloseFile(file)) {
        fprintf(stderr, "close fail: %s\n", argv[3]);
        return 1;
    }
    delete file;
    printf("Put file to bfs %s %ld bytes\n", argv[3], len);
    return 0;
}

int64_t BfsDuRecursive(bfs::FS* fs, const std::string& path) {
    int64_t ret = 0;
    bfs::BfsFileInfo* files = NULL;
    int num = 0;
    fs->ListDirectory(path.c_str(), &files, &num);
    for (int i = 0; i < num; i++) {
        int32_t type = files[i].mode;
        if (type & (1<<9)) {
            ret += BfsDuRecursive(fs, files[i].name);
            continue;
        }
        bfs::BfsFileInfo fileinfo;
        if (fs->Stat(files[i].name, &fileinfo)) {
            ret += fileinfo.size;
            printf("%s\t %ld\n", files[i].name, fileinfo.size);
        }
    }
    delete files;
    return ret;
}

int BfsDu(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 1) {
        print_usage();
        return 1;
    }
    int64_t du = BfsDuRecursive(fs, argv[0]);
    printf("Total:\t%ld\n", du);
    return 0;
}

int BfsList(bfs::FS* fs, int argc, char* argv[]) {
    std::string path("/");
    if (argc == 3) {
        path = argv[2];
    }
    bfs::BfsFileInfo* files = NULL;
    int num;
    fs->ListDirectory(path.c_str(), &files, &num);
    printf("Found %d items\n", num);
    for (int i = 0; i < num; i++) {
        int32_t type = files[i].mode;
        char statbuf[16] = "drwxrwxrwx";
        for (int j = 0; j < 10; j++) {
            if ((type & (1<<(9-j))) == 0) {
                statbuf[j] = '-';
            }
        }
        char timestr[64];
        struct tm stm;
        time_t ctime = files[i].ctime;
        localtime_r(&ctime, &stm);
        snprintf(timestr, sizeof(timestr), "%4d-%02d-%02d %2d:%02d",
            stm.tm_year+1900, stm.tm_mon+1, stm.tm_mday, stm.tm_hour, stm.tm_min);
        printf("%s\t%s  %s\n", statbuf, timestr, files[i].name);
    }
    delete files;
    return 0;
}

int BfsAppend(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 4) {
        print_usage();
        return 0;
    }
    common::timer::AutoTimer at(0, "BfsAppend", argv[3]);
    FILE* fp = fopen(argv[2], "rb");
    if (fp == NULL) {
        fprintf(stderr, "Can't open local file %s\n", argv[2]);
        return 1;
    }

    bfs::File* file;
    if (!fs->OpenFile(argv[3], O_APPEND, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[3]);
        return 1;
    }
    char buf[1024];
    int64_t len = 0;
    int64_t bytes = 0;
    while ( (bytes = fread(buf, 1, sizeof(buf), fp)) > 0) {
        int64_t write_bytes = file->Write(buf, bytes);
        if (write_bytes < bytes) {
            fprintf(stderr, "Append fail: [%s:%ld]\n", argv[3], len);
            return 1;
        }
        len += bytes;
    }
    if (!fs->CloseFile(file)) {
        fprintf(stderr, "close fail: %s\n", argv[3]);
        return 1;
    }
    delete file;
    printf("Append to bfs %s %ld bytes\n", argv[3], len);
    return 0;
}

int BfsRmdir(bfs::FS* fs, int argc, char* argv[], bool recursive) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    bool ret = fs->DeleteDirectory(argv[0], recursive);
    if (!ret) {
        fprintf(stderr, "Remove dir %s fail\n", argv[0]);
        return 1;
    }
    return 0;
}

int BfsChangeReplicaNum(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    char* file_name = argv[0];
    int32_t replica_num = atoi(argv[1]);
    bool ret = fs->ChangeReplicaNum(file_name, replica_num);
    if (!ret) {
        fprintf(stderr, "Change %s replica num to %d fail\n", file_name, replica_num);
        return 1;
    }
    return 0;
}

/// bfs client main
int main(int argc, char* argv[]) {
    FLAGS_flagfile = "./bfs.flag";
    ::google::ParseCommandLineFlags(&argc, &argv, false);

    if (argc < 2) {
        print_usage();
        return 0;
    }

    bfs::FS* fs;
    std::string ns_address = FLAGS_nameserver + ":" + FLAGS_nameserver_port;
    if (!bfs::FS::OpenFileSystem(ns_address.c_str(), &fs)) {
        fprintf(stderr, "Open filesytem %s fail\n", ns_address.c_str());
        return 1;
    }

    int ret = 1;
    if (strcmp(argv[1], "touchz") == 0) {
        if (argc != 3) {
            print_usage();
            return ret;
        }
        bfs::File* file;
        if (!fs->OpenFile(argv[2], O_WRONLY, &file)) {
            fprintf(stderr, "Open %s fail\n", argv[2]);
        } else {
            ret = 0;
        }
    } else if (strcmp(argv[1], "rm") == 0) {
        if (argc != 3) {
            print_usage();
            return ret;
        }
        if (fs->DeleteFile(argv[2])) {
            printf("%s Removed\n", argv[2]);
            ret = 0;
        } else {
            fprintf(stderr, "Remove file fail: %s\n", argv[2]);
        }
    } else if (strcmp(argv[1], "mkdir") == 0) {
        ret = BfsMkdir(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "mv") == 0) {
        ret = BfsRename(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "put") == 0) {
        ret = BfsPut(fs, argc, argv);
    } else if (strcmp(argv[1], "get") == 0 ) {
        ret = BfsGet(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "cat") == 0) {
        ret = BfsCat(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "ls") == 0) {
        ret = BfsList(fs, argc, argv);
    } else if (strcmp(argv[1], "append") == 0) {
        ret = BfsAppend(fs, argc, argv);
    } else if (strcmp(argv[1], "rmdir") == 0) {
        ret = BfsRmdir(fs, argc - 2, argv + 2, false);
    } else if (strcmp(argv[1], "rmr") == 0) {
        ret = BfsRmdir(fs, argc - 2, argv + 2, true);
    } else if (strcmp(argv[1], "change_replica_num") == 0) {
        ret = BfsChangeReplicaNum(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "du") == 0) {
        ret = BfsDu(fs, argc - 2, argv + 2);
    } else {
        fprintf(stderr, "Unknow common: %s\n", argv[1]);
    }
    return ret;
}

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2011-2012.
// 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)
//=======================================================================

#include "assert.hpp"
#include "logging.hpp"

#include "mtac/Function.hpp"
#include "mtac/ControlFlowGraph.hpp"
#include "mtac/basic_block.hpp"

using namespace eddic;

mtac::Function::Function(std::shared_ptr<FunctionContext> c, const std::string& n, eddic::Function& definition) : context(c), _definition(&definition), name(n) {
    //Nothing to do
}

mtac::Function::Function(mtac::Function&& rhs) :
            context(std::move(rhs.context)), _definition(rhs._definition),
            statements(std::move(rhs.statements)),
            count(std::move(rhs.count)), index(std::move(rhs.index)),
            entry(std::move(rhs.entry)), exit(std::move(rhs.exit)),
            _use_registers(std::move(rhs._use_registers)), _use_float_registers(std::move(rhs._use_float_registers)),
            _variable_registers(std::move(rhs._variable_registers)), _variable_float_registers(std::move(rhs._variable_float_registers)),
            last_pseudo_registers(std::move(rhs.last_pseudo_registers)), last_float_pseudo_registers(std::move(rhs.last_float_pseudo_registers)),
            m_loops(std::move(rhs.m_loops)), name(std::move(rhs.name))
        {
    //Reset rhs
    rhs.count = 0;
    rhs.index = 0;
    rhs.last_pseudo_registers = 0;
    rhs.last_float_pseudo_registers = 0;
}

mtac::Function& mtac::Function::operator=(mtac::Function&& rhs){
    _definition = rhs._definition;
    context = std::move(rhs.context);
    statements = std::move(rhs.statements);
    count = std::move(rhs.count);
    index = std::move(rhs.index);
    entry = std::move(rhs.entry);
    exit = std::move(rhs.exit);
    _use_registers = std::move(rhs._use_registers);
    _use_float_registers = std::move(rhs._use_float_registers);
    _variable_registers = std::move(rhs._variable_registers);
    _variable_float_registers = std::move(rhs._variable_float_registers);
    last_pseudo_registers = std::move(rhs.last_pseudo_registers);
    last_float_pseudo_registers = std::move(rhs.last_float_pseudo_registers);
    m_loops = std::move(rhs.m_loops);
    name = std::move(rhs.name);

    //Reset rhs
    rhs.count = 0;
    rhs.index = 0;
    rhs.last_pseudo_registers = 0;
    rhs.last_float_pseudo_registers = 0;

    return *this;
}

bool mtac::Function::is_main() const {
    return name == "_F4main" || name == "_F4mainAS";
}

bool& mtac::Function::pure(){
    return _pure;
}

bool mtac::Function::pure() const {
    return _pure;
}

mtac::Quadruple& mtac::Function::find(std::size_t uid){
    for(auto& block : *this){
        for(auto& quadruple : block){
            if(quadruple.uid() == uid){
                return quadruple;
            }
        }
    }

    eddic_unreachable("The given uid does not exist");
}

mtac::basic_block_iterator mtac::Function::begin(){
    return basic_block_iterator(entry, nullptr);
}

mtac::basic_block_iterator mtac::Function::end(){
    return basic_block_iterator(nullptr, exit);
}

mtac::basic_block_const_iterator mtac::Function::begin() const {
    return basic_block_const_iterator(entry, nullptr);
}

mtac::basic_block_const_iterator mtac::Function::end() const {
    return basic_block_const_iterator(nullptr, exit);
}

mtac::basic_block_iterator mtac::Function::at(std::shared_ptr<basic_block> bb){
    if(bb){
        return basic_block_iterator(bb, bb->prev);
    } else {
        return basic_block_iterator(nullptr, nullptr);
    }
}

mtac::basic_block_p mtac::Function::entry_bb(){
    return entry;
}

mtac::basic_block_p mtac::Function::exit_bb(){
    return exit;
}

mtac::basic_block_p mtac::Function::current_bb(){
    return exit;
}

void mtac::Function::create_entry_bb(){
    ++count;

    auto new_block = std::make_shared<mtac::basic_block>(-1);
    new_block->context = context;

    entry = exit = new_block;
}

void mtac::Function::create_exit_bb(){
    ++count;

    auto new_block = std::make_shared<mtac::basic_block>(-2);
    new_block->context = context;

    exit->next = new_block;
    new_block->prev = exit;

    exit = new_block;
}

mtac::basic_block_p mtac::Function::new_bb(){
    auto bb = std::make_shared<mtac::basic_block>(++index);
    bb->context = context;
    return bb;
}

mtac::basic_block_p mtac::Function::append_bb(){
    auto new_block = new_bb();
    ++count;

    exit->next = new_block;
    new_block->prev = exit;

    exit = new_block;

    return new_block;
}

mtac::basic_block_iterator mtac::Function::insert_before(mtac::basic_block_iterator it, mtac::basic_block_p block){
    auto bb = *it;

    eddic_assert(block, "Cannot add null block");
    eddic_assert(it != begin(), "Cannot add before entry");

    block->context = context;

    ++count;

    block->prev = bb->prev;
    block->next = bb;
    bb->prev->next = block;
    bb->prev = block;

    return at(block);
}

mtac::basic_block_iterator mtac::Function::insert_after(mtac::basic_block_iterator it, mtac::basic_block_p block){
    return insert_before(++it, block);
}

mtac::basic_block_iterator mtac::Function::remove(mtac::basic_block_p block){
    eddic_assert(block, "Cannot remove null block");
    eddic_assert(block != exit, "Cannot remove exit");

    LOG<Debug>("CFG") << "Remove basic block B" << block->index << log::endl;

    auto& next = block->next;

    --count;

    for(auto& succ : block->successors){
        auto it = iterate(succ->predecessors);

        while(it.has_next()){
            auto pred = *it;

            if(pred == block){
                it.erase();
            } else {
                ++it;
            }
        }
    }

    for(auto& pred : block->predecessors){
        auto it = iterate(pred->successors);

        while(it.has_next()){
            auto succ = *it;

            if(succ == block){
                it.erase();
            } else {
                ++it;
            }
        }

        //If there is a Fall through edge, redirect it
        if(pred == block->prev){
            mtac::make_edge(pred, block->next);
        }
    }

    block->successors.clear();
    block->predecessors.clear();

    block->prev->next = next;
    next->prev = block->prev;

    block->prev = nullptr;
    block->next = nullptr;

    return at(next);
}

mtac::basic_block_iterator mtac::Function::remove(mtac::basic_block_iterator it){
    return remove(*it);
}

mtac::basic_block_iterator mtac::Function::merge_basic_blocks(basic_block_iterator it, std::shared_ptr<basic_block> block){
    auto source = *it;

    eddic_assert(source->next == block || source->prev == block, "Can only merge sibling blocks");

    LOG<Debug>("CFG") << "Merge " << source->index << " into " << block->index << log::endl;

    if(!source->statements.empty()){
        //B can have some new successors
        for(auto& succ : source->successors){
            if(succ != source->next){
                mtac::make_edge(block, succ);
            }
        }

        //No need to remove the edges, they will be removed by remove call
    }

    //Insert the statements
    if(source->next == block){
        block->statements.insert(block->statements.begin(), source->statements.begin(), source->statements.end());
    } else {
        block->statements.insert(block->statements.end(), source->statements.begin(), source->statements.end());
    }

    //Remove the source basic block
    remove(source);

    return at(block);
}

std::string mtac::Function::get_name() const {
    return name;
}

eddic::Function& mtac::Function::definition(){
    return *_definition;
}

std::vector<mtac::Quadruple>& mtac::Function::get_statements(){
    return statements;
}

const std::vector<mtac::Quadruple>& mtac::Function::get_statements() const {
    return statements;
}

void mtac::Function::release_statements(){
    statements.clear();
    statements.shrink_to_fit();
}

std::size_t mtac::Function::bb_count() const {
    return count;
}

const std::set<ltac::Register>& mtac::Function::use_registers() const {
    return _use_registers;
}

const std::set<ltac::FloatRegister>& mtac::Function::use_float_registers() const {
    return _use_float_registers;
}

void mtac::Function::use(ltac::Register reg){
    _use_registers.insert(reg);
}

void mtac::Function::use(ltac::FloatRegister reg){
    _use_float_registers.insert(reg);
}

const std::set<ltac::Register>& mtac::Function::variable_registers() const {
    return _variable_registers;
}

const std::set<ltac::FloatRegister>& mtac::Function::variable_float_registers() const {
    return _variable_float_registers;
}

void mtac::Function::variable_use(ltac::Register reg){
    _variable_registers.insert(reg);
}

void mtac::Function::variable_use(ltac::FloatRegister reg){
    _variable_float_registers.insert(reg);
}

std::size_t mtac::Function::pseudo_registers() const {
    return last_pseudo_registers;
}

void mtac::Function::set_pseudo_registers(std::size_t pseudo_registers){
    this->last_pseudo_registers = pseudo_registers;
}

std::size_t mtac::Function::pseudo_float_registers() const {
    return last_float_pseudo_registers;
}

void mtac::Function::set_pseudo_float_registers(std::size_t pseudo_registers){
    this->last_float_pseudo_registers = pseudo_registers;
}

std::size_t mtac::Function::size() const {
    std::size_t size = 0;

    for(auto& block : *this){
        size += block->statements.size();
    }

    return size;
}

std::pair<mtac::basic_block_iterator, mtac::basic_block_iterator> mtac::Function::blocks(){
    return std::make_pair(begin(), end());
}

std::vector<mtac::Loop>& mtac::Function::loops(){
    return m_loops;
}

bool mtac::operator==(const mtac::Function& lhs, const mtac::Function& rhs){
    return lhs.get_name() == rhs.get_name();
}

std::ostream& eddic::mtac::operator<<(std::ostream& stream, const mtac::Function& function){
    stream << "Function " << function.get_name() << "(pure:" << function.pure() << ")" << std::endl;

    for(auto& quadruple : function.get_statements()){
        stream << quadruple << std::endl;
    }

    for(auto& block : function){
        pretty_print(block, stream);

        for(auto& quadruple : block->statements){
            stream << quadruple << std::endl;
        }
    }

    return stream << std::endl;
}
<commit_msg>Improve performances of merge<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2011-2012.
// 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)
//=======================================================================

#include "assert.hpp"
#include "logging.hpp"

#include "mtac/Function.hpp"
#include "mtac/ControlFlowGraph.hpp"
#include "mtac/basic_block.hpp"

using namespace eddic;

mtac::Function::Function(std::shared_ptr<FunctionContext> c, const std::string& n, eddic::Function& definition) : context(c), _definition(&definition), name(n) {
    //Nothing to do
}

mtac::Function::Function(mtac::Function&& rhs) :
            context(std::move(rhs.context)), _definition(rhs._definition),
            statements(std::move(rhs.statements)),
            count(std::move(rhs.count)), index(std::move(rhs.index)),
            entry(std::move(rhs.entry)), exit(std::move(rhs.exit)),
            _use_registers(std::move(rhs._use_registers)), _use_float_registers(std::move(rhs._use_float_registers)),
            _variable_registers(std::move(rhs._variable_registers)), _variable_float_registers(std::move(rhs._variable_float_registers)),
            last_pseudo_registers(std::move(rhs.last_pseudo_registers)), last_float_pseudo_registers(std::move(rhs.last_float_pseudo_registers)),
            m_loops(std::move(rhs.m_loops)), name(std::move(rhs.name))
        {
    //Reset rhs
    rhs.count = 0;
    rhs.index = 0;
    rhs.last_pseudo_registers = 0;
    rhs.last_float_pseudo_registers = 0;
}

mtac::Function& mtac::Function::operator=(mtac::Function&& rhs){
    _definition = rhs._definition;
    context = std::move(rhs.context);
    statements = std::move(rhs.statements);
    count = std::move(rhs.count);
    index = std::move(rhs.index);
    entry = std::move(rhs.entry);
    exit = std::move(rhs.exit);
    _use_registers = std::move(rhs._use_registers);
    _use_float_registers = std::move(rhs._use_float_registers);
    _variable_registers = std::move(rhs._variable_registers);
    _variable_float_registers = std::move(rhs._variable_float_registers);
    last_pseudo_registers = std::move(rhs.last_pseudo_registers);
    last_float_pseudo_registers = std::move(rhs.last_float_pseudo_registers);
    m_loops = std::move(rhs.m_loops);
    name = std::move(rhs.name);

    //Reset rhs
    rhs.count = 0;
    rhs.index = 0;
    rhs.last_pseudo_registers = 0;
    rhs.last_float_pseudo_registers = 0;

    return *this;
}

bool mtac::Function::is_main() const {
    return name == "_F4main" || name == "_F4mainAS";
}

bool& mtac::Function::pure(){
    return _pure;
}

bool mtac::Function::pure() const {
    return _pure;
}

mtac::Quadruple& mtac::Function::find(std::size_t uid){
    for(auto& block : *this){
        for(auto& quadruple : block){
            if(quadruple.uid() == uid){
                return quadruple;
            }
        }
    }

    eddic_unreachable("The given uid does not exist");
}

mtac::basic_block_iterator mtac::Function::begin(){
    return basic_block_iterator(entry, nullptr);
}

mtac::basic_block_iterator mtac::Function::end(){
    return basic_block_iterator(nullptr, exit);
}

mtac::basic_block_const_iterator mtac::Function::begin() const {
    return basic_block_const_iterator(entry, nullptr);
}

mtac::basic_block_const_iterator mtac::Function::end() const {
    return basic_block_const_iterator(nullptr, exit);
}

mtac::basic_block_iterator mtac::Function::at(std::shared_ptr<basic_block> bb){
    if(bb){
        return basic_block_iterator(bb, bb->prev);
    } else {
        return basic_block_iterator(nullptr, nullptr);
    }
}

mtac::basic_block_p mtac::Function::entry_bb(){
    return entry;
}

mtac::basic_block_p mtac::Function::exit_bb(){
    return exit;
}

mtac::basic_block_p mtac::Function::current_bb(){
    return exit;
}

void mtac::Function::create_entry_bb(){
    ++count;

    auto new_block = std::make_shared<mtac::basic_block>(-1);
    new_block->context = context;

    entry = exit = new_block;
}

void mtac::Function::create_exit_bb(){
    ++count;

    auto new_block = std::make_shared<mtac::basic_block>(-2);
    new_block->context = context;

    exit->next = new_block;
    new_block->prev = exit;

    exit = new_block;
}

mtac::basic_block_p mtac::Function::new_bb(){
    auto bb = std::make_shared<mtac::basic_block>(++index);
    bb->context = context;
    return bb;
}

mtac::basic_block_p mtac::Function::append_bb(){
    auto new_block = new_bb();
    ++count;

    exit->next = new_block;
    new_block->prev = exit;

    exit = new_block;

    return new_block;
}

mtac::basic_block_iterator mtac::Function::insert_before(mtac::basic_block_iterator it, mtac::basic_block_p block){
    auto bb = *it;

    eddic_assert(block, "Cannot add null block");
    eddic_assert(it != begin(), "Cannot add before entry");

    block->context = context;

    ++count;

    block->prev = bb->prev;
    block->next = bb;
    bb->prev->next = block;
    bb->prev = block;

    return at(block);
}

mtac::basic_block_iterator mtac::Function::insert_after(mtac::basic_block_iterator it, mtac::basic_block_p block){
    return insert_before(++it, block);
}

mtac::basic_block_iterator mtac::Function::remove(mtac::basic_block_p block){
    eddic_assert(block, "Cannot remove null block");
    eddic_assert(block != exit, "Cannot remove exit");

    LOG<Debug>("CFG") << "Remove basic block B" << block->index << log::endl;

    auto& next = block->next;

    --count;

    for(auto& succ : block->successors){
        auto it = iterate(succ->predecessors);

        while(it.has_next()){
            auto pred = *it;

            if(pred == block){
                it.erase();
            } else {
                ++it;
            }
        }
    }

    for(auto& pred : block->predecessors){
        auto it = iterate(pred->successors);

        while(it.has_next()){
            auto succ = *it;

            if(succ == block){
                it.erase();
            } else {
                ++it;
            }
        }

        //If there is a Fall through edge, redirect it
        if(pred == block->prev){
            mtac::make_edge(pred, block->next);
        }
    }

    block->successors.clear();
    block->predecessors.clear();

    block->prev->next = next;
    next->prev = block->prev;

    block->prev = nullptr;
    block->next = nullptr;

    return at(next);
}

mtac::basic_block_iterator mtac::Function::remove(mtac::basic_block_iterator it){
    return remove(*it);
}

mtac::basic_block_iterator mtac::Function::merge_basic_blocks(basic_block_iterator it, std::shared_ptr<basic_block> block){
    auto source = *it;

    eddic_assert(source->next == block || source->prev == block, "Can only merge sibling blocks");

    LOG<Debug>("CFG") << "Merge " << source->index << " into " << block->index << log::endl;

    if(!source->statements.empty()){
        //B can have some new successors
        for(auto& succ : source->successors){
            if(succ != source->next){
                mtac::make_edge(block, succ);
            }
        }

        //No need to remove the edges, they will be removed by remove call
    }

    //Insert the statements
    if(source->next == block){
        std::move(block->begin(), block->end(), std::back_inserter(source->statements));
        block->statements = std::move(source->statements);
    } else {
        std::move(source->begin(), source->end(), std::back_inserter(block->statements));
    }

    //Remove the source basic block
    remove(source);

    return at(block);
}

std::string mtac::Function::get_name() const {
    return name;
}

eddic::Function& mtac::Function::definition(){
    return *_definition;
}

std::vector<mtac::Quadruple>& mtac::Function::get_statements(){
    return statements;
}

const std::vector<mtac::Quadruple>& mtac::Function::get_statements() const {
    return statements;
}

void mtac::Function::release_statements(){
    statements.clear();
    statements.shrink_to_fit();
}

std::size_t mtac::Function::bb_count() const {
    return count;
}

const std::set<ltac::Register>& mtac::Function::use_registers() const {
    return _use_registers;
}

const std::set<ltac::FloatRegister>& mtac::Function::use_float_registers() const {
    return _use_float_registers;
}

void mtac::Function::use(ltac::Register reg){
    _use_registers.insert(reg);
}

void mtac::Function::use(ltac::FloatRegister reg){
    _use_float_registers.insert(reg);
}

const std::set<ltac::Register>& mtac::Function::variable_registers() const {
    return _variable_registers;
}

const std::set<ltac::FloatRegister>& mtac::Function::variable_float_registers() const {
    return _variable_float_registers;
}

void mtac::Function::variable_use(ltac::Register reg){
    _variable_registers.insert(reg);
}

void mtac::Function::variable_use(ltac::FloatRegister reg){
    _variable_float_registers.insert(reg);
}

std::size_t mtac::Function::pseudo_registers() const {
    return last_pseudo_registers;
}

void mtac::Function::set_pseudo_registers(std::size_t pseudo_registers){
    this->last_pseudo_registers = pseudo_registers;
}

std::size_t mtac::Function::pseudo_float_registers() const {
    return last_float_pseudo_registers;
}

void mtac::Function::set_pseudo_float_registers(std::size_t pseudo_registers){
    this->last_float_pseudo_registers = pseudo_registers;
}

std::size_t mtac::Function::size() const {
    std::size_t size = 0;

    for(auto& block : *this){
        size += block->statements.size();
    }

    return size;
}

std::pair<mtac::basic_block_iterator, mtac::basic_block_iterator> mtac::Function::blocks(){
    return std::make_pair(begin(), end());
}

std::vector<mtac::Loop>& mtac::Function::loops(){
    return m_loops;
}

bool mtac::operator==(const mtac::Function& lhs, const mtac::Function& rhs){
    return lhs.get_name() == rhs.get_name();
}

std::ostream& eddic::mtac::operator<<(std::ostream& stream, const mtac::Function& function){
    stream << "Function " << function.get_name() << "(pure:" << function.pure() << ")" << std::endl;

    for(auto& quadruple : function.get_statements()){
        stream << quadruple << std::endl;
    }

    for(auto& block : function){
        pretty_print(block, stream);

        for(auto& quadruple : block->statements){
            stream << quadruple << std::endl;
        }
    }

    return stream << std::endl;
}
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2017 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <net/configure.hpp>

#include <net/super_stack.hpp>
#include <info>

#define MYINFO(X,...) INFO("Network configure",X,##__VA_ARGS__)

namespace net {

using Addresses = std::vector<ip4::Addr>;

template <typename T>
Addresses parse_iface(T& obj)
{
  Expects(obj.IsArray());

  // Iface can either be empty: [] or contain 3 to 4 IP's (see Inet static config)
  if(not obj.Empty())
  {
    Expects(obj.Size() >= 3 and obj.Size() <= 4);

    Addresses addresses;

    for(auto& addr : obj.GetArray())
    {
      addresses.emplace_back(std::string{addr.GetString()});
    }

    return addresses;
  }

  return {};
}

inline void config_stack(Inet<IP4>& stack, const Addresses& addrs)
{
  if(addrs.empty())
    return;

  Expects((addrs.size() > 2 and addrs.size() < 5)
    && "A network config needs to be between 3 and 4 addresses");

  stack.network_config(
    addrs[0], addrs[1], addrs[2],
    ((addrs.size() == 4) ? addrs[3] : 0)
    );
}

void configure(const rapidjson::Value& net)
{
  MYINFO("Configuring network");

  Expects(net.IsArray() && "Member net is not an array");

  int N = 0;
  for(auto& val : net.GetArray())
  {
    if(N >= static_cast<int>(Super_stack::inet().ip4_stacks().size()))
      break;

    auto& stack = Super_stack::get<IP4>(N);
    // static configs
    if(val.IsArray())
    {
      config_stack(stack, parse_iface(val));
    }
    else if(val.IsString() and strcmp(val.GetString(), "dhcp") == 0)
    {
      stack.negotiate_dhcp(5.0);
    }
    ++N;
  }

  MYINFO("Configuration complete");
}

}
<commit_msg>net: Update comments in configure<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2017 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <net/configure.hpp>

#include <net/super_stack.hpp>
#include <info>

#define MYINFO(X,...) INFO("Netconf",X,##__VA_ARGS__)

namespace net {

using Addresses = std::vector<ip4::Addr>;

template <typename T>
Addresses parse_iface(T& obj)
{
  Expects(obj.IsArray());

  // Iface can either be empty: [] or contain 3 to 4 IP's (see Inet static config)
  if(not obj.Empty())
  {
    Expects(obj.Size() >= 3 and obj.Size() <= 4);

    Addresses addresses;

    for(auto& addr : obj.GetArray())
    {
      addresses.emplace_back(std::string{addr.GetString()});
    }

    return addresses;
  }

  return {};
}

inline void config_stack(Inet<IP4>& stack, const Addresses& addrs)
{
  if(addrs.empty())
    return;

  Expects((addrs.size() > 2 and addrs.size() < 5)
    && "A network config needs to be between 3 and 4 addresses");

  stack.network_config(
    addrs[0], addrs[1], addrs[2],
    ((addrs.size() == 4) ? addrs[3] : 0)
    );
}

void configure(const rapidjson::Value& net)
{
  MYINFO("Configuring network");

  Expects(net.IsArray() && "Member net is not an array");

  int N = 0;
  for(auto& val : net.GetArray())
  {
    if(N >= static_cast<int>(Super_stack::inet().ip4_stacks().size()))
      break;

    auto& stack = Super_stack::get<IP4>(N);
    // static configs
    if(val.IsArray())
    {
      config_stack(stack, parse_iface(val));
    }
    // only negotiate if "dhcp"
    else if(val.IsString() and strcmp(val.GetString(), "dhcp") == 0)
    {
      stack.negotiate_dhcp(5.0);
    }
    // else leave it uninitialized
    ++N;
  }

  MYINFO("Configuration complete");
}

}
<|endoftext|>


<commit_before>/*
 * Funambol is a mobile platform developed by Funambol, Inc.
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program 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 General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

#include "syncml/core/DSMem.h"
#include "base/globalsdef.h"

USE_NAMESPACE

DSMem::DSMem() {
    sharedMem      = false;
    long    maxMem = 0;
    long    maxID  = 0;
}
DSMem::~DSMem() {
    sharedMem      = false;
    long    maxMem = 0;
    long    maxID  = 0;
}

/**
 * Creates a new DSMem object with the given sharedMem, maxMem and maxID
 *
 * @param sharedMem is true if the datastore uses shared memory
 * @param maxMem the maximum memory size for o given datastore
 * @param maxID the maximum number of items that can be stored in a given
 *              datastore
 *
 */
DSMem::DSMem(bool sharedMem, long maxMem, long maxID) {
    setMaxMem(maxMem);
    setMaxID(maxID);
    this->sharedMem = sharedMem;
}

/**
 * Returns the memoryShared status
 *
 * @return true if the datastore memory is shared, false otherwise
 */
bool DSMem::isSharedMem() {
    return (sharedMem != NULL);
}
/**
 * Sets the memoryShared status
 *
 * @param sharedMem the new memoryShared status
 */
void DSMem::setSharedMem(bool sharedMem) {
    this->sharedMem = sharedMem;
}

/**
 * Gets Boolean shared memory
 *
 * @return sharedMem the Boolean sharedMem
 */
bool DSMem::getSharedMem() {

    return sharedMem;
}

/**
 * Gets the maximum memory size in bytes
 *
 * @return if value is -1 indicates that the property value is unspecified
 */
long DSMem::getMaxMem() {
    return maxMem;
}

/**
 * Sets the max memory property
 *
 * @param maxMem the value of max memory property
 *
 */
void DSMem::setMaxMem(long maxMem) {
    this->maxMem = maxMem;
}

/**
 * Gets the maximum number of items
 *
 * @return if value is -1 indicates that the property value is unspecified
 */
long DSMem::getMaxID() {
    return maxID;
}

/**
 * Sets the max ID property
 *
 * @param maxID the value of maxID property
 */
void DSMem::setMaxID(long maxID) {
    this->maxID = maxID;
}

DSMem* DSMem::clone() {
    DSMem* ret = new DSMem(sharedMem, maxMem, maxID);
    return ret;
}
<commit_msg>Minor bugs fixed and code improvements.<commit_after>/*
 * Funambol is a mobile platform developed by Funambol, Inc.
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program 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 General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

#include "syncml/core/DSMem.h"
#include "base/globalsdef.h"

USE_NAMESPACE

DSMem::DSMem() : sharedMem(false),
                 maxMem(0),
                 maxID(0)
{
}

DSMem::~DSMem() {
    sharedMem = false;
    maxMem = 0;
    maxID  = 0;
}

/**
 * Creates a new DSMem object with the given sharedMem, maxMem and maxID
 *
 * @param sharedMem is true if the datastore uses shared memory
 * @param maxMem the maximum memory size for o given datastore
 * @param maxID the maximum number of items that can be stored in a given
 *              datastore
 *
 */
DSMem::DSMem(bool sharedMem, long maxMem, long maxID) {
    setMaxMem(maxMem);
    setMaxID(maxID);
    this->sharedMem = sharedMem;
}

/**
 * Returns the memoryShared status
 *
 * @return true if the datastore memory is shared, false otherwise
 */
bool DSMem::isSharedMem() {
    return (sharedMem != NULL);
}
/**
 * Sets the memoryShared status
 *
 * @param sharedMem the new memoryShared status
 */
void DSMem::setSharedMem(bool sharedMem) {
    this->sharedMem = sharedMem;
}

/**
 * Gets Boolean shared memory
 *
 * @return sharedMem the Boolean sharedMem
 */
bool DSMem::getSharedMem() {

    return sharedMem;
}

/**
 * Gets the maximum memory size in bytes
 *
 * @return if value is -1 indicates that the property value is unspecified
 */
long DSMem::getMaxMem() {
    return maxMem;
}

/**
 * Sets the max memory property
 *
 * @param maxMem the value of max memory property
 *
 */
void DSMem::setMaxMem(long maxMem) {
    this->maxMem = maxMem;
}

/**
 * Gets the maximum number of items
 *
 * @return if value is -1 indicates that the property value is unspecified
 */
long DSMem::getMaxID() {
    return maxID;
}

/**
 * Sets the max ID property
 *
 * @param maxID the value of maxID property
 */
void DSMem::setMaxID(long maxID) {
    this->maxID = maxID;
}

DSMem* DSMem::clone() {
    DSMem* ret = new DSMem(sharedMem, maxMem, maxID);
    return ret;
}
<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2016 Haggi Krey, The appleseedhq Organization
//
// 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.
//

// Interface header.
#include "nodecallbacks.h"

// appleseed-maya headers.
#include "utilities/logging.h"
#include "appleseedutils.h"
#include "mayascene.h"
#include "renderqueue.h"
#include "world.h"

// Maya headers.
#include <maya/MItDag.h>
#include <maya/MPlug.h>

// Boost headers.
#include <boost/shared_ptr.hpp>

//
// basic idea:
//      all important messages like update framebuffer, stop rendering etc. are sent via events to the message queue
//      a timer callback reads the next event and execute it.
// IPR:
//      before IPR rendering starts, callbacks are created.
//      a node dirty callback for every node in the scene will put the the node into a list of modified objects.
//          - because we do need the elements only once but the callbacks are called very often, we throw away the callback
//            from a modified node after putting the node into a list and we later remove duplicate entries
//      a idle callback is created. It will go through all elements from the modified list and update it in the renderer if necessary.
//            then the renderer will be called to update its database or restart render, however a renderer handles interactive rendering.
//          - then the modified list is emptied
//          - because we want to be able to modify the same object again after it is updated, the node dirty callbacks are recreated for
//            all the objects in the list.
//      a scene message is created - we will stop the ipr as soon as a new scene is created or another scene is opened
//      a scene message is created - we have to stop everything as soon as the plugin will be removed, otherwise Maya will crash.
//      IMPORTANT:  We do add dirty callbacks for translated nodes only which are saved in the mayaScene::interactiveUpdateMap.
//                  This map is filled by sceneParsing and shader translation process which are called before rendering and during geometry translation.
//                  So the addIPRCallbacks() has to be called after everything is translated.

void IPRAttributeChangedCallback(MNodeMessage::AttributeMessage msg, MPlug& plug, MPlug& otherPlug, void* userPtr)
{
    Logging::debug(MString("IPRAttributeChangedCallback. attribA: ") + plug.name() + " attribB: " + otherPlug.name());
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;

    if (msg & MNodeMessage::kConnectionMade)
    {
        Logging::debug(MString("IPRAttributeChangedCallback. connection created."));
        MString plugName = plug.name();
        std::string pn = plugName.asChar();
        if (pn.find("instObjGroups[") != std::string::npos)
        {
            Logging::debug(MString("IPRAttributeChangedCallback. InstObjGroups affected, checking other side."));
            if (otherPlug.node().hasFn(MFn::kShadingEngine))
            {
                Logging::debug(MString("IPRAttributeChangedCallback. Found shading group on the other side: ") + getObjectName(otherPlug.node()));
                EditableElement& element = mayaScene->editableElements[MMessage::currentCallbackId()];
                element.isDirty = true;
                mayaScene->isAnyDirty = true;
                element.isDeformed = true; // trigger a complete mesh update
            }
        }
    }
    else if (msg & MNodeMessage::kConnectionBroken)
    {
        Logging::debug(MString("IPRAttributeChangedCallback. connection broken."));
    }
}

void IPRNodeDirtyCallback(void* userPtr)
{
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;

    MCallbackId callbackId = MMessage::currentCallbackId();
    EditableElement& element = mayaScene->editableElements[callbackId];
    element.isDirty = true;

    mayaScene->isAnyDirty = true;
}

namespace
{
    void markTransformsChildrenAsDirty()
    {
        boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;

        for (MayaScene::EditableElementContainer::iterator
            i = mayaScene->editableElements.begin(),
            e = mayaScene->editableElements.end(); i != e; ++i)
        {
            if (i->second.isDirty)
            {
                if (i->second.node.hasFn(MFn::kTransform))
                {
                    MItDag childIter;
                    for (childIter.reset(i->second.node); !childIter.isDone(); childIter.next())
                    {
                        if (childIter.currentItem().hasFn(MFn::kShape))
                        {
                            for (MayaScene::EditableElementContainer::iterator
                                j = mayaScene->editableElements.begin(),
                                f = mayaScene->editableElements.end(); j != f; ++j)
                            {
                                if (childIter.currentItem() == j->second.node)
                                {
                                    j->second.isDirty = true;
                                    j->second.isTransformed = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

void IPRIdleCallback(float time, float lastTime, void* userPtr)
{
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;

    if (!mayaScene->isAnyDirty)
        return;

    stopRendering();

    markTransformsChildrenAsDirty();
    getWorldPtr()->mRenderer->applyInteractiveUpdates(mayaScene->editableElements);

    for (MayaScene::EditableElementContainer::iterator
            i = mayaScene->editableElements.begin(),
            e = mayaScene->editableElements.end(); i != e; ++i)
    {
        i->second.isDirty = false;
        i->second.isTransformed = false;
    }

    mayaScene->isAnyDirty = false;

    startRendering();
}

// Register new created nodes. We need the transform and the shape node to correctly use it in IPR.
// So we simply use the shape node, get it's parent - a shape node and let the scene parser do the rest.
// Then add a node dirty callback for the new elements. By adding the callback ids to the idInteractiveMap, the
// IPR should detect a modification during the netxt update cycle.
// Interestingly, if an object is duplicated, it first receives a prefix called "__PrenotatoPerDuplicare_", then later
// the geometry will be renamed to the correct name.

// Handling of surface shaders is a bit different. A shader is not assigned directly to a surface but it is connected to a shading group
// which is nothing else but a objectSet. If a new surface shader is created, it is not in use until it is assigned to an object what means it is connected
// to a shading group. So I simply add a shadingGroup callback for new shading groups.

void IPRNodeAddedCallback(MObject& node, void* userPtr)
{
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;
    MStatus stat;

    if (node.hasFn(MFn::kTransform))
    {
        MFnDagNode dagNode(node);

        MDagPath dagPath;
        stat = dagNode.getPath(dagPath);
        MString why = stat.errorString();
        stat = dagPath.extendToShape();
        if (!dagPath.node().hasFn(MFn::kMesh))
            return;
    }
    else
    {
        if (!node.hasFn(MFn::kShape))
            return;
    }
    MFnDagNode dagNode(node);
    MDagPath transformPath;
    dagNode.getPath(transformPath);
    MDagPath dagPath = transformPath;
    transformPath.pop();

    // Here the new object and its children are added to the object list and to the interactive object list.
    mayaScene->parseSceneHierarchy(transformPath, 0, boost::shared_ptr<ObjectAttributes>(), boost::shared_ptr<MayaObject>());

    for (MayaScene::EditableElementContainer::iterator
        i = mayaScene->editableElements.begin(),
        e = mayaScene->editableElements.end(); i != e; ++i)
    {
        if (i->second.mayaObject == 0)
            continue;
        if (i->second.mayaObject->dagPath == dagPath)
        {
            i->second.isDirty = true;
            i->second.isDeformed = true;
            mayaScene->isAnyDirty = true;
            break;
        }
    }

}

void IPRNodeRenamedCallback(MObject& node, const MString& oldName, void* userPtr)
{
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;
    for (MayaScene::EditableElementContainer::iterator
        i = mayaScene->editableElements.begin(),
        e = mayaScene->editableElements.end(); i != e; ++i)
    {
        if (i->second.mayaObject != 0)
        {
            if (i->second.node == node)
            {
                break;
            }
        }
    }

}

void IPRNodeRemovedCallback(MObject& node, void* userPtr)
{
    // Find the MayaObject and mark it as removed.
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;
    std::vector<const MCallbackId> removeIds;
    for (MayaScene::EditableElementContainer::iterator
            i = mayaScene->editableElements.begin(),
            e = mayaScene->editableElements.end(); i != e; ++i)
    {
        EditableElement& element = i->second;
        if (element.node == node)
        {
            MNodeMessage::removeCallback(i->first);
            removeIds.push_back(i->first);
            if (element.mayaObject)
            {
                element.mayaObject->removed = true;
                element.isDirty = true;
                element.isDeformed = true; // trigger mesh update
                mayaScene->isAnyDirty = true;
            }
            break;
        }
    }

}
<commit_msg>Fix linux build<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2016 Haggi Krey, The appleseedhq Organization
//
// 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.
//

// Interface header.
#include "nodecallbacks.h"

// appleseed-maya headers.
#include "utilities/logging.h"
#include "appleseedutils.h"
#include "mayascene.h"
#include "renderqueue.h"
#include "world.h"

// Maya headers.
#include <maya/MItDag.h>
#include <maya/MPlug.h>

// Boost headers.
#include <boost/shared_ptr.hpp>

//
// basic idea:
//      all important messages like update framebuffer, stop rendering etc. are sent via events to the message queue
//      a timer callback reads the next event and execute it.
// IPR:
//      before IPR rendering starts, callbacks are created.
//      a node dirty callback for every node in the scene will put the the node into a list of modified objects.
//          - because we do need the elements only once but the callbacks are called very often, we throw away the callback
//            from a modified node after putting the node into a list and we later remove duplicate entries
//      a idle callback is created. It will go through all elements from the modified list and update it in the renderer if necessary.
//            then the renderer will be called to update its database or restart render, however a renderer handles interactive rendering.
//          - then the modified list is emptied
//          - because we want to be able to modify the same object again after it is updated, the node dirty callbacks are recreated for
//            all the objects in the list.
//      a scene message is created - we will stop the ipr as soon as a new scene is created or another scene is opened
//      a scene message is created - we have to stop everything as soon as the plugin will be removed, otherwise Maya will crash.
//      IMPORTANT:  We do add dirty callbacks for translated nodes only which are saved in the mayaScene::interactiveUpdateMap.
//                  This map is filled by sceneParsing and shader translation process which are called before rendering and during geometry translation.
//                  So the addIPRCallbacks() has to be called after everything is translated.

void IPRAttributeChangedCallback(MNodeMessage::AttributeMessage msg, MPlug& plug, MPlug& otherPlug, void* userPtr)
{
    Logging::debug(MString("IPRAttributeChangedCallback. attribA: ") + plug.name() + " attribB: " + otherPlug.name());
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;

    if (msg & MNodeMessage::kConnectionMade)
    {
        Logging::debug(MString("IPRAttributeChangedCallback. connection created."));
        MString plugName = plug.name();
        std::string pn = plugName.asChar();
        if (pn.find("instObjGroups[") != std::string::npos)
        {
            Logging::debug(MString("IPRAttributeChangedCallback. InstObjGroups affected, checking other side."));
            if (otherPlug.node().hasFn(MFn::kShadingEngine))
            {
                Logging::debug(MString("IPRAttributeChangedCallback. Found shading group on the other side: ") + getObjectName(otherPlug.node()));
                EditableElement& element = mayaScene->editableElements[MMessage::currentCallbackId()];
                element.isDirty = true;
                mayaScene->isAnyDirty = true;
                element.isDeformed = true; // trigger a complete mesh update
            }
        }
    }
    else if (msg & MNodeMessage::kConnectionBroken)
    {
        Logging::debug(MString("IPRAttributeChangedCallback. connection broken."));
    }
}

void IPRNodeDirtyCallback(void* userPtr)
{
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;

    MCallbackId callbackId = MMessage::currentCallbackId();
    EditableElement& element = mayaScene->editableElements[callbackId];
    element.isDirty = true;

    mayaScene->isAnyDirty = true;
}

namespace
{
    void markTransformsChildrenAsDirty()
    {
        boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;

        for (MayaScene::EditableElementContainer::iterator
            i = mayaScene->editableElements.begin(),
            e = mayaScene->editableElements.end(); i != e; ++i)
        {
            if (i->second.isDirty)
            {
                if (i->second.node.hasFn(MFn::kTransform))
                {
                    MItDag childIter;
                    for (childIter.reset(i->second.node); !childIter.isDone(); childIter.next())
                    {
                        if (childIter.currentItem().hasFn(MFn::kShape))
                        {
                            for (MayaScene::EditableElementContainer::iterator
                                j = mayaScene->editableElements.begin(),
                                f = mayaScene->editableElements.end(); j != f; ++j)
                            {
                                if (childIter.currentItem() == j->second.node)
                                {
                                    j->second.isDirty = true;
                                    j->second.isTransformed = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

void IPRIdleCallback(float time, float lastTime, void* userPtr)
{
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;

    if (!mayaScene->isAnyDirty)
        return;

    stopRendering();

    markTransformsChildrenAsDirty();
    getWorldPtr()->mRenderer->applyInteractiveUpdates(mayaScene->editableElements);

    for (MayaScene::EditableElementContainer::iterator
            i = mayaScene->editableElements.begin(),
            e = mayaScene->editableElements.end(); i != e; ++i)
    {
        i->second.isDirty = false;
        i->second.isTransformed = false;
    }

    mayaScene->isAnyDirty = false;

    startRendering();
}

// Register new created nodes. We need the transform and the shape node to correctly use it in IPR.
// So we simply use the shape node, get it's parent - a shape node and let the scene parser do the rest.
// Then add a node dirty callback for the new elements. By adding the callback ids to the idInteractiveMap, the
// IPR should detect a modification during the netxt update cycle.
// Interestingly, if an object is duplicated, it first receives a prefix called "__PrenotatoPerDuplicare_", then later
// the geometry will be renamed to the correct name.

// Handling of surface shaders is a bit different. A shader is not assigned directly to a surface but it is connected to a shading group
// which is nothing else but a objectSet. If a new surface shader is created, it is not in use until it is assigned to an object what means it is connected
// to a shading group. So I simply add a shadingGroup callback for new shading groups.

void IPRNodeAddedCallback(MObject& node, void* userPtr)
{
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;
    MStatus stat;

    if (node.hasFn(MFn::kTransform))
    {
        MFnDagNode dagNode(node);

        MDagPath dagPath;
        stat = dagNode.getPath(dagPath);
        MString why = stat.errorString();
        stat = dagPath.extendToShape();
        if (!dagPath.node().hasFn(MFn::kMesh))
            return;
    }
    else
    {
        if (!node.hasFn(MFn::kShape))
            return;
    }
    MFnDagNode dagNode(node);
    MDagPath transformPath;
    dagNode.getPath(transformPath);
    MDagPath dagPath = transformPath;
    transformPath.pop();

    // Here the new object and its children are added to the object list and to the interactive object list.
    mayaScene->parseSceneHierarchy(transformPath, 0, boost::shared_ptr<ObjectAttributes>(), boost::shared_ptr<MayaObject>());

    for (MayaScene::EditableElementContainer::iterator
        i = mayaScene->editableElements.begin(),
        e = mayaScene->editableElements.end(); i != e; ++i)
    {
        if (i->second.mayaObject == 0)
            continue;
        if (i->second.mayaObject->dagPath == dagPath)
        {
            i->second.isDirty = true;
            i->second.isDeformed = true;
            mayaScene->isAnyDirty = true;
            break;
        }
    }

}

void IPRNodeRenamedCallback(MObject& node, const MString& oldName, void* userPtr)
{
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;
    for (MayaScene::EditableElementContainer::iterator
        i = mayaScene->editableElements.begin(),
        e = mayaScene->editableElements.end(); i != e; ++i)
    {
        if (i->second.mayaObject != 0)
        {
            if (i->second.node == node)
            {
                break;
            }
        }
    }

}

void IPRNodeRemovedCallback(MObject& node, void* userPtr)
{
    // Find the MayaObject and mark it as removed.
    boost::shared_ptr<MayaScene> mayaScene = getWorldPtr()->mScene;
    std::vector<MCallbackId> removeIds;
    for (MayaScene::EditableElementContainer::iterator
            i = mayaScene->editableElements.begin(),
            e = mayaScene->editableElements.end(); i != e; ++i)
    {
        EditableElement& element = i->second;
        if (element.node == node)
        {
            MNodeMessage::removeCallback(i->first);
            removeIds.push_back(i->first);
            if (element.mayaObject)
            {
                element.mayaObject->removed = true;
                element.isDirty = true;
                element.isDeformed = true; // trigger mesh update
                mayaScene->isAnyDirty = true;
            }
            break;
        }
    }

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: docvor.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 16:52:06 $
 *
 *  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 _SFXDOCVOR_HXX
#define _SFXDOCVOR_HXX

#ifndef _DIALOG_HXX //autogen
#include <vcl/dialog.hxx>
#endif
#ifndef _SVTREEBOX_HXX //autogen
#include <svtools/svtreebx.hxx>
#endif

#include "objsh.hxx"
#include "orgmgr.hxx"

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

class SfxDocumentTemplates;
class Path;

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

#ifndef _SFX_HXX

class SfxOrganizeDlg_Impl;

class SfxOrganizeListBox_Impl : public SvTreeListBox
{
    enum BMPTYPE            { BMPTYPE_FOLDER, BMPTYPE_DOC };

friend class SfxOrganizeDlg_Impl;

    Image                   aOpenedFolderBmp;
    Image                   aClosedFolderBmp;
    Image                   aOpenedDocBmp;
    Image                   aClosedDocBmp;

    Image                   aOpenedFolderBmpHC;
    Image                   aClosedFolderBmpHC;
    Image                   aOpenedDocBmpHC;
    Image                   aClosedDocBmpHC;

    SfxOrganizeMgr*         pMgr;
    SfxOrganizeDlg_Impl*    pDlg;

    static BOOL             bDropMoveOk;

    DECL_LINK( OnAsyncExecuteDrop, ExecuteDropEvent* );

protected:
    virtual BOOL EditingEntry( SvLBoxEntry* pEntry, Selection & );
    virtual BOOL EditedEntry( SvLBoxEntry* pEntry, const String& rNewText );
    virtual BOOL NotifyMoving(SvLBoxEntry *pSource,
                            SvLBoxEntry* pTarget,
                            SvLBoxEntry *&pNewParent, ULONG &);
    virtual BOOL NotifyCopying(SvLBoxEntry *pSource,
                            SvLBoxEntry* pTarget,
                            SvLBoxEntry *&pNewParent, ULONG &);
    virtual void RequestingChilds( SvLBoxEntry* pParent );
    virtual long ExpandingHdl();
    virtual BOOL Select( SvLBoxEntry* pEntry, BOOL bSelect=TRUE );

    // new d&d
    virtual DragDropMode    NotifyStartDrag( TransferDataContainer&, SvLBoxEntry* );
    virtual BOOL            NotifyAcceptDrop( SvLBoxEntry* );
    virtual sal_Int8        AcceptDrop( const AcceptDropEvent& rEvt );
    virtual sal_Int8        ExecuteDrop( const ExecuteDropEvent& rEvt );
    virtual void            DragFinished( sal_Int8 nDropAction );

public:
    enum DataEnum   { VIEW_TEMPLATES, VIEW_FILES } eViewType;

    SfxOrganizeListBox_Impl( SfxOrganizeDlg_Impl* pDlg, Window* pParent, WinBits, DataEnum );

    DataEnum    GetViewType() const { return eViewType; }
    void        SetViewType(DataEnum eType) { eViewType = eType; }

    void SetMgr(SfxOrganizeMgr *pM) { pMgr = pM; }
    void Reset();
    inline void SetBitmaps(
                    const Image &rOFolderBmp, const Image &rCFolderBmp, const Image &rODocBmp, const Image &rCDocBmp,
                    const Image &rOFolderBmpHC, const Image &rCFolderBmpHC, const Image &rODocBmpHC, const Image &rCDocBmpHC );
    const Image &GetClosedBmp(USHORT nLevel) const;
    const Image &GetOpenedBmp(USHORT nLevel) const;

    virtual PopupMenu*  CreateContextMenu();

private:
    BOOL IsStandard_Impl( SvLBoxEntry *) const;
    BOOL MoveOrCopyTemplates(SvLBox *pSourceBox,
                            SvLBoxEntry *pSource,
                            SvLBoxEntry* pTarget,
                            SvLBoxEntry *&pNewParent,
                            ULONG &rIdx,
                            BOOL bCopy);
    BOOL MoveOrCopyContents(SvLBox *pSourceBox,
                            SvLBoxEntry *pSource,
                            SvLBoxEntry* pTarget,
                            SvLBoxEntry *&pNewParent,
                            ULONG &rIdx,
                            BOOL bCopy);
    inline USHORT       GetDocLevel() const;
    SfxObjectShellRef   GetObjectShell( const Path& );
    BOOL                IsUniqName_Impl( const String &rText,
                                         SvLBoxEntry* pParent, SvLBoxEntry* pEntry = 0 ) const;
    USHORT              GetLevelCount_Impl( SvLBoxEntry* pParent ) const;

    SvLBoxEntry*        InsertEntryByBmpType( const XubString& rText, BMPTYPE eBmpType,
                            SvLBoxEntry* pParent = NULL, BOOL bChildsOnDemand = FALSE,
                            ULONG nPos = LIST_APPEND, void* pUserData = NULL );
};

#endif // _SFX_HXX

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

class SfxTemplateOrganizeDlg : public ModalDialog
{
friend class SfxOrganizeListBox_Impl;

    class SfxOrganizeDlg_Impl *pImp;

//  virtual void    DataChanged( const DataChangedEvent& rDCEvt );
public:
    SfxTemplateOrganizeDlg(Window * pParent, SfxDocumentTemplates* = 0);
    ~SfxTemplateOrganizeDlg();

#define RET_EDIT_STYLE       100

    virtual short Execute();
};

#endif
<commit_msg>INTEGRATION: CWS warnings01 (1.10.66); FILE MERGED 2005/11/28 16:12:56 cd 1.10.66.1: #i55991# Remove warnings<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: docvor.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 21:58:51 $
 *
 *  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 _SFXDOCVOR_HXX
#define _SFXDOCVOR_HXX

#ifndef _DIALOG_HXX //autogen
#include <vcl/dialog.hxx>
#endif
#ifndef _SVTREEBOX_HXX //autogen
#include <svtools/svtreebx.hxx>
#endif

#include "objsh.hxx"
#include "orgmgr.hxx"

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

class SfxDocumentTemplates;
class Path;

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

#ifndef _SFX_HXX

class SfxOrganizeDlg_Impl;

class SfxOrganizeListBox_Impl : public SvTreeListBox
{
    enum BMPTYPE            { BMPTYPE_FOLDER, BMPTYPE_DOC };

friend class SfxOrganizeDlg_Impl;

    Image                   aOpenedFolderBmp;
    Image                   aClosedFolderBmp;
    Image                   aOpenedDocBmp;
    Image                   aClosedDocBmp;

    Image                   aOpenedFolderBmpHC;
    Image                   aClosedFolderBmpHC;
    Image                   aOpenedDocBmpHC;
    Image                   aClosedDocBmpHC;

    SfxOrganizeMgr*         pMgr;
    SfxOrganizeDlg_Impl*    pDlg;

    static BOOL             bDropMoveOk;

    DECL_LINK( OnAsyncExecuteDrop, ExecuteDropEvent* );

protected:
    virtual BOOL EditingEntry( SvLBoxEntry* pEntry, Selection & );
    virtual BOOL EditedEntry( SvLBoxEntry* pEntry, const String& rNewText );
    virtual BOOL NotifyMoving(SvLBoxEntry *pSource,
                            SvLBoxEntry* pTarget,
                            SvLBoxEntry *&pNewParent, ULONG &);
    virtual BOOL NotifyCopying(SvLBoxEntry *pSource,
                            SvLBoxEntry* pTarget,
                            SvLBoxEntry *&pNewParent, ULONG &);
    virtual void RequestingChilds( SvLBoxEntry* pParent );
    virtual long ExpandingHdl();
    virtual BOOL Select( SvLBoxEntry* pEntry, BOOL bSelect=TRUE );

        using SvLBox::ExecuteDrop;
    // new d&d
    virtual DragDropMode    NotifyStartDrag( TransferDataContainer&, SvLBoxEntry* );
    virtual BOOL            NotifyAcceptDrop( SvLBoxEntry* );
    virtual sal_Int8        AcceptDrop( const AcceptDropEvent& rEvt );
    virtual sal_Int8        ExecuteDrop( const ExecuteDropEvent& rEvt );
    virtual void            DragFinished( sal_Int8 nDropAction );

public:
        using SvListView::Select;
    enum DataEnum   { VIEW_TEMPLATES, VIEW_FILES } eViewType;

    SfxOrganizeListBox_Impl( SfxOrganizeDlg_Impl* pDlg, Window* pParent, WinBits, DataEnum );

    DataEnum    GetViewType() const { return eViewType; }
    void        SetViewType(DataEnum eType) { eViewType = eType; }

    void SetMgr(SfxOrganizeMgr *pM) { pMgr = pM; }
    void Reset();
    inline void SetBitmaps(
                    const Image &rOFolderBmp, const Image &rCFolderBmp, const Image &rODocBmp, const Image &rCDocBmp,
                    const Image &rOFolderBmpHC, const Image &rCFolderBmpHC, const Image &rODocBmpHC, const Image &rCDocBmpHC );
    const Image &GetClosedBmp(USHORT nLevel) const;
    const Image &GetOpenedBmp(USHORT nLevel) const;

    virtual PopupMenu*  CreateContextMenu();

private:
    BOOL IsStandard_Impl( SvLBoxEntry *) const;
    BOOL MoveOrCopyTemplates(SvLBox *pSourceBox,
                            SvLBoxEntry *pSource,
                            SvLBoxEntry* pTarget,
                            SvLBoxEntry *&pNewParent,
                            ULONG &rIdx,
                            BOOL bCopy);
    BOOL MoveOrCopyContents(SvLBox *pSourceBox,
                            SvLBoxEntry *pSource,
                            SvLBoxEntry* pTarget,
                            SvLBoxEntry *&pNewParent,
                            ULONG &rIdx,
                            BOOL bCopy);
    inline USHORT       GetDocLevel() const;
    SfxObjectShellRef   GetObjectShell( const Path& );
    BOOL                IsUniqName_Impl( const String &rText,
                                         SvLBoxEntry* pParent, SvLBoxEntry* pEntry = 0 ) const;
    USHORT              GetLevelCount_Impl( SvLBoxEntry* pParent ) const;

    SvLBoxEntry*        InsertEntryByBmpType( const XubString& rText, BMPTYPE eBmpType,
                            SvLBoxEntry* pParent = NULL, BOOL bChildsOnDemand = FALSE,
                            ULONG nPos = LIST_APPEND, void* pUserData = NULL );
};

#endif // _SFX_HXX

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

class SfxTemplateOrganizeDlg : public ModalDialog
{
friend class SfxOrganizeListBox_Impl;

    class SfxOrganizeDlg_Impl *pImp;

//  virtual void    DataChanged( const DataChangedEvent& rDCEvt );
public:
    SfxTemplateOrganizeDlg(Window * pParent, SfxDocumentTemplates* = 0);
    ~SfxTemplateOrganizeDlg();

#define RET_EDIT_STYLE       100

    virtual short Execute();
};

#endif
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 Luke San Antonio
 * All rights reserved.
 */
#include "sweep_and_prune.h"
#include <algorithm>
#include "../common/algorithm.h"
namespace game
{
  namespace detail
  {
    bool operator<(SAP_Endpoint const& se1, SAP_Endpoint const& se2) noexcept
    {
      return se1.value < se2.value;
    }
  }

  SAP_AABB_Ref SAP::insert(AABB const& aabb) noexcept
  {
    // New aabb
    auto id = ref_counter_.get();

    // Build each endpoint
    auto begin_endpoint = detail::SAP_Endpoint{};
    begin_endpoint.id = id;
    begin_endpoint.aabb = aabb;
    begin_endpoint.type = detail::SAP_Endpoint_Type::Begin;
    begin_endpoint.value = aabb.min.x;

    auto end_endpoint = detail::SAP_Endpoint{};
    end_endpoint.id = id;
    end_endpoint.aabb = aabb;
    end_endpoint.type = detail::SAP_Endpoint_Type::End;
    end_endpoint.value = aabb.min.x + aabb.width;

    sorted_insert(x_axis_, begin_endpoint);
    sorted_insert(x_axis_, end_endpoint);

    return id;
  }

  void SAP::update(SAP_AABB_Ref id, AABB const& aabb) noexcept
  {
    bool sort = false;
    for(auto& endpt : x_axis_)
    {
      if(endpt.id == id)
      {
        if(endpt.type == detail::SAP_Endpoint_Type::Begin)
        {
          endpt.value = aabb.min.x;
        }
        else if(endpt.type == detail::SAP_Endpoint_Type::End)
        {
          endpt.value = aabb.min.x + aabb.width;
        }

        sort = true;
      }
    }

    using std::begin; using std::end;
    if(sort) std::sort(begin(x_axis_), end(x_axis_));
  }

  pair_res_t SAP::collisions() const noexcept
  {
    pair_res_t ret;

    std::vector<detail::SAP_Endpoint> active_list;

    for(auto const& endpt : x_axis_)
    {
      if(endpt.type == detail::SAP_Endpoint_Type::Begin)
      {
        active_list.push_back(endpt);
      }
      else if(endpt.type == detail::SAP_Endpoint_Type::End)
      {
        // Pair our endpoints id with every other one in the active list.
        bool start_pairing = false;
        for(auto const& active_endpoint : active_list)
        {
          if(active_endpoint.id != endpt.id && start_pairing)
          {
            auto pair_aabb = active_endpoint.aabb;

            // Check collision in the y and z dimensions.
            if((endpt.aabb.min.y < pair_aabb.min.y &&
                pair_aabb.min.y < endpt.aabb.min.y + endpt.aabb.height) ||
               (endpt.aabb.min.y < pair_aabb.min.y + pair_aabb.height &&
                pair_aabb.min.y + pair_aabb.height <
                  endpt.aabb.min.y + endpt.aabb.height))
            {
              if((endpt.aabb.min.z < pair_aabb.min.z &&
                  pair_aabb.min.z < endpt.aabb.min.z + endpt.aabb.depth) ||
                 (endpt.aabb.min.z < pair_aabb.min.z + pair_aabb.depth &&
                  pair_aabb.min.z + pair_aabb.depth <
                    endpt.aabb.min.z + endpt.aabb.depth))
              {
                ret.emplace_back(endpt.id, active_endpoint.id);
              }
            }
          }
          else if(active_endpoint.id == endpt.id)
          {
            // Start pairing after encountering ourselves.
            start_pairing = true;
          }
        }
      }
    }

    return ret;
  }
}
<commit_msg>We are now using less-than-or-equal-to as opposed to less-than for SAP aabb collision detection.<commit_after>/*
 * Copyright (C) 2015 Luke San Antonio
 * All rights reserved.
 */
#include "sweep_and_prune.h"
#include <algorithm>
#include "../common/algorithm.h"
namespace game
{
  namespace detail
  {
    bool operator<(SAP_Endpoint const& se1, SAP_Endpoint const& se2) noexcept
    {
      return se1.value < se2.value;
    }
  }

  SAP_AABB_Ref SAP::insert(AABB const& aabb) noexcept
  {
    // New aabb
    auto id = ref_counter_.get();

    // Build each endpoint
    auto begin_endpoint = detail::SAP_Endpoint{};
    begin_endpoint.id = id;
    begin_endpoint.aabb = aabb;
    begin_endpoint.type = detail::SAP_Endpoint_Type::Begin;
    begin_endpoint.value = aabb.min.x;

    auto end_endpoint = detail::SAP_Endpoint{};
    end_endpoint.id = id;
    end_endpoint.aabb = aabb;
    end_endpoint.type = detail::SAP_Endpoint_Type::End;
    end_endpoint.value = aabb.min.x + aabb.width;

    sorted_insert(x_axis_, begin_endpoint);
    sorted_insert(x_axis_, end_endpoint);

    return id;
  }

  void SAP::update(SAP_AABB_Ref id, AABB const& aabb) noexcept
  {
    bool sort = false;
    for(auto& endpt : x_axis_)
    {
      if(endpt.id == id)
      {
        if(endpt.type == detail::SAP_Endpoint_Type::Begin)
        {
          endpt.value = aabb.min.x;
        }
        else if(endpt.type == detail::SAP_Endpoint_Type::End)
        {
          endpt.value = aabb.min.x + aabb.width;
        }

        sort = true;
      }
    }

    using std::begin; using std::end;
    if(sort) std::sort(begin(x_axis_), end(x_axis_));
  }

  pair_res_t SAP::collisions() const noexcept
  {
    pair_res_t ret;

    std::vector<detail::SAP_Endpoint> active_list;

    for(auto const& endpt : x_axis_)
    {
      if(endpt.type == detail::SAP_Endpoint_Type::Begin)
      {
        active_list.push_back(endpt);
      }
      else if(endpt.type == detail::SAP_Endpoint_Type::End)
      {
        // Pair our endpoints id with every other one in the active list.
        bool start_pairing = false;
        for(auto const& active_endpoint : active_list)
        {
          if(active_endpoint.id != endpt.id && start_pairing)
          {
            auto pair_aabb = active_endpoint.aabb;

            // Check collision in the y and z dimensions.
            if((endpt.aabb.min.y <= pair_aabb.min.y &&
                pair_aabb.min.y <= endpt.aabb.min.y + endpt.aabb.height) ||
               (endpt.aabb.min.y <= pair_aabb.min.y + pair_aabb.height &&
                pair_aabb.min.y + pair_aabb.height <=
                  endpt.aabb.min.y + endpt.aabb.height))
            {
              if((endpt.aabb.min.z <= pair_aabb.min.z &&
                  pair_aabb.min.z <= endpt.aabb.min.z + endpt.aabb.depth) ||
                 (endpt.aabb.min.z <= pair_aabb.min.z + pair_aabb.depth &&
                  pair_aabb.min.z + pair_aabb.depth <=
                    endpt.aabb.min.z + endpt.aabb.depth))
              {
                ret.emplace_back(endpt.id, active_endpoint.id);
              }
            }
          }
          else if(active_endpoint.id == endpt.id)
          {
            // Start pairing after encountering ourselves.
            start_pairing = true;
          }
        }
      }
    }

    return ret;
  }
}
<|endoftext|>