пятница, 4 апреля 2014 г.

Экспорт/импорт данных в бинарный формат

Подготовил пример использованного в последней игре формата сохранения/загрузки игровых данных (заточен под Lazarus+ZenGl, но при желании можно переделать). Сам формат основан на protobuf (Protocol Buffers от Google). Из основных преимуществ - простота использования в коде и возможность расширения файла данных без страха потери совместимости. Так например ваша программа версии 1, может поднять сохранение из версии 2 (новые части сохранения которые появились в v2 просто проигнорируются). Также версия 2 спокойно поднимет сохранение версии 1. Если кратко, то все данные разбиваются на поля, каждое поле имеет свой ID и размер. В коде при считывании поля с неизвестным ID оно просто игнорируется, если же каких-то полей не хватает, то это также проигнорируется.



Примеры использования в коде


Запись класса:

mCls1: TTestClass; // создаеться позднее в коде

......

procedure TForm1.btnExportClick(Sender: TObject);
var
  se:TStrgExport;
begin
  se := TStrgExport.Create;

  mCls1.OnExport1(0, se);

  se.mStrg.SaveToFile('Test.stg');
  se.Free;
end;

////////////

procedure TTestClass.OnExport1(iFieldID: word; iExp: TStrgExport);
begin
  iExp.StartData(iFieldID, wtpFields);

  iExp.WriteInt    (0, mInt);
  iExp.WriteCard   (1, mCard);
  iExp.WriteString (2, mStr);
  iExp.WriteSingle (3, mSingle);
  iExp.WriteBool   (4, mBool);
  iExp.WriteData   (5, mRec, SizeOf(mRec));

  iExp.EndData;
end;
Считывание класса:

procedure TForm1.btnImportClick(Sender: TObject);
var
  si:TStrgImport;
begin
  si := TStrgImport.Create;
  si.LoadFromFile('Test.stg');

  si.ReadFields(@mCls1.OnImport1);

  si.Free;
end;

procedure TTestClass.OnImport1(iField: PRImportField);
begin
  case iField^.mFieldID of
    0: mInt     := iField^.ReadInt;
    1: mCard    := iField^.ReadCard;
    2: mStr     := iField^.ReadString;
    3: mSingle  := iField^.ReadSingle;
    4: mBool    := iField^.ReadBool;
    5: iField^.ReadData(mRec);
  else
    assert(false);
  end;
end;

Больше примеров и сами исходники можно найти в проекте под Lazarus:
http://yadi.sk/d/bp7QY91hLm7dT

1 комментарий: