Merge remote-tracking branch 'upstream/master'
@ -0,0 +1,979 @@
 | 
			
		||||
/*
 | 
			
		||||
https://github.com/peterix/dfhack
 | 
			
		||||
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
 | 
			
		||||
 | 
			
		||||
This software is provided 'as-is', without any express or implied
 | 
			
		||||
warranty. In no event will the authors be held liable for any
 | 
			
		||||
damages arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
Permission is granted to anyone to use this software for any
 | 
			
		||||
purpose, including commercial applications, and to alter it and
 | 
			
		||||
redistribute it freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
1. The origin of this software must not be misrepresented; you must
 | 
			
		||||
not claim that you wrote the original software. If you use this
 | 
			
		||||
software in a product, an acknowledgment in the product documentation
 | 
			
		||||
would be appreciated but is not required.
 | 
			
		||||
 | 
			
		||||
2. Altered source versions must be plainly marked as such, and
 | 
			
		||||
must not be misrepresented as being the original software.
 | 
			
		||||
 | 
			
		||||
3. This notice may not be removed or altered from any source
 | 
			
		||||
distribution.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "Internal.h"
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#include "MemAccess.h"
 | 
			
		||||
#include "Core.h"
 | 
			
		||||
#include "VersionInfo.h"
 | 
			
		||||
#include "tinythread.h"
 | 
			
		||||
// must be last due to MS stupidity
 | 
			
		||||
#include "DataDefs.h"
 | 
			
		||||
#include "DataIdentity.h"
 | 
			
		||||
#include "LuaWrapper.h"
 | 
			
		||||
 | 
			
		||||
#include "MiscUtils.h"
 | 
			
		||||
 | 
			
		||||
#include <lua.h>
 | 
			
		||||
#include <lauxlib.h>
 | 
			
		||||
 | 
			
		||||
using namespace DFHack;
 | 
			
		||||
using namespace DFHack::LuaWrapper;
 | 
			
		||||
 | 
			
		||||
/**************************************
 | 
			
		||||
 * Identity object read/write methods *
 | 
			
		||||
 **************************************/
 | 
			
		||||
 | 
			
		||||
