some debugging features added to debug PartialRenderPolicy.

This commit is contained in:
rachytski 2011-11-09 14:57:10 +04:00 committed by Alex Zolotarev
parent 47ec490ffd
commit b745266831
15 changed files with 286 additions and 102 deletions

View file

@ -15,14 +15,17 @@ PartialRenderPolicy::PartialRenderPolicy(shared_ptr<WindowHandle> const & wh,
void PartialRenderPolicy::Initialize(shared_ptr<yg::gl::RenderContext> const & rc,
shared_ptr<yg::ResourceManager> const & rm)
{
m_renderQueue.SetGLQueue(&m_glQueue);
m_renderQueue.SetGLQueue(&m_glQueue, &m_glCondition);
RenderPolicyMT::Initialize(rc, rm);
}
void PartialRenderPolicy::ProcessRenderQueue(list<yg::gl::Renderer::Packet> & renderQueue)
{
if (renderQueue.empty())
{
m_hasPacket = false;
m_glCondition.Signal();
}
else
{
m_hasPacket = true;
@ -44,10 +47,10 @@ void PartialRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & paintEvent,
screen->getState(m_state.get());
shared_ptr<yg::gl::Renderer::BaseState> curState = m_state;
m_curState = m_state;
unsigned cmdProcessed = 0;
unsigned const maxCmdPerFrame = 1000;
unsigned const maxCmdPerFrame = 10;
while (true)
{
@ -58,8 +61,8 @@ void PartialRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & paintEvent,
cmdProcessed++;
if (m_currentPacket.m_state)
{
m_currentPacket.m_state->apply(curState.get());
curState = m_currentPacket.m_state;
m_currentPacket.m_state->apply(m_curState.get());
m_curState = m_currentPacket.m_state;
}
m_currentPacket.m_command->perform();
}
@ -70,24 +73,36 @@ void PartialRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & paintEvent,
/// should we continue drawing commands on the next frame
if ((cmdProcessed == maxCmdPerFrame) && m_hasPacket)
{
LOG(LINFO, ("will continue on the next frame"));
windowHandle()->invalidate();
LOG(LINFO, ("will continue on the next frame(", cmdProcessed, ")"));
}
else
LOG(LINFO, ("finished sequence of commands"));
LOG(LINFO, ("finished sequence of commands(", cmdProcessed, ")"));
// OGLCHECK(glFinish());
{
threads::ConditionGuard guard(m_glCondition);
if (m_glQueue.Empty())
guard.Signal();
}
m_state->apply(curState.get());
OGLCHECK(glFinish());
// LOG(LINFO, (cmdProcessed, " commands processed"));
m_state->apply(m_curState.get());
// OGLCHECK(glFinish());
OGLCHECK(glFinish());
/// blitting from the current surface onto screen
RenderPolicyMT::DrawFrame(paintEvent, screenBase);
// OGLCHECK(glFinish());
OGLCHECK(glFinish());
}
void PartialRenderPolicy::EndFrame(shared_ptr<PaintEvent> const & paintEvent,
ScreenBase const & screenBase)
{
RenderPolicyMT::EndFrame(paintEvent, screenBase);
LOG(LINFO, ("-------EndFrame-------"));
}
bool PartialRenderPolicy::NeedRedraw() const
{

View file

@ -11,8 +11,10 @@ class PartialRenderPolicy : public RenderPolicyMT
private:
ThreadedList<yg::gl::Renderer::Packet> m_glQueue;
threads::Condition m_glCondition;
yg::gl::Renderer::Packet m_currentPacket;
shared_ptr<yg::gl::Screen::BaseState> m_curState;
bool m_hasPacket;
shared_ptr<yg::gl::Renderer::BaseState> m_state;
@ -30,5 +32,8 @@ public:
void DrawFrame(shared_ptr<PaintEvent> const & paintEvent,
ScreenBase const & screenBase);
void EndFrame(shared_ptr<PaintEvent> const & paintEvent,
ScreenBase const & screenBase);
bool NeedRedraw() const;
};

View file

@ -3,6 +3,9 @@
#include "render_policy.hpp"
#include "window_handle.hpp"
RenderPolicy::~RenderPolicy()
{}
RenderPolicy::RenderPolicy(shared_ptr<WindowHandle> const & windowHandle,
TRenderFn const & renderFn,
bool doSupportRotation)

View file

@ -47,7 +47,8 @@ public:
/// constructor
RenderPolicy(shared_ptr<WindowHandle> const & windowHandle, TRenderFn const & renderFn, bool doSupportRotation);
virtual ~RenderPolicy() {}
/// destructor
virtual ~RenderPolicy();
/// starting frame
virtual void BeginFrame(shared_ptr<PaintEvent> const & e, ScreenBase const & s);
/// drawing single frame

View file

@ -122,8 +122,9 @@ void RenderQueue::WaitForEmptyAndFinished()
m_routine->waitForEmptyAndFinished();
}
void RenderQueue::SetGLQueue(ThreadedList<yg::gl::Renderer::Packet> * glQueue)
void RenderQueue::SetGLQueue(ThreadedList<yg::gl::Renderer::Packet> * glQueue,
threads::Condition * glCondition)
{
m_routine->SetGLQueue(glQueue);
m_routine->setGLQueue(glQueue, glCondition);
}

View file

@ -77,5 +77,6 @@ public:
void WaitForEmptyAndFinished();
void SetGLQueue(ThreadedList<yg::gl::Renderer::Packet> * glQueue);
void SetGLQueue(ThreadedList<yg::gl::Renderer::Packet> * glQueue,
threads::Condition * glCondition);
};

