boost serialize вопрос
От: nen777w  
Дата: 09.06.09 09:37
Оценка:
Можно ли влиять на последующую сериализацию при загрузке, средствами библиотеки.
Вопрос может быть муторный, сейчас поясню.

Есть некий класс, который хранит идентификатор на хардверный ресурс (hw).
Собствено основная задача класса, помимо встростепенных задач создать hw ресурс.

class hw_keeper
{
private:
  GLuint m_hwId;
};


Есть также класс знающий о m_hwId какого либо объекта hw_keeper.

class texture2d {
  struct tex_data {
    GLuint m_hwId; 
    ...
  }

  tex_data td;
};


Замечу что hw_keeper ничего об texture2d классах не знает, так как texture2d могут создаваться/удаляться в любой момет времени сколько угодно раз.
И через специальный менеджер texture2d делают запросы на выделение хардверного ресурса, затем получают все необходимые параметры. То же происходит при удалении texture2d через специальный менеджер уведомляет что он больше не нуждается в таком то hw ресурсе.

Допустим Я напишу сериализацию так что бы сперва сереализовались данные hw_keeper
(более низкоуровневых объектов класса) а затем texture2d объектов.

Проблема в том что когда hw_keeper будет загружаться он может получить от системы другой Id и нужно в hw_keeper::load() запомнить такую пару:
старый m_hwId <=> новый m_hwId. И дабы правильно настроить texture2d при загрузке эту пару нужно будет у кого то спросить.
Либо же вообще сразу подменить в архиве для объектов texture2d старый id на новый.

Существует ли способ сделать это средствами библиотеки boost::serialize дабы не городить самоу каких то специальных load_helper-ов ?
Re: boost serialize вопрос
От: Mazay Россия  
Дата: 11.06.09 05:00
Оценка: 6 (1)
Здравствуйте, nen777w, Вы писали:

Есть в boost.serialization такая штука как трекинг объектов по указателям. Идея такая. Если есть какой объект A, на который через указатели (обычные или умные) ссылаются множество других объектов B[], то при сохранении в один архив всех этих объектов (и А, и В[]), объект A будет сохранен только один раз, а указатели на него в B[] будут заменены идентификатором. При загрузке архива адрес обхекта A конечно будет отличаться от того что был при сохранении, но у boost.serialization хватает мозгов правильно проинициализировать все указатели на A в B[].

Таким образом, если бы у тебя был какой-то враппер вокруг GLuint и в объектах классов hw_keeper и texture2d хранились указатели на эти врапперы, то проблем бы не было. Выделение хардверного ресурса происходило бы в методе load() этого враппера. Счастье в том, что тебе вовсе не обязательно все время хранить эти врапперы, а можно лишь создавать их при сериализации или десериализации в том же менеджере, который уведомляют объекты texture2d.

Примерно вот так:
<typename Archive>
hw_keeper::load(Archive &a)
{
  wrapper<GLuint> *w;
  a >> w;
  this->m_hwId = w->m_hwId;
}

<typename Archive>
hw_keeper::save(Archive &a)
{
  wrapper<GLuint> *w = HwManager::getHwWrapper(this->m_hwId);
  a << w;
}

// для texture2d аналогично

<typename T, typename Archive>
wrapper<T>::load(Archive &a)
{
   this->m_hwId = HwManager::allocateNewHw();
}

<typename T, typename Archive>
wrapper<T>::save(Archive &a)
{
   // save nothing
}

wrapper<GLuint> HwManager::getHwWrapper(GLuint m_hwId)
{
   // завести std::map<m_hwId, wrapper<m_hwId> >
   // и либо возвращать тот враппер, что уже есть в этом мапе, 
   // либо создавать новый и соотв-но добавлять в мап и возвращать
}


Примерно так. Возможно придется сохранять еще какую-то фиктивную переменную в методах wrapper<T>::save/load, потому что я не уверен, что возможен такой финт ушами как сериализация "ничего".
Ещё могу предложить выдернуть из буста код, который реализует трекинг указателей и использовать его для аналогичного трекинга твоих GLuint'ов.
Главное гармония ...
boost serialization
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.