Commit 968ec9f0 authored by sm's avatar sm

New version 0.7

- Fix TileCoords and Coords bugs
- Minor API changes
parent 81463916
stmm-games (0.7) unstable; urgency=low
* Fix TileCoords and Coords bugs
* Increase minor version
-- Stefano Marsili <efanomars@gmx.ch> Tue, 02 Apr 2019 19:29:39 +0100
stmm-games (0.6) unstable; urgency=low
* Add ProgressWidget
......
......@@ -21,7 +21,7 @@ project(stmm-games-fake CXX)
set(LIBRARY_OUTPUT_DIRECTORY "build")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../share/cmake)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../share/cmake")
include(CommonUtil)
......@@ -36,42 +36,42 @@ set(STMMI_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/include")
set(STMMI_HEADERS_DIR "${STMMI_INCLUDE_DIR}/stmm-games-fake")
# Header files
set(STMMI_HEADERS
${STMMI_HEADERS_DIR}/dumbblockevent.h
${STMMI_HEADERS_DIR}/fakelevelview.h
${STMMI_HEADERS_DIR}/fixtureDevices.h
${STMMI_HEADERS_DIR}/fixtureGame.h
${STMMI_HEADERS_DIR}/fixtureGameOwner.h
${STMMI_HEADERS_DIR}/fixtureLayoutAuto.h
${STMMI_HEADERS_DIR}/fixtureStdConfig.h
${STMMI_HEADERS_DIR}/fixtureStdPreferences.h
${STMMI_HEADERS_DIR}/fixtureTestBase.h
${STMMI_HEADERS_DIR}/fixturevariantHighscoresDefinition.h
${STMMI_HEADERS_DIR}/fixturevariantKeyActions.h
${STMMI_HEADERS_DIR}/fixturevariantLayout.h
${STMMI_HEADERS_DIR}/fixturevariantLevelInit.h
${STMMI_HEADERS_DIR}/fixturevariantOptions.h
${STMMI_HEADERS_DIR}/fixturevariantPlayers.h
${STMMI_HEADERS_DIR}/fixturevariantPrefsDevices.h
${STMMI_HEADERS_DIR}/fixturevariantPrefsPlayers.h
${STMMI_HEADERS_DIR}/fixturevariantTeams.h
${STMMI_HEADERS_DIR}/fixturevariantVariables.h
${STMMI_HEADERS_DIR}/mockevent.h
${STMMI_HEADERS_DIR}/stmm-games-fake.h
${STMMI_HEADERS_DIR}/stmm-games-fake-config.h
"${STMMI_HEADERS_DIR}/dumbblockevent.h"
"${STMMI_HEADERS_DIR}/fakelevelview.h"
"${STMMI_HEADERS_DIR}/fixtureDevices.h"
"${STMMI_HEADERS_DIR}/fixtureGame.h"
"${STMMI_HEADERS_DIR}/fixtureGameOwner.h"
"${STMMI_HEADERS_DIR}/fixtureLayoutAuto.h"
"${STMMI_HEADERS_DIR}/fixtureStdConfig.h"
"${STMMI_HEADERS_DIR}/fixtureStdPreferences.h"
"${STMMI_HEADERS_DIR}/fixtureTestBase.h"
"${STMMI_HEADERS_DIR}/fixturevariantHighscoresDefinition.h"
"${STMMI_HEADERS_DIR}/fixturevariantKeyActions.h"
"${STMMI_HEADERS_DIR}/fixturevariantLayout.h"
"${STMMI_HEADERS_DIR}/fixturevariantLevelInit.h"
"${STMMI_HEADERS_DIR}/fixturevariantOptions.h"
"${STMMI_HEADERS_DIR}/fixturevariantPlayers.h"
"${STMMI_HEADERS_DIR}/fixturevariantPrefsDevices.h"
"${STMMI_HEADERS_DIR}/fixturevariantPrefsPlayers.h"
"${STMMI_HEADERS_DIR}/fixturevariantTeams.h"
"${STMMI_HEADERS_DIR}/fixturevariantVariables.h"
"${STMMI_HEADERS_DIR}/mockevent.h"
"${STMMI_HEADERS_DIR}/stmm-games-fake.h"
"${STMMI_HEADERS_DIR}/stmm-games-fake-config.h"
)
#
# Sources dir
set(STMMI_SOURCES_DIR "${PROJECT_SOURCE_DIR}/src")
# Source files (and headers only used for building)
set(STMMI_SOURCES
${STMMI_SOURCES_DIR}/dumbblockevent.cc
${STMMI_SOURCES_DIR}/fakelevelview.cc
${STMMI_SOURCES_DIR}/mockevent.cc
${STMMI_SOURCES_DIR}/stmm-games-fake.cc
"${STMMI_SOURCES_DIR}/dumbblockevent.cc"
"${STMMI_SOURCES_DIR}/fakelevelview.cc"
"${STMMI_SOURCES_DIR}/mockevent.cc"
"${STMMI_SOURCES_DIR}/stmm-games-fake.cc"
)
# Define library
add_library(stmm-games-fake ${STMMI_SOURCES} ${PROJECT_BINARY_DIR}/stmm-games-fake-config.cc)
add_library(stmm-games-fake ${STMMI_SOURCES} "${PROJECT_BINARY_DIR}/stmm-games-fake-config.cc")
include("stmm-games-fake-defs.cmake")
......
......@@ -20,12 +20,12 @@
# MINOR is REVISION (implementation of interface)
# AGE is always 0
set(STMM_GAMES_FAKE_MAJOR_VERSION 0)
set(STMM_GAMES_FAKE_MINOR_VERSION 6)
set(STMM_GAMES_FAKE_MINOR_VERSION 7)
set(STMM_GAMES_FAKE_VERSION "${STMM_GAMES_FAKE_MAJOR_VERSION}.${STMM_GAMES_FAKE_MINOR_VERSION}.0")
# required stmm-games version
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_MAJOR_VERSION 0)
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_MINOR_VERSION 6)
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_MINOR_VERSION 7)
set(STMM_GAMES_FAKE_REQ_STMM_GAMES_VERSION "${STMM_GAMES_FAKE_REQ_STMM_GAMES_MAJOR_VERSION}.${STMM_GAMES_FAKE_REQ_STMM_GAMES_MINOR_VERSION}")
include("${PROJECT_SOURCE_DIR}/../libstmm-games/stmm-games-defs.cmake")
......
This diff is collapsed.
......@@ -310,8 +310,9 @@ void StdLevelView::drawStepToBuffers(int32_t nViewTick, int32_t nTotViewTicks, b
//std::cout << "StdLevelView::drawStep redraw animated tiles! gameTick=" << m_refLevel->game().gameElapsed() << " m_nViewTick=" << m_nViewTick << '\n';
for (auto it = m_oTickTileAnis.cbegin(); it != m_oTickTileAnis.end(); ++it) {
const int64_t nXY = *it;
const int32_t nX = Coords::getXFromXY(nXY);
const int32_t nY = Coords::getYFromXY(nXY);
const NPoint oXY = Util::unpackPointFromInt64(nXY);
const int32_t nX = oXY.m_nX;
const int32_t nY = oXY.m_nY;
//std::cout << "StdLevelView::drawStep m_oTickTileAnis nX=" << nX << " nY=" << nY << '\n';
m_refBoardCc->save();
m_refBoardCc->set_operator(Cairo::OPERATOR_SOURCE);
......@@ -781,13 +782,15 @@ void StdLevelView::boardAnimateTiles(NRect oArea)
const int32_t nToNY = oArea.m_nY + oArea.m_nH;
for (int32_t nCurX = oArea.m_nX; nCurX < nToNX; ++nCurX) {
for (int32_t nCurY = oArea.m_nY; nCurY < nToNY; ++nCurY) {
m_oTickTileAnis.insert(Coords::packXY(nCurX, nCurY));
const int64_t nCurXY = Util::packPointToInt64(NPoint{nCurX, nCurY});
m_oTickTileAnis.insert(nCurXY);
}
}
}
void StdLevelView::boardAnimateTile(NPoint oXY)
{
m_oTickTileAnis.insert(Coords::packXY(oXY.m_nX, oXY.m_nY));
const int64_t nXY = Util::packPointToInt64(NPoint{oXY.m_nX, oXY.m_nY});
m_oTickTileAnis.insert(nXY);
}
void StdLevelView::reMoveTickAnimatedTiles(int32_t nRemoveX, int32_t nRemoveY, int32_t nRemoveW, int32_t nRemoveH
, int32_t nAreaX, int32_t nAreaY, int32_t nAreaW, int32_t nAreaH
......@@ -799,8 +802,9 @@ void StdLevelView::reMoveTickAnimatedTiles(int32_t nRemoveX, int32_t nRemoveY, i
const int32_t nAreaNToY = nAreaY + nAreaH;
m_oTickTileAnisWork.clear();
for (auto& nXY : m_oTickTileAnis) {
const int32_t nX = Coords::getXFromXY(nXY);
const int32_t nY = Coords::getYFromXY(nXY);
const NPoint oXY = Util::unpackPointFromInt64(nXY);
const int32_t nX = oXY.m_nX;
const int32_t nY = oXY.m_nY;
if ((nX >= nRemoveX) && (nX < nRemoveNToX) && (nY >= nRemoveY) && (nY < nRemoveNToY)) {
continue; // for
}
......@@ -809,7 +813,7 @@ void StdLevelView::reMoveTickAnimatedTiles(int32_t nRemoveX, int32_t nRemoveY, i
const int32_t nNewY = nY + nDy;
assert((nNewX >= 0) && (nNewX < m_nBoardW));
assert((nNewY >= 0) && (nNewY < m_nBoardH));
const int64_t nNewXY = Coords::packXY(nNewX, nNewY);
const int64_t nNewXY = Util::packPointToInt64(NPoint{nNewX, nNewY});
m_oTickTileAnisWork.insert(nNewXY);
} else {
m_oTickTileAnisWork.insert(nXY);
......@@ -1013,7 +1017,7 @@ void StdLevelView::boardPostModify(const Coords& oCoords)
}
void StdLevelView::redrawBoardPos(int32_t nX, int32_t nY)
{
int64_t nXY = Coords::packXY(nX, nY);
const int64_t nXY = Util::packPointToInt64(NPoint{nX, nY});
if (m_oTickTileAnis.find(nXY) == m_oTickTileAnis.end()) {
// only draw if it's not redrawn during view ticks
const int32_t nPixX = nX * m_nTileW;
......@@ -1132,8 +1136,9 @@ void StdLevelView::dump(bool bTickTileAnis) const
if (bTickTileAnis) {
std::cout << "StdLevelView::dump() TickTileAnis (nX,nY)" << '\n';
for (auto& nXY : m_oTickTileAnis) {
const int32_t nX = Coords::getXFromXY(nXY);
const int32_t nY = Coords::getYFromXY(nXY);
const NPoint oXY = Util::unpackPointFromInt64(nXY);
const int32_t nX = oXY.m_nX;
const int32_t nY = oXY.m_nY;
std::cout << " (" << nX << "," << nY << ")";
std::cout << '\n';
}
......
......@@ -20,11 +20,11 @@
# MINOR is REVISION (implementation of interface)
# AGE is always 0
set(STMM_GAMES_GTK_MAJOR_VERSION 0)
set(STMM_GAMES_GTK_MINOR_VERSION 6)
set(STMM_GAMES_GTK_MINOR_VERSION 7)
set(STMM_GAMES_GTK_VERSION "${STMM_GAMES_GTK_MAJOR_VERSION}.${STMM_GAMES_GTK_MINOR_VERSION}.0")
set(STMM_GAMES_GTK_REQ_STMM_GAMES_MAJOR_VERSION 0)
set(STMM_GAMES_GTK_REQ_STMM_GAMES_MINOR_VERSION 6)
set(STMM_GAMES_GTK_REQ_STMM_GAMES_MINOR_VERSION 7)
set(STMM_GAMES_GTK_REQ_STMM_GAMES_VERSION "${STMM_GAMES_GTK_REQ_STMM_GAMES_MAJOR_VERSION}.${STMM_GAMES_GTK_REQ_STMM_GAMES_MINOR_VERSION}")
set(STMM_GAMES_GTK_REQ_STMM_INPUT_GTK_MAJOR_VERSION 0)
......
......@@ -24,8 +24,8 @@ if (BUILD_TESTING)
set(STMMI_TEST_SOURCES_DIR "${PROJECT_SOURCE_DIR}/test")
# Test sources should end with .cxx
set(STMMI_TEST_SOURCES
${STMMI_TEST_SOURCES_DIR}/testGameConstraints.cxx
${STMMI_TEST_SOURCES_DIR}/testSegmentedFunction.cxx
"${STMMI_TEST_SOURCES_DIR}/testGameConstraints.cxx"
"${STMMI_TEST_SOURCES_DIR}/testSegmentedFunction.cxx"
)
TestFiles("${STMMI_TEST_SOURCES}" ""
......
This diff is collapsed.
......@@ -42,7 +42,7 @@
<Image imgId="Gradient7" imgFile="gradient_7.svg"/>
</Images>
<ImageArrays>
<FileArray arrayId="squareP" imgFile="squareplayer%%.svg" sobstStr="%%" fromInt="1" toInt="4"/>
<FileArray arrayId="squareP" imgFile="squareplayer%%.svg" sobstStr="%%" fromInt="0" toInt="4"/>
</ImageArrays>
<Animations>
<PlainText name="Plain" center="true" colorName="black"/>
......@@ -115,11 +115,11 @@
</WidgetFactories>
<Assigns>
<Assign idAss="squareP" arrayId="squareP" imgFromIdx="0">
<Players fromPlayer="0" toPlayer="3"/>
<Players fromPlayer="0" toPlayer="4"/>
</Assign>
<Assign idAss="squarsorP" arrayId="squareP">
<Chars charName="SQUARSOR:SEL"/>
<Players fromPlayer="-1" toPlayer="2"/>
<Players fromPlayer="-1" toPlayer="3"/>
</Assign>
<!--Tiles idAss="bomb" imgFile="bomb.svg" charName="BOMB"/-->
</Assigns>
......
......@@ -20,12 +20,12 @@
# MINOR is REVISION (implementation of interface)
# AGE is always 0
set(STMM_GAMES_XML_MAJOR_VERSION 0)
set(STMM_GAMES_XML_MINOR_VERSION 6)
set(STMM_GAMES_XML_MINOR_VERSION 7)
set(STMM_GAMES_XML_VERSION "${STMM_GAMES_XML_MAJOR_VERSION}.${STMM_GAMES_XML_MINOR_VERSION}.0")
# required stmm-games-gtk version
set(STMM_GAMES_XML_REQ_STMM_GAMES_GTK_MAJOR_VERSION 0)
set(STMM_GAMES_XML_REQ_STMM_GAMES_GTK_MINOR_VERSION 6)
set(STMM_GAMES_XML_REQ_STMM_GAMES_GTK_MINOR_VERSION 7)
set(STMM_GAMES_XML_REQ_STMM_GAMES_GTK_VERSION "${STMM_GAMES_XML_REQ_STMM_GAMES_GTK_MAJOR_VERSION}.${STMM_GAMES_XML_REQ_STMM_GAMES_GTK_MINOR_VERSION}")
# required libxml++-2.6 version
......
......@@ -24,7 +24,7 @@ if (BUILD_TESTING)
set(STMMI_TEST_SOURCES_DIR "${PROJECT_SOURCE_DIR}/test")
# Test sources should end with .cxx
set(STMMI_TEST_SOURCES
${STMMI_TEST_SOURCES_DIR}/testXmlCommonParser.cxx
"${STMMI_TEST_SOURCES_DIR}/testXmlCommonParser.cxx"
)
TestFiles("${STMMI_TEST_SOURCES}" "" "" "stmm-games;stmm-games-gtk;stmm-games-xml" FALSE FALSE FALSE)
......
This diff is collapsed.
......@@ -450,7 +450,6 @@ private:
return oTile;
}
static const Tile s_oNonEmptyTile;
static const Tile s_oEmptyTile;
};
} // namespace stmg
......
......@@ -345,17 +345,6 @@ public:
*/
int32_t boardHeight() const;
static inline int32_t boardPackXYToInt32(int32_t nX, int32_t nY)
{
assert((nX >= -16000) && (nX < 16000));
assert((nY >= -16000) && (nY < 16000));
return (nX + (1 << 15)) | ((nY + (1 << 15)) << 16);
}
static inline void boardUnpackXYFromInt32(int32_t nXY, int32_t& nX, int32_t& nY)
{
nX = (nXY & ((1 << 16) - 1)) - (1 << 15);
nY = ((nXY >> 16) & ((1 << 16) - 1)) - (1 << 15);
}
/** Sets the tile of a board cell.
* @param nX The x (in tiles). Must be \>= 0 and \< boardWidth().
* @param nY The y (in tiles). Must be \>= 0 and \< boardHeight().
......@@ -935,8 +924,6 @@ private:
static const int32_t s_nZObjectZShowText;
static const int32_t s_nZObjectZGameOver;
static const Tile s_oEmptyTile;
private:
Level(const Level& oSource) = delete;
Level& operator=(const Level& oSource) = delete;
......
......@@ -473,6 +473,8 @@ public:
std::cout << ")";
}
#endif //NDEBUG
public:
static const Tile s_oEmptyTile;
};
......
......@@ -29,7 +29,6 @@
namespace stmg
{
////////////////////////////////////////////////////////////////////////////////
class TileBuffer : public TileRect
{
public:
......@@ -44,9 +43,8 @@ public:
inline void reInit(NSize oWH)
{
static Tile s_oEmptyTile{};
m_oBuf.resize(oWH);
m_oBuf.setAll(s_oEmptyTile);
m_oBuf.setAll(Tile::s_oEmptyTile);
}
inline void reInit(NSize oWH, const Tile& oTile)
{
......
......@@ -46,13 +46,13 @@ public:
* All iterators become invalid.
* @param nAtLeastSize The indicative minimum number of unique values.
*/
void reInit(int32_t nAtLeastSize) override;
void reInit(int32_t nAtLeastSize);
using Coords::size;
using Coords::isEmpty;
/** Add a tile coord.
* If a tile already exists at the position overwrite it.
* If the tile already exists at the position overwrites it.
*
* Might invalidate iterators.
* @param nX The x.
......@@ -61,7 +61,7 @@ public:
*/
void add(int32_t nX, int32_t nY, const Tile& oTile);
/** Add a tile coord.
* If a tile already exists at the position overwrite it.
* If the tile already exists at the position overwrites it.
*
* Might invalidate iterators.
* @param oXY The coord to add.
......@@ -136,7 +136,15 @@ public:
using Coords::const_iterator::next;
inline bool operator==(const const_iterator& it) const { return Coords::const_iterator::operator==(it); };
inline bool operator!=(const const_iterator& it) const { return Coords::const_iterator::operator!=(it); };
const Tile& getTile() const { return m_aPosTiles[get()].m_oTile; }
const Tile& getTile() const
{
const int32_t nIdx = get();
if (nIdx < 0) {
return Tile::s_oEmptyTile;
} else {
return m_aPosTiles[nIdx].m_oTile;
}
}
private:
friend class TileCoords;
const_iterator(const TileCoords& oTileCoords, bool bEnd);
......@@ -162,8 +170,13 @@ public:
}
private:
std::unordered_map<int64_t, Tile>::iterator remove(const std::unordered_map<int64_t, Tile>::iterator itFind);
void removeIndex(int32_t nIdx);
private:
std::vector<PosTile> m_aPosTiles;
// Note: if the this->Coords::remove() function is called this
// vector will contain entries that no longer are in use and
// over time grow indefinitely!
std::vector<PosTile> m_aPosTiles; // Size: <= Coords::size()
};
} // namespace stmg
......
......@@ -43,15 +43,36 @@ struct NSize
bool operator==(const NSize& oS1, const NSize& oS2);
struct NRect : public NPoint, public NSize
struct NRect
{
/**< Whether two rectangles intersect. */
int32_t m_nX = 0; /**< Default is 0. */
int32_t m_nY = 0; /**< Default is 0. */
int32_t m_nW = 0; /**< Default is 0. */
int32_t m_nH = 0; /**< Default is 0. */
bool containsPoint(const NPoint& oP) const
{
return ((oP.m_nX >= m_nX) && (oP.m_nX < m_nX + m_nW) && (oP.m_nY >= m_nY) && (oP.m_nY < m_nY + m_nH));
}
NSize getSize() const
{
return NSize{m_nW, m_nH};
}
/** Whether two rectangles intersect.
* @param oR1 Must have positive size.
* @param oR2 Must have positive size.
* @return Whether intersect.
*/
static bool doIntersect(const NRect& oR1, const NRect& oR2)
{
assert((oR1.m_nW >= 0) && (oR1.m_nH >= 0) && (oR2.m_nW >= 0) && (oR2.m_nH >= 0));
return !((oR1.m_nX + oR1.m_nW <= oR2.m_nX) || (oR2.m_nX + oR2.m_nW <= oR1.m_nX)
|| (oR1.m_nY + oR1.m_nH <= oR2.m_nY) || (oR2.m_nY + oR2.m_nH <= oR1.m_nY));
}
/** The minimal rectangle containing two rectangles.
* @param oR1 Must have positive size.
* @param oR2 Must have positive size.
* @return Bounding rectangle.
*/
static NRect boundingRect(const NRect& oR1, const NRect& oR2)
{
assert((oR1.m_nW >= 0) && (oR1.m_nH >= 0) && (oR2.m_nW >= 0) && (oR2.m_nH >= 0));
......@@ -81,8 +102,16 @@ struct FSize
bool operator==(const FSize& oS1, const FSize& oS2);
struct FRect : public FPoint, public FSize
struct FRect
{
double m_fX = 0; /**< Default is 0. */
double m_fY = 0; /**< Default is 0. */
double m_fW = 0; /**< Default is 0. */
double m_fH = 0; /**< Default is 0. */
FSize getSize() const
{
return FSize{m_fW, m_fH};
}
static bool doIntersect(const FRect& oR1, const FRect& oR2)
{
assert((oR1.m_fW >= 0) && (oR1.m_fH >= 0) && (oR2.m_fW >= 0) && (oR2.m_fH >= 0));
......
......@@ -21,6 +21,7 @@
#define STMG_COORDS_H
#include "basictypes.h"
#include "util.h"
#include <unordered_map>
#include <stdint.h>
......@@ -28,6 +29,9 @@
namespace stmg
{
/** Coords class.
* Beware! This class is final, only meant to be subclassed by TileCoords.
*/
class Coords
{
public:
......@@ -47,7 +51,7 @@ public:
* All iterators become invalid.
* @param nAtLeastSize The indicative minimum number of unique values.
*/
virtual void reInit(int32_t nAtLeastSize);
void reInit(int32_t nAtLeastSize);
/** The number of (unique) coords in the instance.
* @return The size.
*/
......@@ -129,26 +133,14 @@ public:
*/
void remove(const Coords& oCoords);
inline static int64_t packXY(int32_t nX, int32_t nY)
{
return ((static_cast<int64_t>(nY)) << 32) | (static_cast<uint32_t>(nX));
}
inline static int32_t getXFromXY(int64_t nXY)
{
return static_cast<int32_t>(nXY);
}
inline static int32_t getYFromXY(int64_t nXY)
{
return static_cast<int32_t>(static_cast<int64_t>(nXY >> 32));
}
public:
friend class const_iterator;
class const_iterator
{
public:
inline int32_t x() const { return Coords::getXFromXY(m_it->first); };
inline int32_t y() const { return Coords::getYFromXY(m_it->first); };
inline int32_t x() const { return Util::unpackPointFromInt64(m_it->first).m_nX; };
inline int32_t y() const { return Util::unpackPointFromInt64(m_it->first).m_nY; };
inline NPoint point() const { return Util::unpackPointFromInt64(m_it->first); };
inline void next() { ++m_it; };
inline bool operator==(const const_iterator& it) const { return m_it == it.m_it; };
inline bool operator!=(const const_iterator& it) const { return !(m_it == it.m_it); };
......@@ -169,19 +161,45 @@ public:
}
protected:
std::pair<bool, int32_t> getData(int32_t nX, int32_t nY) const;
// returns whether already present and the current index
// doesn't overwrite
std::pair<bool, int32_t> addDataPreserve(int32_t nX, int32_t nY, int32_t nIdx);
explicit Coords(bool bTileCoords);
Coords(bool bTileCoords, int32_t nAtLeastSize);
/* Get the index.
* @param nX The x.
* @param nY The y.
* @return Whether present and the idx address associated with the position.
*/
std::pair<bool, int32_t*> getData(int32_t nX, int32_t nY) const;
/* Add a position with associated index preserving index if already present.
* @param nX The x.
* @param nY The y.
* @param nIdx The index.
* @return Whether already present and the pointer to the current index.
*/
std::pair<bool, int32_t*> addDataPreserve(int32_t nX, int32_t nY, int32_t nIdx);
/* Add a position with associated index overwriting index if already present.
* @param nX The x.
* @param nY The y.
* @param nIdx The index.
*/
void addDataOverwrite(int32_t nX, int32_t nY, int32_t nIdx);
/* Removes position if present.
* @param nX The x.
* @param nY The y.
* @return Whether was present and the index.
*/
std::pair<bool, int32_t> removeGetData(int32_t nX, int32_t nY);
/* Reinitialization.
* @param nAtLeastSize
*/
void clearData(int32_t nAtLeastSize);
private:
void addData(int32_t nX, int32_t nY);
std::unordered_map<int64_t, int32_t>::iterator remove(const std::unordered_map<int64_t, int32_t>::iterator& itFind);
private:
std::unordered_map<int64_t, int32_t> m_oXY;
mutable std::unordered_map<int64_t, int32_t> m_oXY;
mutable NRect m_oBoundingRect;
bool m_bTileCoords;
};
} // namespace stmg
......
......@@ -20,11 +20,14 @@
#ifndef STMG_UTIL_H
#define STMG_UTIL_H
#include "basictypes.h"
#include <list>
#include <vector>
#include <string>
#include <sstream>
#include <initializer_list>
#include <utility>
#include <cassert>
#include <iostream>
......@@ -55,6 +58,13 @@ std::vector<std::string> stringComposeParams(const T& ... oParam)
} // namespace Private
//TODO constexpr ???
/** Format a string.
* Ex. stringCompose("%2ce I saw %1 b%2s", 2, "one") returns
* "once I saw 2 bones"
* @param sFormat The format string.
* @param oParam The parameters to be inserted in the format string.
* @return The formatted string.
*/
template <typename ...T>
std::string stringCompose(const std::string& sFormat, const T& ... oParam)
{
......@@ -63,8 +73,11 @@ std::string stringCompose(const std::string& sFormat, const T& ... oParam)
}
//Strips a string of its leading and trailing space chars
// Ex. " HI there " to "HI there"
/** Strips a string of its leading and trailing space characters.
* Ex. " HI there " to "HI there".
* @param sStr The string to strip.
* @return The stripped string.
*/
std::string strStrip(const std::string& sStr);
/** Whether a string contains whitespace characters.
......@@ -78,17 +91,38 @@ bool strContainsWhitespace(const std::string& sStr);
* @param aLine The vector of strings to which the single lines are added.
*/
void strTextToLines(const std::string& sText, std::vector<std::string>& aLine);
/** UTF8 string size in code points rather than bytes.
* @param sUtf8 The UTF8 string.
* @return The size.
*/
int32_t strUTF8SizeInCodePoints(const std::string& sUtf8);
//std::u32string toUTF32(const std::string& sUtf8);
//std::string toUTF8(const std::u32string& sUtf32);
bool strToBool(const std::string& sStr);
/** Formats integer with every 3 digits separator.
* Ex. 12345678 is formatted as "12'345'678".
* @param nValue The value.
* @return The string.
*/
std::string intToMillString(int32_t nValue);
/** Formats milliseconds to minutes and seconds.
* Ex. 1001 outputs string "0:01.001"
* @param nMilliseconds The value in milliseconds.
* @return The formatted string.
*/
std::string millisecToMinSecString(int32_t nMilliseconds);
/** Formats seconds to minutes.
* Ex. 61 outputs string "1:01"
* @param nSeconds The value in seconds.
* @return The formatted string.
*/
std::string secToMinSecString(int32_t nSeconds);
/** Convert a string to boolean.
* @param sStr The string. Cannot be empty.
* @return The result.
* @throws std::runtime_error If cannot figure out the value.
*/
bool strToBool(const std::string& sStr);
///////////////////////////////////////////////////////////////////////////////
namespace Private
{
......@@ -217,6 +251,57 @@ bool listExtract(std::list<LT>& list, const LT value)
return false;
}
////////////////////////////////////////////////////////////////////////////////
/** Packs a point (64 bit) to an int32_t.
* @param oXY The point to pack. Both m_nX and m_nY must be \>= -16384 and \< 16384.
* @return The packed value.
*/
inline int32_t packPointToInt32(NPoint oXY)
{
assert((oXY.m_nX >= -16384) && (oXY.m_nX < 16384));
assert((oXY.m_nY >= -16384) && (oXY.m_nY < 16384));
return (oXY.m_nX + 16384) | ((oXY.m_nY + 16384) << 16);
}
/** Unpacks a point (64 bit) from an int32_t.
* @param nXY The packed value.
* @return The point.
*/
inline NPoint unpackPointFromInt32(int32_t nXY)
{
const int32_t nX = (nXY & ((1 << 16) - 1)) - 16384;
const int32_t nY = ((nXY >> 16) & ((1 << 16) - 1)) - 16384;
return NPoint{nX, nY};
}
/** Packs a point to an int64_t.
* @param oXY The point to pack.
* @return The packed value.
*/
inline int64_t packPointToInt64(NPoint oXY)
{
return ((static_cast<int64_t>(oXY.m_nY)) << 32) | (static_cast<uint32_t>(oXY.m_nX));
}
/** Unpacks a point from an int64_t.
* @param nXY The packed value.
* @return The point.
*/
inline NPoint unpackPointFromInt64(int64_t nXY)
{
const int32_t nX = static_cast<int32_t>(nXY);
const int32_t nY = static_cast<int32_t>(static_cast<int64_t>(nXY >> 32));
return NPoint{nX, nY};
}
/** Unpacks a XY pair from an int64_t.
* @param nXY The packed value.
* @return The point.
*/
inline std::pair<int32_t, int32_t> unpackPairFromInt64(int64_t nXY)
{
const int32_t nX = static_cast<int32_t>(nXY);
const int32_t nY = static_cast<int32_t>(static_cast<int64_t>(nXY >> 32));
return std::make_pair(nX, nY);
}
} // namespace Util
} // namespace stmg
......
......@@ -29,7 +29,6 @@ namespace stmg
{
const Tile Block::s_oNonEmptyTile = Block::getNonEmptyTile();
const Tile Block::s_oEmptyTile;