View file

@ -68,12 +68,7 @@ void RenderQueueRoutine::onSize(int w, int h)
m_newDepthBuffer.reset(new yg::gl::RenderBuffer(texW, texH, true));
m_newActualTarget = m_resourceManager->createRenderTarget(texW, texH);
m_newBackBufferLayers.clear();
m_newBackBufferLayers.resize(m_renderState->m_backBufferLayers.size());
for (unsigned i = 0; i < m_renderState->m_backBufferLayers.size(); ++i)
m_newBackBufferLayers[i] = m_resourceManager->createRenderTarget(texW, texH);
m_newBackBuffer = m_resourceManager->createRenderTarget(texW, texH);
}
void RenderQueueRoutine::processResize(ScreenBase const & frameScreen)
@ -109,27 +104,25 @@ void RenderQueueRoutine::processResize(ScreenBase const & frameScreen)
}
m_auxScreen->endFrame();
for (size_t i = 0; i < m_renderState->m_backBufferLayers.size(); ++i)
shared_ptr<yg::gl::BaseTexture> oldBackBuffer = m_renderState->m_backBuffer;
m_renderState->m_backBuffer.reset();
m_renderState->m_backBuffer = m_newBackBuffer;
m_newBackBuffer.reset();
m_auxScreen->setRenderTarget(m_renderState->m_backBuffer);
m_auxScreen->beginFrame();
m_auxScreen->clear(m_bgColor);
if (oldBackBuffer != 0)
{
shared_ptr<yg::gl::BaseTexture> oldBackBuffer = m_renderState->m_backBufferLayers[i];
m_renderState->m_backBufferLayers[i].reset();
m_renderState->m_backBufferLayers[i] = m_newBackBufferLayers[i];
m_newBackBufferLayers[i].reset();
m_auxScreen->setRenderTarget(m_renderState->m_backBufferLayers[i]);
m_auxScreen->beginFrame();
m_auxScreen->clear(m_bgColor);
if (oldBackBuffer != 0)
{
m_auxScreen->blit(oldBackBuffer,
m_renderState->m_actualScreen,
frameScreen);
oldBackBuffer.reset();
}
m_auxScreen->endFrame();
m_renderState->m_actualScreen = frameScreen;
m_auxScreen->blit(oldBackBuffer,
m_renderState->m_actualScreen,
frameScreen);
oldBackBuffer.reset();
}
m_auxScreen->endFrame();
/// TODO : make as a command
m_renderState->m_actualScreen = frameScreen;
m_renderState->m_isResized = false;
}
@ -187,39 +180,7 @@ void RenderQueueRoutine::getUpdateAreas(
areas.push_back(m2::RectI((int)leftBarMinX, (int)bottomBarMinY, (int)rightBarMinX, (int)bottomBarMaxY));
}
else
{
areas.push_back(newRect);
/* int rectW = (w + 9) / 5;
int rectH = (h + 9) / 5;
m2::RectI r( 2 * rectW, 2 * rectH, 3 * rectW, 3 * rectH);
areas.push_back(r);
areas.push_back(m2::Offset(r, -rectW, 0));
areas.push_back(m2::Offset(r, -rectW, -rectH));
areas.push_back(m2::Offset(r, 0, -rectH));
areas.push_back(m2::Offset(r, rectW, -rectH));
areas.push_back(m2::Offset(r, rectW, 0));
areas.push_back(m2::Offset(r, rectW, rectH));
areas.push_back(m2::Offset(r, 0, rectH));
areas.push_back(m2::Offset(r, -rectW, rectH));
areas.push_back(m2::Offset(r, -2 * rectW, rectH));
areas.push_back(m2::Offset(r, -2 * rectW, 0));
areas.push_back(m2::Offset(r, -2 * rectW, -rectH));
areas.push_back(m2::Offset(r, -2 * rectW, -2*rectH));
areas.push_back(m2::Offset(r, -rectW, -2*rectH));
areas.push_back(m2::Offset(r, 0, -2*rectH));
areas.push_back(m2::Offset(r, rectW, -2*rectH));
areas.push_back(m2::Offset(r, 2 * rectW, -2*rectH));
areas.push_back(m2::Offset(r, 2 * rectW, -rectH));
areas.push_back(m2::Offset(r, 2 * rectW, 0));
areas.push_back(m2::Offset(r, 2 * rectW, rectH));
areas.push_back(m2::Offset(r, 2 * rectW, 2*rectH));
areas.push_back(m2::Offset(r, rectW, 2*rectH));
areas.push_back(m2::Offset(r, 0, 2*rectH));
areas.push_back(m2::Offset(r, -rectW, 2*rectH));
areas.push_back(m2::Offset(r, -2*rectW, 2*rectH));
*/
}
}
void RenderQueueRoutine::setVisualScale(double visualScale)
@ -240,7 +201,8 @@ void RenderQueueRoutine::waitForRenderCommand(list<shared_ptr<RenderModelCommand
void RenderQueueRoutine::Do()
{
m_renderContext->makeCurrent();
if (!m_glQueue)
m_renderContext->makeCurrent();
DrawerYG::params_t params;
@ -379,7 +341,7 @@ void RenderQueueRoutine::Do()
{
/// this fixes some strange issue with multisampled framebuffer.
/// setRenderTarget should be made here.
m_threadDrawer->screen()->setRenderTarget(m_renderState->m_backBufferLayers.front());
m_threadDrawer->screen()->setRenderTarget(m_renderState->m_backBuffer);
m_threadDrawer->beginFrame();
@ -424,6 +386,28 @@ void RenderQueueRoutine::Do()
}
}
// if (m_currentRenderCommand->m_paintEvent->isCancelled())
// {
// /// cancelling all the commands in the queue
// if (m_glQueue)
// {
// m_glQueue->Clear();
//
// {
// threads::ConditionGuard guard(*m_glCondition);
// if (m_glQueue->Empty())
// guard.Wait();
// }
// }
//
// {
// threads::MutexGuard guard(*m_renderState->m_mutex.get());
// /// refreshing shadow parameters from the primary parameters
// m_renderState->m_shadowActualTarget = m_renderState->m_actualTarget;
// m_renderState->m_shadowBackBuffer = m_renderState->m_backBuffer;
// }
// }
/// if something were actually drawn, or (exclusive or) we are repainting the whole rect
if ((!m_renderState->m_isEmptyModelCurrent) || (fullRectRepaint))
m_renderState->m_isEmptyModelActual = m_renderState->m_isEmptyModelCurrent;
@ -440,10 +424,6 @@ void RenderQueueRoutine::Do()
if (!IsCancelled())
{
/// We shouldn't update the actual target as it's already happened (through callback function)
/// in the endFrame function
/// updateActualTarget();
{
threads::ConditionGuard g1(m_hasRenderCommands);
@ -465,7 +445,8 @@ void RenderQueueRoutine::Do()
// By VNG: We can't destroy render context in drawing thread.
// Notify render context instead.
m_renderContext->endThreadDrawing();
if (!m_glQueue)
m_renderContext->endThreadDrawing();
}
void RenderQueueRoutine::addWindowHandle(shared_ptr<WindowHandle> window)
@ -473,11 +454,27 @@ void RenderQueueRoutine::addWindowHandle(shared_ptr<WindowHandle> window)
m_windowHandles.push_back(window);
}
void RenderQueueRoutine::Invalidate::perform()
{
if (isDebugging())
LOG(LINFO, ("performing Invalidate command"));
for_each(m_windowHandles.begin(),
m_windowHandles.end(),
bind(&WindowHandle::invalidate, _1));
}
void RenderQueueRoutine::invalidate()
{
for_each(m_windowHandles.begin(),
m_windowHandles.end(),
bind(&WindowHandle::invalidate, _1));
if (m_glQueue)
{
shared_ptr<Invalidate> command(new Invalidate());
command->m_windowHandles = m_windowHandles;
m_glQueue->PushBack(yg::gl::Renderer::Packet(command));
}
}
void RenderQueueRoutine::addCommand(render_fn_t const & fn, ScreenBase const & frameScreen)
@ -536,7 +533,9 @@ void RenderQueueRoutine::waitForEmptyAndFinished()
guard.Wait();
}
void RenderQueueRoutine::SetGLQueue(ThreadedList<yg::gl::Renderer::Packet> * glQueue)
void RenderQueueRoutine::setGLQueue(ThreadedList<yg::gl::Renderer::Packet> * glQueue,
threads::Condition * glCondition)
{
m_glQueue = glQueue;
m_glCondition = glCondition;
}

