+#ifndef LIBR2C2_BLOCKALLOCATOR_H_
+#define LIBR2C2_BLOCKALLOCATOR_H_
+
+#include <list>
+#include <msp/datafile/objectloader.h>
+#include "block.h"
+#include "blockiter.h"
+
+namespace R2C2 {
+
+class Train;
+
+class BlockAllocator
+{
+public:
+ class Loader: public Msp::DataFile::ObjectLoader<BlockAllocator>
+ {
+ private:
+ Block *prev_block;
+ bool valid;
+
+ public:
+ Loader(BlockAllocator &);
+
+ private:
+ void block(unsigned);
+ void hint(unsigned);
+ };
+
+private:
+ typedef std::list<BlockIter> BlockList;
+
+ Train &train;
+ BlockList blocks;
+ BlockList::iterator cur_blocks_end;
+ Block *pending_block;
+ const Block *stop_at_block;
+ bool reserving;
+
+public:
+ BlockAllocator(Train &);
+
+ void start_from(Block &, unsigned);
+ void clear();
+ bool empty() const { return blocks.empty(); }
+ void stop_at(const Block *);
+
+ const BlockIter &first() const;
+ const BlockIter &last() const;
+ const BlockIter &last_current() const;
+
+ int get_entry_to_block(const Block &) const;
+
+ void reserve_more();
+ void release_until(const Block &);
+ bool release_from(const Block &);
+ void release_noncurrent();
+private:
+ void release_blocks(const BlockList::iterator &, const BlockList::iterator &);
+public:
+ void reverse();
+
+private:
+ void turnout_path_changed(Track &);
+ void block_reserved(Block &, const Train *);
+ void block_state_changed(Block &, Block::State);
+
+public:
+ void save(std::list<Msp::DataFile::Statement> &) const;
+};
+
+} // namepsace R2C2
+
+#endif