freg  0.3
Free-Roaming Elementary Game
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ShredStorage.cpp
Go to the documentation of this file.
1  /* freg, Free-Roaming Elementary Game with open and interactive world
2  * Copyright (C) 2012-2014 Alexander 'mmaulwurff' Kromm
3  * mmaulwurff@gmail.com
4  *
5  * This file is part of FREG.
6  *
7  * FREG is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * FREG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with FREG. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include <QFile>
21 #include "ShredStorage.h"
22 #include "World.h"
23 #include "Shred.h"
24 
25 /// -1 - default for zlib, 0 - no compression, 4 - best for CPU, 8 - optimal.
26 const int COMPRESSION_LEVEL = 8;
27 
28 bool LongLat::operator==(const LongLat & coords) const {
29  return ( longitude==coords.longitude &&
30  latitude==coords.latitude );
31 }
32 
33 LongLat::LongLat(const long longi, const long lati) :
34  longitude(longi),
35  latitude(lati)
36 {}
37 
38 uint qHash(const LongLat & coords) {
39  return ((coords.longitude & 0xffff) << 16) |
40  (coords.latitude & 0xffff);
41 }
42 
43 ShredStorage::ShredStorage(const ushort size_,
44  const long longi_center, const long lati_center)
45  :
46  storage(),
47  size(size_)
48 {
49  storage.reserve(size*size);
50  for (long i=longi_center-size/2; i<=longi_center+size/2; ++i)
51  for (long j= lati_center-size/2; j<= lati_center+size/2; ++j) {
52  AddShredData(i, j);
53  }
54 }
55 
57  if ( preloadThread != nullptr ) {
58  preloadThread->wait();
59  delete preloadThread;
60  }
61  for (auto i=storage.constBegin(); i!=storage.constEnd(); ++i) {
62  if ( i.value() ) {
63  WriteToFileShredData(i.key().longitude, i.key().latitude);
64  }
65  }
66 }
67 
68 void ShredStorage::Shift(const int direction,
69  const long longitude_center, const long latitude_center)
70 {
71  if ( preloadThread != nullptr ) {
72  preloadThread->wait();
73  delete preloadThread;
74  }
75  preloadThread = new PreloadThread(this, direction,
76  longitude_center, latitude_center, size);
77  preloadThread->start();
78 }
79 
80 QByteArray * ShredStorage::GetShredData(const long longi, const long lati)
81 const {
82  return storage.value(LongLat(longi, lati));
83 }
84 
85 void ShredStorage::SetShredData(QByteArray * const data,
86  const long longi, const long lati)
87 {
88  const LongLat coords(longi, lati);
89  delete storage.value(coords);
90  storage.insert(coords, data);
91 }
92 
93 void ShredStorage::AddShredData(const long longitude, const long latitude) {
94  QFile file(Shred::FileName(world->WorldName(), longitude, latitude));
95  storage.insert(LongLat(longitude, latitude),
96  ( file.open(QIODevice::ReadOnly) ?
97  new QByteArray(qUncompress(file.readAll())) : nullptr ));
98 }
99 
100 void ShredStorage::WriteToFileShredData(const long longi, const long lati) {
101  const QByteArray * const data = storage.value(LongLat(longi, lati));
102  if ( data != nullptr ) {
103  QFile file(Shred::FileName(world->WorldName(), longi, lati));
104  if ( file.open(QIODevice::WriteOnly) ) {
105  file.write(qCompress(*data, COMPRESSION_LEVEL));
106  }
107  delete data;
108  }
109 }
110 
111 void ShredStorage::Remove(const long longi, const long lati) {
112  storage.remove(LongLat(longi, lati));
113 }
114 
115 PreloadThread::PreloadThread(ShredStorage * const stor, const int dir,
116  const long longi_c, const long lati_c, const ushort sz)
117  :
118  storage(stor),
119  direction(dir),
120  longi_center(longi_c),
121  lati_center(lati_c),
122  size(sz)
123 {}
124 
126  switch (direction) {
127  case NORTH:
128  for (long i=lati_center-size/2; i<=lati_center+size/2; ++i) {
132  }
133  break;
134  case SOUTH:
135  for (long i=lati_center-size/2; i<=lati_center+size/2; ++i) {
139  }
140  break;
141  case EAST:
142  for (long i=longi_center-size/2; i<=longi_center+size/2; ++i) {
146  }
147  break;
148  case WEST:
149  for (long i=longi_center-size/2; i<=longi_center+size/2; ++i) {
153  }
154  break;
155  default: Q_UNREACHABLE(); break;
156  }
157 }
PreloadThread * preloadThread
Definition: ShredStorage.h:60
ShredStorage *const storage
Definition: ShredStorage.h:76
3
Definition: header.h:90
const int COMPRESSION_LEVEL
-1 - default for zlib, 0 - no compression, 4 - best for CPU, 8 - optimal.
World * world
Definition: World.cpp:32
void run() override
ShredStorage(ushort size, long longi_center, long lati_center)
static QString FileName(QString world_name, long longi, long lati)
Definition: Shred.cpp:340
2
Definition: header.h:89
4
Definition: header.h:91
void Shift(int direction, long longitude, long latitude)
const long latitude
Definition: ShredStorage.h:35
const long lati_center
Definition: ShredStorage.h:79
LongLat(long longitude, long latitude)
void WriteToFileShredData(long longi, long lati)
void SetShredData(QByteArray *, long longi, long lati)
PreloadThread(ShredStorage *, int direction, long longi_center, long lati_center, ushort size)
bool operator==(const LongLat &) const
const long longi_center
Definition: ShredStorage.h:78
QByteArray * GetShredData(long longi, long lati) const
void AddShredData(long longi, long lati)
const long longitude
Definition: ShredStorage.h:34
const int direction
Definition: ShredStorage.h:77
const ushort size
Definition: ShredStorage.h:80
void Remove(long longi, long lati)
QHash< LongLat, QByteArray * > storage
Definition: ShredStorage.h:58
5
Definition: header.h:92
const ushort size
Definition: ShredStorage.h:59
uint qHash(const LongLat &coords)
QString WorldName() const
Definition: World.cpp:65