View file

@ -8,6 +8,7 @@
#include "../std/list.hpp"
#include "../std/function.hpp"
#include "../yg/color.hpp"
#include "../yg/renderer.hpp"
class DrawerYG;
@ -30,7 +31,6 @@ namespace yg
class RenderBuffer;
class BaseTexture;
class RenderState;
class RenderState;
class Screen;
}
}
@ -52,16 +52,24 @@ private:
render_fn_t renderFn);
};
struct Invalidate : public yg::gl::Renderer::Command
{
list<shared_ptr<WindowHandle> > m_windowHandles;
void perform();
};
shared_ptr<yg::gl::RenderContext> m_renderContext;
shared_ptr<yg::gl::FrameBuffer> m_frameBuffer;
shared_ptr<yg::gl::FrameBuffer> m_auxFrameBuffer;
shared_ptr<yg::gl::RenderBuffer> m_newDepthBuffer;
shared_ptr<yg::gl::BaseTexture> m_newActualTarget;
vector<shared_ptr<yg::gl::BaseTexture> > m_newBackBufferLayers;
shared_ptr<DrawerYG> m_threadDrawer;
shared_ptr<yg::gl::Screen> m_auxScreen;
shared_ptr<yg::gl::RenderBuffer> m_newDepthBuffer;
shared_ptr<yg::gl::BaseTexture> m_newActualTarget;
shared_ptr<yg::gl::BaseTexture> m_newBackBuffer;
threads::Condition m_hasRenderCommands;
threads::Condition * m_glCondition;
shared_ptr<RenderModelCommand> m_currentRenderCommand;
list<shared_ptr<RenderModelCommand> > m_renderCommands;
@ -131,5 +139,6 @@ public:
/// wait for all commands are processed.
void waitForEmptyAndFinished();
void SetGLQueue(ThreadedList<yg::gl::Renderer::Packet> * glQueue);
void setGLQueue(ThreadedList<yg::gl::Renderer::Packet> * glQueue,
threads::Condition * glCondition);
};