void constructed_identity::lua_read(lua_State *state, int fname_idx, void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    push_object_internal(state, this, ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void constructed_identity::lua_write(lua_State *state, int fname_idx, void *ptr, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    field_error(state, fname_idx, "complex object", "write");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void enum_identity::lua_read(lua_State *state, int fname_idx, void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    base_type->lua_read(state, fname_idx, ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void enum_identity::lua_write(lua_State *state, int fname_idx, void *ptr, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    base_type->lua_write(state, fname_idx, ptr, val_index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void df::number_identity_base::lua_read(lua_State *state, int fname_idx, void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    lua_pushnumber(state, read(ptr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void df::number_identity_base::lua_write(lua_State *state, int fname_idx, void *ptr, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    if (!lua_isnumber(state, val_index))
 | 
			
		||||
        field_error(state, fname_idx, "number expected", "write");
 | 
			
		||||
 | 
			
		||||
    write(ptr, lua_tonumber(state, val_index));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void df::bool_identity::lua_read(lua_State *state, int fname_idx, void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    lua_pushboolean(state, *(bool*)ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void df::bool_identity::lua_write(lua_State *state, int fname_idx, void *ptr, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    char *pb = (char*)ptr;
 | 
			
		||||
 | 
			
		||||
    if (lua_isboolean(state, val_index) || lua_isnil(state, val_index))
 | 
			
		||||
        *pb = lua_toboolean(state, val_index);
 | 
			
		||||
    else if (lua_isnumber(state, val_index))
 | 
			
		||||
        *pb = lua_tointeger(state, val_index);
 | 
			
		||||
    else
 | 
			
		||||
        field_error(state, fname_idx, "boolean or number expected", "write");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void df::stl_string_identity::lua_read(lua_State *state, int fname_idx, void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    auto pstr = (std::string*)ptr;
 | 
			
		||||
    lua_pushlstring(state, pstr->data(), pstr->size());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void df::stl_string_identity::lua_write(lua_State *state, int fname_idx, void *ptr, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    size_t size;
 | 
			
		||||
    const char *bytes = lua_tolstring(state, val_index, &size);
 | 
			
		||||
    if (!bytes)
 | 
			
		||||
        field_error(state, fname_idx, "string expected", "write");
 | 
			
		||||
 | 
			
		||||
    *(std::string*)ptr = std::string(bytes, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void df::pointer_identity::lua_read(lua_State *state, int fname_idx, void *ptr, type_identity *target)
 | 
			
		||||
{
 | 
			
		||||
    push_object_internal(state, target, *(void**)ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void df::pointer_identity::lua_read(lua_State *state, int fname_idx, void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    lua_read(state, fname_idx, ptr, target);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void df::pointer_identity::lua_write(lua_State *state, int fname_idx, void *ptr,
 | 
			
		||||
                                     type_identity *target, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    auto pptr = (void**)ptr;
 | 
			
		||||
 | 
			
		||||
    if (lua_isnil(state, val_index))
 | 
			
		||||
        *pptr = NULL;
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        void *nval = get_object_internal(state, target, val_index, false);
 | 
			
		||||
        if (nval)
 | 
			
		||||
            *pptr = nval;
 | 
			
		||||
        else
 | 
			
		||||
            field_error(state, fname_idx, "incompatible pointer type", "write");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void df::pointer_identity::lua_write(lua_State *state, int fname_idx, void *ptr, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    lua_write(state, fname_idx, ptr, target, val_index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int container_identity::lua_item_count(lua_State *state, void *ptr, CountMode mode)
 | 
			
		||||
{
 | 
			
		||||
    if (lua_isnumber(state, UPVAL_ITEM_COUNT))
 | 
			
		||||
        return lua_tointeger(state, UPVAL_ITEM_COUNT);
 | 
			
		||||
    else
 | 
			
		||||
        return item_count(ptr, mode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void container_identity::lua_item_reference(lua_State *state, int fname_idx, void *ptr, int idx)
 | 
			
		||||
{
 | 
			
		||||
    auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
 | 
			
		||||
    void *pitem = item_pointer(id, ptr, idx);
 | 
			
		||||
    push_object_internal(state, id, pitem);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void container_identity::lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx)
 | 
			
		||||
{
 | 
			
		||||
    auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
 | 
			
		||||
    void *pitem = item_pointer(id, ptr, idx);
 | 
			
		||||
    id->lua_read(state, fname_idx, pitem);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void container_identity::lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
 | 
			
		||||
    void *pitem = item_pointer(id, ptr, idx);
 | 
			
		||||
    id->lua_write(state, fname_idx, pitem, val_index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool container_identity::lua_insert(lua_State *state, int fname_idx, void *ptr, int idx, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
 | 
			
		||||
 | 
			
		||||
    char tmp[32];
 | 
			
		||||
    void *pitem = &tmp;
 | 
			
		||||
 | 
			
		||||
    if (id->isPrimitive())
 | 
			
		||||
    {
 | 
			
		||||
        if (id->isConstructed())
 | 
			
		||||
            luaL_error(state, "Temporaries of type %s not supported", id->getFullName().c_str());
 | 
			
		||||
 | 
			
		||||
        assert(id->byte_size() <= sizeof(tmp));
 | 
			
		||||
        id->lua_write(state, fname_idx, pitem, val_index);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        pitem = get_object_internal(state, id, val_index, false);
 | 
			
		||||
        if (!pitem)
 | 
			
		||||
            field_error(state, fname_idx, "incompatible object type", "insert");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return insert(ptr, idx, pitem);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ptr_container_identity::lua_item_reference(lua_State *state, int fname_idx, void *ptr, int idx)
 | 
			
		||||
{
 | 
			
		||||
    auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
 | 
			
		||||
    void *pitem = item_pointer(id, ptr, idx);
 | 
			
		||||
    push_adhoc_pointer(state, pitem, id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ptr_container_identity::lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx)
 | 
			
		||||
{
 | 
			
		||||
    auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
 | 
			
		||||
    void *pitem = item_pointer(&df::identity_traits<void*>::identity, ptr, idx);
 | 
			
		||||
    df::pointer_identity::lua_read(state, fname_idx, pitem, id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ptr_container_identity::lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
 | 
			
		||||
    void *pitem = item_pointer(&df::identity_traits<void*>::identity, ptr, idx);
 | 
			
		||||
    df::pointer_identity::lua_write(state, fname_idx, pitem, id, val_index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ptr_container_identity::lua_insert(lua_State *state, int fname_idx, void *ptr, int idx, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    auto id = (type_identity*)lua_touserdata(state, UPVAL_ITEM_ID);
 | 
			
		||||
 | 
			
		||||
    void *pitem = NULL;
 | 
			
		||||
    df::pointer_identity::lua_write(state, fname_idx, &pitem, id, val_index);
 | 
			
		||||
 | 
			
		||||
    return insert(ptr, idx, pitem);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bit_container_identity::lua_item_reference(lua_State *state, int, void *, int)
 | 
			
		||||
{
 | 
			
		||||
    lua_pushnil(state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bit_container_identity::lua_item_read(lua_State *state, int fname_idx, void *ptr, int idx)
 | 
			
		||||
{
 | 
			
		||||
    lua_pushboolean(state, get_item(ptr, idx));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bit_container_identity::lua_item_write(lua_State *state, int fname_idx, void *ptr, int idx, int val_index)
 | 
			
		||||
{
 | 
			
		||||
    if (lua_isboolean(state, val_index) || lua_isnil(state, val_index))
 | 
			
		||||
        set_item(ptr, idx, lua_toboolean(state, val_index));
 | 
			
		||||
    else if (lua_isnumber(state, val_index))
 | 
			
		||||
        set_item(ptr, idx, lua_tointeger(state, val_index) != 0);
 | 
			
		||||
    else
 | 
			
		||||
        field_error(state, fname_idx, "boolean or number expected", "write");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Resolve the field name in UPVAL_FIELDTABLE, die if not found.
 | 
			
		||||
 */
 | 
			
		||||
static void lookup_field(lua_State *state, int index, const char *mode)
 | 
			
		||||
{
 | 
			
		||||
    lua_pushvalue(state, index);
 | 
			
		||||
    lua_gettable(state, UPVAL_FIELDTABLE); // uses metatable with enum keys
 | 
			
		||||
 | 
			
		||||
    if (lua_isnil(state, -1))
 | 
			
		||||
        field_error(state, index, "not found", mode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *find_field(lua_State *state, int index, const char *mode)
 | 
			
		||||
{
 | 
			
		||||
    lookup_field(state, index, mode);
 | 
			
		||||
 | 
			
		||||
    void *p = lua_touserdata(state, -1);
 | 
			
		||||
    lua_pop(state, 1);
 | 
			
		||||
    return p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint8_t *check_method_call(lua_State *state, int min_args, int max_args)
 | 
			
		||||
{
 | 
			
		||||
    int argc = lua_gettop(state)-1;
 | 
			
		||||
    if (argc < min_args || argc > max_args)
 | 
			
		||||
        field_error(state, UPVAL_METHOD_NAME, "wrong argument count", "call");
 | 
			
		||||
 | 
			
		||||
    return get_object_addr(state, 1, UPVAL_METHOD_NAME, "call");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void GetAdHocMetatable(lua_State *state, const struct_field_info *field);
 | 
			
		||||
 | 
			
		||||
static void read_field(lua_State *state, const struct_field_info *field, void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    switch (field->mode)
 | 
			
		||||
    {
 | 
			
		||||
        case struct_field_info::STATIC_STRING:
 | 
			
		||||
        {
 | 
			
		||||
            int len = strnlen((char*)ptr, field->count);
 | 
			
		||||
            lua_pushlstring(state, (char*)ptr, len);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::PRIMITIVE:
 | 
			
		||||
        case struct_field_info::SUBSTRUCT:
 | 
			
		||||
            field->type->lua_read(state, 2, ptr);
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::POINTER:
 | 
			
		||||
            df::pointer_identity::lua_read(state, 2, ptr, field->type);
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::CONTAINER:
 | 
			
		||||
            if (!field->eid || !field->type->isContainer() ||
 | 
			
		||||
                field->eid == ((container_identity*)field->type)->getIndexEnumType())
 | 
			
		||||
            {
 | 
			
		||||
                field->type->lua_read(state, 2, ptr);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // fallthrough
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::STATIC_ARRAY:
 | 
			
		||||
        case struct_field_info::STL_VECTOR_PTR:
 | 
			
		||||
            GetAdHocMetatable(state, field);
 | 
			
		||||
            push_object_ref(state, ptr);
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::END:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lua_pushnil(state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void field_reference(lua_State *state, const struct_field_info *field, void *ptr)
 | 
			
		||||
{
 | 
			
		||||
    switch (field->mode)
 | 
			
		||||
    {
 | 
			
		||||
        case struct_field_info::PRIMITIVE:
 | 
			
		||||
        case struct_field_info::SUBSTRUCT:
 | 
			
		||||
            push_object_internal(state, field->type, ptr);
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::POINTER:
 | 
			
		||||
            push_adhoc_pointer(state, ptr, field->type);
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::CONTAINER:
 | 
			
		||||
            read_field(state, field, ptr);
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::STATIC_STRING:
 | 
			
		||||
        case struct_field_info::STATIC_ARRAY:
 | 
			
		||||
        case struct_field_info::STL_VECTOR_PTR:
 | 
			
		||||
            GetAdHocMetatable(state, field);
 | 
			
		||||
            push_object_ref(state, ptr);
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::END:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lua_pushnil(state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void write_field(lua_State *state, const struct_field_info *field, void *ptr, int value_idx)
 | 
			
		||||
{
 | 
			
		||||
    switch (field->mode)
 | 
			
		||||
    {
 | 
			
		||||
        case struct_field_info::STATIC_STRING:
 | 
			
		||||
        {
 | 
			
		||||
            size_t size;
 | 
			
		||||
            const char *str = lua_tolstring(state, value_idx, &size);
 | 
			
		||||
            if (!str)
 | 
			
		||||
                field_error(state, 2, "string expected", "write");
 | 
			
		||||
            memcpy(ptr, str, std::min(size+1, size_t(field->count)));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::PRIMITIVE:
 | 
			
		||||
        case struct_field_info::SUBSTRUCT:
 | 
			
		||||
        case struct_field_info::CONTAINER:
 | 
			
		||||
            field->type->lua_write(state, 2, ptr, value_idx);
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::POINTER:
 | 
			
		||||
            df::pointer_identity::lua_write(state, 2, ptr, field->type, value_idx);
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::STATIC_ARRAY:
 | 
			
		||||
        case struct_field_info::STL_VECTOR_PTR:
 | 
			
		||||
            field_error(state, 2, "complex object", "write");
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::END:
 | 
			
		||||
            return;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: represent a type node as string.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_type_tostring(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    if (!lua_getmetatable(state, 1))
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    lua_getfield(state, -1, "__metatable");
 | 
			
		||||
    const char *cname = lua_tostring(state, -1);
 | 
			
		||||
 | 
			
		||||
    lua_pushstring(state, stl_sprintf("<type: %s>", cname).c_str());
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: represent a DF object reference as string.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_ptr_tostring(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 0, "access");
 | 
			
		||||
 | 
			
		||||
    lua_getfield(state, UPVAL_METATABLE, "__metatable");
 | 
			
		||||
    const char *cname = lua_tostring(state, -1);
 | 
			
		||||
 | 
			
		||||
    lua_pushstring(state, stl_sprintf("<%s: 0x%08x>", cname, (unsigned)ptr).c_str());
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Resolve the field in the metatable and return
 | 
			
		||||
static int get_metafield(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    lua_rawget(state, UPVAL_METATABLE);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __index for structures.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_struct_index(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 2, "read");
 | 
			
		||||
    auto field = (struct_field_info*)find_field(state, 2, "read");
 | 
			
		||||
    if (!field)
 | 
			
		||||
        return get_metafield(state);
 | 
			
		||||
    read_field(state, field, ptr + field->offset);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Method: _field for structures.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_struct_field_reference(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    if (lua_gettop(state) != 2)
 | 
			
		||||
        luaL_error(state, "Usage: object._field(name)");
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 2, "reference");
 | 
			
		||||
    auto field = (struct_field_info*)find_field(state, 2, "reference");
 | 
			
		||||
    if (!field)
 | 
			
		||||
        field_error(state, 2, "builtin property", "reference");
 | 
			
		||||
    field_reference(state, field, ptr + field->offset);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __newindex for structures.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_struct_newindex(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 2, "write");
 | 
			
		||||
    auto field = (struct_field_info*)find_field(state, 2, "write");
 | 
			
		||||
    if (!field)
 | 
			
		||||
        field_error(state, 2, "builtin property", "write");
 | 
			
		||||
    write_field(state, field, ptr + field->offset, 3);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __index for primitives, i.e. simple object references.
 | 
			
		||||
 *   Fields point to identity, or NULL for metafields.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_primitive_index(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 2, "read");
 | 
			
		||||
    auto type = (type_identity*)find_field(state, 2, "read");
 | 
			
		||||
    if (!type)
 | 
			
		||||
        return get_metafield(state);
 | 
			
		||||
    type->lua_read(state, 2, ptr);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __newindex for primitives.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_primitive_newindex(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 2, "write");
 | 
			
		||||
    auto type = (type_identity*)find_field(state, 2, "write");
 | 
			
		||||
    if (!type)
 | 
			
		||||
        field_error(state, 2, "builtin property", "write");
 | 
			
		||||
    type->lua_write(state, 2, ptr, 3);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __len for containers.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_container_len(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 0, "get length");
 | 
			
		||||
    auto id = (container_identity*)lua_touserdata(state, UPVAL_CONTAINER_ID);
 | 
			
		||||
    int len = id->lua_item_count(state, ptr, container_identity::COUNT_LEN);
 | 
			
		||||
    lua_pushinteger(state, len);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Field lookup for containers:
 | 
			
		||||
 *
 | 
			
		||||
 *   - Numbers are indices and handled directly.
 | 
			
		||||
 *   - NULL userdata are metafields; push and exit;
 | 
			
		||||
 */
 | 
			
		||||
static int lookup_container_field(lua_State *state, int field, const char *mode = NULL)
 | 
			
		||||
{
 | 
			
		||||
    if (lua_type(state, field) == LUA_TNUMBER)
 | 
			
		||||
        return field;
 | 
			
		||||
 | 
			
		||||
    lookup_field(state, field, mode ? mode : "read");
 | 
			
		||||
 | 
			
		||||
    if (lua_isuserdata(state, -1) && !lua_touserdata(state, -1))
 | 
			
		||||
    {
 | 
			
		||||
        if (mode)
 | 
			
		||||
            field_error(state, field, "builtin property", mode);
 | 
			
		||||
 | 
			
		||||
        lua_pop(state, 1);
 | 
			
		||||
        get_metafield(state);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Index verification: number and in range.
 | 
			
		||||
 */
 | 
			
		||||
static int check_container_index(lua_State *state, int len,
 | 
			
		||||
                                 int fidx, int iidx, const char *mode)
 | 
			
		||||
{
 | 
			
		||||
    if (!lua_isnumber(state, iidx))
 | 
			
		||||
        field_error(state, fidx, "invalid index", mode);
 | 
			
		||||
 | 
			
		||||
    int idx = lua_tointeger(state, iidx);
 | 
			
		||||
    if (idx < 0 || (idx >= len && len >= 0))
 | 
			
		||||
        field_error(state, fidx, "index out of bounds", mode);
 | 
			
		||||
 | 
			
		||||
    return idx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __index for containers.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_container_index(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 2, "read");
 | 
			
		||||
    int iidx = lookup_container_field(state, 2);
 | 
			
		||||
    if (!iidx)
 | 
			
		||||
        return 1;
 | 
			
		||||
 | 
			
		||||
    auto id = (container_identity*)lua_touserdata(state, UPVAL_CONTAINER_ID);
 | 
			
		||||
    int len = id->lua_item_count(state, ptr, container_identity::COUNT_READ);
 | 
			
		||||
    int idx = check_container_index(state, len, 2, iidx, "read");
 | 
			
		||||
    id->lua_item_read(state, 2, ptr, idx);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Method: _field for containers.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_container_field_reference(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    if (lua_gettop(state) != 2)
 | 
			
		||||
        luaL_error(state, "Usage: object._field(index)");
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 2, "reference");
 | 
			
		||||
    int iidx = lookup_container_field(state, 2, "reference");
 | 
			
		||||
 | 
			
		||||
    auto id = (container_identity*)lua_touserdata(state, UPVAL_CONTAINER_ID);
 | 
			
		||||
    int len = id->lua_item_count(state, ptr, container_identity::COUNT_WRITE);
 | 
			
		||||
    int idx = check_container_index(state, len, 2, iidx, "reference");
 | 
			
		||||
    id->lua_item_reference(state, 2, ptr, idx);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __index for containers.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_container_newindex(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 2, "write");
 | 
			
		||||
    int iidx = lookup_container_field(state, 2, "write");
 | 
			
		||||
 | 
			
		||||
    auto id = (container_identity*)lua_touserdata(state, UPVAL_CONTAINER_ID);
 | 
			
		||||
    int len = id->lua_item_count(state, ptr, container_identity::COUNT_WRITE);
 | 
			
		||||
    int idx = check_container_index(state, len, 2, iidx, "write");
 | 
			
		||||
    id->lua_item_write(state, 2, ptr, idx, 3);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Method: resize container
 | 
			
		||||
 */
 | 
			
		||||
static int method_container_resize(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = check_method_call(state, 1, 1);
 | 
			
		||||
 | 
			
		||||
    auto id = (container_identity*)lua_touserdata(state, UPVAL_CONTAINER_ID);
 | 
			
		||||
    int idx = check_container_index(state, -1, UPVAL_METHOD_NAME, 2, "call");
 | 
			
		||||
 | 
			
		||||
    if (!id->resize(ptr, idx))
 | 
			
		||||
        field_error(state, UPVAL_METHOD_NAME, "not supported", "call");
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Method: erase item from container
 | 
			
		||||
 */
 | 
			
		||||
static int method_container_erase(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = check_method_call(state, 1, 1);
 | 
			
		||||
 | 
			
		||||
    auto id = (container_identity*)lua_touserdata(state, UPVAL_CONTAINER_ID);
 | 
			
		||||
    int len = id->lua_item_count(state, ptr, container_identity::COUNT_LEN);
 | 
			
		||||
    int idx = check_container_index(state, len, UPVAL_METHOD_NAME, 2, "call");
 | 
			
		||||
 | 
			
		||||
    if (!id->erase(ptr, idx))
 | 
			
		||||
        field_error(state, UPVAL_METHOD_NAME, "not supported", "call");
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Method: insert item into container
 | 
			
		||||
 */
 | 
			
		||||
static int method_container_insert(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = check_method_call(state, 2, 2);
 | 
			
		||||
 | 
			
		||||
    auto id = (container_identity*)lua_touserdata(state, UPVAL_CONTAINER_ID);
 | 
			
		||||
    int len = id->lua_item_count(state, ptr, container_identity::COUNT_LEN);
 | 
			
		||||
    if (len >= 0) len++;
 | 
			
		||||
    int idx = check_container_index(state, len, UPVAL_METHOD_NAME, 2, "call");
 | 
			
		||||
 | 
			
		||||
    if (!id->lua_insert(state, UPVAL_METHOD_NAME, ptr, idx, 3))
 | 
			
		||||
        field_error(state, UPVAL_METHOD_NAME, "not supported", "call");
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __len for bitfields.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_bitfield_len(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 0, "get size");
 | 
			
		||||
    auto id = (bitfield_identity*)lua_touserdata(state, UPVAL_CONTAINER_ID);
 | 
			
		||||
    lua_pushinteger(state, id->getNumBits());
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __index for bitfields.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_bitfield_index(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 2, "read");
 | 
			
		||||
    int iidx = lookup_container_field(state, 2);
 | 
			
		||||
    if (!iidx)
 | 
			
		||||
        return 1;
 | 
			
		||||
 | 
			
		||||
    auto id = (bitfield_identity*)lua_touserdata(state, UPVAL_CONTAINER_ID);
 | 
			
		||||
 | 
			
		||||
    // whole
 | 
			
		||||
    if (lua_isuserdata(state, iidx) && lua_touserdata(state, iidx) == id)
 | 
			
		||||
    {
 | 
			
		||||
        size_t intv = 0;
 | 
			
		||||
        memcpy(&intv, ptr, std::min(sizeof(intv), size_t(id->byte_size())));
 | 
			
		||||
        lua_pushnumber(state, intv);
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int idx = check_container_index(state, id->getNumBits(), 2, iidx, "read");
 | 
			
		||||
    int size = id->getBits()[idx].size;
 | 
			
		||||
 | 
			
		||||
    int value = getBitfieldField(ptr, idx, size);
 | 
			
		||||
    if (size <= 1)
 | 
			
		||||
        lua_pushboolean(state, value != 0);
 | 
			
		||||
    else
 | 
			
		||||
        lua_pushinteger(state, value);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __newindex for bitfields.
 | 
			
		||||
 */
 | 
			
		||||
static int meta_bitfield_newindex(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *ptr = get_object_addr(state, 1, 2, "write");
 | 
			
		||||
    int iidx = lookup_container_field(state, 2, "write");
 | 
			
		||||
 | 
			
		||||
    auto id = (bitfield_identity*)lua_touserdata(state, UPVAL_CONTAINER_ID);
 | 
			
		||||
 | 
			
		||||
    // whole
 | 
			
		||||
    if (lua_isuserdata(state, iidx) && lua_touserdata(state, iidx) == id)
 | 
			
		||||
    {
 | 
			
		||||
        if (!lua_isnumber(state, 3))
 | 
			
		||||
            field_error(state, 2, "number expected", "write");
 | 
			
		||||
 | 
			
		||||
        size_t intv = (size_t)lua_tonumber(state, 3);
 | 
			
		||||
        memcpy(ptr, &intv, std::min(sizeof(intv), size_t(id->byte_size())));
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int idx = check_container_index(state, id->getNumBits(), 2, iidx, "write");
 | 
			
		||||
    int size = id->getBits()[idx].size;
 | 
			
		||||
 | 
			
		||||
    if (lua_isboolean(state, 3) || lua_isnil(state, 3))
 | 
			
		||||
        setBitfieldField(ptr, idx, size, lua_toboolean(state, 3));
 | 
			
		||||
    else if (lua_isnumber(state, 3))
 | 
			
		||||
        setBitfieldField(ptr, idx, size, lua_tointeger(state, 3));
 | 
			
		||||
    else
 | 
			
		||||
        field_error(state, 2, "number or boolean expected", "write");
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __index for df.global
 | 
			
		||||
 */
 | 
			
		||||
static int meta_global_index(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    auto field = (struct_field_info*)find_field(state, 2, "read");
 | 
			
		||||
    if (!field)
 | 
			
		||||
        return get_metafield(state);
 | 
			
		||||
    void *ptr = *(void**)field->offset;
 | 
			
		||||
    if (!ptr)
 | 
			
		||||
        field_error(state, 2, "global address not known", "read");
 | 
			
		||||
    read_field(state, field, ptr);
 | 
			
		||||
    return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Metamethod: __newindex for df.global
 | 
			
		||||
 */
 | 
			
		||||
static int meta_global_newindex(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    auto field = (struct_field_info*)find_field(state, 2, "write");
 | 
			
		||||
    if (!field)
 | 
			
		||||
        field_error(state, 2, "builtin property", "write");
 | 
			
		||||
    void *ptr = *(void**)field->offset;
 | 
			
		||||
    if (!ptr)
 | 
			
		||||
        field_error(state, 2, "global address not known", "write");
 | 
			
		||||
    write_field(state, field, ptr, 3);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Add fields in the array to the UPVAL_FIELDTABLE candidates on the stack.
 | 
			
		||||
 */
 | 
			
		||||
static void IndexFields(lua_State *state, struct_identity *pstruct)
 | 
			
		||||
{
 | 
			
		||||
    // stack: fieldtable
 | 
			
		||||
 | 
			
		||||
    int base = lua_gettop(state);
 | 
			
		||||
 | 
			
		||||
    for (struct_identity *p = pstruct; p; p = p->getParent())
 | 
			
		||||
    {
 | 
			
		||||
        auto fields = p->getFields();
 | 
			
		||||
 | 
			
		||||
        for (; fields; ++fields)
 | 
			
		||||
        {
 | 
			
		||||
            if (fields->mode == struct_field_info::END)
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            lua_pushstring(state,fields->name);
 | 
			
		||||
            lua_pushlightuserdata(state,(void*)fields);
 | 
			
		||||
            lua_rawset(state,base);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Make a struct-style object metatable.
 | 
			
		||||
 */
 | 
			
		||||
static void MakeFieldMetatable(lua_State *state, struct_identity *pstruct,
 | 
			
		||||
                               lua_CFunction reader, lua_CFunction writer)
 | 
			
		||||
{
 | 
			
		||||
    int base = lua_gettop(state);
 | 
			
		||||
 | 
			
		||||
    MakeMetatable(state, pstruct, "struct"); // meta, fields
 | 
			
		||||
 | 
			
		||||
    IndexFields(state, pstruct);
 | 
			
		||||
 | 
			
		||||
    SetStructMethod(state, base+1, base+2, reader, "__index");
 | 
			
		||||
    SetStructMethod(state, base+1, base+2, writer, "__newindex");
 | 
			
		||||
 | 
			
		||||
    // returns: [metatable readfields writefields];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Make a primitive-style metatable
 | 
			
		||||
 */
 | 
			
		||||
static void MakePrimitiveMetatable(lua_State *state, type_identity *type)
 | 
			
		||||
{
 | 
			
		||||
    int base = lua_gettop(state);
 | 
			
		||||
 | 
			
		||||
    MakeMetatable(state, type, "primitive");
 | 
			
		||||
 | 
			
		||||
    SetPtrMethods(state, base+1, base+2);
 | 
			
		||||
 | 
			
		||||
    EnableMetaField(state, base+2, "value", type);
 | 
			
		||||
 | 
			
		||||
    SetStructMethod(state, base+1, base+2, meta_primitive_index, "__index");
 | 
			
		||||
    SetStructMethod(state, base+1, base+2, meta_primitive_newindex, "__newindex");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void AddContainerMethodFun(lua_State *state, int meta_idx, int field_idx,
 | 
			
		||||
                                  lua_CFunction function, const char *name,
 | 
			
		||||
                                  type_identity *container, type_identity *item, int count)
 | 
			
		||||
{
 | 
			
		||||
    lua_pushfstring(state, "%s()", name);
 | 
			
		||||
    SetContainerMethod(state, meta_idx, lua_gettop(state), function, name, container, item, count);
 | 
			
		||||
    lua_pop(state, 1);
 | 
			
		||||
 | 
			
		||||
    EnableMetaField(state, field_idx, name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Make a container-style object metatable.
 | 
			
		||||
 */
 | 
			
		||||
static void MakeContainerMetatable(lua_State *state, container_identity *type,
 | 
			
		||||
                                   type_identity *item, int count, type_identity *ienum)
 | 
			
		||||
{
 | 
			
		||||
    int base = lua_gettop(state);
 | 
			
		||||
 | 
			
		||||
    MakeMetatable(state, type, "container");
 | 
			
		||||
    SetPtrMethods(state, base+1, base+2);
 | 
			
		||||
 | 
			
		||||
    // Update the type name using full info
 | 
			
		||||
    lua_pushstring(state, type->getFullName(item).c_str());
 | 
			
		||||
    lua_dup(state);
 | 
			
		||||
    lua_setfield(state, base+1, "__metatable");
 | 
			
		||||
    lua_setfield(state, base+1, "_type");
 | 
			
		||||
 | 
			
		||||
    lua_pushlightuserdata(state, item);
 | 
			
		||||
    lua_setfield(state, base+1, "_field_identity");
 | 
			
		||||
 | 
			
		||||
    if (count >= 0)
 | 
			
		||||
    {
 | 
			
		||||
        lua_pushinteger(state, count);
 | 
			
		||||
        lua_setfield(state, base+1, "_count");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SetContainerMethod(state, base+1, base+2, meta_container_len, "__len", type, item, count);
 | 
			
		||||
    SetContainerMethod(state, base+1, base+2, meta_container_index, "__index", type, item, count);
 | 
			
		||||
    SetContainerMethod(state, base+1, base+2, meta_container_newindex, "__newindex", type, item, count);
 | 
			
		||||
 | 
			
		||||
    SetContainerMethod(state, base+1, base+2, meta_container_field_reference, "_field", type, item, count);
 | 
			
		||||
 | 
			
		||||
    AddContainerMethodFun(state, base+1, base+2, method_container_resize, "resize", type, item, count);
 | 
			
		||||
    AddContainerMethodFun(state, base+1, base+2, method_container_erase, "erase", type, item, count);
 | 
			
		||||
    AddContainerMethodFun(state, base+1, base+2, method_container_insert, "insert", type, item, count);
 | 
			
		||||
 | 
			
		||||
    AttachEnumKeys(state, base+1, base+2, ienum);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Metatable construction identity methods.
 | 
			
		||||
 */
 | 
			
		||||
void type_identity::build_metatable(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    MakePrimitiveMetatable(state, this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void container_identity::build_metatable(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    MakeContainerMetatable(state, this, getItemType(), -1, getIndexEnumType());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bitfield_identity::build_metatable(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    int base = lua_gettop(state);
 | 
			
		||||
 | 
			
		||||
    MakeMetatable(state, this, "bitfield");
 | 
			
		||||
 | 
			
		||||
    SetPtrMethods(state, base+1, base+2);
 | 
			
		||||
 | 
			
		||||
    SetContainerMethod(state, base+1, base+2, meta_bitfield_len, "__len", this, NULL, -1);
 | 
			
		||||
    SetContainerMethod(state, base+1, base+2, meta_bitfield_index, "__index", this, NULL, -1);
 | 
			
		||||
    SetContainerMethod(state, base+1, base+2, meta_bitfield_newindex, "__newindex", this, NULL, -1);
 | 
			
		||||
 | 
			
		||||
    AttachEnumKeys(state, base+1, base+2, this);
 | 
			
		||||
 | 
			
		||||
    EnableMetaField(state, base+2, "whole", this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void struct_identity::build_metatable(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    int base = lua_gettop(state);
 | 
			
		||||
    MakeFieldMetatable(state, this, meta_struct_index, meta_struct_newindex);
 | 
			
		||||
    SetStructMethod(state, base+1, base+2, meta_struct_field_reference, "_field");
 | 
			
		||||
    SetPtrMethods(state, base+1, base+2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void global_identity::build_metatable(lua_State *state)
 | 
			
		||||
{
 | 
			
		||||
    MakeFieldMetatable(state, this, meta_global_index, meta_global_newindex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Construct a metatable for an object type folded into the field descriptor.
 | 
			
		||||
 * This is done to reduce compile-time symbol table bloat due to templates.
 | 
			
		||||
 */
 | 
			
		||||
static void GetAdHocMetatable(lua_State *state, const struct_field_info *field)
 | 
			
		||||
{
 | 
			
		||||
    lua_pushlightuserdata(state, (void*)field);
 | 
			
		||||
 | 
			
		||||
    if (!LookupTypeInfo(state, true))
 | 
			
		||||
    {
 | 
			
		||||
        switch (field->mode)
 | 
			
		||||
        {
 | 
			
		||||
        case struct_field_info::CONTAINER:
 | 
			
		||||
        {
 | 
			
		||||
            auto ctype = (container_identity*)field->type;
 | 
			
		||||
            MakeContainerMetatable(state, ctype, ctype->getItemType(), -1, field->eid);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::STATIC_STRING:
 | 
			
		||||
            MakeContainerMetatable(state, &df::buffer_container_identity::base_instance,
 | 
			
		||||
                                   &df::identity_traits<char>::identity, field->count, NULL);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::STATIC_ARRAY:
 | 
			
		||||
            MakeContainerMetatable(state, &df::buffer_container_identity::base_instance,
 | 
			
		||||
                                   field->type, field->count, field->eid);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case struct_field_info::STL_VECTOR_PTR:
 | 
			
		||||
            MakeContainerMetatable(state, &df::identity_traits<std::vector<void*> >::identity,
 | 
			
		||||
                                   field->type, -1, field->eid);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            luaL_error(state, "Invalid ad-hoc field: %d", field->mode);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        lua_pop(state, 1);
 | 
			
		||||
 | 
			
		||||
        SaveTypeInfo(state, (void*)field);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LuaWrapper::push_adhoc_pointer(lua_State *state, void *ptr, type_identity *target)
 | 
			
		||||
{
 | 
			
		||||
    if (!target)
 | 
			
		||||
    {
 | 
			
		||||
        push_object_internal(state, &df::identity_traits<void*>::identity, ptr);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LookupInTable(state, target, DFHACK_PTR_IDTABLE_NAME);
 | 
			
		||||
 | 
			
		||||
    type_identity *id = (type_identity*)lua_touserdata(state, -1);
 | 
			
		||||
    lua_pop(state, 1);
 | 
			
		||||
 | 
			
		||||
    if (!id)
 | 
			
		||||
    {
 | 
			
		||||
        /*
 | 
			
		||||
         * HACK: relies on
 | 
			
		||||
         *   1) pointer_identity destructor being no-op
 | 
			
		||||
         *   2) lua gc never moving objects in memory
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        void *newobj = lua_newuserdata(state, sizeof(pointer_identity));
 | 
			
		||||
        id = new (newobj) pointer_identity(target);
 | 
			
		||||
 | 
			
		||||
        SaveInTable(state, target, DFHACK_PTR_IDTABLE_NAME);
 | 
			
		||||
        lua_pop(state, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    push_object_internal(state, id, ptr);
 | 
			
		||||
}
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
#include "Internal.h"
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#include "MemAccess.h"
 | 
			
		||||
#include "Core.h"
 | 
			
		||||
#include "Virtual.h"
 | 
			
		||||
using namespace DFHack;
 | 
			
		||||
 | 
			
		||||
std::string t_virtual::getClassName() const
 | 
			
		||||
{
 | 
			
		||||
    Core & c = Core::getInstance();
 | 
			
		||||
    return c.p->readClassName(vptr);
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,190 @@
 | 
			
		||||
/*
 | 
			
		||||
https://github.com/peterix/dfhack
 | 
			
		||||
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
 | 
			
		||||
 | 
			
		||||
This software is provided 'as-is', without any express or implied
 | 
			
		||||
warranty. In no event will the authors be held liable for any
 | 
			
		||||
damages arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
Permission is granted to anyone to use this software for any
 | 
			
		||||
purpose, including commercial applications, and to alter it and
 | 
			
		||||
redistribute it freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
1. The origin of this software must not be misrepresented; you must
 | 
			
		||||
not claim that you wrote the original software. If you use this
 | 
			
		||||
software in a product, an acknowledgment in the product documentation
 | 
			
		||||
would be appreciated but is not required.
 | 
			
		||||
 | 
			
		||||
2. Altered source versions must be plainly marked as such, and
 | 
			
		||||
must not be misrepresented as being the original software.
 | 
			
		||||
 | 
			
		||||
3. This notice may not be removed or altered from any source
 | 
			
		||||
distribution.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
#include "DataDefs.h"
 | 
			
		||||
 | 
			
		||||
#include <lua.h>
 | 
			
		||||
#include <lauxlib.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Internal header file of the lua wrapper.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
namespace DFHack { namespace LuaWrapper {
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Registry name: hash of type metatables <-> type identities.
 | 
			
		||||
 */
 | 
			
		||||
#define DFHACK_TYPETABLE_NAME "DFHack::DFTypes"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Registry name: hash of type identity -> node in df.etc...
 | 
			
		||||
 */
 | 
			
		||||
#define DFHACK_TYPEID_TABLE_NAME "DFHack::DFTypeIds"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Registry name: hash of enum/bitfield identity -> index lookup table
 | 
			
		||||
 */
 | 
			
		||||
#define DFHACK_ENUM_TABLE_NAME "DFHack::DFEnums"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Registry name: hash of pointer target identity <-> adhoc pointer identity userdata.
 | 
			
		||||
 */
 | 
			
		||||
#define DFHACK_PTR_IDTABLE_NAME "DFHack::PtrDFTypes"
 | 
			
		||||
 | 
			
		||||
// Function registry names
 | 
			
		||||
#define DFHACK_CHANGEERROR_NAME "DFHack::ChangeError"
 | 
			
		||||
#define DFHACK_COMPARE_NAME "DFHack::ComparePtrs"
 | 
			
		||||
#define DFHACK_TYPE_TOSTRING_NAME "DFHack::TypeToString"
 | 
			
		||||
#define DFHACK_SIZEOF_NAME "DFHack::Sizeof"
 | 
			
		||||
#define DFHACK_DISPLACE_NAME "DFHack::Displace"
 | 
			
		||||
#define DFHACK_NEW_NAME "DFHack::New"
 | 
			
		||||
#define DFHACK_ASSIGN_NAME "DFHack::Assign"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Upvalue: contents of DFHACK_TYPETABLE_NAME
 | 
			
		||||
 */
 | 
			
		||||
#define UPVAL_TYPETABLE lua_upvalueindex(1)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Expected metatable of the current object.
 | 
			
		||||
 */
 | 
			
		||||
#define UPVAL_METATABLE lua_upvalueindex(2)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Table mapping field names to indices or data structure pointers.
 | 
			
		||||
 * Enum index table is linked into here via getmetatable($).__index.
 | 
			
		||||
 * Fields that are actually in UPVAL_METATABLE are marked with NULL light udata.
 | 
			
		||||
 */
 | 
			
		||||
#define UPVAL_FIELDTABLE lua_upvalueindex(3)
 | 
			
		||||
#define UPVAL_METHOD_NAME lua_upvalueindex(3)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Only for containers: light udata with container identity.
 | 
			
		||||
 */
 | 
			
		||||
#define UPVAL_CONTAINER_ID lua_upvalueindex(4)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Only for containers: light udata with item identity.
 | 
			
		||||
 */
 | 
			
		||||
#define UPVAL_ITEM_ID lua_upvalueindex(5)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Only for containers: if not nil, overrides the item count.
 | 
			
		||||
 */
 | 
			
		||||
#define UPVAL_ITEM_COUNT lua_upvalueindex(6)
 | 
			
		||||
 | 
			
		||||
    inline void lua_dup(lua_State *state) { lua_pushvalue(state, -1); }
 | 
			
		||||
    inline void lua_swap(lua_State *state) { lua_insert(state, -2); }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Object references are represented as userdata instances
 | 
			
		||||
     * with an appropriate metatable; the payload of userdata is
 | 
			
		||||
     * this structure:
 | 
			
		||||
     */
 | 
			
		||||
    struct DFRefHeader {
 | 
			
		||||
        void *ptr;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Push the pointer as DF object ref using metatable on the stack.
 | 
			
		||||
     */
 | 
			
		||||
    void push_object_ref(lua_State *state, void *ptr);
 | 
			
		||||
    void *get_object_ref(lua_State *state, int val_index);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * The system might be extended to carry some simple
 | 
			
		||||
     * objects inline inside the reference buffer.
 | 
			
		||||
     */
 | 
			
		||||
    inline bool is_self_contained(DFRefHeader *ptr) {
 | 
			
		||||
        void **pp = &ptr->ptr;
 | 
			
		||||
        return **(void****)pp == (pp + 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Report an error while accessing a field (index = field name).
 | 
			
		||||
    */
 | 
			
		||||
    void field_error(lua_State *state, int index, const char *err, const char *mode);
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * If is_method is true, these use UPVAL_TYPETABLE to save a hash lookup.
 | 
			
		||||
     */
 | 
			
		||||
    void push_object_internal(lua_State *state, type_identity *type, void *ptr, bool in_method = true);
 | 
			
		||||
    void *get_object_internal(lua_State *state, type_identity *type, int val_index, bool exact_type, bool in_method = true);
 | 
			
		||||
 | 
			
		||||
    void push_adhoc_pointer(lua_State *state, void *ptr, type_identity *target);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Verify that the object is a DF ref with UPVAL_METATABLE.
 | 
			
		||||
     * If everything ok, extract the address.
 | 
			
		||||
     */
 | 
			
		||||
    uint8_t *get_object_addr(lua_State *state, int obj, int field, const char *mode);
 | 
			
		||||
 | 
			
		||||
    void LookupInTable(lua_State *state, void *id, const char *tname);
 | 
			
		||||
    void SaveInTable(lua_State *state, void *node, const char *tname);
 | 
			
		||||
    void SaveTypeInfo(lua_State *state, void *node);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Look up the key on the stack in DFHACK_TYPETABLE;
 | 
			
		||||
     * if found, put result on the stack and return true.
 | 
			
		||||
     */
 | 
			
		||||
    bool LookupTypeInfo(lua_State *state, bool in_method);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Make a metatable with most common fields, and an empty table for UPVAL_FIELDTABLE.
 | 
			
		||||
     */
 | 
			
		||||
    void MakeMetatable(lua_State *state, type_identity *type, const char *kind);
 | 
			
		||||
    /**
 | 
			
		||||
     * Enable a metafield by injecting an entry into a UPVAL_FIELDTABLE.
 | 
			
		||||
     */
 | 
			
		||||
    void EnableMetaField(lua_State *state, int ftable_idx, const char *name, void *id = NULL);
 | 
			
		||||
    /**
 | 
			
		||||
     * Set metatable properties common to all actual DF object references.
 | 
			
		||||
     */
 | 
			
		||||
    void SetPtrMethods(lua_State *state, int meta_idx, int read_idx);
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a struct-style (3 upvalues) metamethod to the metatable.
 | 
			
		||||
     */
 | 
			
		||||
    void SetStructMethod(lua_State *state, int meta_idx, int ftable_idx,
 | 
			
		||||
                         lua_CFunction function, const char *name);
 | 
			
		||||
    /**
 | 
			
		||||
     * Add a 6 upvalue metamethod to the metatable.
 | 
			
		||||
     */
 | 
			
		||||
    void SetContainerMethod(lua_State *state, int meta_idx, int ftable_idx,
 | 
			
		||||
                            lua_CFunction function, const char *name,
 | 
			
		||||
                            type_identity *container, type_identity *item, int count);
 | 
			
		||||
    /**
 | 
			
		||||
     * If ienum refers to a valid enum, attach its keys to UPVAL_FIELDTABLE,
 | 
			
		||||
     * and the enum itself to the _enum metafield.
 | 
			
		||||
     */
 | 
			
		||||
    void AttachEnumKeys(lua_State *state, int meta_idx, int ftable_idx, type_identity *ienum);
 | 
			
		||||
}}
 | 
			
		||||
 | 
			
		||||
@ -1,36 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
https://github.com/peterix/dfhack
 | 
			
		||||
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
 | 
			
		||||
 | 
			
		||||
This software is provided 'as-is', without any express or implied
 | 
			
		||||
warranty. In no event will the authors be held liable for any
 | 
			
		||||
damages arising from the use of this software.
 | 
			
		||||
 | 
			
		||||
Permission is granted to anyone to use this software for any
 | 
			
		||||
purpose, including commercial applications, and to alter it and
 | 
			
		||||
redistribute it freely, subject to the following restrictions:
 | 
			
		||||
 | 
			
		||||
1. The origin of this software must not be misrepresented; you must
 | 
			
		||||
not claim that you wrote the original software. If you use this
 | 
			
		||||
software in a product, an acknowledgment in the product documentation
 | 
			
		||||
would be appreciated but is not required.
 | 
			
		||||
 | 
			
		||||
2. Altered source versions must be plainly marked as such, and
 | 
			
		||||
must not be misrepresented as being the original software.
 | 
			
		||||
 | 
			
		||||
3. This notice may not be removed or altered from any source
 | 
			
		||||
distribution.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <string>
 | 
			
		||||
namespace DFHack
 | 
			
		||||
{
 | 
			
		||||
    /// very generic representation of a virtual class... just the pointer to the vtable.
 | 
			
		||||
    /// this is intended for instances where wrapping the classes properly hasn't been done yet.
 | 
			
		||||
    struct t_virtual
 | 
			
		||||
    {
 | 
			
		||||
        void * vptr;
 | 
			
		||||
        std::string getClassName() const;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
Subproject commit 1a6d5acf09ac4c11da62c5ed11a567e480d9fb59
 | 
			
		||||
Subproject commit 55a120d5bc823b783aeb8b6931ccaa31402fd850
 | 
			
		||||
@ -1,42 +0,0 @@
 | 
			
		||||
find_package(Qt4 QUIET)
 | 
			
		||||
find_package(OpenGL QUIET)
 | 
			
		||||
 | 
			
		||||
if(QT4_FOUND AND OPENGL_FOUND AND OPENGL_GLU_FOUND)
 | 
			
		||||
    IF(QT_VERSION_MAJOR MATCHES 4 AND QT_VERSION_MINOR GREATER 6)
 | 
			
		||||
        set( QT_USE_QTGUI TRUE )
 | 
			
		||||
        set( QT_USE_QTOPENGL TRUE )
 | 
			
		||||
        INCLUDE( ${QT_USE_FILE} )
 | 
			
		||||
 | 
			
		||||
        include_directories(${QT_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR} "${dfhack_SOURCE_DIR}/library/depends/tthread")
 | 
			
		||||
 | 
			
		||||
        set ( qtplug_SRCS
 | 
			
		||||
            qtplug.cpp
 | 
			
		||||
            blankslade.cpp
 | 
			
		||||
            glwidget.cpp
 | 
			
		||||
            ${dfhack_SOURCE_DIR}/library/depends/tthread/tinythread.cpp
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        SET ( qtplug_UI
 | 
			
		||||
            gui/main.ui
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        SET( qtplug_RCS
 | 
			
		||||
            gui/resources.qrc
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        # this command will generate rules that will run rcc on all files from blankslade_RCS
 | 
			
		||||
        # in result blankslade_RC_SRCS variable will contain paths to files produced by rcc
 | 
			
		||||
        QT4_ADD_RESOURCES( qtplug_RC_SRCS ${qtplug_RCS} )
 | 
			
		||||
 | 
			
		||||
        QT4_WRAP_UI(qtplug_UI_h ${qtplug_UI})
 | 
			
		||||
        qt4_automoc(${qtplug_SRCS})
 | 
			
		||||
        DFHACK_PLUGIN(qtplug ${qtplug_SRCS} ${qtplug_RC_SRCS} ${qtplug_UI_h})
 | 
			
		||||
        # a small texture file
 | 
			
		||||
        install(FILES terrain.png DESTINATION ${DFHACK_LIBRARY_DESTINATION})
 | 
			
		||||
        target_link_libraries(qtplug ${OPENGL_LIBRARIES} ${QT_LIBRARIES} )
 | 
			
		||||
    ELSE(QT_VERSION_MAJOR MATCHES 4 AND QT_VERSION_MINOR GREATER 6)
 | 
			
		||||
        MESSAGE(STATUS "Can't build the Qt plugin. Your Qt is too old.")
 | 
			
		||||
    ENDIF(QT_VERSION_MAJOR MATCHES 4 AND QT_VERSION_MINOR GREATER 6)
 | 
			
		||||
else(QT4_FOUND AND OPENGL_FOUND AND OPENGL_GLU_FOUND)
 | 
			
		||||
    MESSAGE(STATUS "Required libraries (Qt, GL, GLU) not found - Qt plugin can't be built.")
 | 
			
		||||
endif(QT4_FOUND AND OPENGL_FOUND AND OPENGL_GLU_FOUND)
 | 
			
		||||
@ -1,98 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2010 Petr Mrázek (peterix)
 | 
			
		||||
 * See LICENSE for details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "blankslade.h"
 | 
			
		||||
#include <QFileDialog>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include "glwidget.h"
 | 
			
		||||
 | 
			
		||||
blankslade::blankslade(QWidget *parent): QMainWindow(parent)
 | 
			
		||||
{
 | 
			
		||||
    ui.setupUi(this);
 | 
			
		||||
    GLWidget * glw = new GLWidget();
 | 
			
		||||
    ui.gridding->addWidget(glw);
 | 
			
		||||
    connect(ui.actionOpen,SIGNAL(triggered(bool)),this,SLOT(slotOpen(bool)));
 | 
			
		||||
    connect(ui.actionQuit,SIGNAL(triggered(bool)),this,SLOT(slotQuit(bool)));
 | 
			
		||||
    connect(ui.actionSave,SIGNAL(triggered(bool)),this,SLOT(slotSave(bool)));
 | 
			
		||||
    connect(ui.actionSave_As,SIGNAL(triggered(bool)),this,SLOT(slotSaveAs(bool)));
 | 
			
		||||
    ui.actionOpen->setIcon(QIcon::fromTheme("document-open"));
 | 
			
		||||
    ui.actionOpen->setIconText(tr("Open"));
 | 
			
		||||
    ui.actionSave->setIcon(QIcon::fromTheme("document-save"));
 | 
			
		||||
    ui.actionSave->setIconText(tr("Save"));
 | 
			
		||||
    ui.actionSave_As->setIcon(QIcon::fromTheme("document-save-as"));
 | 
			
		||||
    ui.actionSave_As->setIconText(tr("Save As"));
 | 
			
		||||
    ui.actionQuit->setIcon(QIcon::fromTheme("application-exit"));
 | 
			
		||||
    ui.actionQuit->setIconText(tr("Run DF"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
blankslade::~blankslade()
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
void blankslade::slotOpen(bool )
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
    QFileDialog fd(this,tr("Locate the Memoxy.xml file"));
 | 
			
		||||
    fd.setNameFilter(tr("Memory definition (*.xml)"));
 | 
			
		||||
    fd.setFileMode(QFileDialog::ExistingFile);
 | 
			
		||||
    fd.setAcceptMode(QFileDialog::AcceptOpen);
 | 
			
		||||
    int result = fd.exec();
 | 
			
		||||
    if(result == QDialog::Accepted)
 | 
			
		||||
    {
 | 
			
		||||
        QStringList files = fd.selectedFiles();
 | 
			
		||||
        QString fileName = files[0];
 | 
			
		||||
        QDomDocument doc("memxml");
 | 
			
		||||
        QFile file(fileName);
 | 
			
		||||
        if(!file.open(QIODevice::ReadOnly))
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if(!doc.setContent(&file))
 | 
			
		||||
        {
 | 
			
		||||
            file.close();
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        mod = new MemXMLModel(doc,this);
 | 
			
		||||
        ui.entryView->setModel(mod);
 | 
			
		||||
        file.close();
 | 
			
		||||
    }
 | 
			
		||||
    */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void blankslade::slotQuit(bool )
 | 
			
		||||
{
 | 
			
		||||
    close();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void blankslade::slotSave(bool )
 | 
			
		||||
{
 | 
			
		||||
    // blah
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void blankslade::slotRunDF(bool )
 | 
			
		||||
{
 | 
			
		||||
    // blah
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void blankslade::slotSaveAs(bool )
 | 
			
		||||
{
 | 
			
		||||
    QFileDialog fd(this,tr("Choose file to save as..."));
 | 
			
		||||
    fd.setNameFilter(tr("Memory definition (*.xml)"));
 | 
			
		||||
    fd.setFileMode(QFileDialog::AnyFile);
 | 
			
		||||
    fd.selectFile("Memory.xml");
 | 
			
		||||
    fd.setAcceptMode(QFileDialog::AcceptSave);
 | 
			
		||||
    int result = fd.exec();
 | 
			
		||||
    if(result == QDialog::Accepted)
 | 
			
		||||
    {
 | 
			
		||||
        QStringList files = fd.selectedFiles();
 | 
			
		||||
        QString file = files[0];
 | 
			
		||||
        qDebug() << "File:" << file;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void blankslade::slotSetupDFs(bool )
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#include "blankslade.moc"
 | 
			
		||||
@ -1,29 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2010 Petr Mrázek (peterix)
 | 
			
		||||
 * See LICENSE for details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef blankslade_H
 | 
			
		||||
#define blankslade_H
 | 
			
		||||
 | 
			
		||||
#include <QtGui/QMainWindow>
 | 
			
		||||
#include "ui_main.h"
 | 
			
		||||
 | 
			
		||||
class blankslade : public QMainWindow
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    blankslade(QWidget *parent = 0);
 | 
			
		||||
    virtual ~blankslade();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Ui::MainWindow ui;
 | 
			
		||||
public slots:
 | 
			
		||||
    void slotOpen(bool);
 | 
			
		||||
    void slotQuit(bool);
 | 
			
		||||
    void slotSave(bool);
 | 
			
		||||
    void slotSaveAs(bool);
 | 
			
		||||
    void slotRunDF(bool);
 | 
			
		||||
    void slotSetupDFs(bool);
 | 
			
		||||
};
 | 
			
		||||
#endif // blankslade_H
 | 
			
		||||
@ -1,246 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2010 Petr Mrázek (peterix)
 | 
			
		||||
 * See LICENSE for details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "glwidget.h"
 | 
			
		||||
#include <QtOpenGL>
 | 
			
		||||
#include <QGLBuffer>
 | 
			
		||||
#include <QGLShaderProgram>
 | 
			
		||||
#include <QGLPixelBuffer>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <GL/gl.h>
 | 
			
		||||
 | 
			
		||||
struct Vertex
 | 
			
		||||
{
 | 
			
		||||
    float texcoord[2];
 | 
			
		||||
    float color[3];
 | 
			
		||||
    float position[3];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define FRS 0.0625
 | 
			
		||||
#define FRX FRS/2
 | 
			
		||||
 | 
			
		||||
// this is crap
 | 
			
		||||
const Vertex house_vert[] =
 | 
			
		||||
{
 | 
			
		||||
    // walls
 | 
			
		||||
    { { 0.0, 0.0 }, { 0.0, 0.0, 1.0 }, { -4.0, -4.0, -4.0 } },
 | 
			
		||||
    { { 0.0, FRS }, { 0.0, 1.0, 0.0 }, { -4.0, -4.0,  4.0 } },
 | 
			
		||||
    { { FRS, FRS }, { 0.0, 1.0, 1.0 }, {  4.0, -4.0,  4.0 } },
 | 
			
		||||
    { { FRS, 0.0 }, { 1.0, 0.0, 0.0 }, {  4.0, -4.0, -4.0 } },
 | 
			
		||||
 | 
			
		||||
    { { 0.0, 0.0 }, { 1.0, 0.0, 1.0 }, { -4.0,  4.0, -4.0 } },
 | 
			
		||||
    { { 0.0, FRS }, { 1.0, 1.0, 0.0 }, { -4.0,  4.0,  4.0 } },
 | 
			
		||||
    { { FRS, FRS }, { 1.0, 1.0, 1.0 }, {  4.0,  4.0,  4.0 } },
 | 
			
		||||
    { { FRS, 0.0 }, { 0.0, 0.0, 1.0 }, {  4.0,  4.0, -4.0 } },
 | 
			
		||||
 | 
			
		||||
    { { 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, { -4.0, -4.0, -4.0 } },
 | 
			
		||||
    { { 0.0, FRS }, { 0.0, 1.0, 1.0 }, { -4.0, -4.0,  4.0 } },
 | 
			
		||||
    { { FRS, FRS }, { 1.0, 0.0, 0.0 }, { -4.0,  4.0,  4.0 } },
 | 
			
		||||
    { { FRS, 0.0 }, { 1.0, 0.0, 1.0 }, { -4.0,  4.0, -4.0 } },
 | 
			
		||||
 | 
			
		||||
    { { 0.0, 0.0 }, { 0.0, 1.0, 0.0 }, {  4.0, -4.0, -4.0 } },
 | 
			
		||||
    { { 0.0, FRS }, { 0.0, 1.0, 1.0 }, {  4.0, -4.0,  4.0 } },
 | 
			
		||||
    { { FRS, FRS }, { 1.0, 0.0, 0.0 }, {  4.0,  4.0,  4.0 } },
 | 
			
		||||
    { { FRS, 0.0 }, { 1.0, 0.0, 1.0 }, {  4.0,  4.0, -4.0 } },
 | 
			
		||||
    // roof
 | 
			
		||||
    { { 0.0, 0.0 }, { 0.0, 0.0, 1.0 }, { -4.0,  4.0, -4.0 } },
 | 
			
		||||
    { { FRS, 0.0 }, { 0.0, 1.0, 1.0 }, {  4.0,  4.0, -4.0 } },
 | 
			
		||||
    { { FRX, FRX }, { 1.0, 1.0, 1.0 }, {  0.0,  9.0,  0.0 } }, 
 | 
			
		||||
 | 
			
		||||
    { { FRS, 0.0 }, { 1.0, 0.0, 0.0 }, {  4.0,  4.0, -4.0 } },
 | 
			
		||||
    { { FRS, FRS }, { 1.0, 1.0, 0.0 }, {  4.0,  4.0,  4.0 } },
 | 
			
		||||
    { { FRX, FRX },  { 1.0, 1.0, 1.0 }, {  0.0,  9.0,  0.0 } },
 | 
			
		||||
 | 
			
		||||
    { { FRS, FRS }, { 0.0, 1.0, 0.0 }, {  4.0,  4.0,  4.0 } },
 | 
			
		||||
    { { 0.0, FRS }, { 0.0, 1.0, 1.0 }, { -4.0,  4.0,  4.0 } },
 | 
			
		||||
    { { FRX, FRX },  { 1.0, 1.0, 1.0 }, {  0.0,  9.0,  0.0 } },
 | 
			
		||||
 | 
			
		||||
    { { 0.0, FRS }, { 0.0, 1.0, 0.0 }, { -4.0,  4.0,  4.0 } },
 | 
			
		||||
    { { 0.0, 0.0 }, { 1.0, 1.0, 0.0 }, { -4.0,  4.0, -4.0 } },
 | 
			
		||||
    { { FRX, FRX },  { 1.0, 1.0, 1.0 }, {  0.0,  9.0,  0.0 } }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const unsigned char house_idx[] =
 | 
			
		||||
{
 | 
			
		||||
    // walls
 | 
			
		||||
     0,  1,  2,  0,  2,  3,
 | 
			
		||||
     4,  5,  6,  4,  6,  7,
 | 
			
		||||
     8,  9, 10,  8, 10, 11,
 | 
			
		||||
    12, 13, 14, 12, 14, 15,
 | 
			
		||||
    // roof
 | 
			
		||||
    16, 17, 18,
 | 
			
		||||
    19, 20, 21,
 | 
			
		||||
    22, 23, 24,
 | 
			
		||||
    25, 26, 27
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class GLWPrivate
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    QGLBuffer *VBO;
 | 
			
		||||
    QGLBuffer *EBO;
 | 
			
		||||
    QGLShaderProgram prog;
 | 
			
		||||
    int positionAttrib;
 | 
			
		||||
    int colorAttrib;
 | 
			
		||||
    int texcoordsAttrib;
 | 
			
		||||
    int mvpUniform;
 | 
			
		||||
    int textureUniform;
 | 
			
		||||
    int terrain;
 | 
			
		||||
    float pz,rx,ry;
 | 
			
		||||
    QPoint lastMouse;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GLWidget::GLWidget()
 | 
			
		||||
{
 | 
			
		||||
    d = new GLWPrivate;
 | 
			
		||||
    d->pz = -140.0f;
 | 
			
		||||
    d->rx = d->ry = 0.0f;
 | 
			
		||||
    d->VBO = d->EBO = 0;
 | 
			
		||||
    startTimer( 10 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLWidget::~GLWidget()
 | 
			
		||||
{
 | 
			
		||||
    if(d->VBO) delete d->VBO;
 | 
			
		||||
    if(d->EBO) delete d->EBO;
 | 
			
		||||
    delete d;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char * VS_src =
 | 
			
		||||
"#version 130\n"
 | 
			
		||||
"in vec3 position; in vec3 color; uniform mat4 mvp; out vec3 c;"
 | 
			
		||||
"in vec2 tc_in; out vec2 coord;"
 | 
			
		||||
"void main()"
 | 
			
		||||
"{"
 | 
			
		||||
    "gl_Position = mvp*vec4(position,1);"
 | 
			
		||||
    "c = color;"
 | 
			
		||||
    "coord = tc_in;"
 | 
			
		||||
"}";
 | 
			
		||||
 | 
			
		||||
const char * FS_src =
 | 
			
		||||
"#version 130\n"
 | 
			
		||||
"in vec3 c;"
 | 
			
		||||
//"out vec4 gl_FragColor;"
 | 
			
		||||
"in vec2 coord; uniform sampler2D tex;"
 | 
			
		||||
"void main()"
 | 
			
		||||
"{"
 | 
			
		||||
//    "gl_FragColor = vec4(c,1);"
 | 
			
		||||
//    "gl_FragColor = mix( texture(tex, coord), vec4(c,1), 0.5);"
 | 
			
		||||
//    "gl_FragColor = vec4(c,1) - texture(tex, coord);"
 | 
			
		||||
    "gl_FragColor = vec4(c,1) * texture(tex, coord);"
 | 
			
		||||
"}";
 | 
			
		||||
 | 
			
		||||
//initialization of OpenGL
 | 
			
		||||
void GLWidget::initializeGL()
 | 
			
		||||
{
 | 
			
		||||
    bool test = 1;
 | 
			
		||||
    test &= d->prog.addShaderFromSourceCode(QGLShader::Vertex,VS_src);
 | 
			
		||||
    test &= d->prog.addShaderFromSourceCode(QGLShader::Fragment,FS_src);
 | 
			
		||||
    test &= d->prog.link();
 | 
			
		||||
    if(!test)
 | 
			
		||||
        std::cout << "OUCH!" << std::endl;
 | 
			
		||||
 | 
			
		||||
    d->positionAttrib = d->prog.attributeLocation("position");
 | 
			
		||||
    d->colorAttrib = d->prog.attributeLocation("color");
 | 
			
		||||
    d->texcoordsAttrib = d->prog.attributeLocation("tc_in");
 | 
			
		||||
 | 
			
		||||
    d->mvpUniform = d->prog.uniformLocation("mvp");
 | 
			
		||||
    d->textureUniform = d->prog.uniformLocation("tex");
 | 
			
		||||
 | 
			
		||||
    if(d->positionAttrib == -1 || d->colorAttrib == -1 || d->mvpUniform == -1)
 | 
			
		||||
        std::cout << "Bad attribs!" << std::endl;
 | 
			
		||||
 | 
			
		||||
    QGLBuffer &VBO = *(d->VBO = new QGLBuffer(QGLBuffer::VertexBuffer));
 | 
			
		||||
    VBO.create();
 | 
			
		||||
    VBO.bind();
 | 
			
		||||
    VBO.allocate(sizeof(house_vert));
 | 
			
		||||
    VBO.write(0,house_vert,sizeof(house_vert));
 | 
			
		||||
 | 
			
		||||
    QGLBuffer &EBO = *(d->EBO = new QGLBuffer(QGLBuffer::IndexBuffer));
 | 
			
		||||
    EBO.create();
 | 
			
		||||
    EBO.bind();
 | 
			
		||||
    EBO.allocate(sizeof(house_idx));
 | 
			
		||||
    EBO.write(0,house_idx,sizeof(house_idx));
 | 
			
		||||
 | 
			
		||||
    QImage texture;
 | 
			
		||||
    texture.load("terrain.png");
 | 
			
		||||
    d->terrain = bindTexture(texture);
 | 
			
		||||
 | 
			
		||||
    glClearColor(0.0f, 0.0f, 0.0f, 0.f);
 | 
			
		||||
 | 
			
		||||
    glShadeModel( GL_SMOOTH );
 | 
			
		||||
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
 | 
			
		||||
    glEnable( GL_TEXTURE_2D );
 | 
			
		||||
    glEnable( GL_DEPTH_TEST );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLWidget::paintGL()
 | 
			
		||||
{
 | 
			
		||||
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 | 
			
		||||
    d->prog.bind();
 | 
			
		||||
 | 
			
		||||
    QMatrix4x4 projection;
 | 
			
		||||
    QMatrix4x4 mvp;
 | 
			
		||||
 | 
			
		||||
    //projection.ortho(-10,10,-10,10,1,1000);
 | 
			
		||||
    float aspect = (float)width()/(float)height();
 | 
			
		||||
    projection.perspective(10,aspect,1,1000);
 | 
			
		||||
    mvp = projection;
 | 
			
		||||
 | 
			
		||||
    mvp.translate(0,0,d->pz);
 | 
			
		||||
    mvp.rotate(d->ry,1,0,0);
 | 
			
		||||
    mvp.rotate(d->rx,0,1,0);
 | 
			
		||||
    d->prog.setUniformValue(d->mvpUniform,mvp);
 | 
			
		||||
 | 
			
		||||
    //glActiveTexture(GL_TEXTURE0);
 | 
			
		||||
    glBindTexture(GL_TEXTURE_2D, d->terrain);
 | 
			
		||||
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 | 
			
		||||
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 | 
			
		||||
    d->prog.setUniformValue(d->textureUniform,0);
 | 
			
		||||
 | 
			
		||||
    d->prog.enableAttributeArray(d->positionAttrib);
 | 
			
		||||
    d->prog.enableAttributeArray(d->colorAttrib);
 | 
			
		||||
    d->prog.enableAttributeArray(d->texcoordsAttrib);
 | 
			
		||||
 | 
			
		||||
    d->VBO->bind();
 | 
			
		||||
 | 
			
		||||
    d->prog.setAttributeBuffer(d->texcoordsAttrib, GL_FLOAT, offsetof(Vertex, texcoord), 2, sizeof(Vertex));
 | 
			
		||||
    d->prog.setAttributeBuffer(d->positionAttrib, GL_FLOAT, offsetof(Vertex, position), 3, sizeof(Vertex));
 | 
			
		||||
    d->prog.setAttributeBuffer(d->colorAttrib, GL_FLOAT, offsetof(Vertex, color), 3, sizeof(Vertex));
 | 
			
		||||
 | 
			
		||||
    d->EBO->bind();
 | 
			
		||||
 | 
			
		||||
    glDrawElements(GL_TRIANGLES, d->EBO->size(), GL_UNSIGNED_BYTE, NULL);
 | 
			
		||||
 | 
			
		||||
    d->prog.release();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLWidget::resizeGL(int width, int height)
 | 
			
		||||
{
 | 
			
		||||
    glViewport(0, 0, width, height);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLWidget::mousePressEvent(QMouseEvent *event)
 | 
			
		||||
{
 | 
			
		||||
    d->lastMouse = event->pos();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLWidget::mouseMoveEvent(QMouseEvent *event)
 | 
			
		||||
{
 | 
			
		||||
    int dx = event->x() - d->lastMouse.x();
 | 
			
		||||
    int dy = event->y() - d->lastMouse.y();
 | 
			
		||||
 | 
			
		||||
    if (event->buttons() & Qt::LeftButton)
 | 
			
		||||
    {
 | 
			
		||||
        d->rx = d->rx + dx;
 | 
			
		||||
        d->ry = d->ry + dy;
 | 
			
		||||
    }
 | 
			
		||||
    d->lastMouse = event->pos();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GLWidget::timerEvent(QTimerEvent *event)
 | 
			
		||||
{
 | 
			
		||||
    updateGL();
 | 
			
		||||
}
 | 
			
		||||
@ -1,32 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2010 Petr Mrázek (peterix)
 | 
			
		||||
 * See LICENSE for details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef GLWIDGET_H
 | 
			
		||||
#define GLWIDGET_H
 | 
			
		||||
 | 
			
		||||
#include <QGLWidget>
 | 
			
		||||
 | 
			
		||||
class GLWPrivate;
 | 
			
		||||
class GLWidget : public QGLWidget
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    GLWidget();
 | 
			
		||||
    ~GLWidget();
 | 
			
		||||
 | 
			
		||||
    float rot;
 | 
			
		||||
    void resizeGL(int width, int height);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    void initializeGL();
 | 
			
		||||
    void paintGL();
 | 
			
		||||
    void mousePressEvent(QMouseEvent *event);
 | 
			
		||||
    void mouseMoveEvent(QMouseEvent *event);
 | 
			
		||||
    void timerEvent(QTimerEvent *event);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    GLWPrivate * d;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // GLWIDGET_H
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 14 KiB  | 
| 
		 Before Width: | Height: | Size: 12 KiB  | 
| 
		 Before Width: | Height: | Size: 19 KiB  | 
| 
		 Before Width: | Height: | Size: 6.2 KiB  | 
@ -1,361 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<ui version="4.0">
 | 
			
		||||
 <class>MainWindow</class>
 | 
			
		||||
 <widget class="QMainWindow" name="MainWindow">
 | 
			
		||||
  <property name="geometry">
 | 
			
		||||
   <rect>
 | 
			
		||||
    <x>0</x>
 | 
			
		||||
    <y>0</y>
 | 
			
		||||
    <width>662</width>
 | 
			
		||||
    <height>836</height>
 | 
			
		||||
   </rect>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="minimumSize">
 | 
			
		||||
   <size>
 | 
			
		||||
    <width>0</width>
 | 
			
		||||
    <height>0</height>
 | 
			
		||||
   </size>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowTitle">
 | 
			
		||||
   <string>MainWindow</string>
 | 
			
		||||
  </property>
 | 
			
		||||
  <property name="windowIcon">
 | 
			
		||||
   <iconset resource="resources.qrc">
 | 
			
		||||
    <normaloff>:/main_icon/main_64.png</normaloff>:/main_icon/main_64.png</iconset>
 | 
			
		||||
  </property>
 | 
			
		||||
  <widget class="QWidget" name="centralwidget">
 | 
			
		||||
   <layout class="QGridLayout" name="gridding">
 | 
			
		||||
    <property name="margin">
 | 
			
		||||
     <number>0</number>
 | 
			
		||||
    </property>
 | 
			
		||||
    <property name="spacing">
 | 
			
		||||
     <number>0</number>
 | 
			
		||||
    </property>
 | 
			
		||||
   </layout>
 | 
			
		||||
  </widget>
 | 
			
		||||
  <widget class="QStatusBar" name="statusbar"/>
 | 
			
		||||
  <widget class="QDockWidget" name="scene_dock">
 | 
			
		||||
   <property name="features">
 | 
			
		||||
    <set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="allowedAreas">
 | 
			
		||||
    <set>Qt::RightDockWidgetArea</set>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="windowTitle">
 | 
			
		||||
    <string>Scéna</string>
 | 
			
		||||
   </property>
 | 
			
		||||
   <attribute name="dockWidgetArea">
 | 
			
		||||
    <number>2</number>
 | 
			
		||||
   </attribute>
 | 
			
		||||
   <widget class="QWidget" name="dockWidgetContents_2">
 | 
			
		||||
    <layout class="QVBoxLayout" name="verticalLayout_2">
 | 
			
		||||
     <item>
 | 
			
		||||
      <layout class="QVBoxLayout" name="verticalLayout">
 | 
			
		||||
       <item>
 | 
			
		||||
        <layout class="QGridLayout" name="gridLayout_2">
 | 
			
		||||
         <item row="0" column="0">
 | 
			
		||||
          <widget class="QLabel" name="label_3">
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string>Exponent n</string>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item row="1" column="0">
 | 
			
		||||
          <widget class="QSlider" name="slideExponentN">
 | 
			
		||||
           <property name="orientation">
 | 
			
		||||
            <enum>Qt::Horizontal</enum>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item row="1" column="1">
 | 
			
		||||
          <widget class="QDoubleSpinBox" name="spinExponentN"/>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item row="2" column="0">
 | 
			
		||||
          <widget class="QLabel" name="label_4">
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string>Exponent e</string>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item row="3" column="0">
 | 
			
		||||
          <widget class="QSlider" name="slideExponentE">
 | 
			
		||||
           <property name="orientation">
 | 
			
		||||
            <enum>Qt::Horizontal</enum>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item row="3" column="1">
 | 
			
		||||
          <widget class="QDoubleSpinBox" name="spinExponentE"/>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <layout class="QGridLayout" name="gridLayout_3">
 | 
			
		||||
         <item row="1" column="0">
 | 
			
		||||
          <widget class="QDial" name="dialLight"/>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item row="0" column="0">
 | 
			
		||||
          <widget class="QLabel" name="label_5">
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string>Světlo</string>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="alignment">
 | 
			
		||||
            <set>Qt::AlignCenter</set>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item row="0" column="1">
 | 
			
		||||
          <widget class="QLabel" name="label_6">
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string>Objekt</string>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="alignment">
 | 
			
		||||
            <set>Qt::AlignCenter</set>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
         <item row="1" column="1">
 | 
			
		||||
          <widget class="QDial" name="dial_2"/>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <widget class="QLabel" name="label_7">
 | 
			
		||||
         <property name="text">
 | 
			
		||||
          <string>Textura</string>
 | 
			
		||||
         </property>
 | 
			
		||||
         <property name="alignment">
 | 
			
		||||
          <set>Qt::AlignCenter</set>
 | 
			
		||||
         </property>
 | 
			
		||||
        </widget>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <layout class="QHBoxLayout" name="horizontalLayout">
 | 
			
		||||
         <item>
 | 
			
		||||
          <widget class="QPushButton" name="pushButton">
 | 
			
		||||
           <property name="sizePolicy">
 | 
			
		||||
            <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
 | 
			
		||||
             <horstretch>1</horstretch>
 | 
			
		||||
             <verstretch>1</verstretch>
 | 
			
		||||
            </sizepolicy>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="minimumSize">
 | 
			
		||||
            <size>
 | 
			
		||||
             <width>96</width>
 | 
			
		||||
             <height>96</height>
 | 
			
		||||
            </size>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="baseSize">
 | 
			
		||||
            <size>
 | 
			
		||||
             <width>0</width>
 | 
			
		||||
             <height>0</height>
 | 
			
		||||
            </size>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="text">
 | 
			
		||||
            <string/>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="icon">
 | 
			
		||||
            <iconset resource="resources.qrc">
 | 
			
		||||
             <normaloff>:/blah/tileable.jpg</normaloff>:/blah/tileable.jpg</iconset>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="iconSize">
 | 
			
		||||
            <size>
 | 
			
		||||
             <width>80</width>
 | 
			
		||||
             <height>80</height>
 | 
			
		||||
            </size>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="default">
 | 
			
		||||
            <bool>false</bool>
 | 
			
		||||
           </property>
 | 
			
		||||
           <property name="flat">
 | 
			
		||||
            <bool>false</bool>
 | 
			
		||||
           </property>
 | 
			
		||||
          </widget>
 | 
			
		||||
         </item>
 | 
			
		||||
        </layout>
 | 
			
		||||
       </item>
 | 
			
		||||
      </layout>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QPushButton" name="pushButton_2">
 | 
			
		||||
       <property name="text">
 | 
			
		||||
        <string>Render</string>
 | 
			
		||||
       </property>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
     <item>
 | 
			
		||||
      <spacer name="verticalSpacer">
 | 
			
		||||
       <property name="orientation">
 | 
			
		||||
        <enum>Qt::Vertical</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="sizeHint" stdset="0">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>20</width>
 | 
			
		||||
         <height>40</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
      </spacer>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
    <zorder>pushButton_2</zorder>
 | 
			
		||||
    <zorder>verticalLayoutWidget</zorder>
 | 
			
		||||
    <zorder>pushButton</zorder>
 | 
			
		||||
    <zorder>gridLayoutWidget</zorder>
 | 
			
		||||
   </widget>
 | 
			
		||||
  </widget>
 | 
			
		||||
  <widget class="QDockWidget" name="dock_example">
 | 
			
		||||
   <property name="sizePolicy">
 | 
			
		||||
    <sizepolicy hsizetype="Minimum" vsizetype="Minimum">
 | 
			
		||||
     <horstretch>0</horstretch>
 | 
			
		||||
     <verstretch>0</verstretch>
 | 
			
		||||
    </sizepolicy>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="features">
 | 
			
		||||
    <set>QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable</set>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="allowedAreas">
 | 
			
		||||
    <set>Qt::BottomDockWidgetArea|Qt::LeftDockWidgetArea|Qt::TopDockWidgetArea</set>
 | 
			
		||||
   </property>
 | 
			
		||||
   <property name="windowTitle">
 | 
			
		||||
    <string>Ukázky</string>
 | 
			
		||||
   </property>
 | 
			
		||||
   <attribute name="dockWidgetArea">
 | 
			
		||||
    <number>1</number>
 | 
			
		||||
   </attribute>
 | 
			
		||||
   <widget class="QWidget" name="dockWidgetContents_3">
 | 
			
		||||
    <layout class="QVBoxLayout" name="verticalLayout_3">
 | 
			
		||||
     <item>
 | 
			
		||||
      <widget class="QListWidget" name="listWidget">
 | 
			
		||||
       <property name="sizePolicy">
 | 
			
		||||
        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
 | 
			
		||||
         <horstretch>0</horstretch>
 | 
			
		||||
         <verstretch>0</verstretch>
 | 
			
		||||
        </sizepolicy>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="frameShape">
 | 
			
		||||
        <enum>QFrame::StyledPanel</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="frameShadow">
 | 
			
		||||
        <enum>QFrame::Sunken</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="lineWidth">
 | 
			
		||||
        <number>1</number>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="selectionBehavior">
 | 
			
		||||
        <enum>QAbstractItemView::SelectItems</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="iconSize">
 | 
			
		||||
        <size>
 | 
			
		||||
         <width>32</width>
 | 
			
		||||
         <height>32</height>
 | 
			
		||||
        </size>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="movement">
 | 
			
		||||
        <enum>QListView::Static</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="flow">
 | 
			
		||||
        <enum>QListView::TopToBottom</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="isWrapping" stdset="0">
 | 
			
		||||
        <bool>true</bool>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="resizeMode">
 | 
			
		||||
        <enum>QListView::Adjust</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="layoutMode">
 | 
			
		||||
        <enum>QListView::SinglePass</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="spacing">
 | 
			
		||||
        <number>10</number>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="viewMode">
 | 
			
		||||
        <enum>QListView::ListMode</enum>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="uniformItemSizes">
 | 
			
		||||
        <bool>true</bool>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="wordWrap">
 | 
			
		||||
        <bool>false</bool>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="selectionRectVisible">
 | 
			
		||||
        <bool>false</bool>
 | 
			
		||||
       </property>
 | 
			
		||||
       <property name="sortingEnabled">
 | 
			
		||||
        <bool>false</bool>
 | 
			
		||||
       </property>
 | 
			
		||||
       <item>
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>Koule</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="icon">
 | 
			
		||||
         <iconset resource="resources.qrc">
 | 
			
		||||
          <normaloff>:/blah/koule.png</normaloff>:/blah/koule.png</iconset>
 | 
			
		||||
        </property>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>Krychle</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="icon">
 | 
			
		||||
         <iconset resource="resources.qrc">
 | 
			
		||||
          <normaloff>:/blah/krychle.png</normaloff>:/blah/krychle.png</iconset>
 | 
			
		||||
        </property>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>Válec</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="icon">
 | 
			
		||||
         <iconset resource="resources.qrc">
 | 
			
		||||
          <normaloff>:/blah/valec.png</normaloff>:/blah/valec.png</iconset>
 | 
			
		||||
        </property>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>Diamant</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="icon">
 | 
			
		||||
         <iconset resource="resources.qrc">
 | 
			
		||||
          <normaloff>:/blah/diamant.png</normaloff>:/blah/diamant.png</iconset>
 | 
			
		||||
        </property>
 | 
			
		||||
       </item>
 | 
			
		||||
       <item>
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>a=3,b=3</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="icon">
 | 
			
		||||
         <iconset resource="resources.qrc">
 | 
			
		||||
          <normaloff>:/blah/33.png</normaloff>:/blah/33.png</iconset>
 | 
			
		||||
        </property>
 | 
			
		||||
       </item>
 | 
			
		||||
      </widget>
 | 
			
		||||
     </item>
 | 
			
		||||
    </layout>
 | 
			
		||||
   </widget>
 | 
			
		||||
  </widget>
 | 
			
		||||
  <action name="actionOpen">
 | 
			
		||||
   <property name="text">
 | 
			
		||||
    <string>Open</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
  <action name="actionSave">
 | 
			
		||||
   <property name="text">
 | 
			
		||||
    <string>Save</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
  <action name="actionSave_As">
 | 
			
		||||
   <property name="text">
 | 
			
		||||
    <string>Save As</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
  <action name="actionQuit">
 | 
			
		||||
   <property name="text">
 | 
			
		||||
    <string>Quit</string>
 | 
			
		||||
   </property>
 | 
			
		||||
  </action>
 | 
			
		||||
 </widget>
 | 
			
		||||
 <resources>
 | 
			
		||||
  <include location="resources.qrc"/>
 | 
			
		||||
 </resources>
 | 
			
		||||
 <connections/>
 | 
			
		||||
</ui>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 616 B  | 
| 
		 Before Width: | Height: | Size: 1.3 KiB  | 
| 
		 Before Width: | Height: | Size: 2.8 KiB  | 
@ -1,15 +0,0 @@
 | 
			
		||||
<RCC>
 | 
			
		||||
  <qresource prefix="main_icon">
 | 
			
		||||
    <file>main_64.png</file>
 | 
			
		||||
    <file>main_16.png</file>
 | 
			
		||||
    <file>main_32.png</file>
 | 
			
		||||
  </qresource>
 | 
			
		||||
  <qresource prefix="blah">
 | 
			
		||||
    <file>tileable.jpg</file>
 | 
			
		||||
    <file>33.png</file>
 | 
			
		||||
    <file>diamant.png</file>
 | 
			
		||||
    <file>koule.png</file>
 | 
			
		||||
    <file>krychle.png</file>
 | 
			
		||||
    <file>valec.png</file>
 | 
			
		||||
  </qresource>
 | 
			
		||||
</RCC>
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 308 KiB  | 
| 
		 Before Width: | Height: | Size: 18 KiB  | 
@ -1,69 +0,0 @@
 | 
			
		||||
#include "Core.h"
 | 
			
		||||
#include <Console.h>
 | 
			
		||||
#include <Export.h>
 | 
			
		||||
#include <PluginManager.h>
 | 
			
		||||
#include <modules/Maps.h>
 | 
			
		||||
#include <modules/Gui.h>
 | 
			
		||||
//#include <extra/MapExtras.h>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <cstdio>
 | 
			
		||||
#include <stack>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include <QtGui/QApplication>
 | 
			
		||||
#include "blankslade.h"
 | 
			
		||||
#include "tinythread.h"
 | 
			
		||||
 | 
			
		||||
using std::vector;
 | 
			
		||||
using std::string;
 | 
			
		||||
using std::stack;
 | 
			
		||||
using namespace DFHack;
 | 
			
		||||
static void runnable(void *);
 | 
			
		||||
static tthread::mutex * instance_mutex = 0;
 | 
			
		||||
static bool running = false;
 | 
			
		||||
static tthread::thread * QTThread;
 | 
			
		||||
 | 
			
		||||
command_result runqt (Core * c, vector <string> & parameters);
 | 
			
		||||
 | 
			
		||||
DFHACK_PLUGIN("qtplug");
 | 
			
		||||
 | 
			
		||||
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
 | 
			
		||||
{
 | 
			
		||||
    instance_mutex = new tthread::mutex();
 | 
			
		||||
    commands.clear();
 | 
			
		||||
    commands.push_back(PluginCommand("runqt","Open an interactive Qt gui.",runqt));
 | 
			
		||||
    return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DFhackCExport command_result plugin_shutdown ( Core * c )
 | 
			
		||||
{
 | 
			
		||||
    return CR_FAILURE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
command_result runqt (Core * c, vector <string> & parameters)
 | 
			
		||||
{
 | 
			
		||||
    instance_mutex->lock();
 | 
			
		||||
    if(!running)
 | 
			
		||||
    {
 | 
			
		||||
        running = true;
 | 
			
		||||
        QTThread = new tthread::thread(runnable, 0);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        c->con.printerr("The Qt test plugin is already running!\n");
 | 
			
		||||
    }
 | 
			
		||||
    instance_mutex->unlock();
 | 
			
		||||
    return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void runnable(void *)
 | 
			
		||||
{
 | 
			
		||||
    int zero = 0;
 | 
			
		||||
    QApplication app(zero, 0);
 | 
			
		||||
    blankslade appGui;
 | 
			
		||||
    appGui.show();
 | 
			
		||||
    app.exec();
 | 
			
		||||
    instance_mutex->lock();
 | 
			
		||||
    running = false;
 | 
			
		||||
    instance_mutex->unlock();
 | 
			
		||||
}
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 59 KiB  | 
@ -1,42 +0,0 @@
 | 
			
		||||
PROJECT (server)
 | 
			
		||||
SET(PROJECT_SRCS
 | 
			
		||||
    main.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
include_directories( ${CMAKE_SOURCE_DIR} )
 | 
			
		||||
IF(UNIX)
 | 
			
		||||
    OPTION(SERVER_INTERNAL_SO "Link with prebuilt internal zeromq lib and headers." ON)
 | 
			
		||||
    IF(SERVER_INTERNAL_SO)
 | 
			
		||||
        SET(PROJECT_LIBS
 | 
			
		||||
            ${server_SOURCE_DIR}/zeromq/libzmq.so.1
 | 
			
		||||
            ${PROJECT_LIBS}
 | 
			
		||||
        )
 | 
			
		||||
        include_directories (
 | 
			
		||||
            ${include_directories}
 | 
			
		||||
            ${server_SOURCE_DIR}/zeromq
 | 
			
		||||
        )
 | 
			
		||||
        install(PROGRAMS ${server_SOURCE_DIR}/zeromq/libzmq.so.1 DESTINATION ${DFHACK_LIBRARY_DESTINATION})
 | 
			
		||||
    ELSE()
 | 
			
		||||
        SET(PROJECT_LIBS
 | 
			
		||||
            zmq
 | 
			
		||||
            ${PROJECT_LIBS}
 | 
			
		||||
        )
 | 
			
		||||
    ENDIF()
 | 
			
		||||
ELSE()
 | 
			
		||||
        SET(PROJECT_LIBS
 | 
			
		||||
            ${server_SOURCE_DIR}/zeromq/libzmq.lib
 | 
			
		||||
            ${PROJECT_LIBS}
 | 
			
		||||
        )
 | 
			
		||||
        include_directories (
 | 
			
		||||
            ${include_directories}
 | 
			
		||||
            ${server_SOURCE_DIR}/zeromq
 | 
			
		||||
        )
 | 
			
		||||
        install(PROGRAMS ${server_SOURCE_DIR}/zeromq/libzmq.dll DESTINATION ${DFHACK_LIBRARY_DESTINATION})
 | 
			
		||||
 | 
			
		||||
ENDIF()
 | 
			
		||||
 | 
			
		||||
DFHACK_PLUGIN(server ${PROJECT_SRCS} LINK_LIBRARIES ${PROJECT_LIBS})
 | 
			
		||||
 | 
			
		||||
add_executable ( helloclient hello.cpp )
 | 
			
		||||
target_link_libraries ( helloclient ${PROJECT_LIBS})
 | 
			
		||||
install(TARGETS helloclient RUNTIME DESTINATION . )
 | 
			
		||||
@ -1,39 +0,0 @@
 | 
			
		||||
//
 | 
			
		||||
// Hello World client
 | 
			
		||||
// Connects REQ socket to tcp://localhost:5555
 | 
			
		||||
// Sends "Hello" to server, expects "World" back
 | 
			
		||||
//
 | 
			
		||||
#include <zmq.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
//#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
int main (void)
 | 
			
		||||
{
 | 
			
		||||
    void *context = zmq_init (1);
 | 
			
		||||
 | 
			
		||||
    // Socket to talk to server
 | 
			
		||||
    printf ("Connecting to hello world server...\n");
 | 
			
		||||
    void *requester = zmq_socket (context, ZMQ_REQ);
 | 
			
		||||
    zmq_connect (requester, "tcp://localhost:5555");
 | 
			
		||||
 | 
			
		||||
    int request_nbr;
 | 
			
		||||
    for (request_nbr = 0; request_nbr != 10; request_nbr++)
 | 
			
		||||
    {
 | 
			
		||||
        zmq_msg_t request;
 | 
			
		||||
        zmq_msg_init_size (&request, 5);
 | 
			
		||||
        memcpy (zmq_msg_data (&request), "Hello", 5);
 | 
			
		||||
        printf ("Sending Hello %d...\n", request_nbr);
 | 
			
		||||
        zmq_send (requester, &request, 0);
 | 
			
		||||
        zmq_msg_close (&request);
 | 
			
		||||
 | 
			
		||||
        zmq_msg_t reply;
 | 
			
		||||
        zmq_msg_init (&reply);
 | 
			
		||||
        zmq_recv (requester, &reply, 0);
 | 
			
		||||
        printf ("Received World %d\n", request_nbr);
 | 
			
		||||
        zmq_msg_close (&reply);
 | 
			
		||||
    }
 | 
			
		||||
    zmq_close (requester);
 | 
			
		||||
    zmq_term (context);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@ -1,79 +0,0 @@
 | 
			
		||||
#include "Core.h"
 | 
			
		||||
#include <Console.h>
 | 
			
		||||
#include <Export.h>
 | 
			
		||||
#include <PluginManager.h>
 | 
			
		||||
#include <zmq.hpp>
 | 
			
		||||
#ifndef LINUX_BUILD
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
using namespace DFHack;
 | 
			
		||||
 | 
			
		||||
// Here go all the command declarations...
 | 
			
		||||
// mostly to allow having the mandatory stuff on top of the file and commands on the bottom
 | 
			
		||||
command_result server (color_ostream &out, std::vector <std::string> & parameters);
 | 
			
		||||
 | 
			
		||||
// A plugins must be able to return its name. This must correspond to the filename - skeleton.plug.so or skeleton.plug.dll
 | 
			
		||||
DFHACK_PLUGIN("server");
 | 
			
		||||
 | 
			
		||||
// Mandatory init function. If you have some global state, create it here.
 | 
			
		||||
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
 | 
			
		||||
{
 | 
			
		||||
    // Fill the command list with your commands.
 | 
			
		||||
    commands.clear();
 | 
			
		||||
    commands.push_back(PluginCommand("server",
 | 
			
		||||
                                     "Inane zeromq example turned into a plugin.",
 | 
			
		||||
                                     server));
 | 
			
		||||
    return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This is called right before the plugin library is removed from memory.
 | 
			
		||||
DFhackCExport command_result plugin_shutdown ( color_ostream &out )
 | 
			
		||||
{
 | 
			
		||||
    // You *MUST* kill all threads you created before this returns.
 | 
			
		||||
    // If everythin fails, just return CR_FAILURE. Your plugin will be
 | 
			
		||||
    // in a zombie state, but things won't crash.
 | 
			
		||||
    return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This is WRONG and STUPID. Never use this as an example!
 | 
			
		||||
command_result server (color_ostream &out, std::vector <std::string> & parameters)
 | 
			
		||||
{
 | 
			
		||||
    // It's nice to provide a 'help' option for your command.
 | 
			
		||||
    // It's also nice to print the same help if you get invalid options from the user instead of just acting strange
 | 
			
		||||
    for(int i = 0; i < parameters.size();i++)
 | 
			
		||||
    {
 | 
			
		||||
        if(parameters[i] == "help" || parameters[i] == "?")
 | 
			
		||||
        {
 | 
			
		||||
            // Core has a handle to the console. The console is thread-safe.
 | 
			
		||||
            // Only one thing can read from it at a time though...
 | 
			
		||||
            out.print("This command is a simple Hello World example for zeromq!\n");
 | 
			
		||||
            return CR_OK;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // Prepare our context and socket
 | 
			
		||||
    zmq::context_t context (1);
 | 
			
		||||
    zmq::socket_t socket (context, ZMQ_REP);
 | 
			
		||||
    socket.bind ("tcp://*:5555");
 | 
			
		||||
 | 
			
		||||
    while (true)
 | 
			
		||||
    {
 | 
			
		||||
        zmq::message_t request;
 | 
			
		||||
 | 
			
		||||
        // Wait for next request from client
 | 
			
		||||
        socket.recv (&request);
 | 
			
		||||
        out.print("Received Hello\n");
 | 
			
		||||
 | 
			
		||||
        // Do some 'work'
 | 
			
		||||
#ifdef LINUX_BUILD
 | 
			
		||||
        sleep (1);
 | 
			
		||||
#else
 | 
			
		||||
		Sleep(1000);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        // Send reply back to client
 | 
			
		||||
        zmq::message_t reply (5);
 | 
			
		||||
        memcpy ((void *) reply.data (), "World", 5);
 | 
			
		||||
        socket.send (reply);
 | 
			
		||||
    }
 | 
			
		||||
    return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
@ -1,41 +0,0 @@
 | 
			
		||||
# libzmq.la - a libtool library file
 | 
			
		||||
# Generated by ltmain.sh (GNU libtool) 2.2.6b Debian-2.2.6b-2ubuntu1
 | 
			
		||||
#
 | 
			
		||||
# Please DO NOT delete this file!
 | 
			
		||||
# It is necessary for linking the library.
 | 
			
		||||
 | 
			
		||||
# The name that we can dlopen(3).
 | 
			
		||||
dlname='libzmq.so.1'
 | 
			
		||||
 | 
			
		||||
# Names of this library.
 | 
			
		||||
library_names='libzmq.so.1.0.0 libzmq.so.1 libzmq.so'
 | 
			
		||||
 | 
			
		||||
# The name of the static archive.
 | 
			
		||||
old_library='libzmq.a'
 | 
			
		||||
 | 
			
		||||
# Linker flags that can not go in dependency_libs.
 | 
			
		||||
inherited_linker_flags=''
 | 
			
		||||
 | 
			
		||||
# Libraries that this one depends upon.
 | 
			
		||||
dependency_libs=' -luuid -lrt -lpthread'
 | 
			
		||||
 | 
			
		||||
# Names of additional weak libraries provided by this library
 | 
			
		||||
weak_library_names=''
 | 
			
		||||
 | 
			
		||||
# Version information for libzmq.
 | 
			
		||||
current=1
 | 
			
		||||
age=0
 | 
			
		||||
revision=0
 | 
			
		||||
 | 
			
		||||
# Is this an already installed library?
 | 
			
		||||
installed=yes
 | 
			
		||||
 | 
			
		||||
# Should we warn about portability when linking against -modules?
 | 
			
		||||
shouldnotlink=no
 | 
			
		||||
 | 
			
		||||
# Files to dlopen/dlpreopen
 | 
			
		||||
dlopen=''
 | 
			
		||||
dlpreopen=''
 | 
			
		||||
 | 
			
		||||
# Directory that this library needs to be installed in:
 | 
			
		||||
libdir='/home/peterix/zeromq/lib'
 | 
			
		||||
@ -1,269 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
    Copyright (c) 2007-2011 iMatix Corporation
 | 
			
		||||
    Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
 | 
			
		||||
 | 
			
		||||
    This file is part of 0MQ.
 | 
			
		||||
 | 
			
		||||
    0MQ is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
    the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    0MQ 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 program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __ZMQ_H_INCLUDED__
 | 
			
		||||
#define __ZMQ_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#if defined _WIN32
 | 
			
		||||
#include <winsock2.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*  Handle DSO symbol visibility                                             */
 | 
			
		||||
#if defined _WIN32
 | 
			
		||||
#   if defined DLL_EXPORT
 | 
			
		||||
#       define ZMQ_EXPORT __declspec(dllexport)
 | 
			
		||||
#   else
 | 
			
		||||
#       define ZMQ_EXPORT __declspec(dllimport)
 | 
			
		||||
#   endif
 | 
			
		||||
#else
 | 
			
		||||
#   if defined __SUNPRO_C  || defined __SUNPRO_CC
 | 
			
		||||
#       define ZMQ_EXPORT __global
 | 
			
		||||
#   elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER
 | 
			
		||||
#       define ZMQ_EXPORT __attribute__ ((visibility("default")))
 | 
			
		||||
#   else
 | 
			
		||||
#       define ZMQ_EXPORT
 | 
			
		||||
#   endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
/*  0MQ versioning support.                                                   */
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
 | 
			
		||||
/*  Version macros for compile-time API version detection                     */
 | 
			
		||||
#define ZMQ_VERSION_MAJOR 2
 | 
			
		||||
#define ZMQ_VERSION_MINOR 1
 | 
			
		||||
#define ZMQ_VERSION_PATCH 10
 | 
			
		||||
 | 
			
		||||
#define ZMQ_MAKE_VERSION(major, minor, patch) \
 | 
			
		||||
    ((major) * 10000 + (minor) * 100 + (patch))
 | 
			
		||||
#define ZMQ_VERSION \
 | 
			
		||||
    ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH)
 | 
			
		||||
 | 
			
		||||
/*  Run-time API version detection                                            */
 | 
			
		||||
ZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
/*  0MQ errors.                                                               */
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
 | 
			
		||||
/*  A number random enough not to collide with different errno ranges on      */
 | 
			
		||||
/*  different OSes. The assumption is that error_t is at least 32-bit type.   */
 | 
			
		||||
#define ZMQ_HAUSNUMERO 156384712
 | 
			
		||||
 | 
			
		||||
/*  On Windows platform some of the standard POSIX errnos are not defined.    */
 | 
			
		||||
#ifndef ENOTSUP
 | 
			
		||||
#define ENOTSUP (ZMQ_HAUSNUMERO + 1)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EPROTONOSUPPORT
 | 
			
		||||
#define EPROTONOSUPPORT (ZMQ_HAUSNUMERO + 2)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENOBUFS
 | 
			
		||||
#define ENOBUFS (ZMQ_HAUSNUMERO + 3)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENETDOWN
 | 
			
		||||
#define ENETDOWN (ZMQ_HAUSNUMERO + 4)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EADDRINUSE
 | 
			
		||||
#define EADDRINUSE (ZMQ_HAUSNUMERO + 5)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EADDRNOTAVAIL
 | 
			
		||||
#define EADDRNOTAVAIL (ZMQ_HAUSNUMERO + 6)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ECONNREFUSED
 | 
			
		||||
#define ECONNREFUSED (ZMQ_HAUSNUMERO + 7)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef EINPROGRESS
 | 
			
		||||
#define EINPROGRESS (ZMQ_HAUSNUMERO + 8)
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef ENOTSOCK
 | 
			
		||||
#define ENOTSOCK (ZMQ_HAUSNUMERO + 9)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*  Native 0MQ error codes.                                                   */
 | 
			
		||||
#define EFSM (ZMQ_HAUSNUMERO + 51)
 | 
			
		||||
#define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52)
 | 
			
		||||
#define ETERM (ZMQ_HAUSNUMERO + 53)
 | 
			
		||||
#define EMTHREAD (ZMQ_HAUSNUMERO + 54)
 | 
			
		||||
 | 
			
		||||
/*  This function retrieves the errno as it is known to 0MQ library. The goal */
 | 
			
		||||
/*  of this function is to make the code 100% portable, including where 0MQ   */
 | 
			
		||||
/*  compiled with certain CRT library (on Windows) is linked to an            */
 | 
			
		||||
/*  application that uses different CRT library.                              */
 | 
			
		||||
ZMQ_EXPORT int zmq_errno (void);
 | 
			
		||||
 | 
			
		||||
/*  Resolves system errors and 0MQ errors to human-readable string.           */
 | 
			
		||||
ZMQ_EXPORT const char *zmq_strerror (int errnum);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
/*  0MQ message definition.                                                   */
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
 | 
			
		||||
/*  Maximal size of "Very Small Message". VSMs are passed by value            */
 | 
			
		||||
/*  to avoid excessive memory allocation/deallocation.                        */
 | 
			
		||||
/*  If VMSs larger than 255 bytes are required, type of 'vsm_size'            */
 | 
			
		||||
/*  field in zmq_msg_t structure should be modified accordingly.              */
 | 
			
		||||
#define ZMQ_MAX_VSM_SIZE 30
 | 
			
		||||
 | 
			
		||||
/*  Message types. These integers may be stored in 'content' member of the    */
 | 
			
		||||
/*  message instead of regular pointer to the data.                           */
 | 
			
		||||
#define ZMQ_DELIMITER 31
 | 
			
		||||
#define ZMQ_VSM 32
 | 
			
		||||
 | 
			
		||||
/*  Message flags. ZMQ_MSG_SHARED is strictly speaking not a message flag     */
 | 
			
		||||
/*  (it has no equivalent in the wire format), however, making  it a flag     */
 | 
			
		||||
/*  allows us to pack the stucture tigher and thus improve performance.       */
 | 
			
		||||
#define ZMQ_MSG_MORE 1
 | 
			
		||||
#define ZMQ_MSG_SHARED 128
 | 
			
		||||
#define ZMQ_MSG_MASK 129 /* Merges all the flags */
 | 
			
		||||
 | 
			
		||||
/*  A message. Note that 'content' is not a pointer to the raw data.          */
 | 
			
		||||
/*  Rather it is pointer to zmq::msg_content_t structure                      */
 | 
			
		||||
/*  (see src/msg_content.hpp for its definition).                             */
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    void *content;
 | 
			
		||||
    unsigned char flags;
 | 
			
		||||
    unsigned char vsm_size;
 | 
			
		||||
    unsigned char vsm_data [ZMQ_MAX_VSM_SIZE];
 | 
			
		||||
} zmq_msg_t;
 | 
			
		||||
 | 
			
		||||
typedef void (zmq_free_fn) (void *data, void *hint);
 | 
			
		||||
 | 
			
		||||
ZMQ_EXPORT int zmq_msg_init (zmq_msg_t *msg);
 | 
			
		||||
ZMQ_EXPORT int zmq_msg_init_size (zmq_msg_t *msg, size_t size);
 | 
			
		||||
ZMQ_EXPORT int zmq_msg_init_data (zmq_msg_t *msg, void *data,
 | 
			
		||||
    size_t size, zmq_free_fn *ffn, void *hint);
 | 
			
		||||
ZMQ_EXPORT int zmq_msg_close (zmq_msg_t *msg);
 | 
			
		||||
ZMQ_EXPORT int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src);
 | 
			
		||||
ZMQ_EXPORT int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src);
 | 
			
		||||
ZMQ_EXPORT void *zmq_msg_data (zmq_msg_t *msg);
 | 
			
		||||
ZMQ_EXPORT size_t zmq_msg_size (zmq_msg_t *msg);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
/*  0MQ infrastructure (a.k.a. context) initialisation & termination.         */
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
 | 
			
		||||
ZMQ_EXPORT void *zmq_init (int io_threads);
 | 
			
		||||
ZMQ_EXPORT int zmq_term (void *context);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
/*  0MQ socket definition.                                                    */
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
 | 
			
		||||
/*  Socket types.                                                             */ 
 | 
			
		||||
#define ZMQ_PAIR 0
 | 
			
		||||
#define ZMQ_PUB 1
 | 
			
		||||
#define ZMQ_SUB 2
 | 
			
		||||
#define ZMQ_REQ 3
 | 
			
		||||
#define ZMQ_REP 4
 | 
			
		||||
#define ZMQ_DEALER 5
 | 
			
		||||
#define ZMQ_ROUTER 6
 | 
			
		||||
#define ZMQ_PULL 7
 | 
			
		||||
#define ZMQ_PUSH 8
 | 
			
		||||
#define ZMQ_XPUB 9
 | 
			
		||||
#define ZMQ_XSUB 10
 | 
			
		||||
#define ZMQ_XREQ ZMQ_DEALER        /*  Old alias, remove in 3.x               */
 | 
			
		||||
#define ZMQ_XREP ZMQ_ROUTER        /*  Old alias, remove in 3.x               */
 | 
			
		||||
#define ZMQ_UPSTREAM ZMQ_PULL      /*  Old alias, remove in 3.x               */
 | 
			
		||||
#define ZMQ_DOWNSTREAM ZMQ_PUSH    /*  Old alias, remove in 3.x               */
 | 
			
		||||
 | 
			
		||||
/*  Socket options.                                                           */
 | 
			
		||||
#define ZMQ_HWM 1
 | 
			
		||||
#define ZMQ_SWAP 3
 | 
			
		||||
#define ZMQ_AFFINITY 4
 | 
			
		||||
#define ZMQ_IDENTITY 5
 | 
			
		||||
#define ZMQ_SUBSCRIBE 6
 | 
			
		||||
#define ZMQ_UNSUBSCRIBE 7
 | 
			
		||||
#define ZMQ_RATE 8
 | 
			
		||||
#define ZMQ_RECOVERY_IVL 9
 | 
			
		||||
#define ZMQ_MCAST_LOOP 10
 | 
			
		||||
#define ZMQ_SNDBUF 11
 | 
			
		||||
#define ZMQ_RCVBUF 12
 | 
			
		||||
#define ZMQ_RCVMORE 13
 | 
			
		||||
#define ZMQ_FD 14
 | 
			
		||||
#define ZMQ_EVENTS 15
 | 
			
		||||
#define ZMQ_TYPE 16
 | 
			
		||||
#define ZMQ_LINGER 17
 | 
			
		||||
#define ZMQ_RECONNECT_IVL 18
 | 
			
		||||
#define ZMQ_BACKLOG 19
 | 
			
		||||
#define ZMQ_RECOVERY_IVL_MSEC 20   /*  opt. recovery time, reconcile in 3.x   */
 | 
			
		||||
#define ZMQ_RECONNECT_IVL_MAX 21
 | 
			
		||||
    
 | 
			
		||||
/*  Send/recv options.                                                        */
 | 
			
		||||
#define ZMQ_NOBLOCK 1
 | 
			
		||||
#define ZMQ_SNDMORE 2
 | 
			
		||||
 | 
			
		||||
ZMQ_EXPORT void *zmq_socket (void *context, int type);
 | 
			
		||||
ZMQ_EXPORT int zmq_close (void *s);
 | 
			
		||||
ZMQ_EXPORT int zmq_setsockopt (void *s, int option, const void *optval,
 | 
			
		||||
    size_t optvallen); 
 | 
			
		||||
ZMQ_EXPORT int zmq_getsockopt (void *s, int option, void *optval,
 | 
			
		||||
    size_t *optvallen);
 | 
			
		||||
ZMQ_EXPORT int zmq_bind (void *s, const char *addr);
 | 
			
		||||
ZMQ_EXPORT int zmq_connect (void *s, const char *addr);
 | 
			
		||||
ZMQ_EXPORT int zmq_send (void *s, zmq_msg_t *msg, int flags);
 | 
			
		||||
ZMQ_EXPORT int zmq_recv (void *s, zmq_msg_t *msg, int flags);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
/*  I/O multiplexing.                                                         */
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#define ZMQ_POLLIN 1
 | 
			
		||||
#define ZMQ_POLLOUT 2
 | 
			
		||||
#define ZMQ_POLLERR 4
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    void *socket;
 | 
			
		||||
#if defined _WIN32
 | 
			
		||||
    SOCKET fd;
 | 
			
		||||
#else
 | 
			
		||||
    int fd;
 | 
			
		||||
#endif
 | 
			
		||||
    short events;
 | 
			
		||||
    short revents;
 | 
			
		||||
} zmq_pollitem_t;
 | 
			
		||||
 | 
			
		||||
ZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout);
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
/*  Built-in devices                                                          */
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#define ZMQ_STREAMER 1
 | 
			
		||||
#define ZMQ_FORWARDER 2
 | 
			
		||||
#define ZMQ_QUEUE 3
 | 
			
		||||
 | 
			
		||||
ZMQ_EXPORT int zmq_device (int device, void * insocket, void* outsocket);
 | 
			
		||||
 | 
			
		||||
#undef ZMQ_EXPORT
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -1,301 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
    Copyright (c) 2007-2011 iMatix Corporation
 | 
			
		||||
    Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
 | 
			
		||||
 | 
			
		||||
    This file is part of 0MQ.
 | 
			
		||||
 | 
			
		||||
    0MQ is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
    the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    0MQ 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 program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __ZMQ_HPP_INCLUDED__
 | 
			
		||||
#define __ZMQ_HPP_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "zmq.h"
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <exception>
 | 
			
		||||
 | 
			
		||||
namespace zmq
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    typedef zmq_free_fn free_fn;
 | 
			
		||||
    typedef zmq_pollitem_t pollitem_t;
 | 
			
		||||
 | 
			
		||||
    class error_t : public std::exception
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        error_t () : errnum (zmq_errno ()) {}
 | 
			
		||||
 | 
			
		||||
        virtual const char *what () const throw ()
 | 
			
		||||
        {
 | 
			
		||||
            return zmq_strerror (errnum);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int num () const
 | 
			
		||||
        {
 | 
			
		||||
            return errnum;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        int errnum;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    inline int poll (zmq_pollitem_t *items_, int nitems_, long timeout_ = -1)
 | 
			
		||||
    {
 | 
			
		||||
        int rc = zmq_poll (items_, nitems_, timeout_);
 | 
			
		||||
        if (rc < 0)
 | 
			
		||||
            throw error_t ();
 | 
			
		||||
        return rc;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline void device (int device_, void * insocket_, void* outsocket_)
 | 
			
		||||
    {
 | 
			
		||||
        int rc = zmq_device (device_, insocket_, outsocket_);
 | 
			
		||||
        if (rc != 0)
 | 
			
		||||
            throw error_t ();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline void version (int *major_, int *minor_, int *patch_)
 | 
			
		||||
    {
 | 
			
		||||
        zmq_version (major_, minor_, patch_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class message_t : private zmq_msg_t
 | 
			
		||||
    {
 | 
			
		||||
        friend class socket_t;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        inline message_t ()
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_msg_init (this);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline message_t (size_t size_)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_msg_init_size (this, size_);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline message_t (void *data_, size_t size_, free_fn *ffn_,
 | 
			
		||||
            void *hint_ = NULL)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_msg_init_data (this, data_, size_, ffn_, hint_);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline ~message_t ()
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_msg_close (this);
 | 
			
		||||
            assert (rc == 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void rebuild ()
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_msg_close (this);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
            rc = zmq_msg_init (this);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void rebuild (size_t size_)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_msg_close (this);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
            rc = zmq_msg_init_size (this, size_);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void rebuild (void *data_, size_t size_, free_fn *ffn_,
 | 
			
		||||
            void *hint_ = NULL)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_msg_close (this);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
            rc = zmq_msg_init_data (this, data_, size_, ffn_, hint_);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void move (message_t *msg_)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_msg_move (this, (zmq_msg_t*) msg_);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void copy (message_t *msg_)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_msg_copy (this, (zmq_msg_t*) msg_);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void *data ()
 | 
			
		||||
        {
 | 
			
		||||
            return zmq_msg_data (this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline size_t size ()
 | 
			
		||||
        {
 | 
			
		||||
            return zmq_msg_size (this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        //  Disable implicit message copying, so that users won't use shared
 | 
			
		||||
        //  messages (less efficient) without being aware of the fact.
 | 
			
		||||
        message_t (const message_t&);
 | 
			
		||||
        void operator = (const message_t&);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class context_t
 | 
			
		||||
    {
 | 
			
		||||
        friend class socket_t;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        inline context_t (int io_threads_)
 | 
			
		||||
        {
 | 
			
		||||
            ptr = zmq_init (io_threads_);
 | 
			
		||||
            if (ptr == NULL)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline ~context_t ()
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_term (ptr);
 | 
			
		||||
            assert (rc == 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //  Be careful with this, it's probably only useful for
 | 
			
		||||
        //  using the C api together with an existing C++ api.
 | 
			
		||||
        //  Normally you should never need to use this.
 | 
			
		||||
        inline operator void* ()
 | 
			
		||||
        {
 | 
			
		||||
            return ptr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        void *ptr;
 | 
			
		||||
 | 
			
		||||
        context_t (const context_t&);
 | 
			
		||||
        void operator = (const context_t&);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    class socket_t
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
        inline socket_t (context_t &context_, int type_)
 | 
			
		||||
        {
 | 
			
		||||
            ptr = zmq_socket (context_.ptr, type_);
 | 
			
		||||
            if (ptr == NULL)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline ~socket_t ()
 | 
			
		||||
        {
 | 
			
		||||
            close();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline operator void* ()
 | 
			
		||||
        {
 | 
			
		||||
            return ptr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void close()
 | 
			
		||||
        {
 | 
			
		||||
            if(ptr == NULL)
 | 
			
		||||
                // already closed
 | 
			
		||||
                return ;
 | 
			
		||||
            int rc = zmq_close (ptr);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
            ptr = 0 ;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void setsockopt (int option_, const void *optval_,
 | 
			
		||||
            size_t optvallen_)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_setsockopt (ptr, option_, optval_, optvallen_);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void getsockopt (int option_, void *optval_,
 | 
			
		||||
            size_t *optvallen_)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_getsockopt (ptr, option_, optval_, optvallen_);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void bind (const char *addr_)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_bind (ptr, addr_);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline void connect (const char *addr_)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_connect (ptr, addr_);
 | 
			
		||||
            if (rc != 0)
 | 
			
		||||
                throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline bool send (message_t &msg_, int flags_ = 0)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_send (ptr, &msg_, flags_);
 | 
			
		||||
            if (rc == 0)
 | 
			
		||||
                return true;
 | 
			
		||||
            if (rc == -1 && zmq_errno () == EAGAIN)
 | 
			
		||||
                return false;
 | 
			
		||||
            throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        inline bool recv (message_t *msg_, int flags_ = 0)
 | 
			
		||||
        {
 | 
			
		||||
            int rc = zmq_recv (ptr, msg_, flags_);
 | 
			
		||||
            if (rc == 0)
 | 
			
		||||
                return true;
 | 
			
		||||
            if (rc == -1 && zmq_errno () == EAGAIN)
 | 
			
		||||
                return false;
 | 
			
		||||
            throw error_t ();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
        void *ptr;
 | 
			
		||||
 | 
			
		||||
        socket_t (const socket_t&);
 | 
			
		||||
        void operator = (const socket_t&);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,64 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
    Copyright (c) 2007-2011 iMatix Corporation
 | 
			
		||||
    Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
 | 
			
		||||
 | 
			
		||||
    This file is part of 0MQ.
 | 
			
		||||
 | 
			
		||||
    0MQ is free software; you can redistribute it and/or modify it under
 | 
			
		||||
    the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
    the Free Software Foundation; either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    0MQ 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 program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __ZMQ_UTILS_H_INCLUDED__
 | 
			
		||||
#define __ZMQ_UTILS_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*  Handle DSO symbol visibility                                             */
 | 
			
		||||
#if defined _WIN32
 | 
			
		||||
#   if defined DLL_EXPORT
 | 
			
		||||
#       define ZMQ_EXPORT __declspec(dllexport)
 | 
			
		||||
#   else
 | 
			
		||||
#       define ZMQ_EXPORT __declspec(dllimport)
 | 
			
		||||
#   endif
 | 
			
		||||
#else
 | 
			
		||||
#   if defined __SUNPRO_C  || defined __SUNPRO_CC
 | 
			
		||||
#       define ZMQ_EXPORT __global
 | 
			
		||||
#   elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER
 | 
			
		||||
#       define ZMQ_EXPORT __attribute__ ((visibility("default")))
 | 
			
		||||
#   else
 | 
			
		||||
#       define ZMQ_EXPORT
 | 
			
		||||
#   endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*  Helper functions are used by perf tests so that they don't have to care   */
 | 
			
		||||
/*  about minutiae of time-related functions on different OS platforms.       */
 | 
			
		||||
 | 
			
		||||
/*  Starts the stopwatch. Returns the handle to the watch.                    */
 | 
			
		||||
ZMQ_EXPORT void *zmq_stopwatch_start (void);
 | 
			
		||||
 | 
			
		||||
/*  Stops the stopwatch. Returns the number of microseconds elapsed since     */
 | 
			
		||||
/*  the stopwatch was started.                                                */
 | 
			
		||||
ZMQ_EXPORT unsigned long zmq_stopwatch_stop (void *watch_);
 | 
			
		||||
 | 
			
		||||
/*  Sleeps for specified number of seconds.                                   */
 | 
			
		||||
ZMQ_EXPORT void zmq_sleep (int seconds_);
 | 
			
		||||
 | 
			
		||||
#undef ZMQ_EXPORT
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||