Compare commits
1 commit
master
...
new_coordi
Author | SHA1 | Date | |
---|---|---|---|
0bae01fd3f |
12
.gitmodules
vendored
|
@ -4,15 +4,3 @@
|
||||||
[submodule "lib/DeathHandler"]
|
[submodule "lib/DeathHandler"]
|
||||||
path = lib/DeathHandler
|
path = lib/DeathHandler
|
||||||
url = https://github.com/vmarkovtsev/DeathHandler.git
|
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)
|
cmake_minimum_required(VERSION 3.2)
|
||||||
project(mycurry_toplevel CXX)
|
project(mycurry CXX)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/include")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/include")
|
||||||
|
|
||||||
include(TargetArch)
|
include(TargetArch)
|
||||||
include(FindPkgConfig)
|
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_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)
|
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(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)
|
target_architecture(TARGET_ARCH)
|
||||||
message (STATUS "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_RASPBERRY_PI)
|
||||||
endif (CURRY_FORCE_OPENGLES OR 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)
|
find_package(Boost 1.55.0 REQUIRED)
|
||||||
|
|
||||||
if (CURRY_RASPBERRY_PI)
|
if (CURRY_RASPBERRY_PI)
|
||||||
|
@ -44,33 +51,71 @@ if (CURRY_RASPBERRY_PI)
|
||||||
)
|
)
|
||||||
endif (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)
|
if (CURRY_RASPBERRY_PI)
|
||||||
target_link_libraries(${PROJECT_NAME}
|
target_link_libraries(${PROJECT_NAME}
|
||||||
PRIVATE bcm_host
|
PRIVATE bcm_host
|
||||||
)
|
)
|
||||||
endif(CURRY_RASPBERRY_PI)
|
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}
|
target_compile_definitions(${PROJECT_NAME}
|
||||||
INTERFACE $<$<CONFIG:Debug>:KAK_DEBUG>
|
PRIVATE ${PNG_DEFINITIONS}
|
||||||
INTERFACE VWR_OUTER_NAMESPACE=curry
|
PRIVATE VWR_WITH_IMPLICIT_CONVERSIONS=1
|
||||||
)
|
PRIVATE VWR_EXTRA_ACCESSORS
|
||||||
target_include_directories(${PROJECT_NAME}
|
|
||||||
INTERFACE lib/kakoune
|
|
||||||
INTERFACE lib/better-enums
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(lib/clooneljump/src/cloonelgraphics)
|
configure_file(src/${PROJECT_NAME}Config.h.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.h)
|
||||||
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()
|
|
||||||
|
|
|
@ -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">
|
<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">
|
<tileset firstgid="1" name="nonfree" tilewidth="32" tileheight="32" tilecount="90" columns="10">
|
||||||
<image source="nonfree_texture.png" trans="ffffff" width="320" height="288"/>
|
<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>
|
</tileset>
|
||||||
<layer name="ground" width="80" height="60">
|
<layer name="ground" width="80" height="60">
|
||||||
<data encoding="csv">
|
<data encoding="csv">
|
||||||
|
|
|
@ -21,27 +21,58 @@
|
||||||
#include "inputbag.hpp"
|
#include "inputbag.hpp"
|
||||||
#include "gameactions.hpp"
|
#include "gameactions.hpp"
|
||||||
#include "worldgrid.hpp"
|
#include "worldgrid.hpp"
|
||||||
#include "drawing_queue.hpp"
|
|
||||||
#include "worldviewport.hpp"
|
|
||||||
#include "texture.hpp"
|
|
||||||
#include "draw_layer_names.hpp"
|
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace curry {
|
namespace curry {
|
||||||
|
namespace {
|
||||||
|
} //unnamed namespace
|
||||||
|
|
||||||
Character::Character (cloonel::InputBag* parInputBag, const WorldSizeNotifiable::DeferredRegister& parDeferredRegister) :
|
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_input_bag(parInputBag),
|
||||||
|
m_world(parDeferredRegister.world()),
|
||||||
m_speed(1.0f)
|
m_speed(1.0f)
|
||||||
{
|
{
|
||||||
assert(m_input_bag);
|
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 {
|
Rect<float> Character::destination_rect (const vec2f& parWorldPos) const {
|
||||||
return Rect<float>(
|
return Rect<float>(
|
||||||
position() - parWorldPos,
|
m_position.get() - parWorldPos,
|
||||||
position() - parWorldPos + width_height()
|
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) {
|
void Character::do_movement (float parDeltaT) {
|
||||||
const float speed = parDeltaT * m_speed;
|
const float speed = parDeltaT * m_speed;
|
||||||
vec2f offset(0.0f);
|
vec2f offset(0.0f);
|
||||||
|
@ -65,18 +100,10 @@ namespace curry {
|
||||||
offset.y() += speed;
|
offset.y() += speed;
|
||||||
|
|
||||||
const auto old_pos = this->position();
|
const auto old_pos = this->position();
|
||||||
this->set_position(old_pos + offset);
|
const auto new_pos = old_pos + offset;
|
||||||
if (position() == old_pos)
|
|
||||||
return;
|
|
||||||
|
|
||||||
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);
|
this->set_position(new_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,17 +111,4 @@ namespace curry {
|
||||||
assert(parSpeed > 0.0f);
|
assert(parSpeed > 0.0f);
|
||||||
m_speed = parSpeed;
|
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
|
} //namespace curry
|
|
@ -19,11 +19,12 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "texture.hpp"
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
#include "rect.hpp"
|
#include "rect.hpp"
|
||||||
#include "world_moveable.hpp"
|
#include "constrained_position.hpp"
|
||||||
#include "drawable.hpp"
|
#include "worldsizenotifiable.hpp"
|
||||||
#include "collider.hpp"
|
#include "moveable.hpp"
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
class SDLMain;
|
class SDLMain;
|
||||||
|
@ -33,22 +34,29 @@ namespace cloonel {
|
||||||
namespace curry {
|
namespace curry {
|
||||||
class WorldGrid;
|
class WorldGrid;
|
||||||
|
|
||||||
class Character : public Drawable, public WorldMoveable {
|
class Character : public WorldSizeNotifiable, public Moveable {
|
||||||
public:
|
public:
|
||||||
Character (cloonel::InputBag* parInputBag, const WorldSizeNotifiable::DeferredRegister& parDeferredRegister);
|
Character (cloonel::InputBag* parInputBag, const WorldSizeNotifiable::DeferredRegister& parDeferredRegister);
|
||||||
virtual ~Character() noexcept = default;
|
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> destination_rect (const vec2f& parWorldPos) const;
|
||||||
Rect<float> source_rect() 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;
|
virtual void do_movement (float parDeltaT) override;
|
||||||
void set_speed (float parSpeed);
|
void set_speed (float parSpeed);
|
||||||
virtual void draw (DrawingQueue& parDQ, const WorldViewport& parViewport) override;
|
|
||||||
|
|
||||||
private:
|
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;
|
cloonel::InputBag* m_input_bag;
|
||||||
Collider m_collider;
|
WorldGrid* m_world;
|
||||||
float m_speed;
|
float m_speed;
|
||||||
};
|
};
|
||||||
} //namespace curry
|
} //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 <fstream>
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
namespace qi = boost::spirit::qi;
|
namespace qi = boost::spirit::qi;
|
||||||
|
|
||||||
|
@ -48,7 +47,6 @@ namespace curry {
|
||||||
//auto csv_parser = *((qi::int_ % ',') >> -qi::eol) >> qi::eoi;
|
//auto csv_parser = *((qi::int_ % ',') >> -qi::eol) >> qi::eoi;
|
||||||
CSVJointData out_csv;
|
CSVJointData out_csv;
|
||||||
std::size_t row_count = 0;
|
std::size_t row_count = 0;
|
||||||
TileIndex largest_tile_idx = 0;
|
|
||||||
|
|
||||||
for (auto& csv_path : parCsvPath) {
|
for (auto& csv_path : parCsvPath) {
|
||||||
std::ifstream f_map(csv_path);
|
std::ifstream f_map(csv_path);
|
||||||
|
@ -68,9 +66,6 @@ namespace curry {
|
||||||
oss << "Error parsing csv \"" << csv_path << "\"";
|
oss << "Error parsing csv \"" << csv_path << "\"";
|
||||||
throw std::runtime_error(oss.str());
|
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));
|
out_csv.tables.emplace_back(std::move(curr_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,18 +76,6 @@ namespace curry {
|
||||||
else {
|
else {
|
||||||
out_csv.height = out_csv.width = 0;
|
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;
|
return out_csv;
|
||||||
}
|
}
|
||||||
} //namespace curry
|
} //namespace curry
|
|
@ -20,7 +20,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "tileindextype.hpp"
|
#include "tileindextype.hpp"
|
||||||
#include "tileproperty.hpp"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
@ -32,7 +31,6 @@ namespace curry {
|
||||||
CSVJointData (const CSVJointData&) = delete;
|
CSVJointData (const CSVJointData&) = delete;
|
||||||
|
|
||||||
std::vector<std::vector<TileIndex>> tables;
|
std::vector<std::vector<TileIndex>> tables;
|
||||||
std::vector<TileProperty> tile_properties; //not filled in with real values
|
|
||||||
uint16_t width;
|
uint16_t width;
|
||||||
uint16_t height;
|
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/>.
|
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 "sdlmain.hpp"
|
||||||
#include "sizeratio.hpp"
|
|
||||||
#include "rect_to_sdl.hpp"
|
#include "rect_to_sdl.hpp"
|
||||||
|
#include "rect.hpp"
|
||||||
#include "texture.hpp"
|
#include "texture.hpp"
|
||||||
#include <SDL2/SDL.h>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <algorithm>
|
||||||
#include <ciso646>
|
#include <ciso646>
|
||||||
#include <utility>
|
#if !defined(NDEBUG)
|
||||||
#include <vector>
|
# include "compatibility.h"
|
||||||
#include <boost/container/flat_map.hpp>
|
# include <cmath>
|
||||||
#include <cmath>
|
#endif
|
||||||
|
|
||||||
namespace curry {
|
namespace curry {
|
||||||
namespace {
|
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)
|
#if !defined(NDEBUG)
|
||||||
bool are_equal_rel (float parA, float parB, float parEpsilon) a_pure;
|
bool are_equal_rel (float parA, float parB, float parEpsilon) a_pure;
|
||||||
|
|
||||||
|
@ -45,6 +43,39 @@ namespace curry {
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
///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.
|
///parSrc to be the relevant part of the source texture to be drawn.
|
||||||
|
@ -94,85 +125,70 @@ namespace curry {
|
||||||
}
|
}
|
||||||
} //unnamed namespace
|
} //unnamed namespace
|
||||||
|
|
||||||
DrawingQueue::ItemInfo::ItemInfo() = default;
|
GameSceneBase::GameSceneBase (cloonel::SDLMain* parSdlMain) :
|
||||||
DrawingQueue::ItemInfo::ItemInfo (ItemInfo&&) = default;
|
m_time0(std::chrono::steady_clock::now()),
|
||||||
DrawingQueue::ItemInfo::~ItemInfo() noexcept = default;
|
m_input(std::make_unique<cloonel::InputBag>()),
|
||||||
DrawingQueue::ItemInfo& DrawingQueue::ItemInfo::operator=(ItemInfo&&) = default;
|
m_sdlmain(parSdlMain),
|
||||||
|
m_screen_width(static_cast<float>(m_sdlmain->WidthHeight().x())),
|
||||||
struct DrawingQueue::LocalData {
|
m_screen_height(static_cast<float>(m_sdlmain->WidthHeight().y())),
|
||||||
explicit LocalData (cloonel::SDLMain* parSDLMain) :
|
m_wants_to_quit(false)
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
assert(parSDLMain);
|
assert(m_sdlmain);
|
||||||
}
|
}
|
||||||
|
|
||||||
DrawingQueue::~DrawingQueue() noexcept = default;
|
GameSceneBase::~GameSceneBase() noexcept = default;
|
||||||
|
|
||||||
bool DrawingQueue::add_layer (uint16_t parName) {
|
void GameSceneBase::prepare() {
|
||||||
auto& idx_map = m_local_data->layer_idx_map;
|
m_wants_to_quit = false;
|
||||||
auto it_found = idx_map.lower_bound(parName);
|
this->on_prepare();
|
||||||
if (it_found != idx_map.end() and it_found->first == parName) {
|
|
||||||
return false;
|
m_time0 = std::chrono::steady_clock::now();
|
||||||
}
|
|
||||||
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 DrawingQueue::flush_to_renderer() {
|
void GameSceneBase::destroy() noexcept {
|
||||||
assert(not m_local_data->layers.empty());
|
set_wants_to_quit();
|
||||||
for (auto& layer : m_local_data->layers) {
|
this->on_destroy();
|
||||||
for (auto& itm : layer) {
|
|
||||||
draw_clipped(*itm.texture, itm.source, itm.destination);
|
|
||||||
}
|
|
||||||
layer.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawingQueue::add_for_rendering (uint16_t parName, ItemInfo&& parItem) {
|
bool GameSceneBase::wants_to_quit() const {
|
||||||
const auto idx = m_local_data->layer_idx_map.at(parName);
|
return m_wants_to_quit;
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 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));
|
clip_rect(parSrc, parDest, Rect<float>(lefttop, rightbottom));
|
||||||
|
|
||||||
auto src = make_sdlrect(parSrc);
|
auto src = make_sdlrect(parSrc);
|
||||||
auto dst = make_sdlrect(parDest);
|
auto dst = make_sdlrect(parDest);
|
||||||
assert(src.w == dst.w);
|
assert(src.w == dst.w);
|
||||||
assert(src.h == dst.h);
|
assert(src.h == dst.h);
|
||||||
SDL_RenderCopy(m_local_data->sdlmain->GetRenderer(), parTexture.texture(), &src, &dst);
|
SDL_RenderCopy(m_sdlmain->GetRenderer(), parTexture.texture(), &src, &dst);
|
||||||
}
|
|
||||||
|
|
||||||
void DrawingQueue::OnResChanged (const cloonel::SizeRatio& parSizeRatio) {
|
|
||||||
m_local_data->screen_res = vec2f(cl_vec2us(parSizeRatio.Resolution()));
|
|
||||||
}
|
}
|
||||||
} //namespace curry
|
} //namespace curry
|
|
@ -28,8 +28,8 @@ namespace cloonel {
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
||||||
namespace curry {
|
namespace curry {
|
||||||
|
class Texture;
|
||||||
template <typename T> class Rect;
|
template <typename T> class Rect;
|
||||||
class DrawingQueue;
|
|
||||||
|
|
||||||
class GameSceneBase {
|
class GameSceneBase {
|
||||||
public:
|
public:
|
||||||
|
@ -50,13 +50,11 @@ namespace curry {
|
||||||
virtual void on_update (float parDeltaT) = 0;
|
virtual void on_update (float parDeltaT) = 0;
|
||||||
cloonel::SDLMain* sdl_main();
|
cloonel::SDLMain* sdl_main();
|
||||||
cloonel::InputBag& input_bag();
|
cloonel::InputBag& input_bag();
|
||||||
DrawingQueue& drawing_queue();
|
void draw_clipped (Texture& parTexture, Rect<float> parSrc, Rect<float> parDest);
|
||||||
const DrawingQueue& drawing_queue() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::chrono::time_point<std::chrono::steady_clock> m_time0;
|
std::chrono::time_point<std::chrono::steady_clock> m_time0;
|
||||||
std::unique_ptr<cloonel::InputBag> m_input;
|
std::unique_ptr<cloonel::InputBag> m_input;
|
||||||
std::unique_ptr<DrawingQueue> m_drawing_queue;
|
|
||||||
cloonel::SDLMain* m_sdlmain;
|
cloonel::SDLMain* m_sdlmain;
|
||||||
float m_screen_width;
|
float m_screen_width;
|
||||||
float m_screen_height;
|
float m_screen_height;
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#include "ingamescene.hpp"
|
#include "ingamescene.hpp"
|
||||||
#include "sdlmain.hpp"
|
#include "sdlmain.hpp"
|
||||||
#include "mycurry_toplevelConfig.h"
|
#include "mycurryConfig.h"
|
||||||
#include "key.hpp"
|
#include "key.hpp"
|
||||||
#include "inputbag.hpp"
|
#include "inputbag.hpp"
|
||||||
#include "movingobject.hpp"
|
#include "movingobject.hpp"
|
||||||
|
@ -31,9 +31,6 @@
|
||||||
#include "csvloader.hpp"
|
#include "csvloader.hpp"
|
||||||
#include "worlditems.hpp"
|
#include "worlditems.hpp"
|
||||||
#include "gameactions.hpp"
|
#include "gameactions.hpp"
|
||||||
#include "vector.hpp"
|
|
||||||
#include "drawing_queue.hpp"
|
|
||||||
#include "safe_stack_object.hpp"
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -41,21 +38,15 @@
|
||||||
#include <boost/utility/string_ref.hpp>
|
#include <boost/utility/string_ref.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <ciso646>
|
|
||||||
|
|
||||||
namespace curry {
|
namespace curry {
|
||||||
namespace {
|
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
|
} //unnamed namespace
|
||||||
|
|
||||||
struct IngameScene::LocalData {
|
struct IngameScene::LocalData {
|
||||||
LocalData (const vec2us& parTileSize, cloonel::SDLMain* parSDLMain, cloonel::InputBag* parInputBag) :
|
LocalData (const vec2us& parTileSize, cloonel::SDLMain* parSDLMain, cloonel::InputBag* parInputBag) :
|
||||||
world(parTileSize),
|
world(parTileSize),
|
||||||
viewport(&world, vec2f(cl_vec2us(parSDLMain->WidthHeight())), WorldSizeNotifiable::DeferredRegister(&world, &viewport)),
|
viewport(&world, vec2f(parSDLMain->WidthHeight()), WorldSizeNotifiable::DeferredRegister(&world, &viewport)),
|
||||||
player(parTileSize),
|
player(parTileSize),
|
||||||
character(parInputBag, WorldSizeNotifiable::DeferredRegister(&world, &character))
|
character(parInputBag, WorldSizeNotifiable::DeferredRegister(&world, &character))
|
||||||
{
|
{
|
||||||
|
@ -63,7 +54,7 @@ namespace curry {
|
||||||
|
|
||||||
WorldGrid world;
|
WorldGrid world;
|
||||||
WorldViewport viewport;
|
WorldViewport viewport;
|
||||||
SafeStackObject<Texture> worldtiles;
|
Texture worldtiles;
|
||||||
MovingObject player;
|
MovingObject player;
|
||||||
Character character;
|
Character character;
|
||||||
WorldItems moveable_items;
|
WorldItems moveable_items;
|
||||||
|
@ -81,18 +72,12 @@ namespace curry {
|
||||||
inp.AddAction(ActionUp, Key(InputDevice_Keyboard, SDL_SCANCODE_UP), "Move up");
|
inp.AddAction(ActionUp, Key(InputDevice_Keyboard, SDL_SCANCODE_UP), "Move up");
|
||||||
inp.AddAction(ActionRight, Key(InputDevice_Keyboard, SDL_SCANCODE_RIGHT), "Move right");
|
inp.AddAction(ActionRight, Key(InputDevice_Keyboard, SDL_SCANCODE_RIGHT), "Move right");
|
||||||
inp.AddAction(ActionDown, Key(InputDevice_Keyboard, SDL_SCANCODE_DOWN), "Move down");
|
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;
|
IngameScene::~IngameScene() noexcept = default;
|
||||||
|
|
||||||
void IngameScene::on_prepare() {
|
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({
|
CSVJointData tiles = load_csv({
|
||||||
RESOURCES_PATH "nonfree_map_ground.csv",
|
RESOURCES_PATH "nonfree_map_ground.csv",
|
||||||
RESOURCES_PATH "nonfree_map_transparent.csv"
|
RESOURCES_PATH "nonfree_map_transparent.csv"
|
||||||
|
@ -100,13 +85,12 @@ namespace curry {
|
||||||
|
|
||||||
vec2us world_size(tiles.width, tiles.height);
|
vec2us world_size(tiles.width, tiles.height);
|
||||||
m_local_data->world.set_layers(world_size, tiles.tables);
|
m_local_data->world.set_layers(world_size, tiles.tables);
|
||||||
m_local_data->world.set_tile_properties(tiles.tile_properties);
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
std::cout << "World size set to " << world_size << '\n';
|
std::cout << "World size set to " << world_size << '\n';
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_local_data->viewport.allow_overscan(false);
|
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 =
|
const float speed_per_sec =
|
||||||
static_cast<float>(
|
static_cast<float>(
|
||||||
std::max(m_local_data->world.tile_size().x(), m_local_data->world.tile_size().y())
|
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);
|
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);
|
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 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 (auto tile : viewport) {
|
||||||
for (uint16_t z = 0; z < m_local_data->world.layer_count(); ++z) {
|
for (uint16_t z = 0; z < m_local_data->world.layer_count(); ++z) {
|
||||||
if (tile.index[z] < 0)
|
if (tile.index[z] < 0)
|
||||||
|
@ -137,24 +120,15 @@ namespace curry {
|
||||||
|
|
||||||
Rect<float> src_rect(src_rect_xy, src_rect_xy + tilesize);
|
Rect<float> src_rect(src_rect_xy, src_rect_xy + tilesize);
|
||||||
Rect<float> dst_rect(pixel_pos, pixel_pos + 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 {
|
void IngameScene::on_destroy() noexcept {
|
||||||
m_local_data->moveable_items.unregister_all();
|
m_local_data->moveable_items.unregister_all();
|
||||||
m_local_data->worldtiles->unload();
|
m_local_data->worldtiles.unload();
|
||||||
m_local_data->character.unload_textures();
|
m_local_data->character.unload();
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
} //namespace curry
|
} //namespace curry
|
|
@ -20,18 +20,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "gamescenebase.hpp"
|
#include "gamescenebase.hpp"
|
||||||
#include "safe_ptr.hh"
|
|
||||||
#include "draw_layer_names.hpp"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
namespace cloonel {
|
namespace cloonel {
|
||||||
class SDLMain;
|
class SDLMain;
|
||||||
} //namespace cloonel
|
} //namespace cloonel
|
||||||
|
|
||||||
namespace curry {
|
namespace curry {
|
||||||
class Texture;
|
|
||||||
|
|
||||||
class IngameScene : public GameSceneBase {
|
class IngameScene : public GameSceneBase {
|
||||||
public:
|
public:
|
||||||
explicit IngameScene (cloonel::SDLMain* parSDLMain);
|
explicit IngameScene (cloonel::SDLMain* parSDLMain);
|
||||||
|
@ -41,7 +36,6 @@ namespace curry {
|
||||||
virtual void on_prepare() override;
|
virtual void on_prepare() override;
|
||||||
virtual void on_destroy() noexcept override;
|
virtual void on_destroy() noexcept override;
|
||||||
virtual void on_update (float parDeltaT) override;
|
virtual void on_update (float parDeltaT) override;
|
||||||
void draw (DrawaLayerNames parLayer, Kakoune::SafePtr<Texture>& parTexture, Rect<float> parSrc, Rect<float> parDest);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct LocalData;
|
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)
|
cloonel::ushort2(REFERENCE_WIDTH, REFERENCE_HEIGHT)
|
||||||
);
|
);
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
|
||||||
std::cout << "Debug build\n";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
try {
|
try {
|
||||||
sdl_main.Init();
|
sdl_main.Init();
|
|
@ -20,4 +20,3 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define RESOURCES_PATH "@MYCURRY_RESOURCES_PATH@/"
|
#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/>.
|
along with MyCurry. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#include "singlecoordinate.hpp"
|
||||||
|
#include "coordinates.hpp"
|
||||||
|
|
||||||
namespace curry {
|
namespace curry {
|
||||||
struct TileProperty {
|
static_assert(implem::Log2<256>::result == 8, "Wrong logarithm result");
|
||||||
TileProperty() :
|
static_assert(implem::Log2<255>::result == 7, "Wrong logarithm result");
|
||||||
walkable(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool walkable;
|
|
||||||
};
|
|
||||||
} //namespace curry
|
} //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);
|
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 {
|
void Texture::unload() noexcept {
|
||||||
m_texture.reset(nullptr);
|
m_texture.reset(nullptr);
|
||||||
}
|
}
|
|
@ -20,7 +20,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
#include "safe_ptr.hh"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
@ -38,17 +37,14 @@ namespace curry {
|
||||||
uint8_t a;
|
uint8_t a;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Texture : public Kakoune::SafeCountable {
|
class Texture {
|
||||||
public:
|
public:
|
||||||
Texture();
|
Texture();
|
||||||
Texture (const char* parPath, cloonel::SDLMain& parSDLMain);
|
Texture (const char* parPath, cloonel::SDLMain& parSDLMain);
|
||||||
Texture (Texture&&) = default;
|
|
||||||
Texture (const Texture&) = delete;
|
|
||||||
~Texture() noexcept;
|
~Texture() noexcept;
|
||||||
|
|
||||||
void load (const char* parPath, cloonel::SDLMain& parSDLMain);
|
void load (const char* parPath, cloonel::SDLMain& parSDLMain);
|
||||||
void load (const char* parPath, cloonel::SDLMain& parSDLMain, RGBA parColorKey);
|
void load (const char* parPath, cloonel::SDLMain& parSDLMain, RGBA parColorKey);
|
||||||
void load_empty (cloonel::SDLMain& parSDLMain, const vec2us& parSize);
|
|
||||||
void unload() noexcept;
|
void unload() noexcept;
|
||||||
SDL_Texture* texture();
|
SDL_Texture* texture();
|
||||||
const SDL_Texture* texture() const;
|
const SDL_Texture* texture() const;
|