View file

@ -23,19 +23,22 @@ namespace yg
{
if (m_isClippingEnabled)
{
// LOG(LINFO, ("enabling scissors"));
if (m_isDebugging)
LOG(LINFO, ("enabling scissors"));
OGLCHECK(glEnable(GL_SCISSOR_TEST));
}
else
{
// LOG(LINFO, ("disabling scissors"));
if (m_isDebugging)
LOG(LINFO, ("disabling scissors"));
OGLCHECK(glDisable(GL_SCISSOR_TEST));
}
}
if (state->m_clipRect != m_clipRect)
{
// LOG(LINFO, ("scissorRect(", m_clipRect.minX(), m_clipRect.minY(), m_clipRect.maxX(), m_clipRect.maxY(), ")"));
if (m_isDebugging)
LOG(LINFO, ("scissor(", m_clipRect.minX(), m_clipRect.minY(), m_clipRect.maxX(), m_clipRect.maxY(), ")"));
OGLCHECK(glScissor(m_clipRect.minX(), m_clipRect.minY(), m_clipRect.SizeX(), m_clipRect.SizeY()));
}
}

View file

@ -13,7 +13,6 @@ namespace yg
: m_actualInfoLayer(new yg::InfoLayer()),
m_isEmptyModelActual(false),
m_currentInfoLayer(new yg::InfoLayer()),
m_backBufferLayers(1),
m_isEmptyModelCurrent(false),
m_isResized(false),
m_doRepaintAll(false),

