C++, ECS and Saving / Loading

时光怂恿深爱的人放手 提交于 2019-12-24 14:44:24

问题


I have a program that employs an entity-component-system framework. Essentially this means that I have a collection of entities that have various components attached to them. Entities are actually just integer ID numbers, and components are attached to them by mapping the component to the specified ID number of the entity.

Now, I need to store collections of entities and the associated components to a file that can be modified later on, so basically I need a saving and loading functionality. However, being somewhat a newcomer to C++, I have hard time figuring out how to exactly do this.

Coming from Java and C#, my first choice would be to serialize the objects into, say, JSON, and then deserialize them when the JSON is loaded. However, C++ does not have any reflection features. So, the question is: how do I save and load C++ objects? I don't mean the actual file operations, I mean the way the objects and structs should be handled in order to preserve them between program launches.


回答1:


One way of doing is to create Persistent Objects in C++, and store the your data.

check out the following links:

C++ object persistence library similar to eternity

http://sourceforge.net/projects/litesql/

http://en.wikipedia.org/wiki/ODB_(C%2B%2B)

http://drdobbs.com/cpp/184408893

http://tools.devshed.com/c/a/Web-Development/C-Programming-Persistence/

C++ doesn't support persistence directly (there are proposals for adding persistence and reflection to C++ in the future). Persistence support is not as trivial as it may seem at first. The size and memory layout of the same object may vary from one platform to another. Different byte ordering, or endian-ness, complicate matters even further. To make an object persistent, we have to reserve its state in a non-volatile storage device. ie: Write a persistent object to retain its state outside the scope of the program in which it was created.

Other Way, is to store the objects into an array, then push the array buffer to a file. The advantage are that the disk platters don't have waste time ramping up and also the writing can be performed contiguously.

You can increase the performance by using threads. Dump the objects to a buffer, once done trigger a thread to handle the output.

Example: The following code has not been compiled and is for illustrative purposes only.

#include <fstream>
#include <algorithm>

using std::ofstream;
using std::fill;

#define MAX_DATA_LEN  1024 // Assuming max size of data be 1024

class stream_interface
{
    virtual void    load_from_buffer(const unsigned char *& buf_ptr) = 0;
    virtual size_t  size_on_stream(void) const = 0;
    virtual void    store_to_buffer(unsigned char *& buf_ptr) const = 0;
};

struct Component 
    : public stream_interface,
    data_length(MAX_DATA_LEN)
{
    unsigned int entity;
    std::string  data;
    const unsigned int  data_length;

    void load_from_buffer(const unsigned char *& buf_ptr)
    {
        entity = *((unsigned int *) buf_ptr);
        buf_ptr += sizeof(unsigned int);
        data = std::string((char *) buf_ptr);
        buf_ptr += data_length;
        return;
    }
    size_t size_on_stream(void) const
    {
        return sizeof(unsigned int) + data_length;
    }
    void store_to_buffer(unsigned char *& buf_ptr) const
    {
        *((unsigned int *) buf_ptr) = entity;
        buf_ptr += sizeof(unsigned int);
        std::fill(buf_ptr, 0, data_length);
        strncpy((char *) buf_ptr, data.c_str(), data_length);
        buf_ptr += data_length;
        return;
    }
};


int main(void)
{
    Component c1;
    c1.data = "Some Data";
    c1.entity = 5;
    ofstream    data_file("ComponentList.bin", std::ios::binary);

    // Determine size of buffer
    size_t  buffer_size = c1.size_on_stream();

    // Allocate the buffer
    unsigned char * buffer = new unsigned char [buffer_size];
    unsigned char * buf_ptr = buffer;

    // Write / store the object into the buffer.
    c1.store_to_buffer(buf_ptr);

    // Write the buffer to the file / stream.
    data_file.write((char *) buffer, buffer_size);

    data_file.close();
    delete [] buffer;
    return 0;
}


来源:https://stackoverflow.com/questions/28046324/c-ecs-and-saving-loading

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!