Compare commits
1 commit
master
...
new_coordi
Author | SHA1 | Date | |
---|---|---|---|
0bae01fd3f |
12
.gitmodules
vendored
|
@ -4,15 +4,3 @@
|
|||
[submodule "lib/DeathHandler"]
|
||||
path = lib/DeathHandler
|
||||
url = https://github.com/vmarkovtsev/DeathHandler.git
|
||||
[submodule "lib/Catch"]
|
||||
path = lib/Catch
|
||||
url = https://github.com/philsquared/Catch.git
|
||||
[submodule "lib/clooneljump"]
|
||||
path = lib/clooneljump
|
||||
url = https://bitbucket.org/King_DuckZ/clooneljump.git
|
||||
[submodule "lib/better-enums"]
|
||||
path = lib/better-enums
|
||||
url = https://github.com/aantron/better-enums
|
||||
[submodule "lib/tmxlite"]
|
||||
path = lib/tmxlite
|
||||
url = https://github.com/fallahn/tmxlite.git
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
cmake_minimum_required(VERSION 3.2)
|
||||
project(mycurry_toplevel CXX)
|
||||
project(mycurry CXX)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/include")
|
||||
|
||||
include(TargetArch)
|
||||
include(FindPkgConfig)
|
||||
include(CTest)
|
||||
|
||||
set(common_gcc_flags "-Wall -Wextra -pedantic -Wconversion")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${common_gcc_flags} -O0")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${common_gcc_flags}")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${common_gcc_flags} -O0")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${common_gcc_flags}")
|
||||
|
||||
option(CURRY_FORCE_OPENGLES "Try to chose the openGL ES renderer if available. Enable this on Raspberry Pi" OFF)
|
||||
option(CURRY_RASPBERRY_PI "Compile for Raspberry Pi" OFF)
|
||||
|
||||
set(MYCURRY_RESOURCES_PATH "${CMAKE_CURRENT_SOURCE_DIR}" CACHE STRING "Path to the program's resources")
|
||||
set(CLOONEL_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib/clooneljump")
|
||||
|
||||
target_architecture(TARGET_ARCH)
|
||||
message (STATUS "Target architecture: ${TARGET_ARCH}")
|
||||
|
@ -30,6 +34,9 @@ if (CURRY_FORCE_OPENGLES OR CURRY_RASPBERRY_PI)
|
|||
endif(CURRY_RASPBERRY_PI)
|
||||
endif (CURRY_FORCE_OPENGLES OR CURRY_RASPBERRY_PI)
|
||||
|
||||
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
|
||||
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)
|
||||
find_package(PNG REQUIRED)
|
||||
find_package(Boost 1.55.0 REQUIRED)
|
||||
|
||||
if (CURRY_RASPBERRY_PI)
|
||||
|
@ -44,33 +51,71 @@ if (CURRY_RASPBERRY_PI)
|
|||
)
|
||||
endif (CURRY_RASPBERRY_PI)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
src/csvloader.cpp
|
||||
src/main.cpp
|
||||
src/sdlmain.cpp
|
||||
src/ingamescene.cpp
|
||||
src/sizenotifiable.cpp
|
||||
src/sizeratio.cpp
|
||||
src/gamescenebase.cpp
|
||||
src/worldgrid.cpp
|
||||
src/worldviewport.cpp
|
||||
src/inputbag.cpp
|
||||
src/tileiterator.cpp
|
||||
src/texture.cpp
|
||||
src/movingobject.cpp
|
||||
src/character.cpp
|
||||
src/rect_to_sdl.cpp
|
||||
src/worldsizenotifiable.cpp
|
||||
src/worlditems.cpp
|
||||
src/moveable.cpp
|
||||
src/singlecoordinate.cpp
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} SYSTEM
|
||||
PRIVATE ${SDL2_INCLUDE_DIR}
|
||||
PRIVATE ${SDL2IMAGE_INCLUDE_DIRS}
|
||||
PRIVATE ${PNG_INCLUDE_DIRS}
|
||||
PRIVATE ${Boost_INCLUDE_DIRS}
|
||||
PRIVATE lib/tree-2.81/src
|
||||
)
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE src
|
||||
PRIVATE lib/vectorwrapper/include
|
||||
PRIVATE lib/DeathHandler
|
||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE ${SDL2_LIBRARIES}
|
||||
PRIVATE ${SDL2IMAGE_LIBRARIES}
|
||||
PRIVATE ${PNG_LIBRARIES}
|
||||
)
|
||||
|
||||
if (CURRY_RASPBERRY_PI)
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE bcm_host
|
||||
)
|
||||
endif(CURRY_RASPBERRY_PI)
|
||||
|
||||
configure_file(src/${PROJECT_NAME}Config.h.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}Config.h)
|
||||
target_compile_features(${PROJECT_NAME}
|
||||
PRIVATE cxx_nullptr
|
||||
PRIVATE cxx_range_for
|
||||
PRIVATE cxx_lambdas
|
||||
PRIVATE cxx_decltype_auto
|
||||
PRIVATE cxx_defaulted_functions
|
||||
PRIVATE cxx_deleted_functions
|
||||
PRIVATE cxx_auto_type
|
||||
PRIVATE cxx_defaulted_move_initializers
|
||||
PRIVATE cxx_noexcept
|
||||
PRIVATE cxx_rvalue_references
|
||||
)
|
||||
|
||||
set(common_gcc_flags -Wall -Wextra -pedantic -Wconversion -ffast-math)
|
||||
|
||||
add_library(${PROJECT_NAME} INTERFACE)
|
||||
target_compile_options(${PROJECT_NAME} INTERFACE ${common_gcc_flags})
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
INTERFACE $<$<CONFIG:Debug>:KAK_DEBUG>
|
||||
INTERFACE VWR_OUTER_NAMESPACE=curry
|
||||
)
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
INTERFACE lib/kakoune
|
||||
INTERFACE lib/better-enums
|
||||
PRIVATE ${PNG_DEFINITIONS}
|
||||
PRIVATE VWR_WITH_IMPLICIT_CONVERSIONS=1
|
||||
PRIVATE VWR_EXTRA_ACCESSORS
|
||||
)
|
||||
|
||||
add_subdirectory(lib/clooneljump/src/cloonelgraphics)
|
||||
add_subdirectory(lib/tmxlite/tmxlite)
|
||||
add_subdirectory(src/gamelib)
|
||||
add_subdirectory(src/standalone)
|
||||
|
||||
if (BUILD_TESTING)
|
||||
set(CATCH_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/lib/Catch")
|
||||
add_subdirectory(test/unit)
|
||||
endif()
|
||||
configure_file(src/${PROJECT_NAME}Config.h.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.h)
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
EFLAGS bit meaning
|
||||
http://reverseengineering.stackexchange.com/a/9222
|
||||
|
||||
GCC inline assembly
|
||||
http://ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
|
||||
|
||||
Popping the FPU stack
|
||||
http://stackoverflow.com/a/33575875/768582
|
||||
|
||||
Decoding a sample snippet of asm
|
||||
http://stackoverflow.com/questions/9186150/decoding-and-understanding-assembly-code
|
||||
|
||||
GNU assembler examples
|
||||
http://cs.lmu.edu/~ray/notes/gasexamples/
|
||||
|
||||
GCC function attributes (see "naked")
|
||||
https://gcc.gnu.org/onlinedocs/gcc-4.3.5/gcc/Function-Attributes.html
|
||||
|
||||
Fast floating point sign
|
||||
http://stackoverflow.com/a/2508911/768582
|
||||
|
||||
AMD assembly reference
|
||||
http://developer.amd.com/wordpress/media/2012/10/26569_APM_v51.pdf
|
||||
|
||||
Moving values between SSE and FPU
|
||||
http://stackoverflow.com/questions/37567154/intel-x86-64-assembly-how-to-move-between-x87-and-sse2-calculating-arctangent#37573264
|
|
@ -1,48 +0,0 @@
|
|||
#
|
||||
# Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
# This file is part of MyCurry.
|
||||
|
||||
# MyCurry is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# MyCurry is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
.data
|
||||
minus1: .float -1.0
|
||||
|
||||
.global fsgn_asm
|
||||
|
||||
.text
|
||||
fsgn_asm:
|
||||
subq $24,%rsp
|
||||
movss %xmm0,(%rsp)
|
||||
fldz
|
||||
flds (%rsp)
|
||||
fcomp
|
||||
|
||||
fstsw %ax
|
||||
sahf
|
||||
|
||||
fld1
|
||||
fld minus1
|
||||
|
||||
fcmovnbe %st(1),%st
|
||||
fcmove %st(2),%st
|
||||
|
||||
fstps (%rsp)
|
||||
fninit
|
||||
movss (%rsp),%xmm0
|
||||
|
||||
#xorpd %xmm0,%xmm0
|
||||
addq $24,%rsp
|
||||
ret
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "fsgn_timing.hpp"
|
||||
#include "fsgn.hpp"
|
||||
#if defined(FSGN_WITH_TIMING)
|
||||
# include <chrono>
|
||||
# include <random>
|
||||
# include <vector>
|
||||
# include <algorithm>
|
||||
# include <iostream>
|
||||
#endif
|
||||
|
||||
namespace curry {
|
||||
#if defined(FSGN_WITH_TIMING)
|
||||
void do_fsgn_timing() {
|
||||
constexpr const auto count = 1000000U;
|
||||
std::minstd_rand rand;
|
||||
std::vector<float> inputs(count);
|
||||
std::generate(inputs.begin(), inputs.end(), [&](){
|
||||
return static_cast<float>(rand()) - static_cast<float>(rand.max()) / 2.0f;
|
||||
});
|
||||
|
||||
//fast_fsgn
|
||||
{
|
||||
float result = 0.0f;
|
||||
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
for (auto z = 0U; z < count; ++z) {
|
||||
result += fast_fsgn(inputs[z]);
|
||||
}
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
std::cout << "fast_fsgn result: " << result << " in " <<
|
||||
std::chrono::duration<double>(t_end - t_start).count() << '\n';
|
||||
}
|
||||
|
||||
//fsgn_asm
|
||||
{
|
||||
float result = 0.0f;
|
||||
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
for (auto z = 0U; z < count; ++z) {
|
||||
result += fsgn_asm(inputs[z]);
|
||||
}
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
std::cout << "fsgn_asm result: " << result << " in " <<
|
||||
std::chrono::duration<double>(t_end - t_start).count() << '\n';
|
||||
}
|
||||
|
||||
//fsgn
|
||||
{
|
||||
float result = 0.0f;
|
||||
|
||||
auto t_start = std::chrono::high_resolution_clock::now();
|
||||
for (auto z = 0U; z < count; ++z) {
|
||||
result += fsgn(inputs[z]);
|
||||
}
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
std::cout << "fsgn result: " << result << " in " <<
|
||||
std::chrono::duration<double>(t_end - t_start).count() << '\n';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} //namespace curry
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define FSGN_WITH_TIMING
|
||||
|
||||
namespace curry {
|
||||
#if defined(FSGN_WITH_TIMING)
|
||||
void do_fsgn_timing();
|
||||
#endif
|
||||
} //namespace curry
|
|
@ -1,72 +0,0 @@
|
|||
#
|
||||
# Copyright 2015-2017 Michele "King_DuckZ" Santullo
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import gdb.printing
|
||||
|
||||
#NOTE:
|
||||
#This pretty-printer has been written for vectorwrapper + std::array.
|
||||
#You will have to customize it if your wrapped type is different.
|
||||
|
||||
class VectorWrapperStdArrPrinter(object):
|
||||
"Print values in a VectorWrapper<std::array>"
|
||||
|
||||
class _iterator(object):
|
||||
def __init__(self, start, size):
|
||||
self.item = start
|
||||
self.pos = 0
|
||||
self.size = size
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if self.pos == self.size:
|
||||
raise StopIteration
|
||||
elt = self.item.dereference()
|
||||
self.item = self.item + 1
|
||||
self.pos = self.pos + 1
|
||||
return str(elt)
|
||||
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
self.dimensions = int(val.type.template_argument(1))
|
||||
|
||||
def to_string(self):
|
||||
#get the scalar[n] value
|
||||
stdarray_elems = self.val['m_wrapped']['_M_elems']
|
||||
#get the actual scalar type
|
||||
elem_type = self.val['m_wrapped'].type.template_argument(0)
|
||||
#cast scalar[n] to scalar*
|
||||
ptr = stdarray_elems.address.cast(elem_type.pointer())
|
||||
#iterate over the values in scalar* and str() them
|
||||
retval = "vec" + str(self.dimensions) + "<" + \
|
||||
", ".join(
|
||||
str(itm) for itm in self._iterator(ptr, self.dimensions)
|
||||
) + ">"
|
||||
return retval
|
||||
|
||||
def display_hint(self):
|
||||
return 'string'
|
||||
|
||||
def build_pretty_printer():
|
||||
pp = gdb.printing.RegexpCollectionPrettyPrinter(__name__)
|
||||
#add your namespace before 'vwr' if you're using a custom one
|
||||
pp.add_printer('vwr', '^curry::vwr::Vec<std::array.+$', VectorWrapperStdArrPrinter)
|
||||
return pp
|
||||
|
||||
gdb.printing.register_pretty_printer(
|
||||
gdb.current_objfile(),
|
||||
build_pretty_printer()
|
||||
)
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 4d0cd602e37197f1502a419142d8f0167d4a063a
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 37d8f987ca939af846a2d29a8f8198f9bf3ac4b7
|
|
@ -1 +0,0 @@
|
|||
Subproject commit a1b66e99f0fee32f72cb39676e1fc9c957cba96d
|
|
@ -1,115 +0,0 @@
|
|||
#ifndef ref_ptr_hh_INCLUDED
|
||||
#define ref_ptr_hh_INCLUDED
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
struct RefCountable
|
||||
{
|
||||
int refcount = 0;
|
||||
virtual ~RefCountable() = default;
|
||||
};
|
||||
|
||||
struct RefCountablePolicy
|
||||
{
|
||||
static void inc_ref(RefCountable* r, void*) noexcept { ++r->refcount; }
|
||||
static void dec_ref(RefCountable* r, void*) { if (--r->refcount == 0) delete r; }
|
||||
static void ptr_moved(RefCountable*, void*, void*) noexcept {}
|
||||
};
|
||||
|
||||
template<typename T, typename Policy = RefCountablePolicy>
|
||||
struct RefPtr
|
||||
{
|
||||
RefPtr() = default;
|
||||
explicit RefPtr(T* ptr) : m_ptr(ptr) { acquire(); }
|
||||
~RefPtr() { release(); }
|
||||
RefPtr(const RefPtr& other) : m_ptr(other.m_ptr) { acquire(); }
|
||||
RefPtr(RefPtr&& other)
|
||||
noexcept(noexcept(std::declval<RefPtr>().moved(nullptr)))
|
||||
: m_ptr(other.m_ptr) { other.m_ptr = nullptr; moved(&other); }
|
||||
|
||||
RefPtr& operator=(const RefPtr& other)
|
||||
{
|
||||
if (other.m_ptr != m_ptr)
|
||||
{
|
||||
release();
|
||||
m_ptr = other.m_ptr;
|
||||
acquire();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
RefPtr& operator=(RefPtr&& other)
|
||||
{
|
||||
release();
|
||||
m_ptr = other.m_ptr;
|
||||
other.m_ptr = nullptr;
|
||||
moved(&other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
RefPtr& operator=(T* ptr)
|
||||
{
|
||||
if (ptr != m_ptr)
|
||||
{
|
||||
release();
|
||||
m_ptr = ptr;
|
||||
acquire();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[gnu::always_inline]]
|
||||
T* operator->() const { return m_ptr; }
|
||||
[[gnu::always_inline]]
|
||||
T& operator*() const { return *m_ptr; }
|
||||
|
||||
[[gnu::always_inline]]
|
||||
T* get() const { return m_ptr; }
|
||||
|
||||
[[gnu::always_inline]]
|
||||
explicit operator bool() const { return m_ptr; }
|
||||
|
||||
void reset(T* ptr = nullptr)
|
||||
{
|
||||
if (ptr == m_ptr)
|
||||
return;
|
||||
release();
|
||||
m_ptr = ptr;
|
||||
acquire();
|
||||
}
|
||||
|
||||
friend bool operator==(const RefPtr& lhs, const RefPtr& rhs) { return lhs.m_ptr == rhs.m_ptr; }
|
||||
friend bool operator!=(const RefPtr& lhs, const RefPtr& rhs) { return lhs.m_ptr != rhs.m_ptr; }
|
||||
|
||||
private:
|
||||
T* m_ptr = nullptr;
|
||||
|
||||
[[gnu::always_inline]]
|
||||
void acquire()
|
||||
{
|
||||
if (m_ptr)
|
||||
Policy::inc_ref(m_ptr, this);
|
||||
}
|
||||
|
||||
[[gnu::always_inline]]
|
||||
void release()
|
||||
{
|
||||
if (m_ptr)
|
||||
Policy::dec_ref(m_ptr, this);
|
||||
}
|
||||
|
||||
[[gnu::always_inline]]
|
||||
void moved(void* from)
|
||||
noexcept(noexcept(Policy::ptr_moved(nullptr, nullptr, nullptr)))
|
||||
{
|
||||
if (m_ptr)
|
||||
Policy::ptr_moved(m_ptr, from, this);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // ref_ptr_hh_INCLUDED
|
|
@ -1,109 +0,0 @@
|
|||
#ifndef safe_ptr_hh_INCLUDED
|
||||
#define safe_ptr_hh_INCLUDED
|
||||
|
||||
// #define SAFE_PTR_TRACK_CALLSTACKS
|
||||
|
||||
//King_DuckZ:
|
||||
#include <cassert>
|
||||
#define kak_assert(a) assert(a)
|
||||
|
||||
//#include "assert.hh"
|
||||
#include "ref_ptr.hh"
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#ifdef SAFE_PTR_TRACK_CALLSTACKS
|
||||
#include "backtrace.hh"
|
||||
#include "vector.hh"
|
||||
#include <algorithm>
|
||||
#endif
|
||||
|
||||
namespace Kakoune
|
||||
{
|
||||
|
||||
// *** SafePtr: objects that assert nobody references them when they die ***
|
||||
|
||||
class SafeCountable
|
||||
{
|
||||
public:
|
||||
#ifdef KAK_DEBUG
|
||||
SafeCountable() : m_count(0) {}
|
||||
SafeCountable (SafeCountable&&) : m_count(0) {}
|
||||
~SafeCountable()
|
||||
{
|
||||
kak_assert(m_count == 0);
|
||||
#ifdef SAFE_PTR_TRACK_CALLSTACKS
|
||||
kak_assert(m_callstacks.empty());
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
friend struct SafeCountablePolicy;
|
||||
#ifdef SAFE_PTR_TRACK_CALLSTACKS
|
||||
struct Callstack
|
||||
{
|
||||
Callstack(void* p) : ptr(p) {}
|
||||
void* ptr;
|
||||
Backtrace bt;
|
||||
};
|
||||
|
||||
mutable Vector<Callstack> m_callstacks;
|
||||
#endif
|
||||
mutable int m_count;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct SafeCountablePolicy
|
||||
{
|
||||
#ifdef KAK_DEBUG
|
||||
static void inc_ref(const SafeCountable* sc, void* ptr) noexcept
|
||||
{
|
||||
++sc->m_count;
|
||||
#ifdef SAFE_PTR_TRACK_CALLSTACKS
|
||||
sc->m_callstacks.emplace_back(ptr);
|
||||
#else
|
||||
static_cast<void>(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void dec_ref(const SafeCountable* sc, void* ptr) noexcept
|
||||
{
|
||||
--sc->m_count;
|
||||
kak_assert(sc->m_count >= 0);
|
||||
#ifdef SAFE_PTR_TRACK_CALLSTACKS
|
||||
auto it = std::find_if(sc->m_callstacks.begin(), sc->m_callstacks.end(),
|
||||
[=](const SafeCountable::Callstack& cs) { return cs.ptr == ptr; });
|
||||
kak_assert(it != sc->m_callstacks.end());
|
||||
sc->m_callstacks.erase(it);
|
||||
#else
|
||||
static_cast<void>(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ptr_moved(const SafeCountable* sc, void* from, void* to) noexcept
|
||||
{
|
||||
#ifdef SAFE_PTR_TRACK_CALLSTACKS
|
||||
auto it = std::find_if(sc->m_callstacks.begin(), sc->m_callstacks.end(),
|
||||
[=](const SafeCountable::Callstack& cs) { return cs.ptr == from; });
|
||||
kak_assert(it != sc->m_callstacks.end());
|
||||
it->ptr = to;
|
||||
#else
|
||||
static_cast<void>(sc);
|
||||
static_cast<void>(from);
|
||||
static_cast<void>(to);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static void inc_ref(const SafeCountable*, void*) noexcept {}
|
||||
static void dec_ref(const SafeCountable*, void*) noexcept {}
|
||||
static void ptr_moved(const SafeCountable*, void*, void*) noexcept {}
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using SafePtr = RefPtr<T, SafeCountablePolicy>;
|
||||
|
||||
}
|
||||
|
||||
#endif // safe_ptr_hh_INCLUDED
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 3934199e22d68a3a1e7c72049b5f6e85559e99dc
|
391
lib/tree-2.81/ChangeLog
Normal file
|
@ -0,0 +1,391 @@
|
|||
2011-08-23 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Brown paper bag release 2.81.
|
||||
|
||||
2011-08-23 Kasper Peeters <kasper@phi-sci.com>
|
||||
|
||||
* Released 2.8
|
||||
|
||||
* License updated.
|
||||
|
||||
2010-12-24 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Added a number of asserts to trip when passing invalid iterators
|
||||
to append_child/prepend_child members.
|
||||
|
||||
2010-03-24 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 2.70
|
||||
|
||||
* Fixed handling of std::allocator to make it more likely to work
|
||||
on non-GNU platforms.
|
||||
|
||||
2009-12-28 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Fixed the operator= return type and handled self-assignment
|
||||
(thanks to Xinlin Cao for the fix).
|
||||
|
||||
2009-05-05 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 2.65
|
||||
|
||||
* Added skip_children(bool), fixed post-increment/decrement
|
||||
operators to not refer to 'n' anymore.
|
||||
|
||||
2009-04-03 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Added a sibling member for quick access to the n-th sibling
|
||||
(thanks to Adam Connell for sending the patch).
|
||||
|
||||
2009-03-06 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Fixed an old bug in compare_nodes (pointed out to me in 2005 but
|
||||
never fixed properly...)
|
||||
|
||||
2008-08-28 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 2.62
|
||||
|
||||
* Changed the behaviour of max_depth() so that it returns -1 for
|
||||
an empty tree, instead of bailing out with an error (strictly
|
||||
speaking max_depth should be undefined...).
|
||||
|
||||
2008-08-26 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 2.61
|
||||
|
||||
* Fixed a bug in max_depth() which would fail on trees with more
|
||||
than one head node (thanks to Marc Noirot for pointing this out).
|
||||
|
||||
2008-08-23 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 2.60
|
||||
|
||||
* Fixed several problems with fixed_depth iterators: iterating
|
||||
beyond the top node now disabled and operator-- fixed.
|
||||
|
||||
2008-07-25 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Made 'child()' static.
|
||||
|
||||
2008-07-20 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 2.54
|
||||
|
||||
* Changed size() members to return size_t instead of unsigned int.
|
||||
|
||||
* Changed behaviour of operator++ for leaf_iterator so that it can
|
||||
be used in situations where new leaves get added during iteration.
|
||||
|
||||
2008-06-30 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 2.52
|
||||
|
||||
* Made depth member function static so it can be used independent
|
||||
of an actual tree, and added a version with two iterators to
|
||||
measure depths relative to a different node.
|
||||
|
||||
2008-02-28 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 2.51
|
||||
|
||||
* Added a top node to leaf_iterators, so that they can be
|
||||
instructed to iterate only over the leaves of a given node.
|
||||
|
||||
2007-10-19 Kasper Peeters <kasper@pooh>
|
||||
|
||||
* Released 2.4.
|
||||
|
||||
2007-10-18 Kasper Peeters <kasper@pooh>
|
||||
|
||||
* Added max_depth() members.
|
||||
|
||||
* Fixed a bug in begin_fixed() which would fail on
|
||||
|
||||
A
|
||||
/ \
|
||||
B C
|
||||
/ \
|
||||
D E
|
||||
/ \
|
||||
F G
|
||||
|
||||
when asked for the first node at depth 3 from 'A' (since it
|
||||
failed to go back up the tree from 'D').
|
||||
|
||||
2007-08-21 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 2.31.
|
||||
|
||||
* Added GPL version 3 licensing as an option.
|
||||
|
||||
2007-01-19 Kasper Peeters <kasper@pooh>
|
||||
|
||||
* Fixed a bug in "replace" which appeared when trying to replace a
|
||||
head node (it tried to access the parent).
|
||||
|
||||
2006-11-29 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Release 2.3.
|
||||
|
||||
Fixed a bug in number_of_siblings which only counted siblings in
|
||||
one direction (thanks to Fanzhe Cui for pointing this out).
|
||||
|
||||
2006-08-20 Kasper Peeters <kasper@pooh>
|
||||
|
||||
* Released 2.2.
|
||||
|
||||
* Added operator== and operator!= for fixed_depth_iterator.
|
||||
|
||||
2006-08-07 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 2.1.
|
||||
|
||||
* Added leaf iterators, code contributed by Peter Wienemann.
|
||||
|
||||
* Fixed a bug in is_valid (thanks to Antonio Morillas). 1.131.
|
||||
|
||||
2006-07-19 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Fixed bugs in move_before and move_after which would show up
|
||||
when the node was already in the right place. 1.130.
|
||||
|
||||
2006-03-02 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Added the "wrap" member function.
|
||||
|
||||
2006-03-01 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Added a simple queue-based breadth-first iterator.
|
||||
|
||||
2006-01-31 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Fixed move_before to work when the target is a sibling_iterator
|
||||
pointing to the end of a range of siblings.
|
||||
|
||||
2005-11-20 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Added move_after, which for some mysterious reason was
|
||||
missing. Thanks to Dennis Jones for pointing this out.
|
||||
|
||||
* Fixed a bug in operator++ for post_order iterators
|
||||
(skip_children could remain set if no next sibling present).
|
||||
Thanks to Ohad for pointing out the bug.
|
||||
|
||||
2005-10-12 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Fixed a bug in the 'sort' member which takes a Comparator
|
||||
function object (thanks to Robin Taylor for the patch).
|
||||
|
||||
2005-09-14 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Doxygen documentation added, plus a new web page.
|
||||
|
||||
2004-11-05 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Fixed a bug which shows up when inserting nodes at the top of
|
||||
the tree (thanks to Matthias Bernt for pointing me to this one).
|
||||
|
||||
2004-07-21 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Fixed kp::destructor -> destructor.
|
||||
|
||||
* Moved body of 'compare_nodes::operator()' into the class
|
||||
declaration in order to satisfy buggy Borland compilers (and stop
|
||||
regular email messages about this problem).
|
||||
|
||||
* Fixed a completely buggy number_of_siblings() (thanks to Caleb
|
||||
Epstein for the patch).
|
||||
|
||||
2004-02-04 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 1.106
|
||||
|
||||
* Fixed a bug in insert(sibling_iterator, const T&) (thanks to
|
||||
Maxim Yegorushkin for the patch).
|
||||
|
||||
2003-11-21 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Put some things in a namespace to avoid clashes with other
|
||||
libraries.
|
||||
|
||||
2003-10-13 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 1.102.
|
||||
|
||||
* Fixed return type of postincrement/decrement operators (thanks
|
||||
to Yevhen Tymokhin for pointing this out).
|
||||
|
||||
2003-09-18 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Fixes for standard compliance, as required to compile with
|
||||
gcc 3.4 and later.
|
||||
|
||||
2003-08-12 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Added 'empty' member (patch by Michael Vogt).
|
||||
|
||||
2003-08-01 <kasper@whiteroom2.localdomain>
|
||||
|
||||
* Released 1.95
|
||||
|
||||
* Fixed two bugs in sort (which were corrupting the tree); thanks
|
||||
to Michael Vogt for informing me about the problem.
|
||||
|
||||
2003-07-17 <kasper@whiteroom2.localdomain>
|
||||
|
||||
* Added a hack to enable compilation with STLport.
|
||||
|
||||
2003-07-11 <kasper@whiteroom2.localdomain>
|
||||
|
||||
* Released 1.90
|
||||
|
||||
* Added postfix increment and decrement operators; thanks to
|
||||
Claudio Andreatta for sending the patch.
|
||||
|
||||
* Fixed a bug in reparent(iter pos, iter from). Thanks to Claudio
|
||||
Andreatta for fixing this.
|
||||
|
||||
2003-06-25 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Many bug fixes for fixed depth iterators, thanks to Ruben
|
||||
Niederhagen for pointing out several problems (a few still exist,
|
||||
see the 'TODO' part of tree.hh).
|
||||
|
||||
2003-04-17 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 1.85
|
||||
|
||||
* Corrected return type of operator++ and friends.
|
||||
|
||||
* Added preliminary support for 'fixed_depth_iterator' to iterate
|
||||
over children at a given level. Not quite finished yet, sorry.
|
||||
|
||||
2003-03-24 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
* Released 1.83
|
||||
|
||||
* Changed return type of 'child' member function to be a sibling
|
||||
iterator instead of a reference to the actual node (sorry for the
|
||||
incompatibility with previous versions). Change also propagated to
|
||||
tree_msvc.hh.
|
||||
|
||||
2003-02-07 <kasper@whiteroom2.localdomain>
|
||||
|
||||
* Released 1.80
|
||||
|
||||
* Fixed another bug in sort (thanks to Tony Cook for fixing this
|
||||
bug).
|
||||
|
||||
2003-01-29 Kasper Peeters <peekas@xeon25.aei-potsdam.mpg.de>
|
||||
|
||||
* Released 1.78.
|
||||
|
||||
* Fixed a bug in sort, which resulted in a corrupt tree (thanks to
|
||||
Michael Vogt for fixing this bug).
|
||||
|
||||
2003-01-07 Kasper Peeters <peekas@xeon25.aei-potsdam.mpg.de>
|
||||
|
||||
* Released 1.75 and msvc version 1.72
|
||||
|
||||
* Fixed a wrongly specialised 'insert' method for
|
||||
sibling_iterators (thanks to Tony Cook for pointing this out).
|
||||
|
||||
2002-11-15 Kasper Peeters <peekas@xeon25.aei-potsdam.mpg.de>
|
||||
|
||||
* Released 1.72
|
||||
|
||||
* Fixed a bug in 'index' when called on nodes at the top level of
|
||||
the tree (thanks to David Zajic for the bug report). Be warned
|
||||
that the top level is a bit special at the moment; the end
|
||||
sibling_iterator is ill-defined for siblings there (to be fixed in
|
||||
a future version).
|
||||
|
||||
2002-10-31 Kasper Peeters <peekas@sshserv.aei-potsdam.mpg.de>
|
||||
|
||||
* Released 1.70.
|
||||
|
||||
* Finished the merge algorithm, updated the documentation with
|
||||
examples about its use, and added a test-case to the test_tree.cc
|
||||
program.
|
||||
|
||||
* Fixed a bug in pre_order_iterator::operator--.
|
||||
|
||||
2002-10-20 Kasper Peeters <peekas@xeon24.aei-potsdam.mpg.de>
|
||||
|
||||
* Released 1.66.
|
||||
|
||||
2002-10-15 Kasper Peeters <kasper@whiteroom.nikhef.nl>
|
||||
|
||||
* Code for post_order_iterator implemented.
|
||||
|
||||
2002-10-13 Kasper Peeters <peekas@xeon24.aei-potsdam.mpg.de>
|
||||
|
||||
* Rewrote large parts of the code to allow for multiple iterator
|
||||
types, such as pre_order_iterator (which was the previous iterator
|
||||
type), post_order_iterator and so on. This required small changes
|
||||
to the interface, the most visible one being
|
||||
|
||||
- insert(iterator, iterator) for the insertion of a subtree
|
||||
is now called insert_subtree(iterator, iterator).
|
||||
|
||||
Apologies if this breaks your code.
|
||||
|
||||
2002-10-11 Kasper Peeters <peekas@xeon24.aei-potsdam.mpg.de>
|
||||
|
||||
* Removed '(void)' type declarations in favour of the C++ standard
|
||||
empty brackets '()'.
|
||||
|
||||
2002-10-10 Kasper Peeters <peekas@xeon24.aei-potsdam.mpg.de>
|
||||
|
||||
* Added 'index' in response to a discussion on the Boost mailing
|
||||
list.
|
||||
|
||||
2002-10-03 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
|
||||
|
||||
* reparent(iterator,sibling_iterator,sibling_iterator) now accepts
|
||||
an empty range, in which case it does nothing (request by Jos de
|
||||
Laender).
|
||||
|
||||
* Fixed a bug in the iterator(sibling_iterator) constructor
|
||||
(thanks to Jos de Laender for pointing this out).
|
||||
|
||||
2002-09-04 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
|
||||
|
||||
* Fixed a bug in insert_after (thanks to Carl Blanchette for the
|
||||
patch).
|
||||
|
||||
2002-08-29 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
|
||||
|
||||
* The problem in test_tree of the previous item was actually do to
|
||||
tree::end(iterator) returning the end of the tree, not the end of
|
||||
the current sibling list. Fixed now, released 1.55.
|
||||
|
||||
2002-08-26 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
|
||||
|
||||
* Released 1.54.
|
||||
|
||||
* Printing a single-node tree in test_tree would result in a
|
||||
segfault; more robust now (thanks to Yutaka Sato for the bug
|
||||
report).
|
||||
|
||||
2002-05-07 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
|
||||
|
||||
* Fixed a bug in "sort" which would remove duplicate nodes altogether.
|
||||
|
||||
2002-03-24 Kasper Peeters <kasper@whiteroom.nikhef.nl>
|
||||
|
||||
* Added "append_child" without child argument, to add empty child
|
||||
node.
|
||||
|
||||
2002-05-04 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
|
||||
|
||||
* Released 1.45.
|
||||
|
||||
* Removed restriction of having only a single node at the top of
|
||||
the tree (associated with this, the top nodes should now be inserted
|
||||
with "insert", not with "append_child").
|
||||
|
||||
* Fixes for ISO compatibility (now works with gcc-3.1). Thanks to
|
||||
Olivier Verdier.
|
||||
|
27
lib/tree-2.81/Makefile
Normal file
|
@ -0,0 +1,27 @@
|
|||
|
||||
RELEASE=2.8
|
||||
HTML=${HOME}/public_html/
|
||||
|
||||
.PHONY: doc tarball
|
||||
|
||||
tarball:
|
||||
git archive --format=tar --prefix=tree-${RELEASE}/ HEAD | gzip > ${HOME}/tmp/tree-${RELEASE}.tar.gz
|
||||
|
||||
site: tarball doc
|
||||
install -d ${HTML}/tree
|
||||
install -d ${HTML}/tree/doxygen/html
|
||||
install doc/index.html doc/tree.css doc/tree.jpg ChangeLog ${HTML}/tree
|
||||
install src/test_tree.cc src/test_tree.output src/tree_example.cc src/tree.hh src/tree_util.hh ${HTML}/tree
|
||||
install doxygen/html/* ${HTML}/tree/doxygen/html
|
||||
install ${HOME}/tmp/tree-${RELEASE}.tar.gz ${HTML}/tree
|
||||
install ${HOME}/tmp/kt_temp/kt_temp_tree/tree.pdf ${HTML}/tree
|
||||
|
||||
upload:
|
||||
rsync -avz ${HTML}/tree/ zmaya:tree
|
||||
|
||||
doc:
|
||||
(cd doc; kt -f tree.tex)
|
||||
doxygen doc/doxygen_tree.config
|
||||
|
||||
test_tree: test_tree.o
|
||||
g++ -o test_tree test_tree.o
|
220
lib/tree-2.81/doc/documentation.html
Normal file
|
@ -0,0 +1,220 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="verify-v1"
|
||||
content="LkU+jobePpu3F8I4GPuTiOjrTukmo1qpWT+dT6SeAfk=" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
|
||||
<meta name="description" content="The tree.hh library provides C++
|
||||
programmers with a container class to store arbitrary data in
|
||||
n-ary tree form. It is compatible with the STL and its
|
||||
algorithms wherever possible. Available under the terms of the GPL." />
|
||||
<meta name="keywords" content="data structure, C++, programming, STL,
|
||||
open source, container class" />
|
||||
<title>tree.hh: an STL-like C++ tree class, documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="tree.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="title">
|
||||
<div id="share">
|
||||
<!-- AddThis Button BEGIN -->
|
||||
<a class="addthis_button" href="http://www.addthis.com/bookmark.php?v=250&username=kpeeters"><img src="http://s7.addthis.com/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a><script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=kpeeters"></script>
|
||||
<!-- AddThis Button END -->
|
||||
</div>
|
||||
<div id="filler">
|
||||
<img id="treeimg" src="tree2.png" alt="[background image]"/>
|
||||
</div>
|
||||
<div id="titletxt">
|
||||
<h1>tree.hh: an STL-like C++ tree class</h1>
|
||||
<h2 class="author">
|
||||
<a href="http://maths.dur.ac.uk/users/kasper.peeters/">Kasper Peeters</a>, kasper.peeters (at) phi-sci.com
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul id="menubar">
|
||||
<li><a href="index.html">Overview</a></li>
|
||||
<li><a href="download.html">Download</a></li>
|
||||
<li><a href="documentation.html">Documentation</a></li>
|
||||
<li><a href="projects.html">Projects using tree.hh</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="linkbar">
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9577963716105989";
|
||||
/* tree linkbar */
|
||||
google_ad_slot = "0194609917";
|
||||
google_ad_width = 728;
|
||||
google_ad_height = 15;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="sidebar">
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9577963716105989";
|
||||
/* tree.hh vertical ads */
|
||||
google_ad_slot = "3744417434";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<h2>Data structure overview</h2>
|
||||
|
||||
<div class="text">The data structure of the <code>tree</code> class is depicted
|
||||
below (see the documentation for more detailed information).
|
||||
Each node contains a pointer to the first and last child element,
|
||||
and each child contains pointers to its previous and next sibling:
|
||||
<img class="structure" src="structure.png" alt="[structure
|
||||
diagram]" />
|
||||
</div>
|
||||
|
||||
<div class="text">
|
||||
Iterators come in various types. The normal <code>iterator</code> iterates depth-first
|
||||
over all nodes. The beginning and end of the tree can be obtained by using the
|
||||
<code>begin()</code> and <code>end()</code> members. The other type of iterator
|
||||
only iterates over the nodes at one given depth (ie. over all siblings). One
|
||||
typically uses these iterators to iterate over all children of a node, in which
|
||||
case the [begin,end) range can be obtained by calling <code>begin(iterator)</code>
|
||||
and <code>end(iterator)</code>.</div>
|
||||
|
||||
<div class="text">Iterators can be converted from one type to the other; this includes the `end'
|
||||
iterators (all intervals are as usual closed at the beginning and open
|
||||
at the end).</div>
|
||||
|
||||
<h2>Sample program</h2>
|
||||
|
||||
<div class="text">
|
||||
Here is a small sample program to illustrate
|
||||
how <code>tree.hh</code> is used in practise.
|
||||
|
||||
<div class="code">
|
||||
<pre>#include <algorithm>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "tree.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
tree<string> tr;
|
||||
tree<string>::iterator top, one, two, loc, banana;
|
||||
|
||||
top=tr.begin();
|
||||
one=tr.insert(top, "one");
|
||||
two=tr.append_child(one, "two");
|
||||
tr.append_child(two, "apple");
|
||||
banana=tr.append_child(two, "banana");
|
||||
tr.append_child(banana,"cherry");
|
||||
tr.append_child(two, "peach");
|
||||
tr.append_child(one,"three");
|
||||
|
||||
loc=find(tr.begin(), tr.end(), "two");
|
||||
if(loc!=tr.end()) {
|
||||
tree<string>::sibling_iterator sib=tr.begin(loc);
|
||||
while(sib!=tr.end(loc)) {
|
||||
cout << (*sib) << endl;
|
||||
++sib;
|
||||
}
|
||||
cout << endl;
|
||||
tree<string>::iterator sib2=tr.begin(loc);
|
||||
tree<string>::iterator end2=tr.end(loc);
|
||||
while(sib2!=end2) {
|
||||
for(int i=0; i<tr.depth(sib2)-2; ++i)
|
||||
cout << " ";
|
||||
cout << (*sib2) << endl;
|
||||
++sib2;
|
||||
}
|
||||
}
|
||||
}</pre>
|
||||
</div>
|
||||
The output of this program is
|
||||
<div class="code">
|
||||
<pre>apple
|
||||
banana
|
||||
peach
|
||||
|
||||
apple
|
||||
banana
|
||||
cherry
|
||||
peach</pre>
|
||||
</div>
|
||||
Note that this example only has one element at the
|
||||
top of the tree (in this case that is the node containing "one") but
|
||||
it is possible to have an arbitary number of such elements (then the
|
||||
tree is more like a "bush"). Observe the way in which the two types of
|
||||
iterators work. The first block of output, obtained using the
|
||||
sibling_iterator, only displays the children directly below "two". The
|
||||
second block iterates over all children at any depth below "two". In
|
||||
the second output block, the <code>depth</code> member has been used
|
||||
to determine the distance of a given node to the root of the
|
||||
tree.
|
||||
</div>
|
||||
|
||||
<h2>API documentation</h2>
|
||||
|
||||
<div class="text">
|
||||
Documentation is available in the form of
|
||||
a <a href="tree.pdf">pdf</a> file. This file is also available
|
||||
in the tarball as a LaTeX file. Further information can be
|
||||
obtained by reading the test program (included in the
|
||||
distribution). Also look at the <a href="#example">simple
|
||||
example</a> below.
|
||||
</div>
|
||||
|
||||
<div class="text">
|
||||
The most complete documentation of the interface is always
|
||||
available in the <a href="doxygen/html/index.html">doxygen
|
||||
generated documentation</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="flush"></div>
|
||||
|
||||
<p>
|
||||
<a href="http://validator.w3.org/check?uri=referer">
|
||||
<img
|
||||
src="http://www.w3.org/Icons/valid-xhtml10"
|
||||
alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
|
||||
</p>
|
||||
|
||||
<!-- Start of StatCounter Code -->
|
||||
<script type="text/javascript">
|
||||
var sc_project=4068217;
|
||||
var sc_invisible=1;
|
||||
var sc_partition=50;
|
||||
var sc_click_stat=1;
|
||||
var sc_security="3f2419f9";
|
||||
</script>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="http://www.statcounter.com/counter/counter_xhtml.js"></script>
|
||||
<noscript>
|
||||
<div class="statcounter">
|
||||
<a title="blogspot statistics"
|
||||
class="statcounter"
|
||||
href="http://www.statcounter.com/blogger/">
|
||||
<img
|
||||
class="statcounter"
|
||||
src="http://c.statcounter.com/4068217/0/3f2419f9/1/"
|
||||
alt="blogspot statistics" /></a>
|
||||
</div>
|
||||
</noscript>
|
||||
<!-- End of StatCounter Code -->
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
175
lib/tree-2.81/doc/download.html
Normal file
|
@ -0,0 +1,175 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="verify-v1"
|
||||
content="LkU+jobePpu3F8I4GPuTiOjrTukmo1qpWT+dT6SeAfk=" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
|
||||
<meta name="description" content="The tree.hh library provides C++
|
||||
programmers with a container class to store arbitrary data in
|
||||
n-ary tree form. It is compatible with the STL and its
|
||||
algorithms wherever possible. Available under the terms of the GPL." />
|
||||
<meta name="keywords" content="data structure, C++, programming, STL,
|
||||
open source, container class" />
|
||||
<title>tree.hh: an STL-like C++ tree class, download</title>
|
||||
<link rel="stylesheet" type="text/css" href="tree.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="title">
|
||||
<div id="share">
|
||||
<!-- AddThis Button BEGIN -->
|
||||
<a class="addthis_button" href="http://www.addthis.com/bookmark.php?v=250&username=kpeeters"><img src="http://s7.addthis.com/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a><script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=kpeeters"></script>
|
||||
<!-- AddThis Button END -->
|
||||
</div>
|
||||
<div id="filler">
|
||||
<img id="treeimg" src="tree2.png" alt="[background image]"/>
|
||||
</div>
|
||||
<div id="titletxt">
|
||||
<h1>tree.hh: an STL-like C++ tree class</h1>
|
||||
<h2 class="author">
|
||||
<a href="http://maths.dur.ac.uk/users/kasper.peeters/">Kasper Peeters</a>, kasper.peeters (at) phi-sci.com
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul id="menubar">
|
||||
<li><a href="index.html">Overview</a></li>
|
||||
<li><a href="download.html">Download</a></li>
|
||||
<li><a href="documentation.html">Documentation</a></li>
|
||||
<li><a href="projects.html">Projects using tree.hh</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="linkbar">
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9577963716105989";
|
||||
/* tree linkbar */
|
||||
google_ad_slot = "0194609917";
|
||||
google_ad_width = 728;
|
||||
google_ad_height = 15;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="sidebar">
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9577963716105989";
|
||||
/* tree.hh vertical ads */
|
||||
google_ad_slot = "3744417434";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<h2>Download</h2>
|
||||
|
||||
<div class="text">Everything (the header file, examples, documentation
|
||||
and all other things referred to on this page) is contained in the
|
||||
tarball</div>
|
||||
<div class="filename">
|
||||
<a href="tree-2.8.tar.gz">tree-2.8.tar.gz</a>
|
||||
</div>
|
||||
<div class="text">
|
||||
Feel free to copy the header <a href="tree.hh">tree.hh</a>
|
||||
(which is all you need code-wise) into your own source
|
||||
directory as long as you respect the license (see above).
|
||||
</div>
|
||||
|
||||
<div class="text">
|
||||
The list of changes can be found in the <a href="ChangeLog">ChangeLog</a>.
|
||||
</div>
|
||||
|
||||
<div class="text">
|
||||
There is a small utility
|
||||
library <a href="tree_util.hh">tree_util.hh</a> originally
|
||||
written by Linda Buisman. This library contains a number of
|
||||
functions to output a tree as text, to aid in debugging your
|
||||
project.
|
||||
</div>
|
||||
|
||||
<div class="text">The current version works with GNU gcc 3.x and
|
||||
higher, Borland C++ builder and Microsoft Visual C++ 7.1 and
|
||||
higher (I no longer support older versions of Visual C++). It is
|
||||
compatible with STLport (though older versions may not work
|
||||
correctly, best to upgrade to something fairly recent).
|
||||
</div>
|
||||
|
||||
<div class="text">The library is available for free, but if it
|
||||
helps you a lot, why not consider a small donation?
|
||||
<form id="donate"
|
||||
action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<p>
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id"
|
||||
value="YVWFQTJRGD8SW" />
|
||||
<input type="image"
|
||||
src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif"
|
||||
name="submit"
|
||||
alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt=""
|
||||
src="https://www.paypal.com/en_GB/i/scr/pixel.gif"
|
||||
width="1"
|
||||
height="1" />
|
||||
</p>
|
||||
</form>
|
||||
Your contribution is greatly appreciated!
|
||||
</div>
|
||||
|
||||
|
||||
<h2>Installation</h2>
|
||||
|
||||
<div class="text">
|
||||
No installation is required as the tree.hh library is
|
||||
contained in the single header file tree.hh. Just copy it into
|
||||
your source directory (and upgrade it from the master site
|
||||
when a new version becomes available).
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="flush"></div>
|
||||
|
||||
<p>
|
||||
<a href="http://validator.w3.org/check?uri=referer">
|
||||
<img
|
||||
src="http://www.w3.org/Icons/valid-xhtml10"
|
||||
alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
|
||||
</p>
|
||||
|
||||
<!-- Start of StatCounter Code -->
|
||||
<script type="text/javascript">
|
||||
var sc_project=4068217;
|
||||
var sc_invisible=1;
|
||||
var sc_partition=50;
|
||||
var sc_click_stat=1;
|
||||
var sc_security="3f2419f9";
|
||||
</script>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="http://www.statcounter.com/counter/counter_xhtml.js"></script>
|
||||
<noscript>
|
||||
<div class="statcounter">
|
||||
<a title="blogspot statistics"
|
||||
class="statcounter"
|
||||
href="http://www.statcounter.com/blogger/">
|
||||
<img
|
||||
class="statcounter"
|
||||
src="http://c.statcounter.com/4068217/0/3f2419f9/1/"
|
||||
alt="blogspot statistics" /></a>
|
||||
</div>
|
||||
</noscript>
|
||||
<!-- End of StatCounter Code -->
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
270
lib/tree-2.81/doc/doxygen_tree.config
Normal file
|
@ -0,0 +1,270 @@
|
|||
# Doxyfile 1.4.4
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = tree
|
||||
PROJECT_NUMBER = "release 2.0"
|
||||
OUTPUT_DIRECTORY = doxygen
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
USE_WINDOWS_ENCODING = NO
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF = "The $name class" \
|
||||
"The $name widget" \
|
||||
"The $name file" \
|
||||
is \
|
||||
provides \
|
||||
specifies \
|
||||
contains \
|
||||
represents \
|
||||
a \
|
||||
an \
|
||||
the
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = NO
|
||||
INHERIT_DOCS = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 8
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
SUBGROUPING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
HIDE_UNDOC_MEMBERS = YES
|
||||
HIDE_UNDOC_CLASSES = YES
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = YES
|
||||
FILE_VERSION_FILTER =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = src/tree.hh
|
||||
FILE_PATTERNS = *.c \
|
||||
*.cc \
|
||||
*.cxx \
|
||||
*.cpp \
|
||||
*.c++ \
|
||||
*.d \
|
||||
*.java \
|
||||
*.ii \
|
||||
*.ixx \
|
||||
*.ipp \
|
||||
*.i++ \
|
||||
*.inl \
|
||||
*.h \
|
||||
*.hh \
|
||||
*.hxx \
|
||||
*.hpp \
|
||||
*.h++ \
|
||||
*.idl \
|
||||
*.odl \
|
||||
*.cs \
|
||||
*.php \
|
||||
*.php3 \
|
||||
*.inc \
|
||||
*.m \
|
||||
*.mm \
|
||||
*.dox \
|
||||
*.C \
|
||||
*.CC \
|
||||
*.C++ \
|
||||
*.II \
|
||||
*.I++ \
|
||||
*.H \
|
||||
*.HH \
|
||||
*.H++ \
|
||||
*.CS \
|
||||
*.PHP \
|
||||
*.PHP3 \
|
||||
*.M \
|
||||
*.MM
|
||||
RECURSIVE = NO
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = NO
|
||||
REFERENCES_RELATION = NO
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = NO
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = YES
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = NO
|
||||
USE_PDFLATEX = NO
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
MAX_DOT_GRAPH_DEPTH = 1000
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
BIN
lib/tree-2.81/doc/favicon.ico
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
lib/tree-2.81/doc/favicon.png
Normal file
After Width: | Height: | Size: 782 B |
BIN
lib/tree-2.81/doc/filler.png
Normal file
After Width: | Height: | Size: 881 B |
205
lib/tree-2.81/doc/index.html
Normal file
|
@ -0,0 +1,205 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="verify-v1"
|
||||
content="LkU+jobePpu3F8I4GPuTiOjrTukmo1qpWT+dT6SeAfk=" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
|
||||
<meta name="description" content="The tree.hh library provides C++
|
||||
programmers with a container class to store arbitrary data in
|
||||
n-ary tree form. It is compatible with the STL and its
|
||||
algorithms wherever possible. Available under the terms of the GPL." />
|
||||
<meta name="keywords" content="data structure, C++, programming, STL,
|
||||
open source, container class" />
|
||||
<title>tree.hh: an STL-like C++ tree class</title>
|
||||
<link rel="stylesheet" type="text/css" href="tree.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="title">
|
||||
<div id="share">
|
||||
<!-- AddThis Button BEGIN -->
|
||||
<a class="addthis_button" href="http://www.addthis.com/bookmark.php?v=250&username=kpeeters"><img src="http://s7.addthis.com/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a><script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=kpeeters"></script>
|
||||
<!-- AddThis Button END -->
|
||||
</div>
|
||||
<div id="plusone">
|
||||
<!-- Place this tag where you want the +1 button to render -->
|
||||
<g:plusone></g:plusone>
|
||||
|
||||
<!-- Place this tag after the last plusone tag -->
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
|
||||
po.src = 'https://apis.google.com/js/plusone.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<div id="filler">
|
||||
<img id="treeimg" src="tree2.png" alt="[background image]"/>
|
||||
</div>
|
||||
<div id="titletxt">
|
||||
<h1>tree.hh: an STL-like C++ tree class</h1>
|
||||
<h2 class="author">
|
||||
<a href="http://maths.dur.ac.uk/users/kasper.peeters/">Kasper Peeters</a>, kasper.peeters (at) phi-sci.com
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul id="menubar">
|
||||
<li><a href="index.html">Overview</a></li>
|
||||
<li><a href="download.html">Download</a></li>
|
||||
<li><a href="documentation.html">Documentation</a></li>
|
||||
<li><a href="projects.html">Projects using tree.hh</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="linkbar">
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9577963716105989";
|
||||
/* tree linkbar */
|
||||
google_ad_slot = "0194609917";
|
||||
google_ad_width = 728;
|
||||
google_ad_height = 15;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="sidebar">
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9577963716105989";
|
||||
/* tree.hh vertical ads */
|
||||
google_ad_slot = "3744417434";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<h2>Overview</h2>
|
||||
|
||||
<div class="text">
|
||||
The <code>tree.hh</code> library for C++ provides an STL-like container class
|
||||
for <i>n</i>-ary trees, templated over the data stored at the nodes. Various
|
||||
types of iterators are provided (post-order, pre-order, and
|
||||
others). Where possible the access methods are compatible with the STL
|
||||
or alternative algorithms are available. The library is available
|
||||
under the terms of the GNU General Public License version 2 or
|
||||
3 (see below).</div>
|
||||
|
||||
<div class="text">Documentation is available in the form of
|
||||
a <a href="tree.pdf">pdf</a> file. See
|
||||
the <a href="documentation.html">documentation page</a> for
|
||||
more details and sample programs.
|
||||
</div>
|
||||
|
||||
<div class="text">The <code>tree.hh</code> library is meant for generic <i>n</i>-ary
|
||||
trees. For binary trees, AVL trees, quad trees and other data
|
||||
structures, you may want to look elsewhere. </div>
|
||||
|
||||
<div class="text">The library is available for free, but if it
|
||||
helps you a lot, why not consider a small donation?
|
||||
<form id="donate"
|
||||
action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
||||
<p>
|
||||
<input type="hidden" name="cmd" value="_s-xclick" />
|
||||
<input type="hidden" name="hosted_button_id"
|
||||
value="YVWFQTJRGD8SW" />
|
||||
<input type="image"
|
||||
src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif"
|
||||
name="submit"
|
||||
alt="PayPal - The safer, easier way to pay online!" />
|
||||
<img alt=""
|
||||
src="https://www.paypal.com/en_GB/i/scr/pixel.gif"
|
||||
width="1"
|
||||
height="1" />
|
||||
</p>
|
||||
</form>
|
||||
Your contribution is greatly appreciated!
|
||||
</div>
|
||||
|
||||
<div class="text">
|
||||
I have considered this class for inclusion in Boost. However,
|
||||
there are many ways to implement a tree container, and there
|
||||
is no good way to simultaneously satisfy everyone who would
|
||||
use it. See the discussion on the Boost mailing list in
|
||||
<a href="http://lists.boost.org/Archives/boost/2002/10/37383.php">2002</a>
|
||||
and <a href="http://lists.boost.org/Archives/boost/2009/07/153719.php">2009</a>.
|
||||
</div>
|
||||
|
||||
<h2>License</h2>
|
||||
|
||||
<div class="text">In principle, the <code>tree.hh</code> code is
|
||||
available under the terms of the GNU General Public
|
||||
License <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">2</a>
|
||||
or <a href="http://www.gnu.org/copyleft/gpl.html">3</a>. However,
|
||||
if you would like to use <code>tree.hh</code> under different
|
||||
conditions, contact me and we will work something out.</div>
|
||||
|
||||
<div class="license">
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public
|
||||
License along with this program. If not,
|
||||
see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.
|
||||
</div>
|
||||
|
||||
<div class="text">If you use <code>tree.hh</code>,
|
||||
please satisfy my curiosity and write me a small email with
|
||||
a bit of explanation of your software and the role of my tree
|
||||
class in it.</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="flush"></div>
|
||||
|
||||
<p>
|
||||
<a href="http://validator.w3.org/check?uri=referer">
|
||||
<img
|
||||
src="http://www.w3.org/Icons/valid-xhtml10"
|
||||
alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
|
||||
</p>
|
||||
|
||||
<!-- Start of StatCounter Code -->
|
||||
<script type="text/javascript">
|
||||
var sc_project=4068217;
|
||||
var sc_invisible=1;
|
||||
var sc_partition=50;
|
||||
var sc_click_stat=1;
|
||||
var sc_security="3f2419f9";
|
||||
</script>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="http://www.statcounter.com/counter/counter_xhtml.js"></script>
|
||||
<noscript>
|
||||
<div class="statcounter">
|
||||
<a title="blogspot statistics"
|
||||
class="statcounter"
|
||||
href="http://www.statcounter.com/blogger/">
|
||||
<img
|
||||
class="statcounter"
|
||||
src="http://c.statcounter.com/4068217/0/3f2419f9/1/"
|
||||
alt="blogspot statistics" /></a>
|
||||
</div>
|
||||
</noscript>
|
||||
<!-- End of StatCounter Code -->
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
162
lib/tree-2.81/doc/projects.html
Normal file
|
@ -0,0 +1,162 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="verify-v1"
|
||||
content="LkU+jobePpu3F8I4GPuTiOjrTukmo1qpWT+dT6SeAfk=" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
|
||||
<meta name="description" content="The tree.hh library provides C++
|
||||
programmers with a container class to store arbitrary data in
|
||||
n-ary tree form. It is compatible with the STL and its
|
||||
algorithms wherever possible. Available under the terms of the GPL." />
|
||||
<meta name="keywords" content="data structure, C++, programming, STL,
|
||||
open source, container class" />
|
||||
<title>tree.hh: an STL-like C++ tree class, projects using tree.hh</title>
|
||||
<link rel="stylesheet" type="text/css" href="tree.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="title">
|
||||
<div id="share">
|
||||
<!-- AddThis Button BEGIN -->
|
||||
<a class="addthis_button" href="http://www.addthis.com/bookmark.php?v=250&username=kpeeters"><img src="http://s7.addthis.com/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a><script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=kpeeters"></script>
|
||||
<!-- AddThis Button END -->
|
||||
</div>
|
||||
<div id="filler">
|
||||
<img id="treeimg" src="tree2.png" alt="[background image]"/>
|
||||
</div>
|
||||
<div id="titletxt">
|
||||
<h1>tree.hh: an STL-like C++ tree class</h1>
|
||||
<h2 class="author">
|
||||
<a href="http://maths.dur.ac.uk/users/kasper.peeters/">Kasper Peeters</a>, kasper.peeters (at) phi-sci.com
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul id="menubar">
|
||||
<li><a href="index.html">Overview</a></li>
|
||||
<li><a href="download.html">Download</a></li>
|
||||
<li><a href="documentation.html">Documentation</a></li>
|
||||
<li><a href="projects.html">Projects using tree.hh</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="linkbar">
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9577963716105989";
|
||||
/* tree linkbar */
|
||||
google_ad_slot = "0194609917";
|
||||
google_ad_width = 728;
|
||||
google_ad_height = 15;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="sidebar">
|
||||
<script type="text/javascript"><!--
|
||||
google_ad_client = "pub-9577963716105989";
|
||||
/* tree.hh vertical ads */
|
||||
google_ad_slot = "3744417434";
|
||||
google_ad_width = 120;
|
||||
google_ad_height = 600;
|
||||
//-->
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
|
||||
</script>
|
||||
</div>
|
||||
|
||||
<h2>Projects using tree.hh</h2>
|
||||
|
||||
<div class="text">The <code>tree.hh</code> library is used in various projects:
|
||||
<dl>
|
||||
<dt><strong><a
|
||||
href="http://cadabra.phi-sci.com/">Cadabra</a></strong></dt>
|
||||
<dd>A field-theory motivated approach to symbolic computer
|
||||
algebra.</dd>
|
||||
<dt><strong><a
|
||||
href="http://www.gnu.org/software/gnash/">Gnash</a></strong></dt>
|
||||
<dd>Gnash is a GNU Flash movie player. Previously, it was only
|
||||
possible to play flash movies with proprietary software. While there
|
||||
are some other free flash players, none support anything beyond SWF
|
||||
v4. Gnash is based on GameSWF, and supports many SWF v7 features.</dd>
|
||||
<dt><strong><a href="http://htmlcxx.sourceforge.net/">htmlcxx</a></strong></dt>
|
||||
<dd>A simple non-validating css1 and html parser for C++.</dd>
|
||||
<dt><strong><a href="http://www.cs.sfu.ca/~anoop/courses/CMPT-379-Fall-2007/index.html">Principles of Compiler Design</a></strong></dt>
|
||||
<dd>A course in compiler design at the Simon Fraser University, Canada.</dd>
|
||||
<dt><strong><a href="http://sourceforge.net/projects/liborigin/">liborigin</a></strong></dt>
|
||||
<dd>A library for reading OriginLab OPJ project files, which is used
|
||||
by <a href="http://soft.proindependent.com/qtiplot.html">QtiPlot</a>
|
||||
and <a href="http://labplot.sourceforge.net/">LabPlot</a>, two
|
||||
applications for data analysis and visualisation.</dd>
|
||||
<dt><strong><a href="http://www.echem.uni-tuebingen.de/~bs/echem/software/EChem++/echem++.shtml">EChem++</a></strong></dt>
|
||||
<dd>A project realizing the idea of a Problem Solving Environment
|
||||
(PSE) in the field of computational electrochemistry. Computer
|
||||
controlled experimental measurements, numerical simulation and
|
||||
analysis of electrochemical processes will be combined under a common
|
||||
user interface.</dd>
|
||||
<dt><strong><a
|
||||
href="http://www.infor.uva.es/~jadiego/">LZCS</a></strong></dt>
|
||||
<dd>A semistructured document transformation tool. LZCS compresses
|
||||
structured documents taking advantage of the redundant information
|
||||
that can appear in the structure. The main idea is that frequently
|
||||
repeated subtrees may exist and these can be replaced by a backward
|
||||
reference to their first occurance. See the <a
|
||||
href="http://www.dcc.uchile.cl/~gnavarro/ps/dcc04.1.ps.gz">accompanying
|
||||
paper</a> for more details.</dd>
|
||||
<dt><strong><a href="http://libofx.sourceforge.net/">libOFX</a></strong></dt>
|
||||
<dd>A parser and an API designed to allow applications to very easily support OFX
|
||||
command responses, usually provided by financial institutions for
|
||||
statement downloads.</dd>
|
||||
<dt><strong>A genetic programming project</strong></dt>
|
||||
<dd>See this <a
|
||||
href="http://www.cs.adfa.edu.au/~shanyin/publications/peel.pdf">paper</a> for
|
||||
more information.</dd>
|
||||
<dt><strong><a href="http://nlp.lsi.upc.edu/freeling/">FreeLing</a></strong></dt>
|
||||
<dd> The FreeLing package consists of a library providing language analysis services (such as morfological analysis, date recognition, PoS tagging, etc.)</dd>
|
||||
</dl>
|
||||
Let me know about your project when you are using
|
||||
<code>tree.hh</code>, so that I can add it to the list.</div>
|
||||
</div>
|
||||
|
||||
<div id="flush"></div>
|
||||
|
||||
<p>
|
||||
<a href="http://validator.w3.org/check?uri=referer">
|
||||
<img
|
||||
src="http://www.w3.org/Icons/valid-xhtml10"
|
||||
alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
|
||||
</p>
|
||||
|
||||
<!-- Start of StatCounter Code -->
|
||||
<script type="text/javascript">
|
||||
var sc_project=4068217;
|
||||
var sc_invisible=1;
|
||||
var sc_partition=50;
|
||||
var sc_click_stat=1;
|
||||
var sc_security="3f2419f9";
|
||||
</script>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="http://www.statcounter.com/counter/counter_xhtml.js"></script>
|
||||
<noscript>
|
||||
<div class="statcounter">
|
||||
<a title="blogspot statistics"
|
||||
class="statcounter"
|
||||
href="http://www.statcounter.com/blogger/">
|
||||
<img
|
||||
class="statcounter"
|
||||
src="http://c.statcounter.com/4068217/0/3f2419f9/1/"
|
||||
alt="blogspot statistics" /></a>
|
||||
</div>
|
||||
</noscript>
|
||||
<!-- End of StatCounter Code -->
|
||||
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
BIN
lib/tree-2.81/doc/structure.png
Normal file
After Width: | Height: | Size: 23 KiB |
417
lib/tree-2.81/doc/structure.svg
Normal file
|
@ -0,0 +1,417 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="631.06183"
|
||||
height="496.98901"
|
||||
id="svg2"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.46"
|
||||
version="1.0"
|
||||
sodipodi:docname="structure.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
inkscape:export-filename="/home/kasper/git/tree/doc/structure.png"
|
||||
inkscape:export-xdpi="71.308388"
|
||||
inkscape:export-ydpi="71.308388">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path3222"
|
||||
d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
|
||||
</marker>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 526.18109 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="744.09448 : 526.18109 : 1"
|
||||
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
|
||||
id="perspective10" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
gridtolerance="10000"
|
||||
guidetolerance="10"
|
||||
objecttolerance="10"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.7"
|
||||
inkscape:cx="401.3348"
|
||||
inkscape:cy="195.91012"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="904"
|
||||
inkscape:window-height="715"
|
||||
inkscape:window-x="155"
|
||||
inkscape:window-y="123" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-79.177704,-27.247875)">
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect2391"
|
||||
width="75"
|
||||
height="25.714285"
|
||||
x="195.57071"
|
||||
y="51.866875" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
x="204.05081"
|
||||
y="71.504051"
|
||||
id="text2383"
|
||||
sodipodi:linespacing="100%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2385"
|
||||
x="204.05081"
|
||||
y="71.504051">head 1</tspan></text>
|
||||
<g
|
||||
id="g4556"
|
||||
transform="translate(-30.304576,0.5199496)">
|
||||
<g
|
||||
transform="translate(120.20815,-92.934035)"
|
||||
id="g4517">
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect3163"
|
||||
width="75"
|
||||
height="25.714285"
|
||||
x="290.87708"
|
||||
y="144.28096" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
x="299.35718"
|
||||
y="163.91814"
|
||||
id="text3165"
|
||||
sodipodi:linespacing="100%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3167"
|
||||
x="299.35718"
|
||||
y="163.91814">head 2</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g3185">
|
||||
<rect
|
||||
y="260.67743"
|
||||
x="79.677704"
|
||||
height="25.714285"
|
||||
width="60.857864"
|
||||
id="rect3175"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="100%"
|
||||
id="text3181"
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
xml:space="preserve"><tspan
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
id="tspan3183"
|
||||
sodipodi:role="line">node</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g3190"
|
||||
transform="translate(92.934022,-1.0101541)">
|
||||
<rect
|
||||
y="260.67743"
|
||||
x="79.677704"
|
||||
height="25.714285"
|
||||
width="60.857864"
|
||||
id="rect3192"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="100%"
|
||||
id="text3194"
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
xml:space="preserve"><tspan
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
id="tspan3196"
|
||||
sodipodi:role="line">node</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g3198"
|
||||
transform="translate(201.02035,-1.010154)">
|
||||
<rect
|
||||
y="260.67743"
|
||||
x="79.677704"
|
||||
height="25.714285"
|
||||
width="60.857864"
|
||||
id="rect3200"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="100%"
|
||||
id="text3202"
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
xml:space="preserve"><tspan
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
id="tspan3204"
|
||||
sodipodi:role="line">node</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 112.12693,256.36198 C 148.49242,226.0574 178.797,238.17923 196.97975,252.32137"
|
||||
id="path3206"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
x="148.49242"
|
||||
y="228.07771"
|
||||
id="text3208"
|
||||
sodipodi:linespacing="100%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3210"
|
||||
x="148.49242"
|
||||
y="228.07771">next sibling</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
x="108.37365"
|
||||
y="333.25311"
|
||||
id="text3212"
|
||||
sodipodi:linespacing="100%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3214"
|
||||
x="108.37365"
|
||||
y="333.25311">previous sibling</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 200.01021,290.38754 C 163.64472,320.69212 133.34014,308.57029 115.15739,294.42815"
|
||||
id="path3994"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 209.10158,83.625892 L 101.01525,249.29091"
|
||||
id="path3996" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.99999809px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
x="-66.628067"
|
||||
y="212.73572"
|
||||
id="text4513"
|
||||
sodipodi:linespacing="100%"
|
||||
transform="matrix(0.5909299,-0.8067229,0.8067229,0.5909299,0,0)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4515"
|
||||
x="-66.628067"
|
||||
y="212.73572">first child</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 220.21325,254.6613 C 256.57874,224.35672 286.88332,236.47855 305.06607,250.62069"
|
||||
id="path4522"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 306.07622,290.38754 C 269.71073,320.69212 239.40615,308.57029 221.2234,294.42815"
|
||||
id="path4524"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 257.96217,83.372105 L 323.88568,251.56499"
|
||||
id="path4526"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:14.99999809px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
x="241.30775"
|
||||
y="-202.79788"
|
||||
id="text4528"
|
||||
sodipodi:linespacing="100%"
|
||||
transform="matrix(0.4272211,0.9041472,-0.9041472,0.4272211,0,0)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4530"
|
||||
x="241.30775"
|
||||
y="-202.79788">last child</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 274.76149,46.569867 C 311.12698,16.265292 341.43156,28.387122 359.61431,42.529262"
|
||||
id="path4532"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 360.62446,84.316419 C 324.25897,114.621 293.95439,102.49917 275.77164,88.357029"
|
||||
id="path4534"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:9.99999974, 9.99999974;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 471.64002,63.927916 C 549.62414,63.927916 549.62414,63.927916 549.62414,63.927916"
|
||||
id="path4546" />
|
||||
<g
|
||||
id="g4562"
|
||||
transform="translate(-95.964492,0.2910246)">
|
||||
<g
|
||||
transform="translate(365.59772,-92.70511)"
|
||||
id="g4548">
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4550"
|
||||
width="75"
|
||||
height="25.714285"
|
||||
x="290.87708"
|
||||
y="144.28096" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
x="299.35718"
|
||||
y="163.91814"
|
||||
id="text4552"
|
||||
sodipodi:linespacing="100%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4554"
|
||||
x="299.35718"
|
||||
y="163.91814">head n</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g4568"
|
||||
transform="translate(102.53048,214.52734)">
|
||||
<rect
|
||||
y="260.67743"
|
||||
x="79.677704"
|
||||
height="25.714285"
|
||||
width="60.857864"
|
||||
id="rect4570"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="100%"
|
||||
id="text4572"
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
xml:space="preserve"><tspan
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
id="tspan4574"
|
||||
sodipodi:role="line">node</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g4576"
|
||||
transform="translate(195.4645,213.51719)">
|
||||
<rect
|
||||
y="260.67743"
|
||||
x="79.677704"
|
||||
height="25.714285"
|
||||
width="60.857864"
|
||||
id="rect4578"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="100%"
|
||||
id="text4580"
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
xml:space="preserve"><tspan
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
id="tspan4582"
|
||||
sodipodi:role="line">node</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g4584"
|
||||
transform="translate(303.55083,213.51719)">
|
||||
<rect
|
||||
y="260.67743"
|
||||
x="79.677704"
|
||||
height="25.714285"
|
||||
width="60.857864"
|
||||
id="rect4586"
|
||||
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="100%"
|
||||
id="text4588"
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
xml:space="preserve"><tspan
|
||||
y="278.85458"
|
||||
x="87.344574"
|
||||
id="tspan4590"
|
||||
sodipodi:role="line">node</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 214.65741,470.88933 C 251.0229,440.58475 281.32748,452.70658 299.51023,466.84872"
|
||||
id="path4592"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 302.54069,504.91489 C 266.1752,535.21947 235.87062,523.09764 217.68787,508.9555"
|
||||
id="path4602"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 313.65237,301.1837 L 205.56604,466.84872"
|
||||
id="path4604" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 322.74373,469.18865 C 359.10922,438.88407 389.4138,451.0059 407.59655,465.14804"
|
||||
id="path4610"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 408.6067,504.91489 C 372.24121,535.21947 341.93663,523.09764 323.75388,508.9555"
|
||||
id="path4612"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
|
||||
d="M 329.17792,299.91976 L 426.41616,466.09234"
|
||||
id="path4614"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:25px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
|
||||
x="257.5726"
|
||||
y="-691.83954"
|
||||
id="text4620"
|
||||
sodipodi:linespacing="100%"
|
||||
transform="matrix(0,1,-1,0,0,0)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4622"
|
||||
x="257.5726"
|
||||
y="-691.83954">depth</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.70000005;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 665.71429,68.076468 L 665.71429,479.50504"
|
||||
id="path4624" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 20 KiB |
171
lib/tree-2.81/doc/tree.css
Normal file
|
@ -0,0 +1,171 @@
|
|||
|
||||
body {
|
||||
font: 10pt "Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, sans-serif;
|
||||
}
|
||||
div#container {
|
||||
min-width: 700px;
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 30px;
|
||||
background: #f0f0f0;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-box-shadow: 1px 1px 9px #888;
|
||||
padding: 5px 15px 5px 15px;
|
||||
}
|
||||
div#titletxt {
|
||||
margin: -150px 0 30px 240px;
|
||||
height: 70px;
|
||||
}
|
||||
div#filler {
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
background: url("filler.png");
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
margin-top: 5px;
|
||||
-moz-box-shadow: 1px 1px 5px #888;
|
||||
}
|
||||
img#treeimg {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* Donations */
|
||||
|
||||
form#donate {
|
||||
text-align: center;
|
||||
margin-top: 1ex;
|
||||
margin-bottom: 1ex;
|
||||
}
|
||||
|
||||
/* Layout containers */
|
||||
|
||||
div#linkbar {
|
||||
margin-right: 135px;
|
||||
display: inline;
|
||||
}
|
||||
div#main {
|
||||
margin-right: 135px;
|
||||
display: inline;
|
||||
}
|
||||
div#sidebar {
|
||||
margin-top: 16px;
|
||||
float: right;
|
||||
display: inline;
|
||||
width: 125px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
div#flush {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
/* Title color/style */
|
||||
|
||||
#title h1 {
|
||||
font-size: 30px;
|
||||
color: #b00000;
|
||||
}
|
||||
#title h2 {
|
||||
font-size: 11pt;
|
||||
font-weight: normal;
|
||||
color: black;
|
||||
border-bottom: 0px;
|
||||
}
|
||||
|
||||
/* Menu */
|
||||
|
||||
ul#menubar {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 35px;
|
||||
margin-right: 2ex;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#menubar li {
|
||||
display: inline;
|
||||
background: #b00000;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
padding: .5ex 1ex .5ex 1ex;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-box-shadow: 1px 1px 9px #888;
|
||||
}
|
||||
#menubar li:hover {
|
||||
background: #009000;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-box-shadow: 1px 1px 6px #888;
|
||||
}
|
||||
|
||||
#menubar a {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Main color/style */
|
||||
|
||||
div#share {
|
||||
position: absolute;
|
||||
right: 50px;
|
||||
top: 36px;
|
||||
}
|
||||
div#plusone {
|
||||
position: absolute;
|
||||
left: 50px;
|
||||
top: 36px;
|
||||
}
|
||||
|
||||
#main h2 {
|
||||
margin-top: 2ex;
|
||||
margin-right: 135px;
|
||||
display: block;
|
||||
background: #b00000;
|
||||
color: white;
|
||||
padding-left: 1ex;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-box-shadow: 1px 1px 9px #888;
|
||||
}
|
||||
div.text {
|
||||
margin-left: 120px;
|
||||
margin-bottom: 2ex;
|
||||
margin-right: 145px;
|
||||
}
|
||||
div.license {
|
||||
margin-left: 140px;
|
||||
margin-bottom: 2ex;
|
||||
margin-right: 155px;
|
||||
}
|
||||
div.filename {
|
||||
margin-left: 200px;
|
||||
margin-bottom: 1ex;
|
||||
}
|
||||
img.structure {
|
||||
margin-top: 1ex;
|
||||
margin-bottom: 1ex;
|
||||
margin-left: 3ex;
|
||||
}
|
||||
dd {
|
||||
margin-bottom: 2ex;
|
||||
}
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
/* Code listing */
|
||||
|
||||
div.code {
|
||||
margin: 1ex;
|
||||
width: 90%;
|
||||
border: dotted 1px black;
|
||||
background: #f8f8f8;
|
||||
font-size: 8pt;
|
||||
padding: 1ex;
|
||||
}
|
||||
.code pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
BIN
lib/tree-2.81/doc/tree.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
lib/tree-2.81/doc/tree.png
Normal file
After Width: | Height: | Size: 888 KiB |
388
lib/tree-2.81/doc/tree.tex
Normal file
|
@ -0,0 +1,388 @@
|
|||
\documentclass[11pt]{kasper}
|
||||
%
|
||||
% If you do not have 'kasper.cls', see
|
||||
% http://www.damtp.cam.ac.uk/user/kp229/texstuff .
|
||||
|
||||
\usepackage{makeidx}
|
||||
\usepackage{verbatim}
|
||||
\usepackage{relsize}
|
||||
\makeindex
|
||||
%\newcommand{\toindex}[1]{#1\index{#1}}
|
||||
|
||||
\newcommand{\member}[1]{{\tt #1}\index{#1}}
|
||||
%\newcommand{\member}[1]{{\tt #1}}
|
||||
|
||||
\def\mystrut{\vbox to 8.5pt{}\vtop to 3.5pt{}}
|
||||
\def\V{\hskip10pt\vrule\hskip10pt}
|
||||
\def\T{\hskip10pt\vrule\vrule height2.5pt depth -2.1pt width 10pt}
|
||||
\def\L{\hskip10pt\vrule height 8.5pt depth -2.1pt
|
||||
\vrule height2.5pt depth -2.1pt width 10pt}
|
||||
\def\N{\hskip10pt\phantom{\vrule}\hskip10pt}
|
||||
\def\hw{\hskip-1000pt plus 1fil}
|
||||
|
||||
% to test: insert before end of subtree
|
||||
|
||||
\begin{document}
|
||||
\title{{\tt tree.hh} documentation}
|
||||
\author{Kasper Peeters}
|
||||
\email{kasper.peeters@gmail.com}
|
||||
\maketitle
|
||||
\begin{abstract}
|
||||
The {\tt tree.hh} library for C++ provides an STL-like container class
|
||||
for n-ary trees, templated over the data stored at the nodes. Various
|
||||
types of iterators are provided (post-order, pre-order, and
|
||||
others). Where possible the access methods are compatible with the STL
|
||||
or alternative algorithms are available. The library is available
|
||||
under the terms of the GNU General Public License.\\[3ex]
|
||||
Code and examples available at: {\tt http://tree.phi-sci.com/}\\[3ex]
|
||||
{\bf This documentation is not yet entirely complete. Refer to the {\tt
|
||||
tree.hh} header file for a full list of member functions.}
|
||||
\end{abstract}
|
||||
\vfill
|
||||
\maketoc
|
||||
\eject
|
||||
|
||||
\begin{sectionunit}
|
||||
\title{Overview}
|
||||
\maketitle
|
||||
\begin{sectionunit}
|
||||
\title{The container class}
|
||||
\maketitle
|
||||
The tree class of {\tt tree.hh} is a templated container class in the
|
||||
spirit of the STL. It organises data in the form of a so-called n-ary
|
||||
tree. This is a tree in which every node is connected to an arbitrary
|
||||
number of child nodes. Nodes at the same level of the tree are called
|
||||
``siblings'', while nodes that are below a given node are called its
|
||||
``children''. At the top of the tree, there is a set of nodes which
|
||||
are characterised by the fact that they do not have any parents. The
|
||||
collection of these nodes is called the ``head'' of the tree. See
|
||||
figure~\ref{f:overview} for a pictorial illustration of this
|
||||
structure (90 degrees rotated for convenience).
|
||||
\begin{figure}[th]
|
||||
\begin{center}
|
||||
\includegraphics[width=.5\textwidth]{treefig}
|
||||
\caption{Overview of the tree structure. The elements at the top of
|
||||
the tree (here displayed at the left for convenience) are in the
|
||||
``head'' (there can be more than one such element). Every node is
|
||||
linked to its children using the ``first child'' and ``last child''
|
||||
links. In addition, all nodes on a given level are doubly-linked using
|
||||
the ``previous sibling'' and ``next sibling'' links. The ``depth'' of
|
||||
a given node refers to the horizontal distance from the head nodes.}
|
||||
\label{f:overview}
|
||||
\end{center}
|
||||
\end{figure}
|
||||
|
||||
The tree class is templated over the data objects stored at the nodes;
|
||||
just like you can have a {\tt vector<string>} you can now have a
|
||||
{\tt tree<string>}. Many STL algorithms work on this data structure,
|
||||
and where necessary alternatives have been provided.
|
||||
\medskip
|
||||
|
||||
\end{sectionunit}
|
||||
\begin{sectionunit}
|
||||
\title{Iterators}
|
||||
\maketitle
|
||||
|
||||
The essential difference between a container with the structure of a
|
||||
tree and the STL containers is that the latter are ``linear''. While
|
||||
the STL containers thus only have essentially one way in which one can
|
||||
iterate over their elements, this is not true for trees. The {\tt
|
||||
tree.hh} library provides (at present) four different iteration
|
||||
schemes. To describe them, consider the following tree:
|
||||
\begin{equation*}
|
||||
\vcenter{\offinterlineskip
|
||||
\halign{&#\mystrut\hfil\cr
|
||||
root \hw\cr
|
||||
\T A \cr
|
||||
\V \T B \cr
|
||||
\V \L C \cr
|
||||
\L D \cr
|
||||
\N \T E \cr
|
||||
\N \L F \cr}}
|
||||
\end{equation*}
|
||||
The three iteration types and the resulting order in which nodes are
|
||||
visited are tabulated below:
|
||||
\begin{center}
|
||||
\begin{tabular}{llll}
|
||||
pre-order (default) & ``element before children'' &
|
||||
\member{pre\_order\_iterator} & root A B C D E F \\
|
||||
post-order & ``element after children'' &
|
||||
\member{post\_order\_iterator} & B C A E F D root \\
|
||||
breadth-first & &
|
||||
\member{breadth\_first\_iterator} & root A D B C E F \\
|
||||
sibling & ``only siblings'' &
|
||||
\member{sibling\_iterator} & (for ex.) A D \\
|
||||
fixed-depth & &
|
||||
\member{fixed\_depth\_iterator} & (for ex.) A D \\
|
||||
leaf & &
|
||||
\member{leaf\_iterator} & B C E F
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
The pre-order ones are the default iterators, and therefore also known
|
||||
under the name of {\tt iterator}. Sibling iterators and fixed-depth
|
||||
iterators iterate only over the nodes at a given depth of the
|
||||
tree. The former restrict themselves to the child nodes of one given
|
||||
node, while the latter iterates over all child nodes at the given
|
||||
depth. Finally, leaf iterators iterate over all leafs (bottom-most)
|
||||
nodes of the tree.
|
||||
|
||||
There are copy constructors that will convert iterators of the
|
||||
various types into each other. The post- and pre-order iterators are
|
||||
both also known as ``depth-first'', in contrast to the
|
||||
``breadth-first'' iterator.
|
||||
|
||||
The begin and end iterators of a tree can be obtained using
|
||||
\member{begin()} and \member{end()} (for pre-order iterators) or
|
||||
alternatively \member{begin\_post()} and \member{end\_post()} (for
|
||||
post-order iterators) and \member{begin\_leaf()} and
|
||||
\member{end\_leaf()} (for leaf iterators). Similarly, the begin and
|
||||
end sibling iterators can be obtained by calling
|
||||
\member{begin(iterator)} and \member{end(iterator)}. The range of
|
||||
children of a given node can also be obtained directly from an
|
||||
iterator, by using the {\tt iterator::begin()} and {\tt
|
||||
iterator::end()} member functions.
|
||||
|
||||
If you want to (temporarily) make an iterator not go into the child
|
||||
subtree, call the member function \member{skip\_children}. This will only
|
||||
keep effect for a single increment or decrement of the
|
||||
iterator. Finally, whether or not an iterator is actually pointing at
|
||||
a node (i.e.~is not an ``end'' iterator) can be tested using the
|
||||
\member{is\_valid(iterator)} member of the tree class.
|
||||
|
||||
\end{sectionunit}
|
||||
\end{sectionunit}
|
||||
|
||||
\begin{sectionunit}
|
||||
\title{Basic operations}
|
||||
\maketitle
|
||||
\begin{description}
|
||||
\item[Initialising] There are two nontrivial constructors. One which takes
|
||||
a single node element as argument. It constructs a tree with this node
|
||||
begin the sole node in the head (in other words, it is a combination
|
||||
of a trivial constructor together with a \member{set\_head} call).
|
||||
The other non-trivial constructor takes an iterator, and copies the
|
||||
subtree starting at that node into the newly created tree (useful for
|
||||
constructing new tree objects given by subtrees of existing trees).
|
||||
|
||||
\item[Tree traversal] Besides the \member{operator++} and
|
||||
\member{operator--} members for step-wise traversal through the tree,
|
||||
it is also possible to use the \member{operator+=} and \member{operator-=}
|
||||
member functions to make more than one step at the same time (though
|
||||
these are linear time, not amortized constant). The result of stepping
|
||||
beyond the end of the tree or stepping beyond the end of a sibling
|
||||
range (for sibling iterators) is undefined.
|
||||
|
||||
The parent of a given node can be reached by calling the \member{parent}
|
||||
member of the tree object, giving it an iterator pointing to the node.
|
||||
|
||||
If you know the number of children of a given node, you can get direct
|
||||
access to the $n$th child by using the \member{child} member
|
||||
function. Note that the value of the index is not checked and should
|
||||
therefore always be valid.
|
||||
|
||||
\item[Appending child nodes] Nodes can be added as children of a given
|
||||
node using the \member{append\_child} member function.
|
||||
|
||||
\item[Inserting nodes] Nodes can be inserted at the same depth as a
|
||||
given other node using the \member{insert} and \member{insert\_after}
|
||||
members functions. This is also how you insert the first node into a
|
||||
tree.
|
||||
\end{description}
|
||||
\end{sectionunit}
|
||||
|
||||
\begin{sectionunit}
|
||||
\title{Other algorithms}
|
||||
\maketitle
|
||||
\begin{sectionunit}
|
||||
\title{Non-mutating algorithms}
|
||||
\maketitle
|
||||
\begin{description}
|
||||
\item[Counting nodes] The total number of nodes of a tree can be
|
||||
obtained using the \member{size} member function, while the number of
|
||||
children of a given node can be obtained with a call to
|
||||
\member{number\_of\_children(iterator)}. Similarly, the number of
|
||||
nodes at a given depth (the number of siblings of a given node) can be
|
||||
obtained using the \member{number\_of\_siblings} member function.
|
||||
\item[Determining depth] The \member{depth()} member function returns the
|
||||
distance of a node to the root.
|
||||
\item[Accessing siblings by their index] See the next item.
|
||||
\item[Determining index in a sibling range] In order to determine the
|
||||
index of a node in the range of siblings to which it belongs, use the
|
||||
\member{index(sibling\_iterator)} member function. The first sibling node
|
||||
has index 0. The reverse of this function (obtaining a sibling node
|
||||
given its index in the range of siblings) is called
|
||||
\member{child(const iterator\_base\&, unsigned int)}.
|
||||
\item[Comparing trees] While the STL \member{equal} algorithm can be used
|
||||
to compare the values of the nodes in two different trees, it does not
|
||||
know about the structure of the tree. If you want the comparison to
|
||||
take this into account, use the \member{equal(iterator, iterator,
|
||||
iterator, BinaryPredicate)} call of the tree class. As an addition to
|
||||
the STL algorithm, the length of the first range does not have to be
|
||||
equal to the length of the range pointed to by the second iterator.
|
||||
|
||||
There is also an \member{equal\_subtree} algorithm which takes only
|
||||
two iterators, pointing to the (single-node) heads of two
|
||||
subtrees.
|
||||
\end{description}
|
||||
\end{sectionunit}
|
||||
|
||||
\begin{sectionunit}
|
||||
\title{Mutating algorithms}
|
||||
\maketitle
|
||||
\begin{description}
|
||||
\item[Erasing nodes and subtrees] In order to remove a node including
|
||||
its children from the tree, use the \member{erase(iterator)} call. If you
|
||||
just want to erase the children, but not the node itself, use the
|
||||
\member{erase\_children(iterator)} call.
|
||||
|
||||
\item[Replacing individual nodes or subtrees]
|
||||
|
||||
\item[Flattening subtrees] The procedure of moving all children of a
|
||||
given node to be siblings of that node is called ``flattening''; it
|
||||
acts as
|
||||
\begin{equation*}
|
||||
\vcenter{\offinterlineskip
|
||||
\halign{&#\mystrut\hfil\cr
|
||||
apple \hw\cr
|
||||
\T banana\cr
|
||||
\V \T pear \cr
|
||||
\V \T strawberry \cr
|
||||
\V \L cherry \cr
|
||||
\L grape\cr}}\quad\rightarrow\quad
|
||||
\vcenter{\offinterlineskip
|
||||
\halign{&#\mystrut\hfil\cr
|
||||
apple \hw\cr
|
||||
\T banana\cr
|
||||
\T pear \cr
|
||||
\T strawberry \cr
|
||||
\T cherry \cr
|
||||
\L grape\cr}}
|
||||
\end{equation*}
|
||||
% \begin{screen}
|
||||
% apple apple
|
||||
% banana banana
|
||||
% pear -> pear
|
||||
% strawberry strawberry
|
||||
% cherry cherry
|
||||
% grape grape
|
||||
% \end{screen}
|
||||
when the tree is flattened at the ``banana'' node.
|
||||
|
||||
\item[Moving or exchanging subtrees] Simple exchange of one sibling node with the
|
||||
next one is done through the member function \member{swap(sibling\_iterator)}. The
|
||||
iterator remains valid and remains pointing to the moved subtree.
|
||||
|
||||
More complicated move operations are the \member{move\_ontop},
|
||||
\member{move\_before} and \member{move\_after} ones. These all take
|
||||
two iterators, a source and a target. The member
|
||||
\member{move\_ontop(target, source)} removes the `target' node and
|
||||
all its children, and replaces it with the `source' node and its
|
||||
children. The `source' subtree is removed from its original location.
|
||||
The other two move members do a similar thing, differing only in the
|
||||
node which is to be replaced.
|
||||
|
||||
\item[Extracting subtrees] You can create a new tree object
|
||||
filled with the data of a subtree of the original tree. This is
|
||||
analogous to the extraction of a substring of a string. The relevant
|
||||
member function is \member{subtree(sibling\_iterator,
|
||||
sibling\_iterator)} which takes a range of siblings as argument.
|
||||
There is also a slight variation of this member, which does not return
|
||||
a tree object but instead populates one that is passed as an argument
|
||||
(useful if you want to call this on a tree object subclassed from
|
||||
{\tt tree<T>}.
|
||||
|
||||
\item[Sorting] The standard STL sort algorithm is not very useful for
|
||||
trees, because it only exchanges values, not nodes. Applying it to a
|
||||
tree would mean that the structure of the tree remains unmodified,
|
||||
only node values get moved around (not their subtrees).
|
||||
|
||||
Therefore, the {\tt tree} class has its own sort member. It comes in
|
||||
two forms, just like the STL sort, namely
|
||||
\begin{screen}
|
||||
void sort(sibling_iterator from, sibling_iterator to, bool deep=false);
|
||||
|
||||
template<class StrictWeakOrdering>
|
||||
void sort(sibling_iterator from, sibling_iterator to,
|
||||
StrictWeakOrdering comp, bool deep=false);
|
||||
\end{screen}
|
||||
The result of a call to either of these is that the nodes in the range
|
||||
described by the two iterators get sorted. If the boolean {\tt deep}
|
||||
is true, the subtrees of all these nodes will get sorted as well (and
|
||||
so one can sort the entire tree in one call). As in the STL, you can
|
||||
use the second form of this function to pass your own comparison
|
||||
class.
|
||||
|
||||
If the nodes to which the two iterators point are not in the same
|
||||
sibling range (i.e.~not at the same depth in the tree), the result is undefined.
|
||||
|
||||
\item[Merging] One way in which one might think of indicating the
|
||||
position where new nodes are to be inserted, is to give the path that
|
||||
leads to the insertion point. For instance, given the tree
|
||||
\begin{equation*}
|
||||
\vcenter{\offinterlineskip
|
||||
\halign{&#\mystrut\hfil\cr
|
||||
apple \hw\cr
|
||||
\T banana\cr
|
||||
\V \T pear \cr
|
||||
\V \T strawberry \cr
|
||||
\V \L cherry \cr
|
||||
\L grape\cr}}
|
||||
\end{equation*}
|
||||
one could imagine using the sub-tree
|
||||
\begin{equation*}
|
||||
\vcenter{\offinterlineskip
|
||||
\halign{&#\mystrut\hfil\cr
|
||||
apple \hw\cr
|
||||
\L banana\cr
|
||||
\N \T coconut \cr
|
||||
\N \L raspberry \cr}}
|
||||
\end{equation*}
|
||||
to indicate that the nodes ``coconut'' and ``raspberry'' are to be
|
||||
inserted as new children of the ``banana'' node. In {\tt tree.hh} this
|
||||
process is called \emph{tree merging}. It can do the simple addition
|
||||
of children as above, but actually handles the generic case too: as
|
||||
an example consider the merge
|
||||
\begin{equation*}
|
||||
\text{\tt merge}\left[
|
||||
\vcenter{\offinterlineskip
|
||||
\halign{&#\mystrut\hfil\cr
|
||||
apple \hw\cr
|
||||
\T banana\cr
|
||||
\V \T pear \cr
|
||||
\V \T strawberry \cr
|
||||
\V \L cherry \cr
|
||||
\T grape\cr
|
||||
blueberry \cr}}\quad, \quad
|
||||
\vcenter{\offinterlineskip
|
||||
\halign{&#\mystrut\hfil\cr
|
||||
apple \hw\cr
|
||||
\T banana\cr
|
||||
\V \T coconut \cr
|
||||
\V \L raspberry \cr
|
||||
\T tangerine \cr
|
||||
\V \L plum\cr
|
||||
blueberry \cr
|
||||
\N \L orange \cr}}\right]\quad\rightarrow\quad
|
||||
\vcenter{\offinterlineskip
|
||||
\halign{&#\mystrut\hfil\cr
|
||||
apple \hw\cr
|
||||
\T banana\cr
|
||||
\V \T pear\cr
|
||||
\V \T strawberry\cr
|
||||
\V \T cherry\cr
|
||||
\V \T coconut \cr
|
||||
\V \L raspberry \cr
|
||||
\T grape\cr
|
||||
\T tangerine \cr
|
||||
\V \L plum\cr
|
||||
blueberry \cr
|
||||
\N \L orange \cr}}
|
||||
\end{equation*}
|
||||
As is clear from the above, the arguments to \member{merge} are two
|
||||
sibling ranges.
|
||||
\end{description}
|
||||
\end{sectionunit}
|
||||
\end{sectionunit}
|
||||
|
||||
\printindex
|
||||
\end{document}
|
BIN
lib/tree-2.81/doc/tree2.png
Normal file
After Width: | Height: | Size: 141 KiB |
190
lib/tree-2.81/doc/treefig.eps
Normal file
|
@ -0,0 +1,190 @@
|
|||
%!PS-Adobe-2.0 EPSF-2.0
|
||||
%%Title: tree.eps
|
||||
%%Creator: fig2dev Version 3.2 Patchlevel 0-beta3
|
||||
%%CreationDate: Fri May 3 12:41:08 2002
|
||||
%%For: kp229@church.amtp.cam.ac.uk (Kasper Peeters)
|
||||
%%Orientation: Portrait
|
||||
%%BoundingBox: 0 0 324 252
|
||||
%%Pages: 0
|
||||
%%BeginSetup
|
||||
%%EndSetup
|
||||
%%Magnification: 1.0000
|
||||
%%EndComments
|
||||
/$F2psDict 200 dict def
|
||||
$F2psDict begin
|
||||
$F2psDict /mtrx matrix put
|
||||
/col-1 {0 setgray} bind def
|
||||
/col0 {0.000 0.000 0.000 srgb} bind def
|
||||
/col1 {0.000 0.000 1.000 srgb} bind def
|
||||
/col2 {0.000 1.000 0.000 srgb} bind def
|
||||
/col3 {0.000 1.000 1.000 srgb} bind def
|
||||
/col4 {1.000 0.000 0.000 srgb} bind def
|
||||
/col5 {1.000 0.000 1.000 srgb} bind def
|
||||
/col6 {1.000 1.000 0.000 srgb} bind def
|
||||
/col7 {1.000 1.000 1.000 srgb} bind def
|
||||
/col8 {0.000 0.000 0.560 srgb} bind def
|
||||
/col9 {0.000 0.000 0.690 srgb} bind def
|
||||
/col10 {0.000 0.000 0.820 srgb} bind def
|
||||
/col11 {0.530 0.810 1.000 srgb} bind def
|
||||
/col12 {0.000 0.560 0.000 srgb} bind def
|
||||
/col13 {0.000 0.690 0.000 srgb} bind def
|
||||
/col14 {0.000 0.820 0.000 srgb} bind def
|
||||
/col15 {0.000 0.560 0.560 srgb} bind def
|
||||
/col16 {0.000 0.690 0.690 srgb} bind def
|
||||
/col17 {0.000 0.820 0.820 srgb} bind def
|
||||
/col18 {0.560 0.000 0.000 srgb} bind def
|
||||
/col19 {0.690 0.000 0.000 srgb} bind def
|
||||
/col20 {0.820 0.000 0.000 srgb} bind def
|
||||
/col21 {0.560 0.000 0.560 srgb} bind def
|
||||
/col22 {0.690 0.000 0.690 srgb} bind def
|
||||
/col23 {0.820 0.000 0.820 srgb} bind def
|
||||
/col24 {0.500 0.190 0.000 srgb} bind def
|
||||
/col25 {0.630 0.250 0.000 srgb} bind def
|
||||
/col26 {0.750 0.380 0.000 srgb} bind def
|
||||
/col27 {1.000 0.500 0.500 srgb} bind def
|
||||
/col28 {1.000 0.630 0.630 srgb} bind def
|
||||
/col29 {1.000 0.750 0.750 srgb} bind def
|
||||
/col30 {1.000 0.880 0.880 srgb} bind def
|
||||
/col31 {1.000 0.840 0.000 srgb} bind def
|
||||
|
||||
end
|
||||
save
|
||||
-126.0 342.0 translate
|
||||
1 -1 scale
|
||||
|
||||
/cp {closepath} bind def
|
||||
/ef {eofill} bind def
|
||||
/gr {grestore} bind def
|
||||
/gs {gsave} bind def
|
||||
/sa {save} bind def
|
||||
/rs {restore} bind def
|
||||
/l {lineto} bind def
|
||||
/m {moveto} bind def
|
||||
/rm {rmoveto} bind def
|
||||
/n {newpath} bind def
|
||||
/s {stroke} bind def
|
||||
/sh {show} bind def
|
||||
/slc {setlinecap} bind def
|
||||
/slj {setlinejoin} bind def
|
||||
/slw {setlinewidth} bind def
|
||||
/srgb {setrgbcolor} bind def
|
||||
/rot {rotate} bind def
|
||||
/sc {scale} bind def
|
||||
/sd {setdash} bind def
|
||||
/ff {findfont} bind def
|
||||
/sf {setfont} bind def
|
||||
/scf {scalefont} bind def
|
||||
/sw {stringwidth} bind def
|
||||
/tr {translate} bind def
|
||||
/tnt {dup dup currentrgbcolor
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add
|
||||
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
|
||||
bind def
|
||||
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
|
||||
4 -2 roll mul srgb} bind def
|
||||
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
|
||||
/$F2psEnd {$F2psEnteredState restore end} def
|
||||
%%EndProlog
|
||||
|
||||
$F2psBegin
|
||||
10 setmiterlimit
|
||||
n -1000 6700 m -1000 -1000 l 8494 -1000 l 8494 6700 l cp clip
|
||||
0.06000 0.06000 sc
|
||||
% Polyline
|
||||
7.500 slw
|
||||
gs clippath
|
||||
4380 3828 m 4350 3948 l 4320 3828 l 4320 3990 l 4380 3990 l cp
|
||||
4320 3222 m 4350 3102 l 4380 3222 l 4380 3060 l 4320 3060 l cp
|
||||
clip
|
||||
n 4350 3075 m 4350 3975 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 4320 3222 m 4350 3102 l 4380 3222 l 4350 3222 l 4320 3222 l cp gs 0.00 setgray ef gr col0 s
|
||||
% arrowhead
|
||||
n 4380 3828 m 4350 3948 l 4320 3828 l 4350 3828 l 4380 3828 l cp gs 0.00 setgray ef gr col0 s
|
||||
% Polyline
|
||||
[60] 0 sd
|
||||
n 4350 4350 m 4350 5475 l gs col0 s gr [] 0 sd
|
||||
% Polyline
|
||||
gs clippath
|
||||
4021 5328 m 4039 5450 l 3966 5351 l 4028 5500 l 4083 5477 l cp
|
||||
clip
|
||||
n 2550 1875 m 4050 5475 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 4021 5328 m 4039 5450 l 3966 5351 l 3993 5339 l 4021 5328 l cp gs 0.00 setgray ef gr col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
4380 2628 m 4350 2748 l 4320 2628 l 4320 2790 l 4380 2790 l cp
|
||||
4320 2022 m 4350 1902 l 4380 2022 l 4380 1860 l 4320 1860 l cp
|
||||
clip
|
||||
n 4350 1875 m 4350 2775 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 4320 2022 m 4350 1902 l 4380 2022 l 4350 2022 l 4320 2022 l cp gs 0.00 setgray ef gr col0 s
|
||||
% arrowhead
|
||||
n 4380 2628 m 4350 2748 l 4320 2628 l 4350 2628 l 4380 2628 l cp gs 0.00 setgray ef gr col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
3903 1695 m 4023 1725 l 3903 1755 l 4065 1755 l 4065 1695 l cp
|
||||
clip
|
||||
n 2550 1725 m 4050 1725 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 3903 1695 m 4023 1725 l 3903 1755 l 3903 1725 l 3903 1695 l cp gs 0.00 setgray ef gr col0 s
|
||||
% Polyline
|
||||
gs clippath
|
||||
6828 1695 m 6948 1725 l 6828 1755 l 6990 1755 l 6990 1695 l cp
|
||||
clip
|
||||
n 4725 1725 m 6975 1725 l gs col0 s gr gr
|
||||
|
||||
% arrowhead
|
||||
n 6828 1695 m 6948 1725 l 6828 1755 l 6828 1725 l 6828 1695 l cp gs 0.00 setgray ef gr col0 s
|
||||
% Polyline
|
||||
[60] 0 sd
|
||||
n 7275 1950 m 7275 2625 l gs col0 s gr [] 0 sd
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
2100 1800 m
|
||||
gs 1 -1 sc (head) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
4200 1800 m
|
||||
gs 1 -1 sc (node) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
4200 3000 m
|
||||
gs 1 -1 sc (node) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
4200 4200 m
|
||||
gs 1 -1 sc (node) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
4200 5700 m
|
||||
gs 1 -1 sc (node) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
4575 2250 m
|
||||
gs 1 -1 sc (next sibling) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
4575 2475 m
|
||||
gs 1 -1 sc (prev sibling) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
4575 3450 m
|
||||
gs 1 -1 sc (next sibling) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
4575 3675 m
|
||||
gs 1 -1 sc (prev sibling) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
5850 1650 m
|
||||
gs 1 -1 sc (first child) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
2925 1650 m
|
||||
gs 1 -1 sc (first child) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
7125 1800 m
|
||||
gs 1 -1 sc (node) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
7125 2925 m
|
||||
gs 1 -1 sc (node) col0 sh gr
|
||||
/Times-Roman ff 180.00 scf sf
|
||||
2550 3900 m
|
||||
gs 1 -1 sc (last child) col0 sh gr
|
||||
$F2psEnd
|
||||
rs
|
44
lib/tree-2.81/doc/treefig.fig
Normal file
|
@ -0,0 +1,44 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
4350 3075 4350 3975
|
||||
2 1 1 1 0 7 0 0 -1 4.000 0 0 -1 0 0 2
|
||||
4350 4350 4350 5475
|
||||
2 1 0 1 0 7 0 0 -1 4.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2550 1875 4050 5475
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 1 2
|
||||
1 1 1.00 60.00 120.00
|
||||
1 1 1.00 60.00 120.00
|
||||
4350 1875 4350 2775
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
2550 1725 4050 1725
|
||||
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
|
||||
1 1 1.00 60.00 120.00
|
||||
4725 1725 6975 1725
|
||||
2 1 1 1 0 7 0 0 -1 4.000 0 0 -1 0 0 2
|
||||
7275 1950 7275 2625
|
||||
4 0 0 0 0 0 12 0.0000 0 135 360 2100 1800 head\001
|
||||
4 0 0 0 0 0 12 0.0000 4 135 360 4200 1800 node\001
|
||||
4 0 0 0 0 0 12 0.0000 4 135 360 4200 3000 node\001
|
||||
4 0 0 0 0 0 12 0.0000 4 135 360 4200 4200 node\001
|
||||
4 0 0 0 0 0 12 0.0000 4 135 360 4200 5700 node\001
|
||||
4 0 0 0 0 0 12 0.0000 4 180 870 4575 2250 next sibling\001
|
||||
4 0 0 0 0 0 12 0.0000 4 180 870 4575 2475 prev sibling\001
|
||||
4 0 0 0 0 0 12 0.0000 4 180 870 4575 3450 next sibling\001
|
||||
4 0 0 0 0 0 12 0.0000 4 180 870 4575 3675 prev sibling\001
|
||||
4 0 0 0 0 0 12 0.0000 4 135 720 5850 1650 first child\001
|
||||
4 0 0 0 0 0 12 0.0000 4 135 720 2925 1650 first child\001
|
||||
4 0 0 0 0 0 12 0.0000 4 135 360 7125 1800 node\001
|
||||
4 0 0 0 0 0 12 0.0000 4 135 360 7125 2925 node\001
|
||||
4 0 0 0 0 0 12 0.0000 4 135 690 2550 3900 last child\001
|
71
lib/tree-2.81/doc/treefig.pdf
Normal file
|
@ -0,0 +1,71 @@
|
|||
%PDF-1.3
|
||||
%Çì<C387>¢
|
||||
6 0 obj
|
||||
<</Length 7 0 R/Filter /FlateDecode>>
|
||||
stream
|
||||
xœUK<EFBFBD>Ó0¾ûWøÖ©YÏø}]‰—…H‡¥<E280A1>MPZØí
|
||||
øùŒ_‰³©©h¤zÆóøÆó°E\„/¯›{b·<±{"?±°{ Ô(øÀ$ª9ˆŽ<CB86>4Ž l<C2A0>´AjÁAh n Nb‘N ‰t°Jt—%Ê™Æ<E284A2>>´vÄÍ$+œvjô—èŽðž©Fó_ŃÕSDR“ÖÇx² ·qÒØþíq<>ƒŽ‚X’²I3‚_k`?siø*Û6:£<>*=46†c‰Œl%!HÀ™ðM¬èpzÀ$s>0Ræ„Ô•CKPècáÀ΋u[*5! ˜Æ¤&˺<C38B>ÿËc·4±@NÕ¥´¶.e’Ϊip<12>QT]ˆh«.̲ÂI1N¦ÏNÉŠHŸœ'Í׃s…ƒip.KÙ¤Y
ÎrÓÅUB<>(!c7éÐå(]Èb‘IccûX?§ƒÍÙ<C38D>æy ²«ª —VšuA®t°43褙pÐ7áYÂA/Õœ>—™x¿çÔ Gýwj VšUj®uðê¶•tES#ë<>¥HSw¥HŸèöޝo^6~×Ò+ìiƒÜµ{–gàkÑú¡R@˜Š·vÓí¶oÚoè¼Ý²›ã÷í.ìXäíûÌ®ÆÕ‹z‘ΈÂ&ÃÝï~ê¿ýñ1º”$Ê?žw?GÁŠÑ—ög«ê[Cû€¤³ïŸO/|ÓõC|M×IÄ95_ûÙ©Œ-àék´¡Në)µ‡w-¿§^øöÌÐcendstream
|
||||
endobj
|
||||
7 0 obj
|
||||
588
|
||||
endobj
|
||||
10 0 obj
|
||||
<</R4
|
||||
4 0 R>>
|
||||
endobj
|
||||
11 0 obj
|
||||
<</R9
|
||||
9 0 R>>
|
||||
endobj
|
||||
5 0 obj
|
||||
<</Type/Page/MediaBox [0 0 324 252]
|
||||
/Rotate 0/Parent 3 0 R
|
||||
/Resources<</ProcSet[/PDF /Text]
|
||||
/ExtGState 10 0 R
|
||||
/Font 11 0 R
|
||||
>>
|
||||
/Contents 6 0 R
|
||||
>>
|
||||
endobj
|
||||
3 0 obj
|
||||
<< /Type /Pages /Kids [
|
||||
5 0 R
|
||||
] /Count 1
|
||||
>>
|
||||
endobj
|
||||
1 0 obj
|
||||
<</Type /Catalog /Pages 3 0 R
|
||||
>>
|
||||
endobj
|
||||
4 0 obj
|
||||
<</Type/ExtGState/Name/R4/TR/Identity/OPM 1/SM 0.02>>
|
||||
endobj
|
||||
9 0 obj
|
||||
<</Subtype/Type1/BaseFont/Times-Roman/Type/Font/Name/R9>>
|
||||
endobj
|
||||
8 0 obj
|
||||
<</Type/FontDescriptor/FontName/Times-Roman>>
|
||||
endobj
|
||||
2 0 obj
|
||||
<</Producer (GNU Ghostscript 6.51)
|
||||
>>endobj
|
||||
xref
|
||||
0 12
|
||||
0000000000 65535 f
|
||||
0000000971 00000 n
|
||||
0000001222 00000 n
|
||||
0000000912 00000 n
|
||||
0000001019 00000 n
|
||||
0000000752 00000 n
|
||||
0000000015 00000 n
|
||||
0000000673 00000 n
|
||||
0000001161 00000 n
|
||||
0000001088 00000 n
|
||||
0000000692 00000 n
|
||||
0000000722 00000 n
|
||||
trailer
|
||||
<< /Size 12 /Root 1 0 R /Info 2 0 R
|
||||
>>
|
||||
startxref
|
||||
1274
|
||||
%%EOF
|
3
lib/tree-2.81/src/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
*.o
|
||||
*.res
|
||||
test1
|
14
lib/tree-2.81/src/Makefile
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
%.o: %.cc
|
||||
g++ -c -I. $^
|
||||
|
||||
test1: test1.o
|
||||
g++ -o test1 test1.o
|
||||
|
||||
run_tests: test1 test1.req
|
||||
./test1 > test1.res
|
||||
@diff test1.res test1.req
|
||||
@echo "*** All tests OK ***"
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ *.res
|
1560
lib/tree-2.81/src/simple tree.hpp
Normal file
18
lib/tree-2.81/src/test1.cc
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include "tree.hh"
|
||||
#include "tree_util.hh"
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
tree<int> tr;
|
||||
|
||||
tr.insert(tr.begin(), 1);
|
||||
tree<int>::iterator i2 = tr.insert(tr.end(), 2);
|
||||
tree<int>::iterator i3 = tr.insert(tr.end(), 3);
|
||||
tr.append_child(i2, 21);
|
||||
tr.append_child(i3, 31);
|
||||
tree<int>::iterator i4 = tr.insert(tr.end(), 4);
|
||||
|
||||
kptree::print_tree_bracketed(tr, std::cout);
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
4
lib/tree-2.81/src/test1.req
Normal file
|
@ -0,0 +1,4 @@
|
|||
1
|
||||
2(21)
|
||||
3(31)
|
||||
4
|
378
lib/tree-2.81/src/test_tree.cc
Normal file
|
@ -0,0 +1,378 @@
|
|||
/*
|
||||
|
||||
STL-like templated tree class; test program.
|
||||
Copyright (C) 2001-2009 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include "tree.hh"
|
||||
#include "tree_util.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <utility>
|
||||
#include <stdexcept>
|
||||
|
||||
/*
|
||||
|
||||
Simple test program for the tree.hh class library. Run it and see
|
||||
what happens. Or, if you want to see that it does not leak memory,
|
||||
run it like
|
||||
|
||||
./test_tree 10000 >/dev/null
|
||||
|
||||
or some other large number and have 'top' running in a different
|
||||
shell. This will run the tests 10000 times, creating and destroying
|
||||
the trees for every iteration of the loop.
|
||||
|
||||
*/
|
||||
|
||||
bool truefunc(std::string& one, std::string& two)
|
||||
{
|
||||
// std::cout << "comparing " << one << "==" << two << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void print_tree(const tree<std::string>& tr, tree<std::string>::pre_order_iterator it, tree<std::string>::pre_order_iterator end)
|
||||
{
|
||||
if(!tr.is_valid(it)) return;
|
||||
int rootdepth=tr.depth(it);
|
||||
std::cout << "-----" << std::endl;
|
||||
while(it!=end) {
|
||||
for(int i=0; i<tr.depth(it)-rootdepth; ++i)
|
||||
std::cout << " ";
|
||||
std::cout << (*it) << std::endl << std::flush;
|
||||
++it;
|
||||
}
|
||||
std::cout << "-----" << std::endl;
|
||||
}
|
||||
|
||||
void print_tree_post(const tree<std::string>& tr, tree<std::string>::post_order_iterator it, tree<std::string>::post_order_iterator end)
|
||||
{
|
||||
int rootdepth=tr.depth(it);
|
||||
std::cout << "-----" << std::endl;
|
||||
while(it!=end) {
|
||||
for(int i=0; i<tr.depth(it)-rootdepth; ++i)
|
||||
std::cout << " ";
|
||||
std::cout << (*it) << std::endl << std::flush;
|
||||
++it;
|
||||
}
|
||||
std::cout << "-----" << std::endl;
|
||||
}
|
||||
|
||||
void print_tree_rev(const tree<std::string>& tr, tree<std::string>::pre_order_iterator it, tree<std::string>::pre_order_iterator end)
|
||||
{
|
||||
--it;
|
||||
int rootdepth=0;//tr.depth(it);
|
||||
std::cout << "-----" << std::endl;
|
||||
while(1==1) {
|
||||
for(int i=0; i<tr.depth(it)-rootdepth; ++i)
|
||||
std::cout << " ";
|
||||
std::cout << (*it) << std::endl;
|
||||
if(it==end) break;
|
||||
--it;
|
||||
}
|
||||
std::cout << "-----" << std::endl;
|
||||
}
|
||||
|
||||
void print_tree_rev_post(const tree<std::string>& tr, tree<std::string>::post_order_iterator it, tree<std::string>::post_order_iterator end)
|
||||
{
|
||||
--it;
|
||||
int rootdepth=0;//tr.depth(it);
|
||||
std::cout << "-----" << std::endl;
|
||||
while(1==1) {
|
||||
for(int i=0; i<tr.depth(it)-rootdepth; ++i)
|
||||
std::cout << " ";
|
||||
std::cout << (*it) << std::endl;
|
||||
if(it==end) break;
|
||||
--it;
|
||||
}
|
||||
std::cout << "-----" << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
unsigned int maxloop=1;
|
||||
if(argc>1)
|
||||
maxloop=atoi(argv[1]);
|
||||
|
||||
for(unsigned int j=0; j<maxloop; ++j) {
|
||||
tree<std::string> tr9;
|
||||
tr9.set_head("hi");
|
||||
tr9.insert(tr9.begin().begin(), "0");
|
||||
tr9.insert(tr9.begin().begin(), "1");
|
||||
print_tree(tr9, tr9.begin(), tr9.end());
|
||||
|
||||
|
||||
tree<std::string> tr;
|
||||
tree<std::string>::pre_order_iterator html, body, h1, h3, bh1, mv1;
|
||||
|
||||
std::cout << "empty tree to begin with:" << std::endl;
|
||||
print_tree(tr, tr.begin(), tr.end());
|
||||
|
||||
html=tr.insert(tr.begin(), "html");
|
||||
tr.insert(html,"extra");
|
||||
// tr.insert(html,"zextra2");
|
||||
body=tr.append_child(html, "body");
|
||||
h1 =tr.append_child(body, "h1");
|
||||
std::cout << tr.index(h1) << std::endl;
|
||||
bh1 =tr.insert(h1,"before h1");
|
||||
tr.append_child(h1, "some text");
|
||||
tree<std::string>::sibling_iterator more_text=tr.append_child(body, "more text");
|
||||
|
||||
std::cout << " 'more text' is sibling " << tr.index(more_text) << " in its sibling range" << std::endl;
|
||||
|
||||
std::cout << "filled tree:" << std::endl;
|
||||
print_tree(tr, tr.begin(), tr.end());
|
||||
|
||||
std::cout << "filled tree, post-order traversal:" << std::endl;
|
||||
print_tree_post(tr, tr.begin_post(), tr.end_post());
|
||||
|
||||
tr.swap(bh1);
|
||||
std::cout << "swapped elements:" << std::endl;
|
||||
print_tree(tr, tr.begin(), tr.end());
|
||||
tr.swap(h1);
|
||||
std::cout << "swapped back:" << std::endl;
|
||||
print_tree(tr, tr.begin(), tr.end());
|
||||
|
||||
tree<std::string> copytree(h1);
|
||||
std::cout << "copied tree:" << std::endl;
|
||||
print_tree(copytree, copytree.begin(), copytree.end());
|
||||
|
||||
// Now test the STL algorithms
|
||||
std::cout << "result of search for h1 and kasper:" << std::endl;
|
||||
tree<std::string>::pre_order_iterator it;
|
||||
it=std::find(tr.begin(),tr.end(),std::string("h1"));
|
||||
if(it!=tr.end()) print_tree(tr, it, tr.next_sibling(it));
|
||||
else std::cout << "h1 not found" << std::endl;
|
||||
it=std::find(tr.begin(),tr.end(), std::string("kasper"));
|
||||
if(it!=tr.end()) print_tree(tr, it, tr.next_sibling(it));
|
||||
else std::cout << "kasper not found" << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// remove the h1, replace it with new subtree
|
||||
tree<std::string> replacement;
|
||||
h3 =replacement.insert(replacement.begin(), "h3");
|
||||
replacement.append_child(h3, "text in h3");
|
||||
std::cout << "replacement tree:" << std::endl;
|
||||
print_tree(replacement, replacement.begin(), replacement.end());
|
||||
print_tree(tr, tr.begin(), tr.end());
|
||||
h1=tr.replace(tree<std::string>::sibling_iterator(h1), tr.next_sibling(h1),
|
||||
tree<std::string>::sibling_iterator(h3), tr.next_sibling(h3));
|
||||
std::cout << "filled tree with replacement done:" << std::endl;
|
||||
print_tree(tr, tr.begin(), tr.end());
|
||||
|
||||
// replace h3 node while keeping children
|
||||
h1=tr.replace(h1, "<foobar>");
|
||||
print_tree(tr, tr.begin(), tr.end());
|
||||
|
||||
// add a sibling to the head
|
||||
tr.insert_after(h1, "more");
|
||||
|
||||
// Copy object.
|
||||
tree<std::string> tr2=tr;
|
||||
print_tree(tr2, tr2.begin(), tr2.end());
|
||||
tree<std::string> tr3(tr);
|
||||
|
||||
// reparent "before h1" to h3 node
|
||||
tr.reparent(h1, bh1, tr.next_sibling(bh1));
|
||||
std::cout << "moved content:" << std::endl;
|
||||
print_tree(tr, tr.begin(), tr.end());
|
||||
|
||||
// iterate over children only
|
||||
tree<std::string>::sibling_iterator ch=tr.begin(h1);
|
||||
std::cout << "children of h1:" << std::endl;
|
||||
while(ch!=tr.end(h1)) {
|
||||
std::cout << (*ch) << std::endl;
|
||||
++ch;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
// flatten the h3 node
|
||||
tr.flatten(h1);
|
||||
std::cout << "flattened (at h3) tree:" << std::endl;
|
||||
print_tree(tr, tr.begin(), tr.end());
|
||||
|
||||
// Erase the subtree of tr below body.
|
||||
tr.erase_children(body);
|
||||
std::cout << "children of body erased:" << std::endl;
|
||||
print_tree(tr, tr.begin(), tr.end());
|
||||
it=std::find(tr.begin(),tr.end(),"h1");
|
||||
if(it!=tr.end()) print_tree(tr, it, tr.next_sibling(it));
|
||||
else std::cout << "h1 not found" << std::endl;
|
||||
|
||||
// Erase everything
|
||||
tr.erase(tr.begin());
|
||||
std::cout << "erased tree:" << std::endl;
|
||||
print_tree(tr, tr.begin(), tr.end());
|
||||
|
||||
// The copies are deep, ie. all nodes have been copied.
|
||||
std::cout << "copies still exist:" << std::endl;
|
||||
print_tree(tr2, tr2.begin(), tr2.end());
|
||||
print_tree(tr3, tr3.begin(), tr3.end());
|
||||
|
||||
// Test comparison
|
||||
std::cout << "testing comparison functions:" << std::endl;
|
||||
std::cout << std::equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
|
||||
<< " (should be 1)" << std::endl;
|
||||
// modify content but not structure
|
||||
tree<std::string>::pre_order_iterator fl3=tr3.begin();
|
||||
fl3+=4; // pointing to "<foobar>" node
|
||||
std::cout << (*fl3) << std::endl;
|
||||
std::string tmpfl3=(*fl3);
|
||||
(*fl3)="modified";
|
||||
std::cout << std::equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
|
||||
<< " (should be 0)" << std::endl;
|
||||
std::cout << tr2.equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
|
||||
<< " (should be 0)" << std::endl;
|
||||
std::cout << tr2.equal(tr2.begin(), tr2.end(), tr3.begin(), truefunc)
|
||||
<< " (should be 1)" << std::endl;
|
||||
// modify tr3 structure (but not content)
|
||||
(*fl3)=tmpfl3;
|
||||
tr3.flatten(fl3);
|
||||
std::cout << "tree flattened, test again" << std::endl;
|
||||
print_tree(tr3, tr3.begin(), tr3.end());
|
||||
|
||||
// Test comparison again
|
||||
std::cout << tr2.equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
|
||||
<< " (should be 0)" << std::endl;
|
||||
std::cout << std::equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
|
||||
<< " (should be 1)" << std::endl;
|
||||
// Change content
|
||||
(*fl3)="modified";
|
||||
// Test comparison again
|
||||
std::cout << std::equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
|
||||
<< " (should be 0)" << std::endl;
|
||||
std::cout << tr2.equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
|
||||
<< " (should be 0)" << std::endl;
|
||||
|
||||
// Testing sort. First add a subtree to one leaf
|
||||
tree<std::string>::pre_order_iterator txx3=tr3.begin();
|
||||
txx3+=5;
|
||||
tr3.append_child(txx3,"ccc");
|
||||
tr3.append_child(txx3,"bbb");
|
||||
tr3.append_child(txx3,"bbb");
|
||||
tr3.append_child(txx3,"aaa");
|
||||
std::less<std::string> comp;
|
||||
tree<std::string>::pre_order_iterator bdy=tr3.begin();
|
||||
bdy+=2;
|
||||
assert(tr.is_valid(bdy));
|
||||
std::cout << "unsorted subtree:" << std::endl;
|
||||
print_tree(tr3, tr3.begin(), tr3.end());
|
||||
tree<std::string>::sibling_iterator sortit1=tr3.begin(bdy), sortit2=tr3.begin(bdy);
|
||||
sortit1+=2;
|
||||
sortit2+=4;
|
||||
assert(tr.is_valid(sortit1));
|
||||
assert(tr.is_valid(sortit2));
|
||||
std::cout << "partially sorted subtree: ("
|
||||
<< "sorted from " << (*sortit1) << " to "
|
||||
<< (*sortit2) << ", excluding the last element)" << std::endl;
|
||||
|
||||
|
||||
mv1=tr3.begin();
|
||||
++mv1;
|
||||
tr3.sort(sortit1, sortit2);
|
||||
print_tree(tr3, tr3.begin(), tr3.end());
|
||||
tr3.sort(tr3.begin(bdy), tr3.end(bdy), comp, true); // false: no sorting of subtrees
|
||||
// Sorting the entire tree, level by level, is much simpler:
|
||||
// tr3.sort(tr3.begin(), tr3.end(), true);
|
||||
std::cout << "sorted subtree:" << std::endl;
|
||||
print_tree(tr3, tr3.begin(), tr3.end());
|
||||
|
||||
// Michael's problem
|
||||
// std::cout << mv1.node << ", " << tr3.feet << ", " << tr3.feet->prev_sibling << std::endl;
|
||||
// std::cout << mv1.node->next_sibling << ", " << tr3.feet->prev_sibling << ", " << tr3.end().node << std::endl;
|
||||
// tr3.sort(tr3.begin(), tr3.end(), true);
|
||||
// std::cout << mv1.node << ", " << tr3.feet << ", " << tr3.feet->prev_sibling << std::endl;
|
||||
// std::cout << mv1.node->next_sibling << ", " << tr3.feet->prev_sibling << ", " << tr3.end().node << std::endl;
|
||||
// print_tree(tr3, tr3.begin(), tr3.end());
|
||||
// tr3.sort(tr3.begin(), tr3.end(), true);
|
||||
// std::cout << mv1.node << ", " << tr3.feet << ", " << tr3.feet->prev_sibling << std::endl;
|
||||
// std::cout << mv1.node->next_sibling << ", " << tr3.feet->prev_sibling << ", " << tr3.end().node << std::endl;
|
||||
// print_tree(tr3, tr3.begin(), tr3.end());
|
||||
// return 1;
|
||||
|
||||
// Test merge algorithm.
|
||||
std::cout << "test merge" << std::endl;
|
||||
tree<std::string> mtree;
|
||||
tree<std::string>::pre_order_iterator mt1, mt2, mt3;
|
||||
mt1=mtree.insert(mtree.begin(),"html");
|
||||
mt2=mtree.append_child(mt1,"head");
|
||||
mt3=mtree.append_child(mt1,"body");
|
||||
// Adding it without head having any children tests whether we can
|
||||
// insert at the end of an empty list of children.
|
||||
mtree.append_child(mt2,"title");
|
||||
mtree.append_child(mt3,"h1");
|
||||
mtree.append_child(mt3,"h1");
|
||||
|
||||
tree<std::string> mtBree;
|
||||
tree<std::string>::pre_order_iterator mtB1, mtB2;
|
||||
mtB1=mtBree.insert(mtBree.begin(),"head");
|
||||
mtB2=mtBree.append_child(mtB1,"another title");
|
||||
print_tree(mtree, mtree.begin(), mtree.end());
|
||||
print_tree(mtBree, mtBree.begin(), mtBree.end());
|
||||
|
||||
mtree.merge(mtree.begin(), mtree.end(), mtBree.begin(), mtBree.end(), true);
|
||||
print_tree(mtree, mtree.begin(), mtree.end());
|
||||
mtree.merge(mtree.begin(mtree.begin()), mtree.end(mtree.begin()), mtBree.begin(), mtBree.end(), true);
|
||||
print_tree(mtree, mtree.begin(), mtree.end());
|
||||
|
||||
// Print tree in reverse (test operator--)
|
||||
print_tree_rev(mtree, mtree.end(), mtree.begin());
|
||||
print_tree_rev_post(mtree, mtree.end_post(), mtree.begin_post());
|
||||
|
||||
// Breadth-first
|
||||
tree<std::string> bft;
|
||||
tree<std::string>::iterator bfB,bfC,bfD;
|
||||
bft.set_head("A");
|
||||
bfB=bft.append_child(bft.begin(), "B");
|
||||
bfC=bft.append_child(bft.begin(), "C");
|
||||
bfD=bft.append_child(bft.begin(), "D");
|
||||
bft.append_child(bfB, "E");
|
||||
bft.append_child(bfB, "F");
|
||||
bft.append_child(bfC, "G");
|
||||
bft.append_child(bfC, "H");
|
||||
bft.append_child(bfD, "I");
|
||||
tree<std::string>::breadth_first_queued_iterator bfq=bft.begin_breadth_first();
|
||||
while(bfq!=bft.end_breadth_first()) {
|
||||
std::cout << *bfq << std::endl;
|
||||
++bfq;
|
||||
}
|
||||
|
||||
print_tree(bft, bft.begin(), bft.end());
|
||||
bft.wrap(bfD, "wrap");
|
||||
print_tree(bft, bft.begin(), bft.end());
|
||||
|
||||
tree<std::string>::leaf_iterator li=tr.begin_leaf(bfC);
|
||||
while(li!=tr.end_leaf(bfC)) {
|
||||
std::cout << *li << std::endl;
|
||||
++li;
|
||||
}
|
||||
|
||||
// tree<std::string> testfixed;
|
||||
// testfixed.insert(testfixed.begin(), "one");
|
||||
// testfixed.insert(testfixed.begin(), "two");
|
||||
// testfixed.insert(testfixed.begin(), "three");
|
||||
// tree<std::string>::fixed_depth_iterator fit=testfixed.begin();
|
||||
// while(testfixed.is_valid(fit)) {
|
||||
// std::cout << *fit << std::endl;
|
||||
// ++fit;
|
||||
// }
|
||||
}
|
||||
}
|
311
lib/tree-2.81/src/test_tree.output
Normal file
|
@ -0,0 +1,311 @@
|
|||
empty tree to begin with:
|
||||
0
|
||||
'more text' is sibling 2 in its sibling range
|
||||
filled tree:
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
h1
|
||||
some text
|
||||
more text
|
||||
-----
|
||||
filled tree, post-order traversal:
|
||||
-----
|
||||
extra
|
||||
before h1
|
||||
some text
|
||||
h1
|
||||
more text
|
||||
body
|
||||
html
|
||||
-----
|
||||
swapped elements:
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
h1
|
||||
some text
|
||||
before h1
|
||||
more text
|
||||
-----
|
||||
swapped back:
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
h1
|
||||
some text
|
||||
more text
|
||||
-----
|
||||
copied tree:
|
||||
-----
|
||||
h1
|
||||
some text
|
||||
-----
|
||||
result of search for h1 and kasper:
|
||||
-----
|
||||
h1
|
||||
some text
|
||||
-----
|
||||
kasper not found
|
||||
|
||||
replacement tree:
|
||||
-----
|
||||
h3
|
||||
text in h3
|
||||
-----
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
h1
|
||||
some text
|
||||
more text
|
||||
-----
|
||||
filled tree with replacement done:
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
h3
|
||||
text in h3
|
||||
more text
|
||||
-----
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
<foobar>
|
||||
text in h3
|
||||
more text
|
||||
-----
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
<foobar>
|
||||
text in h3
|
||||
more
|
||||
more text
|
||||
-----
|
||||
moved content:
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
<foobar>
|
||||
text in h3
|
||||
before h1
|
||||
more
|
||||
more text
|
||||
-----
|
||||
children of h1:
|
||||
text in h3
|
||||
before h1
|
||||
|
||||
flattened (at h3) tree:
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
<foobar>
|
||||
text in h3
|
||||
before h1
|
||||
more
|
||||
more text
|
||||
-----
|
||||
children of body erased:
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
-----
|
||||
h1 not found
|
||||
erased tree:
|
||||
-----
|
||||
html
|
||||
body
|
||||
-----
|
||||
copies still exist:
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
<foobar>
|
||||
text in h3
|
||||
more
|
||||
more text
|
||||
-----
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
<foobar>
|
||||
text in h3
|
||||
more
|
||||
more text
|
||||
-----
|
||||
testing comparison functions:
|
||||
1 (should be 1)
|
||||
<foobar>
|
||||
0 (should be 0)
|
||||
0 (should be 0)
|
||||
1 (should be 1)
|
||||
tree flattened, test again
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
<foobar>
|
||||
text in h3
|
||||
more
|
||||
more text
|
||||
-----
|
||||
0 (should be 0)
|
||||
1 (should be 1)
|
||||
0 (should be 0)
|
||||
0 (should be 0)
|
||||
unsorted subtree:
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
modified
|
||||
text in h3
|
||||
ccc
|
||||
bbb
|
||||
bbb
|
||||
aaa
|
||||
more
|
||||
more text
|
||||
-----
|
||||
partially sorted subtree: (sorted from text in h3 to more text, excluding the last element)
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
modified
|
||||
more
|
||||
text in h3
|
||||
ccc
|
||||
bbb
|
||||
bbb
|
||||
aaa
|
||||
more text
|
||||
-----
|
||||
sorted subtree:
|
||||
-----
|
||||
extra
|
||||
html
|
||||
body
|
||||
before h1
|
||||
modified
|
||||
more
|
||||
more text
|
||||
text in h3
|
||||
aaa
|
||||
bbb
|
||||
bbb
|
||||
ccc
|
||||
-----
|
||||
test merge
|
||||
-----
|
||||
html
|
||||
head
|
||||
title
|
||||
body
|
||||
h1
|
||||
h1
|
||||
-----
|
||||
-----
|
||||
head
|
||||
another title
|
||||
-----
|
||||
-----
|
||||
html
|
||||
head
|
||||
title
|
||||
body
|
||||
h1
|
||||
h1
|
||||
head
|
||||
another title
|
||||
-----
|
||||
-----
|
||||
html
|
||||
head
|
||||
title
|
||||
another title
|
||||
body
|
||||
h1
|
||||
h1
|
||||
head
|
||||
another title
|
||||
-----
|
||||
-----
|
||||
another title
|
||||
head
|
||||
h1
|
||||
h1
|
||||
body
|
||||
another title
|
||||
title
|
||||
head
|
||||
html
|
||||
-----
|
||||
-----
|
||||
head
|
||||
another title
|
||||
html
|
||||
body
|
||||
h1
|
||||
h1
|
||||
head
|
||||
another title
|
||||
title
|
||||
-----
|
||||
A
|
||||
B
|
||||
C
|
||||
D
|
||||
E
|
||||
F
|
||||
G
|
||||
H
|
||||
I
|
||||
-----
|
||||
A
|
||||
B
|
||||
E
|
||||
F
|
||||
C
|
||||
G
|
||||
H
|
||||
D
|
||||
I
|
||||
-----
|
||||
-----
|
||||
A
|
||||
B
|
||||
E
|
||||
F
|
||||
C
|
||||
G
|
||||
H
|
||||
wrap
|
||||
D
|
||||
I
|
||||
-----
|
2786
lib/tree-2.81/src/tree.hh
Normal file
59
lib/tree-2.81/src/tree_example.cc
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
|
||||
Cadabra: a field-theory motivated computer algebra system.
|
||||
Copyright (C) 2001-2009 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
This program is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include "tree.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int, char **)
|
||||
{
|
||||
tree<string> tr;
|
||||
tree<string>::iterator top, one, two, loc, banana;
|
||||
|
||||
top=tr.begin();
|
||||
one=tr.insert(top, "one");
|
||||
two=tr.append_child(one, "two");
|
||||
tr.append_child(two, "apple");
|
||||
banana=tr.append_child(two, "banana");
|
||||
tr.append_child(banana,"cherry");
|
||||
tr.append_child(two, "peach");
|
||||
tr.append_child(one,"three");
|
||||
|
||||
loc=find(tr.begin(), tr.end(), "two");
|
||||
if(loc!=tr.end()) {
|
||||
tree<string>::sibling_iterator sib=tr.begin(loc);
|
||||
while(sib!=tr.end(loc)) {
|
||||
cout << (*sib) << endl;
|
||||
++sib;
|
||||
}
|
||||
cout << endl;
|
||||
tree<string>::iterator sib2=tr.begin(loc);
|
||||
tree<string>::iterator end2=tr.end(loc);
|
||||
while(sib2!=end2) {
|
||||
for(int i=0; i<tr.depth(sib2)-2; ++i)
|
||||
cout << " ";
|
||||
cout << (*sib2) << endl;
|
||||
++sib2;
|
||||
}
|
||||
}
|
||||
}
|
92
lib/tree-2.81/src/tree_util.hh
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
|
||||
A collection of miscellaneous utilities that operate on the templated
|
||||
tree.hh class.
|
||||
|
||||
|
||||
Copyright (C) 2001-2009 Kasper Peeters <kasper.peeters@aei.mpg.de>
|
||||
|
||||
(At the moment this only contains a printing utility, thanks to Linda
|
||||
Buisman <linda.buisman@studentmail.newcastle.edu.au>)
|
||||
|
||||
This program is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef tree_util_hh_
|
||||
#define tree_util_hh_
|
||||
|
||||
#include <iostream>
|
||||
#include "tree.hh"
|
||||
|
||||
namespace kptree {
|
||||
|
||||
template<class T>
|
||||
void print_tree_bracketed(const tree<T>& t, std::ostream& str=std::cout);
|
||||
|
||||
template<class T>
|
||||
void print_subtree_bracketed(const tree<T>& t, typename tree<T>::iterator iRoot,
|
||||
std::ostream& str=std::cout);
|
||||
|
||||
|
||||
|
||||
// Iterate over all roots (the head) and print each one on a new line
|
||||
// by calling printSingleRoot.
|
||||
|
||||
template<class T>
|
||||
void print_tree_bracketed(const tree<T>& t, std::ostream& str)
|
||||
{
|
||||
int headCount = t.number_of_siblings(t.begin());
|
||||
int headNum = 0;
|
||||
for(typename tree<T>::sibling_iterator iRoots = t.begin(); iRoots != t.end(); ++iRoots, ++headNum) {
|
||||
print_subtree_bracketed(t,iRoots,str);
|
||||
if (headNum != headCount) {
|
||||
str << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Print everything under this root in a flat, bracketed structure.
|
||||
|
||||
template<class T>
|
||||
void print_subtree_bracketed(const tree<T>& t, typename tree<T>::iterator iRoot, std::ostream& str)
|
||||
{
|
||||
if(t.empty()) return;
|
||||
if (t.number_of_children(iRoot) == 0) {
|
||||
str << *iRoot;
|
||||
}
|
||||
else {
|
||||
// parent
|
||||
str << *iRoot;
|
||||
str << "(";
|
||||
// child1, ..., childn
|
||||
int siblingCount = t.number_of_siblings(t.begin(iRoot));
|
||||
int siblingNum;
|
||||
typename tree<T>::sibling_iterator iChildren;
|
||||
for (iChildren = t.begin(iRoot), siblingNum = 0; iChildren != t.end(iRoot); ++iChildren, ++siblingNum) {
|
||||
// recursively print child
|
||||
print_subtree_bracketed(t,iChildren,str);
|
||||
// comma after every child except the last one
|
||||
if (siblingNum != siblingCount ) {
|
||||
str << ", ";
|
||||
}
|
||||
}
|
||||
str << ")";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
1579
lib/tree-2.81/src/xinlin.hh
Normal file
|
@ -1 +1 @@
|
|||
Subproject commit 50ebba1c3157196d142bc06ebf2d290c7702b084
|
||||
Subproject commit fc7b66642959e7de19aade010b6ebc1e59ba4b7a
|
450
nonfree_map.tmx
|
@ -2,456 +2,6 @@
|
|||
<map version="1.0" orientation="orthogonal" renderorder="right-down" width="80" height="60" tilewidth="32" tileheight="32" nextobjectid="1">
|
||||
<tileset firstgid="1" name="nonfree" tilewidth="32" tileheight="32" tilecount="90" columns="10">
|
||||
<image source="nonfree_texture.png" trans="ffffff" width="320" height="288"/>
|
||||
<tile id="0">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="1">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="2">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="3">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="4">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="5">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="6">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="7">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="8">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="9">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="10">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="11">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="12">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="13">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="14">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="15">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="16">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="17">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="18">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="19">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="20">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="21">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="22">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="23">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="24">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="25">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="26">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="27">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="28">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="29">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="30">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="31">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="32">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="33">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="34">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="35">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="36">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="37">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="38">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="39">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="40">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="41">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="42">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="43">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="44">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="45">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="46">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="47">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="48">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="49">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="50">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="51">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="52">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="53">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="54">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="55">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="56">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="57">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="58">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="59">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="60">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="61">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="62">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="63">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="64">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="65">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="66">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="67">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="68">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="69">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="70">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="71">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="72">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="73">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="74">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="75">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="true"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="76">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="77">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="78">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="79">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="80">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="81">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="82">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="83">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="84">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="85">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="86">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="87">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="88">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
<tile id="89">
|
||||
<properties>
|
||||
<property name="walkable" type="bool" value="false"/>
|
||||
</properties>
|
||||
</tile>
|
||||
</tileset>
|
||||
<layer name="ground" width="80" height="60">
|
||||
<data encoding="csv">
|
||||
|
|
|
@ -21,27 +21,58 @@
|
|||
#include "inputbag.hpp"
|
||||
#include "gameactions.hpp"
|
||||
#include "worldgrid.hpp"
|
||||
#include "drawing_queue.hpp"
|
||||
#include "worldviewport.hpp"
|
||||
#include "texture.hpp"
|
||||
#include "draw_layer_names.hpp"
|
||||
#include <ciso646>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
namespace curry {
|
||||
namespace {
|
||||
} //unnamed namespace
|
||||
|
||||
Character::Character (cloonel::InputBag* parInputBag, const WorldSizeNotifiable::DeferredRegister& parDeferredRegister) :
|
||||
WorldMoveable(parDeferredRegister),
|
||||
WorldSizeNotifiable(parDeferredRegister),
|
||||
m_position(vec2f(0.0f), vec2f(0.0f), vec2f(0.0f)),
|
||||
m_width_height(0.0f),
|
||||
m_input_bag(parInputBag),
|
||||
m_world(parDeferredRegister.world()),
|
||||
m_speed(1.0f)
|
||||
{
|
||||
assert(m_input_bag);
|
||||
assert(m_world);
|
||||
}
|
||||
|
||||
void Character::load (const char* parTexturePath, cloonel::SDLMain& parSDLMain) {
|
||||
const auto old_wh = m_width_height;
|
||||
m_texture.load(parTexturePath, parSDLMain);
|
||||
m_width_height = vector_cast<vec2f>(m_texture.width_height());
|
||||
const auto& new_wh = m_width_height;
|
||||
if (m_position.get_min() != m_position.get_max())
|
||||
m_position.change_minmax(m_position.get_min(), m_position.get_max() + old_wh - new_wh);
|
||||
}
|
||||
|
||||
void Character::unload() {
|
||||
m_texture.unload();
|
||||
}
|
||||
|
||||
void Character::set_position (const vec2f& parPos) {
|
||||
m_position = parPos;
|
||||
}
|
||||
|
||||
const vec2f& Character::position() const {
|
||||
return m_position.get();
|
||||
}
|
||||
|
||||
const vec2f& Character::width_height() const {
|
||||
return m_width_height;
|
||||
}
|
||||
|
||||
Texture& Character::texture() {
|
||||
return m_texture;
|
||||
}
|
||||
|
||||
Rect<float> Character::destination_rect (const vec2f& parWorldPos) const {
|
||||
return Rect<float>(
|
||||
position() - parWorldPos,
|
||||
position() - parWorldPos + width_height()
|
||||
m_position.get() - parWorldPos,
|
||||
m_position.get() - parWorldPos + width_height()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -52,6 +83,10 @@ namespace curry {
|
|||
);
|
||||
}
|
||||
|
||||
void Character::world_size_changed (const vec2us&, const vec2i& parPixelSize) {
|
||||
m_position.change_minmax(m_position.get_min(), vector_cast<vec2f>(parPixelSize));
|
||||
}
|
||||
|
||||
void Character::do_movement (float parDeltaT) {
|
||||
const float speed = parDeltaT * m_speed;
|
||||
vec2f offset(0.0f);
|
||||
|
@ -65,18 +100,10 @@ namespace curry {
|
|||
offset.y() += speed;
|
||||
|
||||
const auto old_pos = this->position();
|
||||
this->set_position(old_pos + offset);
|
||||
if (position() == old_pos)
|
||||
return;
|
||||
const auto new_pos = old_pos + offset;
|
||||
|
||||
WorldGrid& world = this->world();
|
||||
//if (m_world
|
||||
|
||||
const vec2f new_pos = m_collider.try_reach_tile(
|
||||
texture()->width_height() / world.tile_size(),
|
||||
old_pos,
|
||||
position(),
|
||||
world
|
||||
);
|
||||
this->set_position(new_pos);
|
||||
}
|
||||
|
||||
|
@ -84,17 +111,4 @@ namespace curry {
|
|||
assert(parSpeed > 0.0f);
|
||||
m_speed = parSpeed;
|
||||
}
|
||||
|
||||
void Character::draw (DrawingQueue& parDQ, const WorldViewport& parViewport) {
|
||||
DrawingQueue::ItemInfo item;
|
||||
item.source = source_rect();
|
||||
item.destination = destination_rect(parViewport.position());
|
||||
item.texture = texture();
|
||||
parDQ.add_for_rendering(DrawaLayerNames::Characters, std::move(item));
|
||||
assert(not item.texture);
|
||||
}
|
||||
|
||||
void Character::on_texture_size_changed (const vec2f& parOldSz, const vec2f& parNewSz) {
|
||||
this->update_moveable_size(parOldSz, parNewSz);
|
||||
}
|
||||
} //namespace curry
|
|
@ -19,11 +19,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "texture.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "rect.hpp"
|
||||
#include "world_moveable.hpp"
|
||||
#include "drawable.hpp"
|
||||
#include "collider.hpp"
|
||||
#include "constrained_position.hpp"
|
||||
#include "worldsizenotifiable.hpp"
|
||||
#include "moveable.hpp"
|
||||
|
||||
namespace cloonel {
|
||||
class SDLMain;
|
||||
|
@ -33,22 +34,29 @@ namespace cloonel {
|
|||
namespace curry {
|
||||
class WorldGrid;
|
||||
|
||||
class Character : public Drawable, public WorldMoveable {
|
||||
class Character : public WorldSizeNotifiable, public Moveable {
|
||||
public:
|
||||
Character (cloonel::InputBag* parInputBag, const WorldSizeNotifiable::DeferredRegister& parDeferredRegister);
|
||||
virtual ~Character() noexcept = default;
|
||||
|
||||
void load (const char* parTexturePath, cloonel::SDLMain& parSDLMain);
|
||||
void unload();
|
||||
const vec2f& position() const;
|
||||
void set_position (const vec2f& parPos);
|
||||
const vec2f& width_height() const;
|
||||
Texture& texture();
|
||||
Rect<float> destination_rect (const vec2f& parWorldPos) const;
|
||||
Rect<float> source_rect() const;
|
||||
virtual void world_size_changed (const vec2us& parSize, const vec2i& parPixelSize) override;
|
||||
virtual void do_movement (float parDeltaT) override;
|
||||
void set_speed (float parSpeed);
|
||||
virtual void draw (DrawingQueue& parDQ, const WorldViewport& parViewport) override;
|
||||
|
||||
private:
|
||||
virtual void on_texture_size_changed (const vec2f& parOldSz, const vec2f& parNewSz) override;
|
||||
|
||||
ConstrainedPosition<vec2f> m_position;
|
||||
Texture m_texture;
|
||||
vec2f m_width_height;
|
||||
cloonel::InputBag* m_input_bag;
|
||||
Collider m_collider;
|
||||
WorldGrid* m_world;
|
||||
float m_speed;
|
||||
};
|
||||
} //namespace curry
|
53
src/coordinates.hpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "singlecoordinate.hpp"
|
||||
|
||||
namespace vwr {
|
||||
template <>
|
||||
struct VectorWrapperInfo<std::array<::curry::SingleCoordinate, 2>> {
|
||||
enum { dimensions = 2 };
|
||||
typedef ::curry::SingleCoordinate scalar_type;
|
||||
typedef std::array<scalar_type, dimensions> vector_type;
|
||||
static scalar_type& get_at (size_t parIndex, vector_type& parVector) {
|
||||
return parVector[parIndex];
|
||||
}
|
||||
};
|
||||
} //namespace vwr
|
||||
|
||||
namespace curry {
|
||||
using vec2c = vwr::Vec<std::array<SingleCoordinate, 2>>;
|
||||
|
||||
inline vec2i to_screen_coordinates (vec2c parVec, const vec2i& parWorldOffset, vec2us parTileSize) {
|
||||
return vec2i(
|
||||
parVec.x().screen_coordinate(parWorldOffset.x(), parTileSize.x()),
|
||||
parVec.y().screen_coordinate(parWorldOffset.y(), parTileSize.y())
|
||||
);
|
||||
}
|
||||
|
||||
inline vec2us to_tiles (vec2c parVec) {
|
||||
return vec2us(
|
||||
parVec.x().tile(),
|
||||
parVec.y().tile()
|
||||
);
|
||||
}
|
||||
} //namespace curry
|
|
@ -35,7 +35,6 @@
|
|||
#include <fstream>
|
||||
#include <ciso646>
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
|
||||
namespace qi = boost::spirit::qi;
|
||||
|
||||
|
@ -48,7 +47,6 @@ namespace curry {
|
|||
//auto csv_parser = *((qi::int_ % ',') >> -qi::eol) >> qi::eoi;
|
||||
CSVJointData out_csv;
|
||||
std::size_t row_count = 0;
|
||||
TileIndex largest_tile_idx = 0;
|
||||
|
||||
for (auto& csv_path : parCsvPath) {
|
||||
std::ifstream f_map(csv_path);
|
||||
|
@ -68,9 +66,6 @@ namespace curry {
|
|||
oss << "Error parsing csv \"" << csv_path << "\"";
|
||||
throw std::runtime_error(oss.str());
|
||||
}
|
||||
if (not curr_data.empty()) {
|
||||
largest_tile_idx = std::max(*std::max_element(curr_data.begin(), curr_data.end()), largest_tile_idx);
|
||||
}
|
||||
out_csv.tables.emplace_back(std::move(curr_data));
|
||||
}
|
||||
|
||||
|
@ -81,18 +76,6 @@ namespace curry {
|
|||
else {
|
||||
out_csv.height = out_csv.width = 0;
|
||||
}
|
||||
|
||||
out_csv.tile_properties.resize(static_cast<size_t>(largest_tile_idx) + 1);
|
||||
out_csv.tile_properties[2].walkable = false;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
for (const auto& table : out_csv.tables) {
|
||||
for (const auto& val : table) {
|
||||
const auto casted_val = static_cast<size_t>(val);
|
||||
assert(val < 0 or casted_val < out_csv.tile_properties.size());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return out_csv;
|
||||
}
|
||||
} //namespace curry
|
|
@ -20,7 +20,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "tileindextype.hpp"
|
||||
#include "tileproperty.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
@ -32,7 +31,6 @@ namespace curry {
|
|||
CSVJointData (const CSVJointData&) = delete;
|
||||
|
||||
std::vector<std::vector<TileIndex>> tables;
|
||||
std::vector<TileProperty> tile_properties; //not filled in with real values
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
};
|
|
@ -1,52 +0,0 @@
|
|||
project(mycurry_gamelib CXX)
|
||||
|
||||
PKG_SEARCH_MODULE(SDL2 REQUIRED IMPORTED_TARGET sdl2)
|
||||
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED IMPORTED_TARGET SDL2_image>=2.0.0)
|
||||
find_package(PNG REQUIRED)
|
||||
|
||||
add_library(${PROJECT_NAME}
|
||||
csvloader.cpp
|
||||
ingamescene.cpp
|
||||
gamescenebase.cpp
|
||||
worldgrid.cpp
|
||||
worldviewport.cpp
|
||||
tileiterator.cpp
|
||||
texture.cpp
|
||||
movingobject.cpp
|
||||
character.cpp
|
||||
rect_to_sdl.cpp
|
||||
worldsizenotifiable.cpp
|
||||
worlditems.cpp
|
||||
moveable.cpp
|
||||
grid_raytrace.cpp
|
||||
drawable.cpp
|
||||
drawing_queue.cpp
|
||||
world_moveable.cpp
|
||||
collider.cpp
|
||||
)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} SYSTEM
|
||||
PRIVATE ${PNG_INCLUDE_DIRS}
|
||||
PRIVATE ${Boost_INCLUDE_DIRS}
|
||||
)
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PUBLIC ${CMAKE_SOURCE_DIR}/lib/vectorwrapper/include
|
||||
PRIVATE ${CMAKE_BINARY_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE PkgConfig::SDL2
|
||||
PRIVATE PkgConfig::SDL2IMAGE
|
||||
PRIVATE ${PNG_LIBRARIES}
|
||||
PUBLIC mycurry_toplevel
|
||||
PUBLIC cloonelgraphics
|
||||
PRIVATE tmxlite
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME}
|
||||
PRIVATE ${PNG_DEFINITIONS}
|
||||
PUBLIC VWR_WITH_IMPLICIT_CONVERSIONS=1
|
||||
PUBLIC VWR_EXTRA_ACCESSORS
|
||||
)
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
Copyright 2016-2018 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "collider.hpp"
|
||||
#include "grid_raytrace.hpp"
|
||||
#include "worldgrid.hpp"
|
||||
#include "vectorwrapper/sequence_range.hpp"
|
||||
#include <cstdint>
|
||||
|
||||
namespace curry {
|
||||
namespace {
|
||||
vec2us collision_borders (const vec2us& parObjSize, const vec2f& parDirection) {
|
||||
assert(parObjSize > 0);
|
||||
const uint16_t horz_offs = (parDirection.x() > 0.0f ? static_cast<uint16_t>(parObjSize.x() - 1) : 0);
|
||||
const uint16_t vert_offs = (parDirection.y() > 0.0f ? static_cast<uint16_t>(parObjSize.y() - 1) : 0);
|
||||
return vec2us(horz_offs, vert_offs);
|
||||
}
|
||||
|
||||
vec2us check_tiles_count (const vec2us& parObjSize, const vec2f& parDirection) {
|
||||
assert(parObjSize > 0);
|
||||
const uint16_t horz = (parDirection.y() != 0.0f ? parObjSize.x() : 1);
|
||||
const uint16_t vert = (parDirection.x() != 0.0f ? parObjSize.y() : 1);
|
||||
return vec2us(horz, vert);
|
||||
}
|
||||
|
||||
vec2f direction_mask (const vec2f& parDirection) {
|
||||
const auto horz = (parDirection.x() == 0.0f ? 0.0f : 1.0f);
|
||||
const auto vert = (parDirection.y() == 0.0f ? 0.0f : 1.0f);
|
||||
return vec2f(horz, vert);
|
||||
}
|
||||
|
||||
vec2f make_pixel_side_offset (
|
||||
const vec2us& parTileSize,
|
||||
const vec2us& parSideOffset,
|
||||
const vec2f& parDirection
|
||||
) {
|
||||
const vec2f tile_size = vector_cast<vec2f>(parTileSize);
|
||||
vec2f tile_start = tile_size * vector_cast<vec2f>(parSideOffset);
|
||||
if (parDirection.x() > 0.0f)
|
||||
tile_start.x() += tile_size.x() - 1.0f;
|
||||
if (parDirection.y() > 0.0f)
|
||||
tile_start.y() += tile_size.y() - 1.0f;
|
||||
return tile_start;
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
vec2f Collider::try_reach_tile (
|
||||
const vec2us& parObjectSize,
|
||||
const vec2f& parFrom,
|
||||
const vec2f& parTo,
|
||||
const WorldGrid& parWorld
|
||||
) {
|
||||
const vec2f direction = parTo - parFrom;
|
||||
if (direction == 0.0f)
|
||||
return parTo;
|
||||
|
||||
const vec2us side_offset = collision_borders(parObjectSize, direction);
|
||||
const vec2us length = check_tiles_count(parObjectSize, direction);
|
||||
const vec2f pix_side_offset =
|
||||
make_pixel_side_offset(parWorld.tile_size(), side_offset, direction);
|
||||
const vec2f to = parTo + pix_side_offset;
|
||||
const vec2f from = parFrom + pix_side_offset;
|
||||
vec2us stop_at = pixel_to_world_tile(parWorld, from);
|
||||
const vec2us dest_tile = pixel_to_world_tile(parWorld, to);
|
||||
vec2f tile_relative_offs = to - world_tile_to_pixel(parWorld, dest_tile);
|
||||
assert(tile_relative_offs < vector_cast<vec2f>(parWorld.tile_size()));
|
||||
|
||||
vec2f collision_mask(0.0f);
|
||||
auto forward_callback = [=,&parWorld,&stop_at,&tile_relative_offs,&collision_mask](vec2us tile) {
|
||||
for (auto curr_pos : vwr::increasing_sequence_range<vec2us>(tile, tile + length)) {
|
||||
const bool walkable = parWorld.tile_property(parWorld.tile(curr_pos)).walkable;
|
||||
if (not walkable) {
|
||||
collision_mask = direction_mask(direction);
|
||||
tile_relative_offs *= (1.0f - collision_mask);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
stop_at = tile;
|
||||
return true;
|
||||
};
|
||||
|
||||
for_each_cell_under_segment(
|
||||
from,
|
||||
to,
|
||||
parObjectSize,
|
||||
parWorld,
|
||||
forward_callback,
|
||||
false
|
||||
);
|
||||
|
||||
return world_tile_to_pixel(parWorld, stop_at) + tile_relative_offs - pix_side_offset + collision_mask * direction_mask(pix_side_offset) * 31.0f;
|
||||
}
|
||||
} //namespace curry
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
Copyright 2016-2018 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "rect.hpp"
|
||||
#include <functional>
|
||||
|
||||
namespace curry {
|
||||
class WorldGrid;
|
||||
|
||||
class Collider {
|
||||
public:
|
||||
Collider() = default;
|
||||
~Collider() = default;
|
||||
|
||||
vec2f try_reach_tile (
|
||||
const vec2us& parObjectSize,
|
||||
const vec2f& parFrom,
|
||||
const vec2f& parTo,
|
||||
const WorldGrid& parWorld
|
||||
);
|
||||
|
||||
private:
|
||||
};
|
||||
} //namespace curry
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "enum.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace curry {
|
||||
#if !defined(NDEBUG)
|
||||
BETTER_ENUM(DrawaLayerNames, uint16_t,
|
||||
Background,
|
||||
Debug,
|
||||
Characters
|
||||
)
|
||||
#else
|
||||
BETTER_ENUM(DrawaLayerNames, uint16_t,
|
||||
Background,
|
||||
Characters
|
||||
)
|
||||
#endif
|
||||
} //namespace curry
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "drawable.hpp"
|
||||
#include "texture.hpp"
|
||||
#include "safe_stack_object.hpp"
|
||||
#include <utility>
|
||||
#include <algorithm>
|
||||
#include <ciso646>
|
||||
#include <cassert>
|
||||
|
||||
namespace curry {
|
||||
namespace {
|
||||
vec2f max_size (const vec2f& parA, const vec2f& parB) {
|
||||
return vec2f(
|
||||
std::max(parA.x(), parB.x()),
|
||||
std::max(parA.y(), parB.y())
|
||||
);
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
Drawable::Drawable() :
|
||||
m_width_height(0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
Drawable::~Drawable() noexcept = default;
|
||||
|
||||
size_t Drawable::add_texture (const char* parTexturePath, cloonel::SDLMain& parSDLMain) {
|
||||
SafeStackObject<Texture> new_texture;
|
||||
new_texture->load(parTexturePath, parSDLMain);
|
||||
const auto retval = store_new_texture(std::move(new_texture));
|
||||
return retval;
|
||||
}
|
||||
|
||||
size_t Drawable::add_texture (const vec2f& parSize, cloonel::SDLMain& parSDLMain) {
|
||||
assert(parSize > 0.0f);
|
||||
SafeStackObject<Texture> new_texture;
|
||||
new_texture->load_empty(parSDLMain, static_cast<vec2us>(parSize));
|
||||
const auto retval = store_new_texture(std::move(new_texture));
|
||||
return retval;
|
||||
}
|
||||
|
||||
void Drawable::unload_textures() noexcept {
|
||||
for (auto& tex : m_textures) {
|
||||
tex->unload();
|
||||
}
|
||||
m_textures.clear();
|
||||
}
|
||||
|
||||
const vec2f& Drawable::width_height() const {
|
||||
return m_width_height;
|
||||
}
|
||||
|
||||
Kakoune::SafePtr<Texture>& Drawable::texture() {
|
||||
assert(not m_textures.empty());
|
||||
auto& retval = m_textures[0];
|
||||
return retval;
|
||||
}
|
||||
|
||||
void Drawable::on_texture_size_changed (const vec2f&, const vec2f&) {
|
||||
}
|
||||
|
||||
size_t Drawable::store_new_texture (SafeStackObject<Texture>&& parNewTexture) {
|
||||
const auto old_wh = m_width_height;
|
||||
m_width_height = max_size(vector_cast<vec2f>(parNewTexture->width_height()), old_wh);
|
||||
const auto& new_wh = m_width_height;
|
||||
if (new_wh != old_wh)
|
||||
this->on_texture_size_changed(old_wh, new_wh);
|
||||
|
||||
m_textures.push_back(std::move(parNewTexture));
|
||||
assert(m_textures.size() > 0);
|
||||
return m_textures.size() - 1;
|
||||
}
|
||||
} //namespace curry
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "safe_ptr.hh"
|
||||
#include "vector.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace cloonel {
|
||||
class SDLMain;
|
||||
} //namespace cloonel
|
||||
|
||||
namespace curry {
|
||||
template <typename T> class SafeStackObject;
|
||||
class Texture;
|
||||
class DrawingQueue;
|
||||
class WorldViewport;
|
||||
|
||||
class Drawable {
|
||||
public:
|
||||
Drawable();
|
||||
virtual ~Drawable() noexcept;
|
||||
|
||||
size_t add_texture (const char* parTexturePath, cloonel::SDLMain& parSDLMain);
|
||||
size_t add_texture (const vec2f& parSize, cloonel::SDLMain& parSDLMain);
|
||||
|
||||
void unload_textures() noexcept;
|
||||
const vec2f& width_height() const;
|
||||
Kakoune::SafePtr<Texture>& texture();
|
||||
virtual void draw ( DrawingQueue& parDQ, const WorldViewport& parViewport ) = 0;
|
||||
|
||||
private:
|
||||
size_t store_new_texture (SafeStackObject<Texture>&& parNewTexture);
|
||||
virtual void on_texture_size_changed (const vec2f& parOldSz, const vec2f& parNewSz);
|
||||
|
||||
std::vector<SafeStackObject<Texture>> m_textures;
|
||||
vec2f m_width_height;
|
||||
};
|
||||
} //namespace curry
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "safe_ptr.hh"
|
||||
#include "rect.hpp"
|
||||
#include "sizenotifiable.hpp"
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
|
||||
namespace cloonel {
|
||||
class SDLMain;
|
||||
} //namespace cloonel
|
||||
|
||||
namespace curry {
|
||||
class Texture;
|
||||
|
||||
class DrawingQueue : public cloonel::SizeNotifiable<cloonel::regbehaviours::AutoRegister> {
|
||||
typedef cloonel::SizeNotifiable<cloonel::regbehaviours::AutoRegister> SizeNotifiableBase;
|
||||
public:
|
||||
struct ItemInfo;
|
||||
|
||||
DrawingQueue (cloonel::SDLMain* parSDLMain, const cloonel::DeferredRegister& parDeferredRegister);
|
||||
virtual ~DrawingQueue() noexcept;
|
||||
|
||||
bool add_layer (uint16_t parName);
|
||||
std::size_t default_layer_id() const;
|
||||
void flush_to_renderer();
|
||||
void add_for_rendering (uint16_t parName, ItemInfo&& parItem);
|
||||
|
||||
private:
|
||||
void draw_clipped (Texture& parTexture, Rect<float> parSrc, Rect<float> parDest);
|
||||
virtual void OnResChanged ( const cloonel::SizeRatio& parSizeRatio ) override;
|
||||
|
||||
struct LocalData;
|
||||
|
||||
std::unique_ptr<LocalData> m_local_data;
|
||||
};
|
||||
|
||||
struct DrawingQueue::ItemInfo {
|
||||
ItemInfo();
|
||||
ItemInfo (ItemInfo&&);
|
||||
ItemInfo (const ItemInfo&) = delete;
|
||||
~ItemInfo() noexcept;
|
||||
|
||||
ItemInfo& operator= (ItemInfo&&);
|
||||
ItemInfo& operator= (const ItemInfo&) = delete;
|
||||
|
||||
Rect<float> source;
|
||||
Rect<float> destination;
|
||||
Kakoune::SafePtr<Texture> texture;
|
||||
};
|
||||
} //namespace curry
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gamescenebase.hpp"
|
||||
#include "inputbag.hpp"
|
||||
#include "sdlmain.hpp"
|
||||
#include "rect.hpp"
|
||||
#include "drawing_queue.hpp"
|
||||
#include <cassert>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <algorithm>
|
||||
#include <ciso646>
|
||||
#if !defined(NDEBUG)
|
||||
# include "compatibility.h"
|
||||
# include <cmath>
|
||||
#endif
|
||||
|
||||
namespace curry {
|
||||
namespace {
|
||||
///---------------------------------------------------------------------
|
||||
///---------------------------------------------------------------------
|
||||
bool DoEvents (cloonel::InputBag& parInput, cloonel::SDLMain* parSdlMain) {
|
||||
using cloonel::InputDevice_Keyboard;
|
||||
using cloonel::ushort2;
|
||||
|
||||
SDL_Event eve;
|
||||
while (SDL_PollEvent(&eve)) {
|
||||
switch (eve.type) {
|
||||
case SDL_KEYDOWN:
|
||||
//eve.key.keysym.sym
|
||||
parInput.NotifyKeyAction(InputDevice_Keyboard, eve.key.keysym.scancode, true);
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
parInput.NotifyKeyAction(InputDevice_Keyboard, eve.key.keysym.scancode, false);
|
||||
break;
|
||||
|
||||
case SDL_QUIT:
|
||||
return true;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
if (SDL_WINDOWEVENT_RESIZED == eve.window.event) {
|
||||
parSdlMain->SetResolution(ushort2(static_cast<uint16_t>(eve.window.data1), static_cast<uint16_t>(eve.window.data2)));
|
||||
}
|
||||
else if (SDL_WINDOWEVENT_CLOSE == eve.window.event) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
GameSceneBase::GameSceneBase (cloonel::SDLMain* parSdlMain) :
|
||||
m_time0(std::chrono::steady_clock::now()),
|
||||
m_input(std::make_unique<cloonel::InputBag>()),
|
||||
m_drawing_queue(std::make_unique<DrawingQueue>(parSdlMain, cloonel::DeferredRegister())),
|
||||
m_sdlmain(parSdlMain),
|
||||
m_screen_width(static_cast<float>(m_sdlmain->WidthHeight().x())),
|
||||
m_screen_height(static_cast<float>(m_sdlmain->WidthHeight().y())),
|
||||
m_wants_to_quit(false)
|
||||
{
|
||||
assert(m_sdlmain);
|
||||
}
|
||||
|
||||
GameSceneBase::~GameSceneBase() noexcept = default;
|
||||
|
||||
void GameSceneBase::prepare() {
|
||||
m_wants_to_quit = false;
|
||||
this->on_prepare();
|
||||
|
||||
m_time0 = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
void GameSceneBase::destroy() noexcept {
|
||||
set_wants_to_quit();
|
||||
this->on_destroy();
|
||||
}
|
||||
|
||||
bool GameSceneBase::wants_to_quit() const {
|
||||
return m_wants_to_quit;
|
||||
}
|
||||
|
||||
void GameSceneBase::set_wants_to_quit() {
|
||||
m_wants_to_quit = true;
|
||||
}
|
||||
|
||||
void GameSceneBase::exec() {
|
||||
const auto time1 = std::chrono::steady_clock::now();
|
||||
|
||||
const bool quit = DoEvents(*m_input, m_sdlmain);
|
||||
m_input->KeyStateUpdateFinished();
|
||||
if (quit)
|
||||
set_wants_to_quit();
|
||||
|
||||
const float delta = std::chrono::duration<float>(time1 - m_time0).count();
|
||||
m_time0 = time1;
|
||||
this->on_update(delta);
|
||||
m_drawing_queue->flush_to_renderer();
|
||||
SDL_RenderPresent(this->sdl_main()->GetRenderer());
|
||||
}
|
||||
|
||||
cloonel::SDLMain* GameSceneBase::sdl_main() {
|
||||
return m_sdlmain;
|
||||
}
|
||||
|
||||
cloonel::InputBag& GameSceneBase::input_bag() {
|
||||
return *m_input;
|
||||
}
|
||||
|
||||
DrawingQueue& GameSceneBase::drawing_queue() {
|
||||
return *m_drawing_queue;
|
||||
}
|
||||
|
||||
const DrawingQueue& GameSceneBase::drawing_queue() const {
|
||||
return *m_drawing_queue;
|
||||
}
|
||||
} //namespace curry
|
|
@ -1,169 +0,0 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "grid_raytrace.hpp"
|
||||
#include "worldgrid.hpp"
|
||||
#include "vectorwrapper/vectorops.hpp"
|
||||
#include "tileproperty.hpp"
|
||||
#include <cassert>
|
||||
#include <ciso646>
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
#include <cfloat>
|
||||
#include <algorithm>
|
||||
#include <cfloat>
|
||||
|
||||
namespace curry {
|
||||
#if !defined(BUILD_TESTING)
|
||||
namespace {
|
||||
#endif
|
||||
float inv_length (const vec2f& parVec) {
|
||||
return 1.0f / std::sqrt(parVec.x() * parVec.x() + parVec.y() * parVec.y());
|
||||
}
|
||||
|
||||
vec2f abs (const vec2f& parVec) {
|
||||
return vec2f(std::abs(parVec.x()), std::abs(parVec.y()));
|
||||
}
|
||||
|
||||
float segment_intersection (const vec2f& parA, const vec2f& parDirA, const vec2f& parB, const vec2f& parDirB) {
|
||||
const auto& p = parA;
|
||||
const auto& r = parDirA;
|
||||
const auto& q = parB;
|
||||
const auto& s = parDirB;
|
||||
|
||||
const auto r_cross_s = cross(r, s);
|
||||
if (std::abs(r_cross_s) <= FLT_EPSILON) {
|
||||
if (std::abs(cross(q - p, r)) <= FLT_EPSILON) {
|
||||
assert(std::abs(dot(r, r)) > FLT_EPSILON);
|
||||
auto t0 = dot(q - p, r) / dot(r, r);
|
||||
auto t1 = dot(q - p + s, r) / dot(r, r);
|
||||
if (dot(s, r) < 0.0f)
|
||||
std::swap(t0, t1);
|
||||
assert(t0 <= t1);
|
||||
if (0.0f <= t0)
|
||||
return t0;
|
||||
else if (t1 <= 1.0f)
|
||||
return t1;
|
||||
else
|
||||
return INFINITY;
|
||||
}
|
||||
else {
|
||||
return INFINITY;
|
||||
}
|
||||
}
|
||||
|
||||
assert(not (std::abs(r_cross_s) <= FLT_EPSILON));
|
||||
const auto inv_r_cross_s = 1.0f / r_cross_s;
|
||||
const auto t = cross(q - p, s) * inv_r_cross_s;
|
||||
//const auto u = cross(q - p, r) * inv_r_cross_s;
|
||||
|
||||
return t;
|
||||
//if (0.0f <= t and t <= 1.0f and 0.0f <= u and u <= 1.0f)
|
||||
//return t;
|
||||
//else
|
||||
//return INFINITY;
|
||||
}
|
||||
|
||||
vec2f frac (vec2f parVal) {
|
||||
return parVal - vec2f(std::floor(parVal.x()), std::floor(parVal.y()));
|
||||
}
|
||||
|
||||
template <typename T> int sgn (T val) {
|
||||
return (T(0) < val) - (val < T(0));
|
||||
}
|
||||
#if !defined(BUILD_TESTING)
|
||||
} //unnamed namespace
|
||||
#endif
|
||||
|
||||
//see:
|
||||
//http://stackoverflow.com/questions/24679963/precise-subpixel-line-drawing-algorithm-rasterization-algorithm
|
||||
void for_each_cell_under_segment (
|
||||
const vec2f& parFrom,
|
||||
const vec2f& parTo,
|
||||
vec2us parObjSize,
|
||||
const WorldGrid& parWorld,
|
||||
std::function<bool(vec2us)> parFunc,
|
||||
bool parInclFirst
|
||||
) {
|
||||
const vec2f tile_size = vector_cast<vec2f>(parWorld.tile_size());
|
||||
//in this simplified case everything should be part of the world grid
|
||||
assert(parFrom >= vec2f(0.0f));
|
||||
assert(parTo >= vec2f(0.0f));
|
||||
assert(parFrom / tile_size <= vector_cast<vec2f>(parWorld.world_size()));
|
||||
assert(parTo / tile_size <= vector_cast<vec2f>(parWorld.world_size()));
|
||||
|
||||
//float t = 0.0f;
|
||||
const vec2f& u = parFrom;
|
||||
const vec2f v = parTo - parFrom;
|
||||
|
||||
const auto delta = tile_size / abs(v);
|
||||
const auto fr = frac(u / tile_size);
|
||||
assert(fr.x() >= 0.0f and fr.x() < 1.0f);
|
||||
assert(fr.y() >= 0.0f and fr.y() < 1.0f);
|
||||
|
||||
//see:
|
||||
//http://stackoverflow.com/questions/12367071/how-do-i-initialize-the-t-variables-in-a-fast-voxel-traversal-algorithm-for-ray#12370474
|
||||
const vec2i step(sgn(v.x()), sgn(v.y()));
|
||||
vec2f max;
|
||||
if (step.x() > 0)
|
||||
max.x() = delta.x() * (1.0f - fr.x());
|
||||
else if (step.x() < 0)
|
||||
max.x() = delta.x() * fr.x();
|
||||
else
|
||||
max.x() = FLT_MAX;
|
||||
if (step.y() > 0)
|
||||
max.y() = delta.y() * (1.0f - fr.y());
|
||||
else if (step.y() < 0)
|
||||
max.y() = delta.y() * fr.y();
|
||||
else
|
||||
max.y() = FLT_MAX;
|
||||
|
||||
vec2us curr_tile = pixel_to_world_tile(parWorld, u);
|
||||
const vec2us last_tile = pixel_to_world_tile(parWorld, parTo);
|
||||
bool& do_callback = parInclFirst;
|
||||
while (
|
||||
((do_callback and parFunc(curr_tile)) or not do_callback)
|
||||
and last_tile != curr_tile
|
||||
) {
|
||||
do_callback = true;
|
||||
if (max.x() < max.y()) {
|
||||
assert(step.x());
|
||||
assert(
|
||||
std::max(static_cast<uint16_t>(curr_tile.x() + step.x()), last_tile.x()) -
|
||||
std::min(static_cast<uint16_t>(curr_tile.x() + step.x()), last_tile.x()) <
|
||||
std::max(curr_tile.x(), last_tile.x()) -
|
||||
std::min(curr_tile.x(), last_tile.x())
|
||||
);
|
||||
max.x() += delta.x();
|
||||
curr_tile.x() = static_cast<uint16_t>(curr_tile.x() + step.x());
|
||||
}
|
||||
else {
|
||||
assert(step.y());
|
||||
assert(
|
||||
std::max(static_cast<uint16_t>(curr_tile.y() + step.y()), last_tile.y()) -
|
||||
std::min(static_cast<uint16_t>(curr_tile.y() + step.y()), last_tile.y()) <
|
||||
std::max(curr_tile.y(), last_tile.y()) -
|
||||
std::min(curr_tile.y(), last_tile.y())
|
||||
);
|
||||
max.y() += delta.y();
|
||||
curr_tile.y() = static_cast<uint16_t>(curr_tile.y() + step.y());
|
||||
}
|
||||
}
|
||||
}
|
||||
} //namespace curry
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "mycurry_toplevelConfig.h"
|
||||
#include <functional>
|
||||
|
||||
namespace curry {
|
||||
class WorldGrid;
|
||||
|
||||
#if defined(BUILD_TESTING)
|
||||
float segment_intersection (const vec2f& parA, const vec2f& parDirA, const vec2f& parB, const vec2f& parDirB);
|
||||
#endif
|
||||
|
||||
void for_each_cell_under_segment (
|
||||
const vec2f& parFrom,
|
||||
const vec2f& parTo,
|
||||
vec2us parObjSize,
|
||||
const WorldGrid& parWorld,
|
||||
std::function<bool(vec2us)> parFunc,
|
||||
bool parInclFirst
|
||||
);
|
||||
} //namespace curry
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "safe_ptr.hh"
|
||||
#include <utility>
|
||||
|
||||
namespace curry {
|
||||
template <typename T>
|
||||
class SafeStackObject {
|
||||
public:
|
||||
typedef Kakoune::SafePtr<T> safe_ptr;
|
||||
|
||||
SafeStackObject();
|
||||
SafeStackObject (SafeStackObject&& parOther);
|
||||
SafeStackObject (const SafeStackObject& parOther) = delete;
|
||||
~SafeStackObject() noexcept = default;
|
||||
|
||||
SafeStackObject& operator= (SafeStackObject&& parOther) = delete;
|
||||
SafeStackObject& operator= (const SafeStackObject& parOther) = delete;
|
||||
|
||||
operator Kakoune::SafePtr<T>&();
|
||||
safe_ptr& operator*();
|
||||
safe_ptr& operator->();
|
||||
|
||||
private:
|
||||
T m_obj;
|
||||
safe_ptr m_obj_ptr;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
SafeStackObject<T>::SafeStackObject() :
|
||||
m_obj(),
|
||||
m_obj_ptr(&m_obj)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
SafeStackObject<T>::SafeStackObject (SafeStackObject&& parOther) :
|
||||
m_obj(std::move(parOther.m_obj)),
|
||||
m_obj_ptr(&m_obj)
|
||||
{
|
||||
}
|
||||
|
||||
//template <typename T>
|
||||
//SafeStackObject& SafeStackObject<T>::operator= (SafeStackObject&& parOther) {
|
||||
// m_obj = std::move(parOther.m_obj);
|
||||
// m_obj_ptr = std::move(parOther.m_obj_ptr);
|
||||
// m_ob
|
||||
//}
|
||||
|
||||
//template <typename T>
|
||||
//SafeStackObject& SafeStackObject<T>::operator= (const SafeStackObject& parOther) {
|
||||
//}
|
||||
|
||||
template <typename T>
|
||||
SafeStackObject<T>::operator Kakoune::SafePtr<T>&() {
|
||||
return m_obj_ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto SafeStackObject<T>::operator*() -> safe_ptr& {
|
||||
return m_obj_ptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto SafeStackObject<T>::operator->() -> safe_ptr& {
|
||||
return m_obj_ptr;
|
||||
}
|
||||
} //namespace curry
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
Copyright 2016-2018 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "world_moveable.hpp"
|
||||
#include <cassert>
|
||||
|
||||
namespace curry {
|
||||
WorldMoveable::WorldMoveable (const WorldSizeNotifiable::DeferredRegister& parDeferredRegister) :
|
||||
WorldSizeNotifiable(parDeferredRegister),
|
||||
m_position(vec2f(0.0f), vec2f(0.0f), vec2f(0.0f)),
|
||||
m_world(parDeferredRegister.world())
|
||||
{
|
||||
assert(m_world);
|
||||
}
|
||||
void WorldMoveable::world_size_changed (const vec2us&, const vec2i& parPixelSize) {
|
||||
m_position.change_minmax(m_position.get_min(), vector_cast<vec2f>(parPixelSize));
|
||||
}
|
||||
|
||||
void WorldMoveable::set_position (const vec2f& parPos) {
|
||||
m_position = parPos;
|
||||
}
|
||||
|
||||
const vec2f& WorldMoveable::position() const {
|
||||
return m_position.get();
|
||||
}
|
||||
|
||||
void WorldMoveable::update_moveable_size (const vec2f& parOldSz, const vec2f& parNewSz) {
|
||||
if (m_position.get_min() != m_position.get_max())
|
||||
m_position.change_minmax(m_position.get_min(), m_position.get_max() + parOldSz - parNewSz);
|
||||
}
|
||||
|
||||
WorldGrid& WorldMoveable::world() {
|
||||
assert(m_world);
|
||||
return *m_world;
|
||||
}
|
||||
|
||||
const WorldGrid& WorldMoveable::world() const {
|
||||
assert(m_world);
|
||||
return *m_world;
|
||||
}
|
||||
} //namespace curry
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
Copyright 2016-2018 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "moveable.hpp"
|
||||
#include "worldsizenotifiable.hpp"
|
||||
#include "constrained_position.hpp"
|
||||
|
||||
namespace curry {
|
||||
class WorldGrid;
|
||||
|
||||
class WorldMoveable : public Moveable, public WorldSizeNotifiable {
|
||||
public:
|
||||
explicit WorldMoveable (const WorldSizeNotifiable::DeferredRegister& parDeferredRegister);
|
||||
virtual ~WorldMoveable() = default;
|
||||
|
||||
virtual void world_size_changed (const vec2us& parSize, const vec2i& parPixelSize) override;
|
||||
const vec2f& position() const;
|
||||
void set_position (const vec2f& parPos);
|
||||
WorldGrid& world();
|
||||
const WorldGrid& world() const;
|
||||
|
||||
protected:
|
||||
void update_moveable_size (const vec2f& parOldSz, const vec2f& parNewSz);
|
||||
|
||||
private:
|
||||
ConstrainedPosition<vec2f> m_position;
|
||||
WorldGrid* m_world;
|
||||
};
|
||||
} //namespace curry
|
|
@ -17,25 +17,23 @@
|
|||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "drawing_queue.hpp"
|
||||
#include "gamescenebase.hpp"
|
||||
#include "inputbag.hpp"
|
||||
#include "sdlmain.hpp"
|
||||
#include "sizeratio.hpp"
|
||||
#include "rect_to_sdl.hpp"
|
||||
#include "rect.hpp"
|
||||
#include "texture.hpp"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <cassert>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <algorithm>
|
||||
#include <ciso646>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <boost/container/flat_map.hpp>
|
||||
#include <cmath>
|
||||
#if !defined(NDEBUG)
|
||||
# include "compatibility.h"
|
||||
# include <cmath>
|
||||
#endif
|
||||
|
||||
namespace curry {
|
||||
namespace {
|
||||
typedef std::vector<DrawingQueue::ItemInfo> TextureList;
|
||||
typedef std::vector<TextureList> LayerList;
|
||||
typedef boost::container::flat_map<uint16_t, std::size_t> LayerIdxMap;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
bool are_equal_rel (float parA, float parB, float parEpsilon) a_pure;
|
||||
|
||||
|
@ -45,6 +43,39 @@ namespace curry {
|
|||
}
|
||||
#endif
|
||||
|
||||
///---------------------------------------------------------------------
|
||||
///---------------------------------------------------------------------
|
||||
bool DoEvents (cloonel::InputBag& parInput, cloonel::SDLMain* parSdlMain) {
|
||||
using cloonel::InputDevice_Keyboard;
|
||||
|
||||
SDL_Event eve;
|
||||
while (SDL_PollEvent(&eve)) {
|
||||
switch (eve.type) {
|
||||
case SDL_KEYDOWN:
|
||||
//eve.key.keysym.sym
|
||||
parInput.NotifyKeyAction(InputDevice_Keyboard, eve.key.keysym.scancode, true);
|
||||
break;
|
||||
|
||||
case SDL_KEYUP:
|
||||
parInput.NotifyKeyAction(InputDevice_Keyboard, eve.key.keysym.scancode, false);
|
||||
break;
|
||||
|
||||
case SDL_QUIT:
|
||||
return true;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
if (SDL_WINDOWEVENT_RESIZED == eve.window.event) {
|
||||
parSdlMain->SetResolution(vec2us(static_cast<uint16_t>(eve.window.data1), static_cast<uint16_t>(eve.window.data2)));
|
||||
}
|
||||
else if (SDL_WINDOWEVENT_CLOSE == eve.window.event) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------
|
||||
///Adjustes parSrc and parDest so that parDest will fit into parClip and
|
||||
///parSrc to be the relevant part of the source texture to be drawn.
|
||||
|
@ -94,85 +125,70 @@ namespace curry {
|
|||
}
|
||||
} //unnamed namespace
|
||||
|
||||
DrawingQueue::ItemInfo::ItemInfo() = default;
|
||||
DrawingQueue::ItemInfo::ItemInfo (ItemInfo&&) = default;
|
||||
DrawingQueue::ItemInfo::~ItemInfo() noexcept = default;
|
||||
DrawingQueue::ItemInfo& DrawingQueue::ItemInfo::operator=(ItemInfo&&) = default;
|
||||
|
||||
struct DrawingQueue::LocalData {
|
||||
explicit LocalData (cloonel::SDLMain* parSDLMain) :
|
||||
sdlmain(parSDLMain),
|
||||
screen_res(0.0f),
|
||||
def_layer_id(0)
|
||||
{
|
||||
}
|
||||
|
||||
LayerList layers;
|
||||
LayerIdxMap layer_idx_map;
|
||||
cloonel::SDLMain* sdlmain;
|
||||
vec2f screen_res;
|
||||
std::size_t def_layer_id;
|
||||
};
|
||||
|
||||
DrawingQueue::DrawingQueue (cloonel::SDLMain* parSDLMain, const cloonel::DeferredRegister& parDeferredRegister) :
|
||||
SizeNotifiableBase(parSDLMain, parDeferredRegister),
|
||||
m_local_data(new LocalData(parSDLMain))
|
||||
GameSceneBase::GameSceneBase (cloonel::SDLMain* parSdlMain) :
|
||||
m_time0(std::chrono::steady_clock::now()),
|
||||
m_input(std::make_unique<cloonel::InputBag>()),
|
||||
m_sdlmain(parSdlMain),
|
||||
m_screen_width(static_cast<float>(m_sdlmain->WidthHeight().x())),
|
||||
m_screen_height(static_cast<float>(m_sdlmain->WidthHeight().y())),
|
||||
m_wants_to_quit(false)
|
||||
{
|
||||
assert(parSDLMain);
|
||||
assert(m_sdlmain);
|
||||
}
|
||||
|
||||
DrawingQueue::~DrawingQueue() noexcept = default;
|
||||
GameSceneBase::~GameSceneBase() noexcept = default;
|
||||
|
||||
bool DrawingQueue::add_layer (uint16_t parName) {
|
||||
auto& idx_map = m_local_data->layer_idx_map;
|
||||
auto it_found = idx_map.lower_bound(parName);
|
||||
if (it_found != idx_map.end() and it_found->first == parName) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
m_local_data->layers.push_back(TextureList());
|
||||
const auto new_layer_index = m_local_data->layers.size() - 1;
|
||||
idx_map.insert(it_found, std::make_pair(parName, new_layer_index));
|
||||
return true;
|
||||
}
|
||||
void GameSceneBase::prepare() {
|
||||
m_wants_to_quit = false;
|
||||
this->on_prepare();
|
||||
|
||||
m_time0 = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
void DrawingQueue::flush_to_renderer() {
|
||||
assert(not m_local_data->layers.empty());
|
||||
for (auto& layer : m_local_data->layers) {
|
||||
for (auto& itm : layer) {
|
||||
draw_clipped(*itm.texture, itm.source, itm.destination);
|
||||
}
|
||||
layer.clear();
|
||||
}
|
||||
void GameSceneBase::destroy() noexcept {
|
||||
set_wants_to_quit();
|
||||
this->on_destroy();
|
||||
}
|
||||
|
||||
void DrawingQueue::add_for_rendering (uint16_t parName, ItemInfo&& parItem) {
|
||||
const auto idx = m_local_data->layer_idx_map.at(parName);
|
||||
auto& layers = m_local_data->layers;
|
||||
assert(idx < layers.size());
|
||||
assert(parItem.source.is_valid());
|
||||
assert(parItem.destination.is_valid());
|
||||
assert(parItem.texture);
|
||||
layers[idx].push_back(std::move(parItem));
|
||||
assert(not layers[idx].empty());
|
||||
assert(layers[idx].back().source.is_valid());
|
||||
assert(layers[idx].back().destination.is_valid());
|
||||
bool GameSceneBase::wants_to_quit() const {
|
||||
return m_wants_to_quit;
|
||||
}
|
||||
|
||||
void DrawingQueue::draw_clipped (Texture& parTexture, Rect<float> parSrc, Rect<float> parDest) {
|
||||
void GameSceneBase::set_wants_to_quit() {
|
||||
m_wants_to_quit = true;
|
||||
}
|
||||
|
||||
void GameSceneBase::exec() {
|
||||
const auto time1 = std::chrono::steady_clock::now();
|
||||
|
||||
const bool quit = DoEvents(*m_input, m_sdlmain);
|
||||
m_input->KeyStateUpdateFinished();
|
||||
if (quit)
|
||||
set_wants_to_quit();
|
||||
|
||||
const float delta = std::chrono::duration<float>(time1 - m_time0).count();
|
||||
m_time0 = time1;
|
||||
this->on_update(delta);
|
||||
SDL_RenderPresent(this->sdl_main()->GetRenderer());
|
||||
}
|
||||
|
||||
cloonel::SDLMain* GameSceneBase::sdl_main() {
|
||||
return m_sdlmain;
|
||||
}
|
||||
|
||||
cloonel::InputBag& GameSceneBase::input_bag() {
|
||||
return *m_input;
|
||||
}
|
||||
|
||||
void GameSceneBase::draw_clipped (Texture& parTexture, Rect<float> parSrc, Rect<float> parDest) {
|
||||
const vec2f lefttop(0.0f);
|
||||
const vec2f& rightbottom = m_local_data->screen_res;
|
||||
const vec2f rightbottom(m_screen_width, m_screen_height);
|
||||
clip_rect(parSrc, parDest, Rect<float>(lefttop, rightbottom));
|
||||
|
||||
auto src = make_sdlrect(parSrc);
|
||||
auto dst = make_sdlrect(parDest);
|
||||
assert(src.w == dst.w);
|
||||
assert(src.h == dst.h);
|
||||
SDL_RenderCopy(m_local_data->sdlmain->GetRenderer(), parTexture.texture(), &src, &dst);
|
||||
}
|
||||
|
||||
void DrawingQueue::OnResChanged (const cloonel::SizeRatio& parSizeRatio) {
|
||||
m_local_data->screen_res = vec2f(cl_vec2us(parSizeRatio.Resolution()));
|
||||
SDL_RenderCopy(m_sdlmain->GetRenderer(), parTexture.texture(), &src, &dst);
|
||||
}
|
||||
} //namespace curry
|
|
@ -28,8 +28,8 @@ namespace cloonel {
|
|||
} //namespace cloonel
|
||||
|
||||
namespace curry {
|
||||
class Texture;
|
||||
template <typename T> class Rect;
|
||||
class DrawingQueue;
|
||||
|
||||
class GameSceneBase {
|
||||
public:
|
||||
|
@ -50,13 +50,11 @@ namespace curry {
|
|||
virtual void on_update (float parDeltaT) = 0;
|
||||
cloonel::SDLMain* sdl_main();
|
||||
cloonel::InputBag& input_bag();
|
||||
DrawingQueue& drawing_queue();
|
||||
const DrawingQueue& drawing_queue() const;
|
||||
void draw_clipped (Texture& parTexture, Rect<float> parSrc, Rect<float> parDest);
|
||||
|
||||
private:
|
||||
std::chrono::time_point<std::chrono::steady_clock> m_time0;
|
||||
std::unique_ptr<cloonel::InputBag> m_input;
|
||||
std::unique_ptr<DrawingQueue> m_drawing_queue;
|
||||
cloonel::SDLMain* m_sdlmain;
|
||||
float m_screen_width;
|
||||
float m_screen_height;
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "ingamescene.hpp"
|
||||
#include "sdlmain.hpp"
|
||||
#include "mycurry_toplevelConfig.h"
|
||||
#include "mycurryConfig.h"
|
||||
#include "key.hpp"
|
||||
#include "inputbag.hpp"
|
||||
#include "movingobject.hpp"
|
||||
|
@ -31,9 +31,6 @@
|
|||
#include "csvloader.hpp"
|
||||
#include "worlditems.hpp"
|
||||
#include "gameactions.hpp"
|
||||
#include "vector.hpp"
|
||||
#include "drawing_queue.hpp"
|
||||
#include "safe_stack_object.hpp"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
@ -41,21 +38,15 @@
|
|||
#include <boost/utility/string_ref.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <cassert>
|
||||
#include <ciso646>
|
||||
|
||||
namespace curry {
|
||||
namespace {
|
||||
void add_layer_assert_done (DrawingQueue& parDQ, DrawaLayerNames parName) {
|
||||
const bool layer_added = parDQ.add_layer(parName);
|
||||
assert(layer_added);
|
||||
static_cast<void>(layer_added);
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
struct IngameScene::LocalData {
|
||||
LocalData (const vec2us& parTileSize, cloonel::SDLMain* parSDLMain, cloonel::InputBag* parInputBag) :
|
||||
world(parTileSize),
|
||||
viewport(&world, vec2f(cl_vec2us(parSDLMain->WidthHeight())), WorldSizeNotifiable::DeferredRegister(&world, &viewport)),
|
||||
viewport(&world, vec2f(parSDLMain->WidthHeight()), WorldSizeNotifiable::DeferredRegister(&world, &viewport)),
|
||||
player(parTileSize),
|
||||
character(parInputBag, WorldSizeNotifiable::DeferredRegister(&world, &character))
|
||||
{
|
||||
|
@ -63,7 +54,7 @@ namespace curry {
|
|||
|
||||
WorldGrid world;
|
||||
WorldViewport viewport;
|
||||
SafeStackObject<Texture> worldtiles;
|
||||
Texture worldtiles;
|
||||
MovingObject player;
|
||||
Character character;
|
||||
WorldItems moveable_items;
|
||||
|
@ -81,18 +72,12 @@ namespace curry {
|
|||
inp.AddAction(ActionUp, Key(InputDevice_Keyboard, SDL_SCANCODE_UP), "Move up");
|
||||
inp.AddAction(ActionRight, Key(InputDevice_Keyboard, SDL_SCANCODE_RIGHT), "Move right");
|
||||
inp.AddAction(ActionDown, Key(InputDevice_Keyboard, SDL_SCANCODE_DOWN), "Move down");
|
||||
|
||||
add_layer_assert_done(drawing_queue(), DrawaLayerNames::Background);
|
||||
add_layer_assert_done(drawing_queue(), DrawaLayerNames::Characters);
|
||||
#if !defined(NDEBUG)
|
||||
add_layer_assert_done(drawing_queue(), DrawaLayerNames::Debug);
|
||||
#endif
|
||||
}
|
||||
|
||||
IngameScene::~IngameScene() noexcept = default;
|
||||
|
||||
void IngameScene::on_prepare() {
|
||||
m_local_data->worldtiles->load(RESOURCES_PATH "nonfree_texture.png", *this->sdl_main(), RGBA{255, 255, 255, 0});
|
||||
m_local_data->worldtiles.load(RESOURCES_PATH "nonfree_texture.png", *this->sdl_main(), RGBA{255, 255, 255, 0});
|
||||
CSVJointData tiles = load_csv({
|
||||
RESOURCES_PATH "nonfree_map_ground.csv",
|
||||
RESOURCES_PATH "nonfree_map_transparent.csv"
|
||||
|
@ -100,13 +85,12 @@ namespace curry {
|
|||
|
||||
vec2us world_size(tiles.width, tiles.height);
|
||||
m_local_data->world.set_layers(world_size, tiles.tables);
|
||||
m_local_data->world.set_tile_properties(tiles.tile_properties);
|
||||
#if !defined(NDEBUG)
|
||||
std::cout << "World size set to " << world_size << '\n';
|
||||
#endif
|
||||
|
||||
m_local_data->viewport.allow_overscan(false);
|
||||
m_local_data->character.add_texture(RESOURCES_PATH "LPC_Sara_Preview.png", *this->sdl_main());
|
||||
m_local_data->character.load(RESOURCES_PATH "LPC_Sara_Preview.png", *this->sdl_main());
|
||||
const float speed_per_sec =
|
||||
static_cast<float>(
|
||||
std::max(m_local_data->world.tile_size().x(), m_local_data->world.tile_size().y())
|
||||
|
@ -124,9 +108,8 @@ namespace curry {
|
|||
m_local_data->moveable_items.move_items(parDeltaT);
|
||||
viewport.set_position(m_local_data->character.position() - (viewport.size() - m_local_data->character.width_height()) / 2.0f);
|
||||
|
||||
//TODO: move drawing code into the world map or something
|
||||
const auto tilesize(static_cast<vec2f>(world.tile_size()));
|
||||
const auto tilecount(m_local_data->worldtiles->width_height() / world.tile_size());
|
||||
const auto tilecount(m_local_data->worldtiles.width_height() / world.tile_size());
|
||||
for (auto tile : viewport) {
|
||||
for (uint16_t z = 0; z < m_local_data->world.layer_count(); ++z) {
|
||||
if (tile.index[z] < 0)
|
||||
|
@ -137,24 +120,15 @@ namespace curry {
|
|||
|
||||
Rect<float> src_rect(src_rect_xy, src_rect_xy + tilesize);
|
||||
Rect<float> dst_rect(pixel_pos, pixel_pos + tilesize);
|
||||
this->draw(DrawaLayerNames::Background, m_local_data->worldtiles, src_rect, dst_rect);
|
||||
this->draw_clipped(m_local_data->worldtiles, src_rect, dst_rect);
|
||||
}
|
||||
}
|
||||
m_local_data->character.draw(drawing_queue(), viewport);
|
||||
this->draw_clipped(m_local_data->character.texture(), m_local_data->character.source_rect(), m_local_data->character.destination_rect(viewport.position()));
|
||||
}
|
||||
|
||||
void IngameScene::on_destroy() noexcept {
|
||||
m_local_data->moveable_items.unregister_all();
|
||||
m_local_data->worldtiles->unload();
|
||||
m_local_data->character.unload_textures();
|
||||
}
|
||||
|
||||
void IngameScene::draw (DrawaLayerNames parLayer, Kakoune::SafePtr<Texture>& parTexture, Rect<float> parSrc, Rect<float> parDest) {
|
||||
DrawingQueue::ItemInfo item{};
|
||||
item.source = parSrc;
|
||||
item.destination = parDest;
|
||||
item.texture = parTexture;
|
||||
drawing_queue().add_for_rendering(parLayer, std::move(item));
|
||||
assert(not item.texture);
|
||||
m_local_data->worldtiles.unload();
|
||||
m_local_data->character.unload();
|
||||
}
|
||||
} //namespace curry
|
|
@ -20,18 +20,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "gamescenebase.hpp"
|
||||
#include "safe_ptr.hh"
|
||||
#include "draw_layer_names.hpp"
|
||||
#include <memory>
|
||||
#include <cstddef>
|
||||
|
||||
namespace cloonel {
|
||||
class SDLMain;
|
||||
} //namespace cloonel
|
||||
|
||||
namespace curry {
|
||||
class Texture;
|
||||
|
||||
class IngameScene : public GameSceneBase {
|
||||
public:
|
||||
explicit IngameScene (cloonel::SDLMain* parSDLMain);
|
||||
|
@ -41,7 +36,6 @@ namespace curry {
|
|||
virtual void on_prepare() override;
|
||||
virtual void on_destroy() noexcept override;
|
||||
virtual void on_update (float parDeltaT) override;
|
||||
void draw (DrawaLayerNames parLayer, Kakoune::SafePtr<Texture>& parTexture, Rect<float> parSrc, Rect<float> parDest);
|
||||
|
||||
private:
|
||||
struct LocalData;
|
150
src/inputbag.cpp
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "inputbag.hpp"
|
||||
#include "key.hpp"
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <ciso646>
|
||||
|
||||
namespace cloonel {
|
||||
struct Action {
|
||||
Key key;
|
||||
const std::string name;
|
||||
InputBag::ActionStateType state;
|
||||
bool newStatePressed;
|
||||
|
||||
bool operator== ( const Key& parKey ) const { return key == parKey; }
|
||||
};
|
||||
|
||||
struct InputBag::LocalData {
|
||||
std::vector<Action> actions;
|
||||
std::map<int, Action*> mappings;
|
||||
};
|
||||
|
||||
namespace {
|
||||
// | rl | pr
|
||||
// -----------------
|
||||
// rel | rel | jpr
|
||||
// prs | jrl | prs
|
||||
// jrl | rel | jpr
|
||||
// jpr | jrl | prs
|
||||
const InputBag::ActionStateType g_stateTruthTable[] = {
|
||||
InputBag::ActionState_Released,
|
||||
InputBag::ActionState_JustReleased,
|
||||
InputBag::ActionState_Released,
|
||||
InputBag::ActionState_JustReleased,
|
||||
InputBag::ActionState_JustPressed,
|
||||
InputBag::ActionState_Pressed,
|
||||
InputBag::ActionState_JustPressed,
|
||||
InputBag::ActionState_Pressed
|
||||
};
|
||||
|
||||
///----------------------------------------------------------------------
|
||||
///When actions vector is reallocated, update pointers in mappings.
|
||||
///----------------------------------------------------------------------
|
||||
void UpdatePointers (Action* parOldAddrStart, Action* parNewAddress, std::map<int, Action*>& parUpdate, int parOffset) {
|
||||
for (auto& itMap : parUpdate) {
|
||||
if (itMap.second >= parOldAddrStart) {
|
||||
itMap.second = parNewAddress + (itMap.second - parOldAddrStart) + parOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
InputBag::InputBag() :
|
||||
m_localdata(new LocalData)
|
||||
{
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
InputBag::~InputBag() noexcept {
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void InputBag::AddAction (int parAction, const Key& parKey, std::string&& parName) {
|
||||
Action* const oldBuff = m_localdata->actions.data();
|
||||
m_localdata->actions.push_back(Action({parKey, parName, ActionState_Released, false}));
|
||||
Action* const newBuff = m_localdata->actions.data();
|
||||
if (oldBuff != newBuff) {
|
||||
UpdatePointers(oldBuff, newBuff, m_localdata->mappings, 0);
|
||||
}
|
||||
m_localdata->mappings[parAction] = &m_localdata->actions.back();
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
InputBag::ActionStateType InputBag::ActionState (int parAction) const {
|
||||
assert(m_localdata->mappings.find(parAction) != m_localdata->mappings.end());
|
||||
return m_localdata->mappings[parAction]->state;
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void InputBag::Clear() {
|
||||
m_localdata->actions.clear();
|
||||
m_localdata->mappings.clear();
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void InputBag::NotifyKeyAction (InputDeviceType parDev, int parScancode, bool parPressed) {
|
||||
const Key searchKey(parDev, parScancode);
|
||||
auto itFound = std::find(m_localdata->actions.begin(), m_localdata->actions.end(), searchKey);
|
||||
//This method gets called every time a keypress or keyrelease is
|
||||
//produced, but if the key is of any use is decided here. So it possible
|
||||
//that a keystroke is not bound to any action and therefore no
|
||||
//corresponding element is present in the actions list.
|
||||
if (m_localdata->actions.end() != itFound)
|
||||
itFound->newStatePressed = parPressed;
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void InputBag::KeyStateUpdateFinished() noexcept {
|
||||
for (auto& currAction : m_localdata->actions) {
|
||||
const int numericState = static_cast<int>(currAction.state);
|
||||
assert(numericState < 4);
|
||||
const int index = (currAction.newStatePressed ? 4 : 0) + numericState;
|
||||
currAction.state = g_stateTruthTable[index];
|
||||
}
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void InputBag::ClearState() {
|
||||
for (auto& currAction : m_localdata->actions) {
|
||||
currAction.newStatePressed = false;
|
||||
currAction.state = ActionState_Released;
|
||||
}
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
bool IsPressed (const InputBag& parInput, int parAction) {
|
||||
const InputBag::ActionStateType state = parInput.ActionState(parAction);
|
||||
return InputBag::ActionState_Pressed == state or InputBag::ActionState_JustPressed == state;
|
||||
}
|
||||
} //namespace cloonel
|
59
src/inputbag.hpp
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef idF4E67FC292A5480DA4305B806170F520
|
||||
#define idF4E67FC292A5480DA4305B806170F520
|
||||
|
||||
#include "inputdevicetype.hpp"
|
||||
#include <memory>
|
||||
#include <ciso646>
|
||||
|
||||
namespace cloonel {
|
||||
struct Key;
|
||||
|
||||
class InputBag {
|
||||
public:
|
||||
enum ActionStateType {
|
||||
ActionState_Released,
|
||||
ActionState_Pressed,
|
||||
ActionState_JustReleased,
|
||||
ActionState_JustPressed
|
||||
};
|
||||
|
||||
InputBag ( void );
|
||||
~InputBag ( void ) noexcept;
|
||||
|
||||
void AddAction ( int parAction, const Key& parKey, std::string&& parName );
|
||||
ActionStateType ActionState ( int parAction ) const;
|
||||
void Clear ( void );
|
||||
void NotifyKeyAction ( InputDeviceType parDev, int parScancode, bool parPressed );
|
||||
void KeyStateUpdateFinished ( void ) noexcept;
|
||||
void ClearState ( void );
|
||||
|
||||
private:
|
||||
struct LocalData;
|
||||
|
||||
const std::unique_ptr<LocalData> m_localdata;
|
||||
};
|
||||
|
||||
bool IsPressed ( const InputBag& parInput, int parAction );
|
||||
inline bool IsReleased ( const InputBag& parInput, int parAction ) { return not IsPressed(parInput, parAction); }
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
29
src/inputdevicetype.hpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef idED0C5C9767B64910A2998ACDAE14A509
|
||||
#define idED0C5C9767B64910A2998ACDAE14A509
|
||||
|
||||
namespace cloonel {
|
||||
enum InputDeviceType {
|
||||
InputDevice_Keyboard
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
62
src/key.hpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef id8F6145D6CFBA40338C5804DEC032CE16
|
||||
#define id8F6145D6CFBA40338C5804DEC032CE16
|
||||
|
||||
#include "inputdevicetype.hpp"
|
||||
#include <ciso646>
|
||||
|
||||
namespace cloonel {
|
||||
struct Key {
|
||||
Key ( void ) = default;
|
||||
Key ( InputDeviceType parDev, int parScancode, const char parLabel[4] ) :
|
||||
srcdevice(parDev),
|
||||
scancode(parScancode)
|
||||
{
|
||||
label[0] = parLabel[0];
|
||||
label[1] = parLabel[1];
|
||||
label[2] = parLabel[2];
|
||||
label[3] = parLabel[3];
|
||||
}
|
||||
Key ( InputDeviceType parDev, int parScancode ) :
|
||||
srcdevice(parDev),
|
||||
scancode(parScancode),
|
||||
label {0, 0, 0, 0}
|
||||
{
|
||||
}
|
||||
~Key ( void ) noexcept = default;
|
||||
|
||||
bool operator== ( const Key& parOther ) const {
|
||||
return srcdevice == parOther.srcdevice and scancode == parOther.scancode;
|
||||
}
|
||||
bool operator!= ( const Key& parOther ) const {
|
||||
return not this->operator==(parOther);
|
||||
}
|
||||
bool operator< ( const Key& parOther ) const {
|
||||
return (srcdevice == parOther.srcdevice and scancode < parOther.scancode) or (srcdevice < parOther.srcdevice);
|
||||
}
|
||||
|
||||
InputDeviceType srcdevice;
|
||||
int scancode;
|
||||
char label[4];
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
|
@ -48,10 +48,6 @@ int main() {
|
|||
cloonel::ushort2(REFERENCE_WIDTH, REFERENCE_HEIGHT)
|
||||
);
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
std::cout << "Debug build\n";
|
||||
#endif
|
||||
|
||||
int ret_val = 0;
|
||||
try {
|
||||
sdl_main.Init();
|
|
@ -20,4 +20,3 @@
|
|||
#pragma once
|
||||
|
||||
#define RESOURCES_PATH "@MYCURRY_RESOURCES_PATH@/"
|
||||
#cmakedefine BUILD_TESTING
|
180
src/observersmanager.hpp
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef idF5E41734950640CDA3C949E0D3A9A30D
|
||||
#define idF5E41734950640CDA3C949E0D3A9A30D
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <ciso646>
|
||||
#include <tree.hh>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <unordered_set>
|
||||
|
||||
#if defined (WITH_VERBOSE_OBS_MANAGER) && defined(__GNUC__) && __GNUC__ >= 2 && !defined(NDEBUG)
|
||||
# define OBS_MANAGER_LOG
|
||||
#endif
|
||||
|
||||
#if defined(OBS_MANAGER_LOG)
|
||||
# include <iostream>
|
||||
#endif
|
||||
|
||||
namespace cloonel {
|
||||
template <typename T>
|
||||
class ObserversManager {
|
||||
public:
|
||||
typedef size_t TicketType;
|
||||
|
||||
private:
|
||||
struct TicketedWrapper {
|
||||
TicketedWrapper ( void ) = default;
|
||||
TicketedWrapper ( T parItem, TicketType parTicket ) :
|
||||
itm(parItem),
|
||||
ticket(parTicket)
|
||||
{
|
||||
}
|
||||
|
||||
T itm;
|
||||
TicketType ticket;
|
||||
|
||||
bool operator== ( const TicketedWrapper& parOther ) const { return parOther.ticket == ticket; }
|
||||
bool operator== ( TicketType parOther ) const { return parOther == ticket; }
|
||||
};
|
||||
static T& TicketedWrapperToItm ( TicketedWrapper& parWrapper ) { return parWrapper.itm; }
|
||||
|
||||
typedef tree<TicketedWrapper> TreeType;
|
||||
typedef typename tree<TicketedWrapper>::iterator TreeIteratorType;
|
||||
|
||||
public:
|
||||
enum {
|
||||
Ticket_Null = 0
|
||||
};
|
||||
typedef boost::transform_iterator<std::function<T&(TicketedWrapper&)>, TreeIteratorType> iterator;
|
||||
|
||||
ObserversManager ( void );
|
||||
~ObserversManager ( void ) noexcept;
|
||||
|
||||
TicketType Add ( T parObserver, TicketType parParent=Ticket_Null );
|
||||
void Remove ( TicketType parTicket ) noexcept;
|
||||
void RemoveAll ( void ) noexcept;
|
||||
void Update ( TicketType parTicket, T parObserver );
|
||||
std::size_t size ( void ) const { return m_tree.size(); }
|
||||
iterator begin ( void ) { return iterator(m_tree.begin(), &TicketedWrapperToItm); }
|
||||
iterator end ( void ) { return iterator(m_tree.end(), &TicketedWrapperToItm); }
|
||||
void CopyObservers ( std::unordered_set<T>& parOut );
|
||||
|
||||
private:
|
||||
TreeIteratorType GetByTicket_AssertPresent ( TicketType parTicket );
|
||||
|
||||
TreeType m_tree;
|
||||
TicketType m_nextTicket;
|
||||
};
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
ObserversManager<T>::ObserversManager() :
|
||||
m_nextTicket(1)
|
||||
{
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
ObserversManager<T>::~ObserversManager() noexcept {
|
||||
assert(m_tree.empty());
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
typename ObserversManager<T>::TicketType ObserversManager<T>::Add (T parObserver, TicketType parParent) {
|
||||
const auto currTicket = m_nextTicket;
|
||||
if (Ticket_Null == parParent)
|
||||
m_tree.insert(m_tree.begin(), TicketedWrapper(parObserver, currTicket));
|
||||
else
|
||||
m_tree.append_child(GetByTicket_AssertPresent(parParent), TicketedWrapper(parObserver, currTicket));
|
||||
|
||||
#if defined(OBS_MANAGER_LOG)
|
||||
std::cout << __PRETTY_FUNCTION__ << " registering " << currTicket << " as a child of " << parParent << "\n";
|
||||
#endif
|
||||
++m_nextTicket;
|
||||
return currTicket;
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void ObserversManager<T>::Remove (TicketType parTicket) noexcept {
|
||||
auto deleme = GetByTicket_AssertPresent(parTicket);
|
||||
#if defined(OBS_MANAGER_LOG)
|
||||
for (auto it(deleme); it != m_tree.end(); ++it) {
|
||||
std::cout << __PRETTY_FUNCTION__ << " unregistering " << it->ticket << "\n";
|
||||
}
|
||||
#endif
|
||||
m_tree.erase(deleme);
|
||||
if (parTicket == m_nextTicket - 1)
|
||||
--m_nextTicket;
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void ObserversManager<T>::RemoveAll() noexcept {
|
||||
if (not m_tree.empty()) {
|
||||
for (typename TreeType::sibling_iterator it(m_tree.begin()), itEND(m_tree.end()); it != itEND; ++it) {
|
||||
const TicketType ticket = it->ticket;
|
||||
this->Remove(ticket);
|
||||
}
|
||||
assert(m_tree.empty());
|
||||
}
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void ObserversManager<T>::Update (TicketType parTicket, T parObserver) {
|
||||
std::swap(GetByTicket_AssertPresent(parTicket)->itm, parObserver);
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
typename ObserversManager<T>::TreeIteratorType ObserversManager<T>::GetByTicket_AssertPresent (TicketType parTicket) {
|
||||
auto ret = std::find(m_tree.begin(), m_tree.end(), parTicket);
|
||||
assert(m_tree.end() != ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
void ObserversManager<T>::CopyObservers (std::unordered_set<T>& parOut) {
|
||||
for (const auto& itm : m_tree) {
|
||||
parOut.insert(itm.itm);
|
||||
}
|
||||
}
|
||||
} //namespace cloonel
|
||||
|
||||
#if defined(OBS_MANAGER_LOG)
|
||||
# undef OBS_MANAGER_LOG
|
||||
#endif
|
||||
#endif
|
236
src/sdlmain.cpp
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sdlmain.hpp"
|
||||
#include "observersmanager.hpp"
|
||||
#include "sizenotifiable.hpp"
|
||||
#include "sizeratio.hpp"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <ciso646>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
#if defined(RASPBERRY_PI)
|
||||
#include <bcm_host.h>
|
||||
#endif
|
||||
|
||||
namespace cloonel {
|
||||
namespace {
|
||||
///----------------------------------------------------------------------
|
||||
///----------------------------------------------------------------------
|
||||
std::pair<int, std::string> GetRenderingDriver() {
|
||||
typedef std::pair<int, std::string> RetPairType;
|
||||
|
||||
const int count = SDL_GetNumRenderDrivers();
|
||||
int opengles = -1;
|
||||
int opengles2 = -1;
|
||||
int opengl = -1;
|
||||
SDL_RendererInfo info;
|
||||
for (int z = 0; z < count; ++z) {
|
||||
const int ret = SDL_GetRenderDriverInfo(z, &info);
|
||||
if (0 == ret) {
|
||||
if (std::strcmp("opengles", info.name) == 0)
|
||||
opengles = z;
|
||||
else if (std::strcmp("opengles2", info.name) == 0)
|
||||
opengles2 = z;
|
||||
else if (std::strcmp("opengl", info.name) == 0)
|
||||
opengl = z;
|
||||
}
|
||||
}
|
||||
#if !defined(FORCE_OPENGLES)
|
||||
if (opengl > -1)
|
||||
return RetPairType(opengl, "opengl");
|
||||
#endif
|
||||
if (opengles2 > -1)
|
||||
return RetPairType(opengles2, "opengles2");
|
||||
if (opengles > -1)
|
||||
return RetPairType(opengles, "opengles");
|
||||
#if defined(FORCE_OPENGLES)
|
||||
if (opengl > -1)
|
||||
return RetPairType(opengl, "opengl");
|
||||
#endif
|
||||
|
||||
return RetPairType(-1, "default");
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
struct SDLMain::LocalData {
|
||||
SDL_Window* window;
|
||||
SDL_Renderer* renderer;
|
||||
SizeRatio sizeratio;
|
||||
ObserversManager<SizeNotifiableBase*> resChangeNotifList;
|
||||
bool initialized;
|
||||
#if defined(RASPBERRY_PI)
|
||||
bool bcmInitialized;
|
||||
#endif
|
||||
};
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
SDLMain::SDLMain (const char* parGameName, ushort2 parRes, ushort2 parReferenceRes) :
|
||||
m_gameName(parGameName),
|
||||
m_localData(new LocalData)
|
||||
{
|
||||
m_localData->sizeratio.SetOriginal(static_cast<float2>(parReferenceRes), static_cast<float2>(parRes));
|
||||
m_localData->initialized = false;
|
||||
#if defined(RASPBERRY_PI)
|
||||
m_localData->bcmInitialized = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
SDLMain::~SDLMain() noexcept {
|
||||
ClearIFN(*m_localData);
|
||||
#if defined(RASPBERRY_PI)
|
||||
assert(not m_localData->bcmInitialized);
|
||||
#endif
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
void SDLMain::Init() {
|
||||
if (not m_localData->initialized)
|
||||
InitSDL(*m_localData);
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
void SDLMain::InitSDL (LocalData& parInitSDL) {
|
||||
#if defined(RASPBERRY_PI)
|
||||
assert(not parInitSDL.bcmInitialized);
|
||||
bcm_host_init();
|
||||
parInitSDL.bcmInitialized = true;
|
||||
#endif
|
||||
|
||||
parInitSDL.window = nullptr;
|
||||
parInitSDL.renderer = nullptr;
|
||||
parInitSDL.initialized = false;
|
||||
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
|
||||
throw std::runtime_error(SDL_GetError());
|
||||
parInitSDL.initialized = true;
|
||||
|
||||
#if defined(FORCE_OPENGLES)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
#endif
|
||||
|
||||
const float2 wh(m_localData->sizeratio.Resolution());
|
||||
SDL_Window* const win = SDL_CreateWindow(m_gameName.c_str(), 100, 100, static_cast<int>(wh.x()), static_cast<int>(wh.y()), SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
|
||||
if (!win)
|
||||
throw std::runtime_error(SDL_GetError());
|
||||
parInitSDL.window = win;
|
||||
|
||||
const auto rendererDriver = GetRenderingDriver();
|
||||
m_rendererName = rendererDriver.second;
|
||||
SDL_Renderer* const renderer = SDL_CreateRenderer(win, rendererDriver.first, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
|
||||
if (!renderer)
|
||||
throw std::runtime_error(SDL_GetError());
|
||||
parInitSDL.renderer = renderer;
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
void SDLMain::ClearIFN (LocalData& parInitSDL) noexcept {
|
||||
if (parInitSDL.renderer)
|
||||
SDL_DestroyRenderer(parInitSDL.renderer);
|
||||
if (parInitSDL.window)
|
||||
SDL_DestroyWindow(parInitSDL.window);
|
||||
if (parInitSDL.initialized) {
|
||||
parInitSDL.initialized = false;
|
||||
SDL_Quit();
|
||||
}
|
||||
#if defined(RASPBERRY_PI)
|
||||
if (parInitSDL.bcmInitialized) {
|
||||
parInitSDL.bcmInitialized = false;
|
||||
bcm_host_deinit();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
SDL_Renderer* SDLMain::GetRenderer() {
|
||||
if (m_localData->initialized)
|
||||
return m_localData->renderer;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
void SDLMain::SetResolution (ushort2 parRes) {
|
||||
m_localData->sizeratio.UpdateResolution(static_cast<float2>(parRes));
|
||||
{
|
||||
SDL_Renderer* const renderer = GetRenderer();
|
||||
assert(renderer);
|
||||
const int retVal = SDL_RenderSetLogicalSize(renderer, parRes.x(), parRes.y());
|
||||
if (retVal) {
|
||||
std::ostringstream oss;
|
||||
oss << "Error setting logical size to renderer to " << parRes.x() << "x" << parRes.y() << ": " << SDL_GetError();
|
||||
throw std::runtime_error(oss.str());
|
||||
}
|
||||
|
||||
const SDL_Rect area = { 0, 0, parRes.x(), parRes.y() };
|
||||
const int retValViewport = SDL_RenderSetViewport(renderer, &area);
|
||||
if (retValViewport) {
|
||||
std::ostringstream oss;
|
||||
oss << "Error setting viewport to renderer to " << parRes.x() << "x" << parRes.y() << ": " << SDL_GetError();
|
||||
throw std::runtime_error(oss.str());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto currNotifiable : m_localData->resChangeNotifList) {
|
||||
currNotifiable->NotifyResChanged(m_localData->sizeratio);
|
||||
}
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
size_t SDLMain::RegisterForResChange (SizeNotifiableBase* parNotif) {
|
||||
parNotif->NotifyResChanged(m_localData->sizeratio);
|
||||
return m_localData->resChangeNotifList.Add(parNotif);
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
void SDLMain::UnregisterForResChange (size_t parID) noexcept {
|
||||
m_localData->resChangeNotifList.Remove(parID);
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
void SDLMain::SwapRegisteredForResChange (size_t parID, SizeNotifiableBase* parNotif) {
|
||||
m_localData->resChangeNotifList.Update(parID, parNotif);
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
ushort2 SDLMain::WidthHeight() const noexcept {
|
||||
return static_cast<ushort2>(m_localData->sizeratio.Resolution());
|
||||
}
|
||||
|
||||
///------------------------------------------------------------------------
|
||||
///------------------------------------------------------------------------
|
||||
std::string SDLMain::GetVideoDriverName() const {
|
||||
return std::string(SDL_GetCurrentVideoDriver());
|
||||
}
|
||||
} //namespace cloonel
|
60
src/sdlmain.hpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef id8E7A054DAC9040B887F2620EFD229EE8
|
||||
#define id8E7A054DAC9040B887F2620EFD229EE8
|
||||
|
||||
#include "vector.hpp"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
struct SDL_Renderer;
|
||||
|
||||
namespace cloonel {
|
||||
class SizeNotifiableBase;
|
||||
|
||||
class SDLMain {
|
||||
public:
|
||||
SDLMain ( const char* parGameName, ushort2 parRes, ushort2 parReferenceRes );
|
||||
~SDLMain ( void ) noexcept;
|
||||
|
||||
void Init ( void );
|
||||
SDL_Renderer* GetRenderer ( void );
|
||||
ushort2 WidthHeight ( void ) const noexcept;
|
||||
|
||||
void SetResolution ( ushort2 parRes );
|
||||
size_t RegisterForResChange ( SizeNotifiableBase* parNotif );
|
||||
void UnregisterForResChange ( size_t parID ) noexcept;
|
||||
void SwapRegisteredForResChange ( size_t parID, SizeNotifiableBase* parNotif );
|
||||
const std::string& GetRendererName ( void ) const { return m_rendererName; }
|
||||
std::string GetVideoDriverName ( void ) const;
|
||||
|
||||
private:
|
||||
struct LocalData;
|
||||
|
||||
void InitSDL ( LocalData& parData );
|
||||
void ClearIFN ( LocalData& parData ) noexcept;
|
||||
|
||||
const std::string m_gameName;
|
||||
std::string m_rendererName;
|
||||
std::unique_ptr<LocalData> m_localData;
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
|
@ -17,15 +17,10 @@
|
|||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "singlecoordinate.hpp"
|
||||
#include "coordinates.hpp"
|
||||
|
||||
namespace curry {
|
||||
struct TileProperty {
|
||||
TileProperty() :
|
||||
walkable(true)
|
||||
{
|
||||
}
|
||||
|
||||
bool walkable;
|
||||
};
|
||||
static_assert(implem::Log2<256>::result == 8, "Wrong logarithm result");
|
||||
static_assert(implem::Log2<255>::result == 7, "Wrong logarithm result");
|
||||
} //namespace curry
|
110
src/singlecoordinate.hpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "vector.hpp"
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
#include <ciso646>
|
||||
|
||||
namespace curry {
|
||||
namespace implem {
|
||||
template <uint32_t V, uint32_t R=0, uint32_t I=5, bool=(I>0)>
|
||||
struct Log2;
|
||||
|
||||
template <uint32_t V, uint32_t R, uint32_t I>
|
||||
struct Log2<V, R, I, true> {
|
||||
static constexpr const uint32_t b[5] = {0x2, 0xc, 0xf0, 0xff00, 0xffff0000};
|
||||
static constexpr const uint32_t S[5] = {1, 2, 4, 8, 16};
|
||||
enum {
|
||||
result = Log2<(V & b[I - 1] ? V >> S[I - 1] : V), (V & b[I - 1] ? R | S[I - 1] : R), I - 1>::result
|
||||
};
|
||||
};
|
||||
template <uint32_t V, uint32_t R, uint32_t I>
|
||||
struct Log2<V, R, I, false> {
|
||||
enum {
|
||||
result = R
|
||||
};
|
||||
};
|
||||
|
||||
template <uint32_t V>
|
||||
struct NextPow2 {
|
||||
static_assert(V > 0, "V must be greater than zero");
|
||||
enum {
|
||||
result = (1U << Log2<V - 1>::result) + 1
|
||||
};
|
||||
};
|
||||
} //namespace implem
|
||||
|
||||
class SingleCoordinate {
|
||||
public:
|
||||
SingleCoordinate() = default;
|
||||
SingleCoordinate (const SingleCoordinate&) = default;
|
||||
explicit SingleCoordinate (uint32_t parTile);
|
||||
SingleCoordinate (uint32_t parTile, uint32_t parOffset);
|
||||
~SingleCoordinate() noexcept = default;
|
||||
|
||||
int32_t screen_coordinate (int32_t parWorldOffset, uint32_t parTileSize) const;
|
||||
uint32_t tile() const;
|
||||
|
||||
private:
|
||||
static constexpr const auto MaxTileSize = 128U;
|
||||
static constexpr const auto OffsetBits = implem::Log2<MaxTileSize>::result;
|
||||
static constexpr const auto OffsetMask = implem::NextPow2<MaxTileSize>::result - 1;
|
||||
|
||||
uint32_t m_data;
|
||||
};
|
||||
|
||||
inline int32_t SingleCoordinate::screen_coordinate (int32_t parWorldOffset, uint32_t parTileSize) const {
|
||||
assert(parTileSize <= MaxTileSize);
|
||||
return ((m_data - parWorldOffset) & OffsetMask) +
|
||||
(static_cast<uint32_t>(m_data - parWorldOffset) >> OffsetBits) * parTileSize;
|
||||
}
|
||||
|
||||
inline uint32_t SingleCoordinate::tile() const {
|
||||
int beyond_tile;
|
||||
const int offset = m_data & OffsetMask;
|
||||
asm(
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"subl %1,%%eax\n\t"
|
||||
"xorl %%eax,%%eax\n\t"
|
||||
"adcl %%eax,0\n\t"
|
||||
"movl %%eax,%0"
|
||||
:"=r"(beyond_tile)
|
||||
:"r"(offset)
|
||||
:"%eax"
|
||||
);
|
||||
assert(0 == beyond_tile or 1 == beyond_tile);
|
||||
return (m_data >> OffsetBits) + beyond_tile;
|
||||
}
|
||||
|
||||
SingleCoordinate::SingleCoordinate (uint32_t parTile) :
|
||||
m_data(parTile << OffsetBits)
|
||||
{
|
||||
assert(this->tile() == parTile);
|
||||
}
|
||||
|
||||
SingleCoordinate::SingleCoordinate (uint32_t parTile, uint32_t parOffset) :
|
||||
m_data((parTile << OffsetBits) + (parOffset & OffsetMask))
|
||||
{
|
||||
assert((not parOffset and this->tile() == parTile) or (this->tile() == parTile + 1));
|
||||
assert((m_data bitand OffsetMask) == parOffset);
|
||||
}
|
||||
} //namespace curry
|
78
src/sizenotifiable.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sizenotifiable.hpp"
|
||||
#include "sizeratio.hpp"
|
||||
#include "sdlmain.hpp"
|
||||
#include <cassert>
|
||||
#include <ciso646>
|
||||
|
||||
namespace cloonel {
|
||||
namespace implem {
|
||||
} //namespace implem
|
||||
|
||||
namespace regbehaviours {
|
||||
///----------------------------------------------------------------------
|
||||
///----------------------------------------------------------------------
|
||||
void AutoRegister::Register (SizeNotifiableBase* parNotifiable) {
|
||||
assert(m_sdlmain);
|
||||
#if !defined(NDEBUG)
|
||||
assert(not m_registered);
|
||||
m_registered = true;
|
||||
#endif
|
||||
m_id = m_sdlmain->RegisterForResChange(parNotifiable);
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------
|
||||
///----------------------------------------------------------------------
|
||||
void AutoRegister::Unregister() noexcept {
|
||||
#if !defined(NDEBUG)
|
||||
assert(m_registered or not m_sdlmain);
|
||||
m_registered = false;
|
||||
#endif
|
||||
if (m_sdlmain) {
|
||||
m_sdlmain->UnregisterForResChange(m_id);
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------
|
||||
///----------------------------------------------------------------------
|
||||
AutoRegister::AutoRegister (AutoRegister&& parOther, SizeNotifiableBase* parSwapTo) :
|
||||
m_sdlmain(nullptr),
|
||||
m_id(0)
|
||||
#if !defined(NDEBUG)
|
||||
, m_registered(false)
|
||||
#endif
|
||||
{
|
||||
std::swap(m_sdlmain, parOther.m_sdlmain);
|
||||
std::swap(m_id, parOther.m_id);
|
||||
#if !defined(NDEBUG)
|
||||
std::swap(m_registered, parOther.m_registered);
|
||||
#endif
|
||||
assert(m_sdlmain);
|
||||
m_sdlmain->SwapRegisteredForResChange(m_id, parSwapTo);
|
||||
}
|
||||
} //namespace regbehaviours
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void SizeNotifiableBase::NotifyResChanged (const SizeRatio& parSize) {
|
||||
m_scaleRatio = parSize.Ratio();
|
||||
}
|
||||
} //namespace cloonel
|
128
src/sizenotifiable.hpp
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef id78906DE4FB0D43219CD3F0D9C620FC06
|
||||
#define id78906DE4FB0D43219CD3F0D9C620FC06
|
||||
|
||||
#include "vector.hpp"
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
|
||||
namespace cloonel {
|
||||
class SizeRatio;
|
||||
class SDLMain;
|
||||
class SizeNotifiableBase;
|
||||
|
||||
namespace regbehaviours {
|
||||
class DontRegister {
|
||||
public:
|
||||
enum { SDLMAIN_NEEDED = false };
|
||||
|
||||
DontRegister ( void ) = default;
|
||||
DontRegister ( DontRegister&&, SizeNotifiableBase* ) { }
|
||||
~DontRegister ( void ) noexcept = default;
|
||||
|
||||
void Register ( SizeNotifiableBase* ) const noexcept { return; }
|
||||
void Unregister ( void ) const noexcept { return; }
|
||||
};
|
||||
|
||||
class AutoRegister {
|
||||
public:
|
||||
enum { SDLMAIN_NEEDED = true };
|
||||
|
||||
AutoRegister ( AutoRegister&& parOther, SizeNotifiableBase* parSwapTo );
|
||||
explicit AutoRegister ( SDLMain* parMain ) :
|
||||
m_sdlmain(parMain)
|
||||
#if !defined(NDEBUG)
|
||||
, m_registered(false)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
~AutoRegister ( void ) noexcept = default;
|
||||
|
||||
void Register ( SizeNotifiableBase* parNotifiable );
|
||||
void Unregister ( void ) noexcept;
|
||||
|
||||
private:
|
||||
SDLMain* m_sdlmain;
|
||||
size_t m_id;
|
||||
#if !defined(NDEBUG)
|
||||
bool m_registered;
|
||||
#endif
|
||||
};
|
||||
} //namespace regbehaviours
|
||||
|
||||
class SizeNotifiableBase {
|
||||
protected:
|
||||
SizeNotifiableBase ( void ) = default;
|
||||
SizeNotifiableBase ( const SizeNotifiableBase& ) = default;
|
||||
virtual ~SizeNotifiableBase ( void ) noexcept = default;
|
||||
SizeNotifiableBase& operator= ( const SizeNotifiableBase& ) = delete;
|
||||
|
||||
public:
|
||||
virtual void NotifyResChanged ( const SizeRatio& parSize );
|
||||
const float2& Ratio ( void ) const noexcept { return m_scaleRatio; }
|
||||
|
||||
private:
|
||||
float2 m_scaleRatio;
|
||||
};
|
||||
|
||||
template <class RegisterBehaviour, bool=RegisterBehaviour::SDLMAIN_NEEDED>
|
||||
class SizeNotifiable;
|
||||
|
||||
template <class RegisterBehaviour>
|
||||
class SizeNotifiable<RegisterBehaviour, false> : private RegisterBehaviour, public SizeNotifiableBase {
|
||||
static_assert(RegisterBehaviour::SDLMAIN_NEEDED == false, "SdlMainNeeded mismatches expected value");
|
||||
public:
|
||||
SizeNotifiable ( const SizeNotifiable& ) = delete;
|
||||
SizeNotifiable ( SizeNotifiable&& parOther ) :
|
||||
RegisterBehaviour(std::move(parOther), this),
|
||||
SizeNotifiableBase(parOther)
|
||||
{
|
||||
}
|
||||
SizeNotifiable ( void ) {
|
||||
this->Register(this);
|
||||
}
|
||||
virtual ~SizeNotifiable ( void ) noexcept {
|
||||
this->Unregister();
|
||||
}
|
||||
};
|
||||
|
||||
template <class RegisterBehaviour>
|
||||
class SizeNotifiable<RegisterBehaviour, true> : private RegisterBehaviour, public SizeNotifiableBase {
|
||||
static_assert(RegisterBehaviour::SDLMAIN_NEEDED == true, "SdlMainNeeded mismatches expected value");
|
||||
public:
|
||||
SizeNotifiable ( const SizeNotifiable& ) = delete;
|
||||
SizeNotifiable ( SizeNotifiable&& parOther ) :
|
||||
RegisterBehaviour(std::move(parOther), this),
|
||||
SizeNotifiableBase(parOther)
|
||||
{
|
||||
}
|
||||
explicit SizeNotifiable ( SDLMain* parSdlMain ) :
|
||||
RegisterBehaviour(parSdlMain)
|
||||
{
|
||||
this->Register(this);
|
||||
}
|
||||
virtual ~SizeNotifiable ( void ) noexcept {
|
||||
this->Unregister();
|
||||
}
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
66
src/sizeratio.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
Copyright 2016, 2017 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of MyCurry.
|
||||
|
||||
MyCurry is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MyCurry is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "sizeratio.hpp"
|
||||
#include "compatibility.h"
|
||||
|
||||
namespace cloonel {
|
||||
namespace {
|
||||
float2 CalculateRatio ( float2 parOriginal, float2 parResolution ) a_pure;
|
||||
|
||||
///----------------------------------------------------------------------
|
||||
///----------------------------------------------------------------------
|
||||
float2 CalculateRatio (float2 parOriginal, float2 parResolution) {
|
||||
return parResolution / parOriginal;
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
SizeRatio::SizeRatio (const float2& parOriginal) :
|
||||
m_original(parOriginal),
|
||||
m_size(parOriginal),
|
||||
m_ratio(1.0f)
|
||||
{
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
SizeRatio::SizeRatio (const float2& parOriginal, const float2& parSize) :
|
||||
m_original(parOriginal),
|
||||
m_size(parSize),
|
||||
m_ratio(CalculateRatio(parOriginal, parSize))
|
||||
{
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void SizeRatio::SetOriginal (const float2& parOriginal, const float2& parRes) {
|
||||
m_original = parOriginal;
|
||||
m_size = parRes;
|
||||
m_ratio = CalculateRatio(parOriginal, parRes);
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
void SizeRatio::UpdateResolution (const float2& parNewRes) {
|
||||
m_size = parNewRes;
|
||||
m_ratio = CalculateRatio(m_original, parNewRes);
|
||||
}
|
||||
} //namespace cloonel
|
45
src/sizeratio.hpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef id3098F08C14B84E3C8CE169CBA05C9C86
|
||||
#define id3098F08C14B84E3C8CE169CBA05C9C86
|
||||
|
||||
#include "vector.hpp"
|
||||
|
||||
namespace cloonel {
|
||||
class SizeRatio {
|
||||
public:
|
||||
SizeRatio ( void ) = default;
|
||||
explicit SizeRatio ( const float2& parOriginal );
|
||||
SizeRatio ( const float2& parOriginal, const float2& parSize );
|
||||
~SizeRatio ( void ) noexcept = default;
|
||||
|
||||
const float2& Ratio ( void ) const noexcept { return m_ratio; }
|
||||
const float2& Resolution ( void ) const noexcept { return m_size; }
|
||||
void SetOriginal ( const float2& parOriginal, const float2& parRes );
|
||||
void UpdateResolution ( const float2& parNewRes );
|
||||
|
||||
private:
|
||||
float2 m_original;
|
||||
float2 m_size;
|
||||
float2 m_ratio;
|
||||
};
|
||||
} //namespace cloonel
|
||||
|
||||
#endif
|
|
@ -1,17 +0,0 @@
|
|||
project(mycurry CXX)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
main.cpp
|
||||
)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 14)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE "${CMAKE_SOURCE_DIR}/src/gamelib"
|
||||
PRIVATE ${CMAKE_BINARY_DIR}
|
||||
PRIVATE ${CMAKE_SOURCE_DIR}/lib/DeathHandler
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE mycurry_gamelib
|
||||
)
|
|
@ -73,20 +73,6 @@ namespace curry {
|
|||
m_texture = load_texture(parPath, parSDLMain, true, parColorKey);
|
||||
}
|
||||
|
||||
void Texture::load_empty (cloonel::SDLMain& parSDLMain, const vec2us& parSize) {
|
||||
assert(parSize > static_cast<uint16_t>(0));
|
||||
m_texture = SDLTextureAuto(
|
||||
SDL_CreateTexture(
|
||||
parSDLMain.GetRenderer(),
|
||||
SDL_PIXELFORMAT_RGBA8888,
|
||||
SDL_TEXTUREACCESS_TARGET,
|
||||
static_cast<int>(parSize.x()),
|
||||
static_cast<int>(parSize.y())
|
||||
),
|
||||
&SDL_DestroyTexture
|
||||
);
|
||||
}
|
||||
|
||||
void Texture::unload() noexcept {
|
||||
m_texture.reset(nullptr);
|
||||
}
|
|
@ -20,7 +20,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "safe_ptr.hh"
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
|
||||
|
@ -38,17 +37,14 @@ namespace curry {
|
|||
uint8_t a;
|
||||
};
|
||||
|
||||
class Texture : public Kakoune::SafeCountable {
|
||||
class Texture {
|
||||
public:
|
||||
Texture();
|
||||
Texture (const char* parPath, cloonel::SDLMain& parSDLMain);
|
||||
Texture (Texture&&) = default;
|
||||
Texture (const Texture&) = delete;
|
||||
~Texture() noexcept;
|
||||
|
||||
void load (const char* parPath, cloonel::SDLMain& parSDLMain);
|
||||
void load (const char* parPath, cloonel::SDLMain& parSDLMain, RGBA parColorKey);
|
||||
void load_empty (cloonel::SDLMain& parSDLMain, const vec2us& parSize);
|
||||
void unload() noexcept;
|
||||
SDL_Texture* texture();
|
||||
const SDL_Texture* texture() const;
|