View file

@ -42,7 +42,7 @@ namespace yg
/// information layer
shared_ptr<yg::InfoLayer> m_currentInfoLayer;
/// at least one backBuffer layer
vector<shared_ptr<BaseTexture> > m_backBufferLayers;
shared_ptr<BaseTexture> m_backBuffer;
/// depth buffer used for rendering
shared_ptr<RenderBuffer> m_depthBuffer;
/// Duration of the rendering operation

View file

@ -51,8 +51,11 @@ namespace yg
void RenderStateUpdater::UpdateActualTarget::perform()
{
OGLCHECK(glFinish());
if (m_doSynchronize)
m_renderState->m_mutex->Lock();
swap(m_renderState->m_actualTarget, m_renderState->m_backBuffer);
m_renderState->m_actualScreen = m_currentScreen;
if (m_doSynchronize)
m_renderState->m_mutex->Unlock();
@ -63,11 +66,15 @@ namespace yg
if (isDebugging())
LOG(LINFO, ("performing UpdateBackBuffer command"));
if (m_doSynchronize)
m_renderState->m_mutex->Lock();
OGLCHECK(glFinish());
OGLCHECK(glDisable(GL_SCISSOR_TEST));
OGLCHECK(glClearColor(192 / 255.0, 192 / 255.0, 192 / 255.0, 1.0));
OGLCHECK(glClear(GL_COLOR_BUFFER_BIT));
shared_ptr<IMMDrawTexturedRect> immDrawTexturedRect(
@ -83,6 +90,12 @@ namespace yg
OGLCHECK(glFinish());
if (m_doSynchronize)
m_renderState->m_mutex->Unlock();
}
void RenderStateUpdater::Invalidate::perform()
{
m_renderState->invalidate();
}
@ -93,8 +106,6 @@ namespace yg
m_renderState->m_mutex->Lock();
swap(m_renderState->m_actualTarget, m_renderState->m_backBufferLayers.front());
shared_ptr<UpdateActualTarget> command(new UpdateActualTarget());
command->m_renderState = m_renderState;
command->m_currentScreen = m_renderState->m_currentScreen;
@ -107,15 +118,22 @@ namespace yg
command1->m_renderState = m_renderState;
command1->m_resourceManager = resourceManager();
command1->m_isClipRectEnabled = clipRectEnabled();
command1->m_doSynchronize = renderQueue();
/// blitting will be performed through
/// non-multisampled framebuffer for the sake of speed
setRenderTarget(m_renderState->m_backBufferLayers.front());
setRenderTarget(m_renderState->m_backBuffer);
// m_renderState->m_actualScreen = m_renderState->m_currentScreen;
m_renderState->m_mutex->Unlock();
processCommand(command1);
m_renderState->invalidate();
shared_ptr<Invalidate> command2(new Invalidate());
command2->m_renderState = m_renderState;
processCommand(command2);
}
void RenderStateUpdater::beginFrame()

View file

@ -40,10 +40,17 @@ namespace yg
shared_ptr<RenderState> m_renderState;
shared_ptr<ResourceManager> m_resourceManager;
bool m_isClipRectEnabled;
bool m_doSynchronize;
void perform();
};
struct Invalidate : base_t::Command
{
shared_ptr<RenderState> m_renderState;
void perform();
};
public:
struct Params : base_t::Params

View file

