OSDN Git Service

航路保存機能試作。
[gvonavish/GVONavish.git] / GVONavish / GVONavish / GVOShipRouteList.cpp
1 #include "stdafx.h"
2 #include "GVOShipRouteList.h"
3
4
5 namespace {
6         struct FileHeaderV1 {
7                 enum {
8                         k_FileVersion = 1,
9                 };
10                 const uint32_t version = k_FileVersion;
11                 uint32_t favoritsCount = 0;
12         };
13
14         typedef FileHeaderV1 FileHeader;
15 }
16
17
18 bool GVOShipRouteList::saveToFile( const std::wstring & filePath )
19 {
20         std::unique_ptr<FILE, decltype(&::fclose)> file(::_wfopen(filePath.c_str(), L"wb"), &::fclose);
21         if ( !file ) {
22                 return false;
23         }
24
25         FileHeader fileHeader;
26
27         ::fseek( file.get(), sizeof(FileHeader), SEEK_SET );
28
29         for ( const auto & shipRoute : m_shipRouteList ) {
30                 if ( shipRoute->isFavorite() ) {
31                         ++fileHeader.favoritsCount;
32
33                         std::time_t dateTime = std::time_t();
34                         dateTime = shipRoute->earliestDateTime();
35                         ::fwrite( &dateTime, sizeof(dateTime), 1, file.get() );
36                         dateTime = shipRoute->latestDateTime();
37                         ::fwrite( &dateTime, sizeof(dateTime), 1, file.get() );
38
39                         const size_t lineCount = shipRoute->getLines().size();
40                         ::fwrite( &lineCount, sizeof(lineCount), 1, file.get() );
41
42                         for ( const auto & line : shipRoute->getLines() ) {
43                                 const size_t count = line.size();
44                                 ::fwrite( &count, sizeof(count), 1, file.get() );
45                                 if ( !line.empty() ) {
46                                         ::fwrite( &line[0], sizeof(line[0]), line.size(), file.get() );
47                                 }
48                         }
49                 }
50         }
51
52         ::fseek( file.get(), 0, SEEK_SET );
53         ::fwrite( &fileHeader, sizeof(fileHeader), 1, file.get() );
54         return true;
55 }
56
57
58 bool GVOShipRouteList::loadFromFile( const std::wstring & filePath )
59 {
60         std::unique_ptr<FILE, decltype(&::fclose)> file( ::_wfopen( filePath.c_str(), L"rb" ), &::fclose );
61         if ( !file ) {
62                 return false;
63         }
64
65         FileHeader fileHeader;
66         ::fread( &fileHeader, sizeof( fileHeader ), 1, file.get() );
67
68         if ( fileHeader.version != FileHeader::k_FileVersion ) {
69                 return false;
70         }
71
72         m_shipRouteList.clear();
73
74         for ( uint32_t i = 0; i < fileHeader.favoritsCount; ++i ) {
75                 GVOShipRoutePtr shipRoute( new GVOShipRoute() );
76                 shipRoute->setFavorite( true );
77
78                 std::time_t dateTime = std::time_t();
79                 ::fread( &dateTime, sizeof(dateTime), 1, file.get() );
80                 shipRoute->setEarliestDateTime( dateTime );
81                 ::fread( &dateTime, sizeof(dateTime), 1, file.get() );
82                 shipRoute->setLatestDateTime( dateTime );
83
84                 size_t lineCount = 0;
85                 ::fread( &lineCount, sizeof(lineCount), 1, file.get() );
86
87                 for ( size_t k = 0; k < lineCount; ++k ) {
88                         size_t pointCount = 0;
89                         ::fread( &pointCount, sizeof(pointCount), 1, file.get() );
90                         if ( 0 < pointCount ) {
91                                 GVOShipRoute::Line tmp( pointCount );
92                                 ::fread( &tmp[0], sizeof(tmp[0]), tmp.size(), file.get() );
93                                 shipRoute->addLine( std::move( tmp ) );
94                         }
95                 }
96
97                 m_shipRouteList.push_back( std::move( shipRoute ) );
98         }
99
100         return true;
101 }
102
103
104 void GVOShipRouteList::closeRoute()
105 {
106         if ( !m_shipRouteList.empty() ) {
107                 m_shipRouteList.back()->setFix( true );
108         }
109 }
110
111
112 void GVOShipRouteList::addRoutePoint( const GVONormalizedPoint point )
113 {
114         if ( m_shipRouteList.empty() || m_shipRouteList.back()->isFixed() ) {
115                 addRoute();
116         }
117         m_shipRouteList.back()->addRoutePoint( point );
118         if ( m_observer ) {
119                 m_observer->onShipRouteListUpdateRoute( m_shipRouteList.back() );
120         }
121 }
122
123
124 void GVOShipRouteList::removeShipRoute( GVOShipRoutePtr shipRoute )
125 {
126         _ASSERT( shipRoute != nullptr );
127         auto it = std::find( m_shipRouteList.begin(), m_shipRouteList.end(), shipRoute );
128         if ( it == m_shipRouteList.end() ) {
129                 return;
130         }
131         GVOShipRoutePtr removeTarget = shipRoute;
132         m_shipRouteList.erase( it );
133         if ( m_observer ) {
134                 m_observer->onShipRouteListRemoveItem( removeTarget );
135         }
136 }
137
138
139 void GVOShipRouteList::clearAllItems()
140 {
141         m_shipRouteList.clear();
142         if ( m_observer ) {
143                 m_observer->onShipRouteListRemoveAllItems();
144         }
145 }
146
147
148 void GVOShipRouteList::addRoute()
149 {
150         // \92Ç\89Á\82Æ\92Ê\92m
151         m_shipRouteList.push_back( GVOShipRoutePtr( new GVOShipRoute() ) );
152         if ( m_observer ) {
153                 m_observer->onShipRouteListAddRoute( m_shipRouteList.back() );
154         }
155
156         // \88ì\82ê\82½\95ª\82ð\8dí\8f\9c
157         // \82Æ\82è\82 \82¦\82¸\83^\83R\83R\81[\83h\82Å\8bð\92¼\82É\8f\91\82¢\82Ä\82¨\82­\81B
158         int favorits = 0;
159         for ( auto route : m_shipRouteList ) {
160                 if ( route->isFavorite() ) {
161                         ++favorits;
162                 }
163         }
164         const int overCount = m_shipRouteList.size() - (m_maxRouteCountWithoutFavorits + favorits);
165         if ( 0 < overCount ) {
166                 int removeCount = 0;
167                 auto it = m_shipRouteList.begin();
168                 while ( it != m_shipRouteList.end() && removeCount < overCount) {
169                         if ( (*it)->isFavorite() ) {
170                                 ++it;
171                                 continue;
172                         }
173                         auto itNext = std::next( it, 1 );
174                         m_shipRouteList.erase( it );
175                         ++removeCount;
176                         it = itNext;
177                 }
178         }
179 }
180
181
182 void GVOShipRouteList::joinPreviousRouteAtReverseIndex( int reverseIndex )
183 {
184         _ASSERT( 0 <= reverseIndex );
185         _ASSERT( reverseIndex < (int)m_shipRouteList.size() );
186
187         RouteList::iterator itBase;
188         itBase = m_shipRouteList.begin();
189         std::advance( itBase, indexFromReverseIndex( reverseIndex ) );
190         RouteList::iterator itPrev = std::prev( itBase );
191         _ASSERT( itPrev != m_shipRouteList.end() );
192         GVOShipRoutePtr baseRoute = *itBase;
193         GVOShipRoutePtr prevRoute = *itPrev;
194
195         m_shipRouteList.erase( itPrev );
196
197         // remove\82µ\82½\8e\9e\82É\92Ê\92m\83n\83\93\83h\83\89\82Å\91®\90«\82ª\95Ï\8dX\82³\82ê\82Ä\82µ\82Ü\82¤\82Ì\82Å\81A
198         // \82±\82Ì\8e\9e\93_\82Å\8b­\92²\91®\90«\82ð\95Û\91\82µ\82Ä\82¨\82­\81B
199         bool isHilight = prevRoute->isHilight() | baseRoute->isHilight();
200         if ( m_observer ) {
201                 m_observer->onShipRouteListRemoveItem( prevRoute );
202         }
203
204         baseRoute->jointPreviousLinesWithRoute( *prevRoute );
205         baseRoute->setHilight( isHilight );
206
207         // \92Ê\92m
208         if ( m_observer ) {
209                 m_observer->onShipRouteListUpdateRoute( baseRoute );
210         }
211 }