iw4x-client/src/Components/Modules/AssetInterfaces/ImenuDef_t.cpp

710 lines
18 KiB
C++
Raw Normal View History

#include <STDInclude.hpp>
#include "ImenuDef_t.hpp"
2017-02-25 14:55:04 -05:00
namespace Assets
{
std::unordered_map<std::string, Game::menuDef_t*> ImenuDef_t::LoadedMenus;
void ImenuDef_t::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* /*builder*/)
{
// load from disk
auto menus = Components::Menus::LoadMenu(Utils::String::VA("ui_mp/%s.menu", name.data()));
if (menus.size() == 0) return;
if (menus.size() > 1) Components::Logger::Print("Menu '{}' on disk has more than one menudef in it. Only saving the first one\n", name);
header->menu = menus[0].second;
}
2017-02-25 15:11:17 -05:00
void ImenuDef_t::mark(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
{
Game::menuDef_t *asset = header.menu;
if (asset->window.background)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->window.background);
}
2017-02-25 15:11:17 -05:00
// mark items
2017-04-24 16:33:13 -04:00
for (int i = 0; i < asset->itemCount; ++i)
2017-02-25 15:11:17 -05:00
{
if (asset->items[i]->window.background)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->items[i]->window.background);
}
if (asset->items[i]->focusSound)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_SOUND, asset->items[i]->focusSound);
}
if (asset->items[i]->type == 6 && asset->items[i]->typeData.listBox &&
asset->items[i]->typeData.listBox->selectIcon)
{
builder->loadAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->items[i]->typeData.listBox->selectIcon);
}
2017-02-25 15:11:17 -05:00
}
}
void ImenuDef_t::save_ExpressionSupportingData(Game::ExpressionSupportingData* asset, Components::ZoneBuilder::Zone* builder)
{
AssertSize(Game::ExpressionSupportingData, 24);
Utils::Stream* buffer = builder->getBuffer();
#ifdef WRITE_LOGS
buffer->enterStruct("ExpressionSupportingData");
#endif
buffer->align(Utils::Stream::ALIGN_4);
Game::ExpressionSupportingData *dest = buffer->dest<Game::ExpressionSupportingData>();
buffer->save(asset);
if (asset->uifunctions.functions)
{
buffer->align(Utils::Stream::ALIGN_4);
Game::Statement_s **destStatement = buffer->dest<Game::Statement_s*>();
buffer->saveArray(asset->uifunctions.functions, asset->uifunctions.totalFunctions);
2017-04-24 16:33:13 -04:00
for (int i = 0; i < asset->uifunctions.totalFunctions; ++i)
{
if (asset->uifunctions.functions[i])
{
Utils::Stream::ClearPointer(&destStatement[i]);
buffer->align(Utils::Stream::ALIGN_4);
this->save_Statement_s(asset->uifunctions.functions[i], builder);
}
}
Utils::Stream::ClearPointer(&dest->uifunctions.functions);
}
if (asset->staticDvarList.staticDvars)
{
buffer->align(Utils::Stream::ALIGN_4);
Game::StaticDvar **destStaticDvars = buffer->dest<Game::StaticDvar*>();
buffer->saveArray(asset->staticDvarList.staticDvars, asset->staticDvarList.numStaticDvars);
2017-04-24 16:33:13 -04:00
for (int i = 0; i < asset->staticDvarList.numStaticDvars; ++i)
{
if (asset->staticDvarList.staticDvars[i])
{
Utils::Stream::ClearPointer(&destStaticDvars[i]);
buffer->align(Utils::Stream::ALIGN_4);
Game::StaticDvar *destStaticDvar = buffer->dest<Game::StaticDvar>();
buffer->save(asset->staticDvarList.staticDvars[i]);
if (asset->staticDvarList.staticDvars[i]->dvarName)
{
buffer->saveString(asset->staticDvarList.staticDvars[i]->dvarName);
Utils::Stream::ClearPointer(&destStaticDvar->dvarName);
}
}
}
Utils::Stream::ClearPointer(&dest->staticDvarList.staticDvars);
}
if (asset->uiStrings.strings)
{
buffer->align(Utils::Stream::ALIGN_4);
const char **destuiStrings = buffer->dest<const char*>();
buffer->saveArray(asset->uiStrings.strings, asset->uiStrings.totalStrings);
2017-04-24 16:33:13 -04:00
for (int i = 0; i < asset->uiStrings.totalStrings; ++i)
{
if (asset->uiStrings.strings[i])
{
buffer->saveString(asset->uiStrings.strings[i]);
Utils::Stream::ClearPointer(&destuiStrings[i]);
}
}
}
#ifdef WRITE_LOGS
buffer->leaveStruct();
#endif
}
void ImenuDef_t::save_Statement_s(Game::Statement_s* asset, Components::ZoneBuilder::Zone* builder)
2017-02-25 14:55:04 -05:00
{
AssertSize(Game::Statement_s, 24);
AssertSize(Game::expressionEntry, 12);
2017-02-25 14:55:04 -05:00
Utils::Stream* buffer = builder->getBuffer();
#ifdef WRITE_LOGS
buffer->enterStruct("Statement_s");
#endif
2017-02-25 14:55:04 -05:00
// Write header data
Game::Statement_s *dest = buffer->dest<Game::Statement_s>();
buffer->save(asset);
// Write statement entries
if (asset->entries)
{
#ifdef WRITE_LOGS
buffer->enterStruct("statement entries");
#endif
2017-02-25 14:55:04 -05:00
buffer->align(Utils::Stream::ALIGN_4);
// Write entries
Game::expressionEntry *destEntries = buffer->dest<Game::expressionEntry>();
buffer->save(asset->entries, sizeof(Game::expressionEntry), asset->numEntries);
// Loop through entries
2017-04-24 16:33:13 -04:00
for (int i = 0; i < asset->numEntries; ++i)
2017-02-25 14:55:04 -05:00
{
#ifdef WRITE_LOGS
buffer->enterStruct("entry");
#endif
2017-02-25 14:55:04 -05:00
if (asset->entries[i].type)
{
switch (asset->entries[i].data.operand.dataType)
{
// Those types do not require additional data
case 0:
case 1:
break;
// Expression string
case 2:
if (asset->entries[i].data.operand.internals.stringVal.string)
{
buffer->saveString(asset->entries[i].data.operand.internals.stringVal.string);
Utils::Stream::ClearPointer(&destEntries[i].data.operand.internals.stringVal.string);
}
break;
// Function
case 3:
if (asset->entries[i].data.operand.internals.function)
{
buffer->align(Utils::Stream::ALIGN_4);
this->save_Statement_s(asset->entries[i].data.operand.internals.function, builder);
2017-02-25 14:55:04 -05:00
Utils::Stream::ClearPointer(&destEntries[i].data.operand.internals.function);
}
break;
}
}
#ifdef WRITE_LOGS
buffer->leaveStruct();
#endif
2017-02-25 14:55:04 -05:00
}
#ifdef WRITE_LOGS
buffer->leaveStruct();
#endif
2017-02-25 14:55:04 -05:00
}
2017-02-25 14:55:04 -05:00
if (asset->supportingData)
{
this->save_ExpressionSupportingData(asset->supportingData, builder);
Utils::Stream::ClearPointer(&dest->supportingData);
2017-02-25 14:55:04 -05:00
}
#ifdef WRITE_LOGS
buffer->leaveStruct();
#endif
2017-02-25 14:55:04 -05:00
}
void ImenuDef_t::save_MenuEventHandlerSet(Game::MenuEventHandlerSet* asset, Components::ZoneBuilder::Zone* builder)
2017-02-25 14:55:04 -05:00
{
AssertSize(Game::MenuEventHandlerSet, 8);
Utils::Stream* buffer = builder->getBuffer();
#ifdef WRITE_LOGS
buffer->enterStruct("MenuEventHandlerSet");
#endif
2017-02-25 14:55:04 -05:00
// Write header data
Game::MenuEventHandlerSet *destset = buffer->dest<Game::MenuEventHandlerSet>();
buffer->save(asset);
// Event handlers
if (asset->eventHandlers)
{
buffer->align(Utils::Stream::ALIGN_4);
// Write pointers to zone
buffer->save(asset->eventHandlers, sizeof(Game::MenuEventHandler*), asset->eventHandlerCount);
// Loop through eventHandlers
2017-04-24 16:33:13 -04:00
for (int i = 0; i < asset->eventHandlerCount; ++i)
2017-02-25 14:55:04 -05:00
{
if (asset->eventHandlers[i])
{
buffer->align(Utils::Stream::ALIGN_4);
#ifdef WRITE_LOGS
buffer->enterStruct("MenuEventHandler");
#endif
2017-02-25 14:55:04 -05:00
// Write menu event handler
Game::MenuEventHandler *dest = buffer->dest<Game::MenuEventHandler>();
buffer->save(asset->eventHandlers[i]);
// Write additional data based on type
switch (asset->eventHandlers[i]->eventType)
{
// unconditional scripts
case 0:
if (asset->eventHandlers[i]->eventData.unconditionalScript)
{
buffer->saveString(asset->eventHandlers[i]->eventData.unconditionalScript);
Utils::Stream::ClearPointer(&dest->eventData.unconditionalScript);
}
break;
// ConditionalScript
case 1:
if (asset->eventHandlers[i]->eventData.conditionalScript)
{
buffer->align(Utils::Stream::ALIGN_4);
Game::ConditionalScript *destConditionalScript = buffer->dest<Game::ConditionalScript>();
buffer->save(asset->eventHandlers[i]->eventData.conditionalScript);
// eventExpression
if (asset->eventHandlers[i]->eventData.conditionalScript->eventExpression)
{
buffer->align(Utils::Stream::ALIGN_4);
this->save_Statement_s(asset->eventHandlers[i]->eventData.conditionalScript->eventExpression, builder);
2017-02-25 14:55:04 -05:00
Utils::Stream::ClearPointer(&destConditionalScript->eventExpression);
}
// eventHandlerSet
if (asset->eventHandlers[i]->eventData.conditionalScript->eventHandlerSet)
{
buffer->align(Utils::Stream::ALIGN_4);
this->save_MenuEventHandlerSet(asset->eventHandlers[i]->eventData.conditionalScript->eventHandlerSet, builder);
2017-02-25 14:55:04 -05:00
Utils::Stream::ClearPointer(&destConditionalScript->eventHandlerSet);
}
Utils::Stream::ClearPointer(&dest->eventData.conditionalScript);
}
break;
// elseScript
case 2:
if (asset->eventHandlers[i]->eventData.elseScript)
{
buffer->align(Utils::Stream::ALIGN_4);
this->save_MenuEventHandlerSet(asset->eventHandlers[i]->eventData.elseScript, builder);
2017-02-25 14:55:04 -05:00
Utils::Stream::ClearPointer(&dest->eventData.elseScript);
}
break;
// localVarData expressions
case 3:
case 4:
case 5:
case 6:
if (asset->eventHandlers[i]->eventData.setLocalVarData)
{
buffer->align(Utils::Stream::ALIGN_4);
2017-02-25 14:55:04 -05:00
// header data
Game::SetLocalVarData *destLocalVarData = buffer->dest<Game::SetLocalVarData>();
buffer->save(asset->eventHandlers[i]->eventData.setLocalVarData);
// localVarName
if (asset->eventHandlers[i]->eventData.setLocalVarData->localVarName)
{
buffer->saveString(asset->eventHandlers[i]->eventData.setLocalVarData->localVarName);
Utils::Stream::ClearPointer(&destLocalVarData->localVarName);
}
// statement
if (asset->eventHandlers[i]->eventData.setLocalVarData->expression)
{
buffer->align(Utils::Stream::ALIGN_4);
this->save_Statement_s(asset->eventHandlers[i]->eventData.setLocalVarData->expression, builder);
2017-02-25 14:55:04 -05:00
Utils::Stream::ClearPointer(&destLocalVarData->expression);
}
Utils::Stream::ClearPointer(&dest->eventData.setLocalVarData);
}
break;
}
#ifdef WRITE_LOGS
buffer->leaveStruct();
#endif
2017-02-25 14:55:04 -05:00
}
}
Utils::Stream::ClearPointer(&destset->eventHandlers);
}
#ifdef WRITE_LOGS
buffer->leaveStruct();
#endif
2017-02-25 14:55:04 -05:00
}
void ImenuDef_t::save_ItemKeyHandler(Game::ItemKeyHandler* asset, Components::ZoneBuilder::Zone* builder)
2017-02-25 14:55:04 -05:00
{
AssertSize(Game::ItemKeyHandler, 12);
Utils::Stream* buffer = builder->getBuffer();
#ifdef WRITE_LOGS
buffer->enterStruct("ItemKeyHandler");
#endif
2017-02-25 14:55:04 -05:00
while (asset)
{
// Write header
Game::ItemKeyHandler* dest = buffer->dest<Game::ItemKeyHandler>();
buffer->save(asset);
// MenuEventHandlerSet
if (asset->action)
{
buffer->align(Utils::Stream::ALIGN_4);
this->save_MenuEventHandlerSet(asset->action, builder);
2017-02-25 14:55:04 -05:00
Utils::Stream::ClearPointer(&dest->action);
}
if (asset->next)
{
// align every indice, besides the first one?
buffer->align(Utils::Stream::ALIGN_4);
}
2017-02-25 14:55:04 -05:00
// Next key handler
asset = asset->next;
}
#ifdef WRITE_LOGS
buffer->leaveStruct();
#endif
2017-02-25 14:55:04 -05:00
}
#define EVENTHANDLERSET(__indice) \
if (asset->__indice) \
{ \
buffer->align(Utils::Stream::ALIGN_4); \
this->save_MenuEventHandlerSet(asset->__indice, builder); \
2017-02-25 14:55:04 -05:00
Utils::Stream::ClearPointer(&dest->__indice); \
}
#define STATEMENT(__indice) \
if (asset->__indice) \
{ \
buffer->align(Utils::Stream::ALIGN_4); \
this->save_Statement_s(asset->__indice, builder); \
2017-02-25 14:55:04 -05:00
Utils::Stream::ClearPointer(&dest->__indice); \
}
2018-05-09 08:33:52 -04:00
void ImenuDef_t::save_itemDefData_t(Game::itemDefData_t* asset, int type, Game::itemDef_s* dest, Components::ZoneBuilder::Zone* builder)
{
AssertSize(Game::newsTickerDef_s, 28);
AssertSize(Game::listBoxDef_s, 324);
AssertSize(Game::editFieldDef_s, 32);
AssertSize(Game::multiDef_s, 392);
Utils::Stream* buffer = builder->getBuffer();
#ifdef WRITE_LOGS
buffer->enterStruct("itemDefData_t");
#endif
// feeder
if (type == 6)
{
buffer->align(Utils::Stream::ALIGN_4);
Game::listBoxDef_s* destlb = buffer->dest<Game::listBoxDef_s>();
buffer->save(asset->listBox);
2018-05-09 08:33:52 -04:00
if (asset->listBox->onDoubleClick)
{
buffer->align(Utils::Stream::ALIGN_4);
2018-05-09 08:33:52 -04:00
this->save_MenuEventHandlerSet(asset->listBox->onDoubleClick, builder);
}
if (asset->listBox->selectIcon)
{
destlb->selectIcon = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_MATERIAL, asset->listBox->selectIcon).material;
}
}
// HexRays spaghetti
else if (type != 4
&& type != 9
&& type != 16
&& type != 18
&& type != 11
&& type != 14
&& type != 10
&& type != 17
&& type != 22
&& type != 23
&& type != 0)
{
switch (type)
{
// enum dvar
case 13:
buffer->saveString(asset->enumDvarName);
break;
// newsticker
case 20:
buffer->align(Utils::Stream::ALIGN_4);
buffer->save(asset->ticker);
break;
// textScrollDef
case 21:
buffer->align(Utils::Stream::ALIGN_4);
buffer->save(asset->scroll);
break;
case 12:
buffer->align(Utils::Stream::ALIGN_4);
Game::multiDef_s* destdef = buffer->dest<Game::multiDef_s>();
2018-05-09 08:33:52 -04:00
buffer->save(asset->multi);
2017-04-24 16:33:13 -04:00
for (int i = 0; i < 32; ++i)
{
2018-05-09 08:33:52 -04:00
if (asset->multi->dvarList[i])
{
2018-05-09 08:33:52 -04:00
buffer->saveString(asset->multi->dvarList[i]);
Utils::Stream::ClearPointer(&destdef->dvarList[i]);
}
}
2017-04-24 16:33:13 -04:00
for (int i = 0; i < 32; ++i)
{
2018-05-09 08:33:52 -04:00
if (asset->multi->dvarStr[i])
{
2018-05-09 08:33:52 -04:00
buffer->saveString(asset->multi->dvarStr[i]);
Utils::Stream::ClearPointer(&destdef->dvarStr[i]);
}
}
break;
}
}
// editFieldDef
else
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->save(asset->editField);
}
Utils::Stream::ClearPointer(&dest->typeData.data);
#ifdef WRITE_LOGS
buffer->leaveStruct();
#endif
}
2018-05-09 08:33:52 -04:00
void ImenuDef_t::save_itemDef_s(Game::itemDef_s *asset, Components::ZoneBuilder::Zone* builder)
2017-02-25 14:55:04 -05:00
{
2018-05-09 08:33:52 -04:00
AssertSize(Game::itemDef_s, 380);
2017-02-25 14:55:04 -05:00
Utils::Stream* buffer = builder->getBuffer();
2018-05-09 08:33:52 -04:00
Game::itemDef_s* dest = buffer->dest<Game::itemDef_s>();
2017-02-25 14:55:04 -05:00
#ifdef WRITE_LOGS
if (asset->window.name)
buffer->enterStruct(Utils::String::VA("itemDef_s: name = '%s'", asset->window.name));
else if (asset->window.background)
buffer->enterStruct(Utils::String::VA("itemDef_s: bg = '%s'", asset->window.background->info.name));
else
buffer->enterStruct("itemDef_s");
#endif
2017-02-25 14:55:04 -05:00
buffer->save(asset);
// window data
2018-05-09 08:33:52 -04:00
save_windowDef_t<Game::itemDef_s>(&asset->window, dest, builder);
2017-02-25 14:55:04 -05:00
// text
if (asset->text)
{
buffer->saveString(asset->text);
Utils::Stream::ClearPointer(&dest->text);
}
// MenuEventHandlerSets
EVENTHANDLERSET(mouseEnterText);
EVENTHANDLERSET(mouseExitText);
EVENTHANDLERSET(mouseEnter);
EVENTHANDLERSET(mouseExit);
EVENTHANDLERSET(action);
EVENTHANDLERSET(accept);
EVENTHANDLERSET(onFocus);
EVENTHANDLERSET(leaveFocus);
// Dvar strings
if (asset->dvar)
{
buffer->saveString(asset->dvar);
Utils::Stream::ClearPointer(&dest->dvar);
}
2017-02-25 14:55:04 -05:00
if (asset->dvarTest)
{
buffer->saveString(asset->dvarTest);
Utils::Stream::ClearPointer(&dest->dvarTest);
}
// ItemKeyHandler
if (asset->onKey)
{
buffer->align(Utils::Stream::ALIGN_4);
this->save_ItemKeyHandler(asset->onKey, builder);
2017-02-25 14:55:04 -05:00
Utils::Stream::ClearPointer(&dest->onKey);
}
// Dvar strings
if (asset->enableDvar)
{
buffer->saveString(asset->enableDvar);
Utils::Stream::ClearPointer(&dest->enableDvar);
}
2017-02-25 14:55:04 -05:00
if (asset->localVar)
{
buffer->saveString(asset->localVar);
Utils::Stream::ClearPointer(&dest->localVar);
}
// Focus sound
if (asset->focusSound)
{
dest->focusSound = builder->saveSubAsset(Game::XAssetType::ASSET_TYPE_SOUND, asset->focusSound).sound;
}
// itemDefData
if (asset->typeData.data)
{
this->save_itemDefData_t(&asset->typeData, asset->type, dest, builder);
}
2017-02-25 14:55:04 -05:00
// floatExpressions
if (asset->floatExpressions)
{
buffer->align(Utils::Stream::ALIGN_4);
#ifdef WRITE_LOGS
buffer->enterStruct("floatExpressions");
#endif
Game::ItemFloatExpression* destExp = buffer->dest<Game::ItemFloatExpression>();
buffer->saveArray(asset->floatExpressions, asset->floatExpressionCount);
2017-04-24 16:33:13 -04:00
for (int i = 0; i < asset->floatExpressionCount; ++i)
{
buffer->align(Utils::Stream::ALIGN_4);
this->save_Statement_s(asset->floatExpressions[i].expression, builder);
Utils::Stream::ClearPointer(&destExp[i].expression);
}
Utils::Stream::ClearPointer(&dest->floatExpressions);
#ifdef WRITE_LOGS
buffer->leaveStruct();
#endif
}
2017-02-25 14:55:04 -05:00
// Statements
STATEMENT(visibleExp);
STATEMENT(disabledExp);
STATEMENT(textExp);
STATEMENT(materialExp);
#ifdef WRITE_LOGS
buffer->leaveStruct();
#endif
2017-02-25 14:55:04 -05:00
}
2017-02-25 15:07:27 -05:00
void ImenuDef_t::save(Game::XAssetHeader header, Components::ZoneBuilder::Zone* builder)
2017-02-25 14:55:04 -05:00
{
AssertSize(Game::menuDef_t, 400);
#ifdef WRITE_LOGS
buffer->enterStruct("ImenuDef_t");
#endif
2017-02-25 14:55:04 -05:00
Utils::Stream* buffer = builder->getBuffer();
Game::menuDef_t* asset = header.menu;
Game::menuDef_t* dest = buffer->dest<Game::menuDef_t>();
buffer->save(asset);
buffer->pushBlock(Game::XFILE_BLOCK_VIRTUAL);
// ExpressionSupportingData
if (asset->expressionData)
{
// dest->expressionData = nullptr;
this->save_ExpressionSupportingData(asset->expressionData, builder);
Utils::Stream::ClearPointer(&dest->expressionData);
}
2017-02-25 14:55:04 -05:00
// Window data
save_windowDef_t<Game::menuDef_t>(&asset->window, dest, builder);
// Font
if (asset->font)
{
buffer->saveString(asset->font);
Utils::Stream::ClearPointer(&dest->font);
}
// MenuEventHandlerSets
EVENTHANDLERSET(onOpen);
2018-05-09 08:33:52 -04:00
EVENTHANDLERSET(onCloseRequest);
2017-02-25 14:55:04 -05:00
EVENTHANDLERSET(onClose);
2018-05-09 08:33:52 -04:00
EVENTHANDLERSET(onESC);
2017-02-25 14:55:04 -05:00
// ItemKeyHandler
if (asset->onKey)
{
buffer->align(Utils::Stream::ALIGN_4);
this->save_ItemKeyHandler(asset->onKey, builder);
2017-02-25 14:55:04 -05:00
Utils::Stream::ClearPointer(&dest->onKey);
}
// Statement
STATEMENT(visibleExp);
// Strings
if (asset->allowedBinding)
{
buffer->saveString(asset->allowedBinding);
Utils::Stream::ClearPointer(&dest->allowedBinding);
}
2018-05-09 08:33:52 -04:00
if (asset->soundName)
2017-02-25 14:55:04 -05:00
{
2018-05-09 08:33:52 -04:00
buffer->saveString(asset->soundName);
Utils::Stream::ClearPointer(&dest->soundName);
2017-02-25 14:55:04 -05:00
}
// Statements
STATEMENT(rectXExp);
STATEMENT(rectYExp);
STATEMENT(rectHExp);
STATEMENT(rectWExp);
STATEMENT(openSoundExp);
STATEMENT(closeSoundExp);
// Items
if (asset->items)
{
buffer->align(Utils::Stream::ALIGN_4);
buffer->saveArray(asset->items, asset->itemCount);
2017-04-24 16:33:13 -04:00
for (int i = 0; i < asset->itemCount; ++i)
2017-02-25 14:55:04 -05:00
{
if (asset->items[i])
{
buffer->align(Utils::Stream::ALIGN_4);
2018-05-09 08:33:52 -04:00
this->save_itemDef_s(asset->items[i], builder);
2017-02-25 14:55:04 -05:00
}
}
}
#ifdef WRITE_LOGS
buffer->leaveStruct();
#endif
2017-02-25 14:55:04 -05:00
buffer->popBlock();
}
}