@ -11,6 +11,10 @@ namespace yg
{
namespace gl
{
Renderer::BaseState::BaseState()
: m_isDebugging(false)
{}
Renderer::BaseState::~BaseState()
{}
@ -36,24 +40,134 @@ namespace yg
if (m_frameBuffer == prevState->m_frameBuffer)
{
// LOG(LINFO, ("equal framebuffers"));
if (m_isDebugging)
{
std::ostringstream out;
out << "equal frameBuffers, ";
if (m_frameBuffer)
out << m_frameBuffer->id() << ", " << prevState->m_frameBuffer->id();
else
out << "(null), (null)";
LOG(LINFO, (out.str().c_str()));
}
if (m_renderTarget != prevState->m_renderTarget)
{
// LOG(LINFO, ("non-equal renderbuffers, ", m_renderTarget.get(), prevState->m_renderTarget.get()));
if (m_isDebugging)
{
std::ostringstream out;
out << "non-equal renderBuffers, ";
if (prevState->m_renderTarget)
out << prevState->m_renderTarget->id();
else
out << "(null)";
out << " => ";
if (m_renderTarget)
out << m_renderTarget->id();
else
out << "(null)";
LOG(LINFO, (out.str().c_str()));
}
m_frameBuffer->setRenderTarget(m_renderTarget);
shouldApply = true;
}
else
{
if (m_isDebugging)
{
std::ostringstream out;
out << "equal renderBuffers, ";
if (m_renderTarget)
out << m_renderTarget->id() << ", " << m_renderTarget->id();
else
out << "(null), (null)";
LOG(LINFO, (out.str().c_str()));
}
}
if (m_depthBuffer != prevState->m_depthBuffer)
{
// LOG(LINFO, ("non-equal depthbuffers, ", m_depthBuffer.get(), prevState->m_depthBuffer.get()));
if (m_isDebugging)
{
std::ostringstream out;
out << "non-equal depthBuffers, ";
if (prevState->m_depthBuffer)
out << prevState->m_depthBuffer->id();
else
out << "(null)";
out << " => ";
if (m_depthBuffer)
out << m_depthBuffer->id();
else
out << "(null)";
LOG(LINFO, (out.str().c_str()));
}
m_frameBuffer->setDepthBuffer(m_depthBuffer);
shouldApply = true;
}
else
{
if (m_isDebugging)
{
std::ostringstream out;
out << "equal depthBuffers, ";
if (m_depthBuffer)
out << m_depthBuffer->id() << ", " << m_depthBuffer->id();
else
out << "(null), (null)";
LOG(LINFO, (out.str().c_str()));
}
}
}
else
{
// LOG(LINFO, ("non-equal framebuffers"));
if (m_isDebugging)
{
ostringstream out;
out << "non-equal frameBuffers, ";
if (prevState->m_frameBuffer)
out << prevState->m_frameBuffer->id() << ", ";
else
out << "(null)";
out << " => ";
if (m_frameBuffer)
out << m_frameBuffer->id() << ", ";
else
out << "(null)";
LOG(LINFO, (out.str().c_str()));
out.str("");
out << "renderTarget=";
if (m_renderTarget)
out << m_renderTarget->id();
else
out << "(null)";
out << ", depthBuffer=";
if (m_depthBuffer)
out << m_depthBuffer->id();
else
out << "(null)";
LOG(LINFO, (out.str().c_str()));
}
m_frameBuffer->setRenderTarget(m_renderTarget);
m_frameBuffer->setDepthBuffer(m_depthBuffer);
shouldApply = true;
@ -69,10 +183,17 @@ namespace yg
Renderer::Packet::Packet()
{}
Renderer::Packet::Packet(shared_ptr<Command> const & command)
: m_command(command)
{}
Renderer::Packet::Packet(shared_ptr<BaseState> const & state,
shared_ptr<Command> const & command)
: m_state(state), m_command(command)
{}
{
if (m_state && m_command)
m_state->m_isDebugging = m_command->isDebugging();
}
Renderer::Params::Params()
: m_isDebugging(false),
@ -189,7 +310,6 @@ namespace yg
command->m_clearRT = clearRT;
command->m_depth = depth;
command->m_clearDepth = clearDepth;
command->m_isDebugging = renderQueue();
processCommand(command);
}

View file

@ -23,6 +23,8 @@ namespace yg
struct BaseState
{
bool m_isDebugging;
BaseState();
virtual ~BaseState();
virtual void apply(BaseState const * prev) = 0;
};
@ -58,6 +60,7 @@ namespace yg
shared_ptr<BaseState> m_state;
shared_ptr<Command> m_command;
Packet();
Packet(shared_ptr<Command> const & command);
Packet(shared_ptr<BaseState> const & state,
shared_ptr<Command> const & command);
};