Add auxiliary data type for extra command data
This commit is contained in:
@@ -84,6 +84,7 @@ add_files(
|
|||||||
clear_map.h
|
clear_map.h
|
||||||
cmd_helper.h
|
cmd_helper.h
|
||||||
command.cpp
|
command.cpp
|
||||||
|
command_aux.h
|
||||||
command_func.h
|
command_func.h
|
||||||
command_type.h
|
command_type.h
|
||||||
company_base.h
|
company_base.h
|
||||||
|
119
src/command_aux.h
Normal file
119
src/command_aux.h
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD 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, version 2.
|
||||||
|
* OpenTTD 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 OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file command_aux.h Command auxiliary data. */
|
||||||
|
|
||||||
|
#ifndef COMMAND_AUX_H
|
||||||
|
#define COMMAND_AUX_H
|
||||||
|
|
||||||
|
#include "command_type.h"
|
||||||
|
#include "command_func.h"
|
||||||
|
#include "string_type.h"
|
||||||
|
#include "core/serialisation.hpp"
|
||||||
|
#include "3rdparty/optional/ottd_optional.h"
|
||||||
|
|
||||||
|
struct CommandDeserialisationBuffer : public BufferDeserialisationHelper<CommandDeserialisationBuffer> {
|
||||||
|
const uint8 *buffer;
|
||||||
|
size_t size;
|
||||||
|
size_t pos = 0;
|
||||||
|
bool error = false;
|
||||||
|
|
||||||
|
CommandDeserialisationBuffer(const uint8 *buffer, size_t size) : buffer(buffer), size(size) {}
|
||||||
|
|
||||||
|
const byte *GetDeserialisationBuffer() const { return this->buffer; }
|
||||||
|
size_t GetDeserialisationBufferSize() const { return this->size; }
|
||||||
|
size_t &GetDeserialisationPosition() { return this->pos; }
|
||||||
|
|
||||||
|
bool CanDeserialiseBytes(size_t bytes_to_read, bool raise_error)
|
||||||
|
{
|
||||||
|
if (this->error) return false;
|
||||||
|
|
||||||
|
/* Check if variable is within packet-size */
|
||||||
|
if (this->pos + bytes_to_read > this->size) {
|
||||||
|
if (raise_error) this->error = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CommandSerialisationBuffer : public BufferSerialisationHelper<CommandSerialisationBuffer> {
|
||||||
|
std::vector<byte> &buffer;
|
||||||
|
size_t limit;
|
||||||
|
|
||||||
|
CommandSerialisationBuffer(std::vector<byte> &buffer, size_t limit) : buffer(buffer), limit(limit) {}
|
||||||
|
|
||||||
|
std::vector<byte> &GetSerialisationBuffer() { return this->buffer; }
|
||||||
|
size_t GetSerialisationLimit() const { return this->limit; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CommandAuxiliarySerialised : public CommandAuxiliaryBase {
|
||||||
|
std::vector<byte> serialised_data;
|
||||||
|
|
||||||
|
CommandAuxiliaryBase *Clone() const
|
||||||
|
{
|
||||||
|
return new CommandAuxiliarySerialised(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const std::vector<uint8> *GetDeserialisationSrc() const override { return &(this->serialised_data); }
|
||||||
|
|
||||||
|
virtual void Serialise(CommandSerialisationBuffer &buffer) const override { buffer.Send_binary((const char *)this->serialised_data.data(), this->serialised_data.size()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct CommandAuxiliarySerialisable : public CommandAuxiliaryBase {
|
||||||
|
virtual const std::vector<uint8> *GetDeserialisationSrc() const override { return nullptr; }
|
||||||
|
|
||||||
|
CommandAuxiliaryBase *Clone() const
|
||||||
|
{
|
||||||
|
return new T(*static_cast<const T *>(this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct CommandAuxData {
|
||||||
|
private:
|
||||||
|
opt::optional<T> store;
|
||||||
|
const T *data = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
inline CommandCost Load(const CommandAuxiliaryBase *base)
|
||||||
|
{
|
||||||
|
if (base == nullptr) return CMD_ERROR;
|
||||||
|
const std::vector<uint8> *deserialise_from = base->GetDeserialisationSrc();
|
||||||
|
if (deserialise_from != nullptr) {
|
||||||
|
this->store = T();
|
||||||
|
CommandDeserialisationBuffer buffer(deserialise_from->data(), deserialise_from->size());
|
||||||
|
CommandCost res = this->store->Deserialise(buffer);
|
||||||
|
if (res.Failed()) return res;
|
||||||
|
if (buffer.error || buffer.pos != buffer.size) {
|
||||||
|
/* Other deserialisation error or wrong number of bytes read */
|
||||||
|
return CMD_ERROR;
|
||||||
|
}
|
||||||
|
this->data = &(*(this->store));
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
this->data = dynamic_cast<const T*>(base);
|
||||||
|
if (this->data == nullptr) return CMD_ERROR;
|
||||||
|
return CommandCost();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const T *operator->() const
|
||||||
|
{
|
||||||
|
return this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const T &operator*() const
|
||||||
|
{
|
||||||
|
return *(this->data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* COMMAND_AUX_H */
|
||||||
|
|
@@ -689,6 +689,40 @@ typedef void CommandCallback(const CommandCost &result, TileIndex tile, uint32 p
|
|||||||
|
|
||||||
#define MAX_CMD_TEXT_LENGTH 32000
|
#define MAX_CMD_TEXT_LENGTH 32000
|
||||||
|
|
||||||
|
struct CommandSerialisationBuffer;
|
||||||
|
|
||||||
|
struct CommandAuxiliaryBase {
|
||||||
|
virtual ~CommandAuxiliaryBase() {}
|
||||||
|
|
||||||
|
virtual CommandAuxiliaryBase *Clone() const = 0;
|
||||||
|
|
||||||
|
virtual const std::vector<uint8> *GetDeserialisationSrc() const = 0;
|
||||||
|
|
||||||
|
virtual void Serialise(CommandSerialisationBuffer &buffer) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CommandAuxiliaryPtr : public std::unique_ptr<CommandAuxiliaryBase>
|
||||||
|
{
|
||||||
|
using std::unique_ptr<CommandAuxiliaryBase>::unique_ptr;
|
||||||
|
|
||||||
|
CommandAuxiliaryPtr() {};
|
||||||
|
|
||||||
|
CommandAuxiliaryPtr(const CommandAuxiliaryPtr &other) :
|
||||||
|
std::unique_ptr<CommandAuxiliaryBase>(CommandAuxiliaryPtr::Clone(other)) {}
|
||||||
|
|
||||||
|
CommandAuxiliaryPtr& operator=(const CommandAuxiliaryPtr &other)
|
||||||
|
{
|
||||||
|
this->reset(CommandAuxiliaryPtr::Clone(other));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static CommandAuxiliaryBase *Clone(const CommandAuxiliaryPtr &other)
|
||||||
|
{
|
||||||
|
return other != nullptr ? other->Clone() : nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure for buffering the build command when selecting a station to join.
|
* Structure for buffering the build command when selecting a station to join.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user