text:
const float D3D12PipelineStateCache::IntermediateClearColor[4] = { 0.0f, 0.2f, 0.3f, 1.0f };

D3D12PipelineStateCache::D3D12PipelineStateCache(UINT width, UINT height, std::wstring name) :
    DXSample(width, height, name),
    m_psoLibrary(FrameCount, RootParameterUberShaderCB),
    m_frameIndex(0),
    m_swapChainEvent(0),
    m_drawIndex(0),
    m_maxDrawsPerFrame(256),
    m_dynamicCB(sizeof(DrawConstantBuffer), m_maxDrawsPerFrame, FrameCount),
    m_viewport(0.0f, 0.0f, static_cast<float>(width), static_cast<float>(height)),
    m_scissorRect(0, 0, static_cast<LONG>(width), static_cast<LONG>(height)),
    m_rtvDescriptorSize(0),
    m_srvDescriptorSize(0),
    m_fenceValues{}
{
    memset(m_enabledEffects, true, sizeof(m_enabledEffects));
}

void D3D12PipelineStateCache::OnInit()
{
    UpdateWindowTextPso();
    m_camera.Init({ 0.0f, 0.0f, 5.0f });
    m_camera.SetMoveSpeed(1.0f);

    m_projectionMatrix = m_camera.GetProjectionMatrix(0.8f, m_aspectRatio);

    LoadPipeline();
    LoadAssets();
}

// Load the rendering pipeline dependencies.
void D3D12PipelineStateCache::LoadPipeline()
{
    UINT dxgiFactoryFlags = 0;

#if defined(_DEBUG)
    // Enable the debug layer (requires the Graphics Tools "optional feature").
    // NOTE: Enabling the debug layer after device creation will invalidate the active device.
    {
        ComPtr<ID3D12Debug> debugController;
        if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
        {
            debugController->EnableDebugLayer();

            // Enable additional debug layers.
            dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG;
        }
    }
#endif

    ComPtr<IDXGIFactory4> factory;
    ThrowIfFailed(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory)));

    if (m_useWarpDevice)
    {
        ComPtr<IDXGIAdapter> warpAdapter;
        ThrowIfFailed(factory->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));

        ThrowIfFailed(D3D12CreateDevice(
            warpAdapter.Get(),
            D3D_FEATURE_LEVEL_11_0,
            IID_PPV_ARGS(&m_device)
            ));
    }
    else
    {
        ComPtr<IDXGIAdapter1> hardwareAdapter;
        GetHardwareAdapter(factory.Get(), &hardwareAdapter);

        ThrowIfFailed(D3D12CreateDevice(
            hardwareAdapter.Get(),
            D3D_FEATURE_LEVEL_11_0,
            IID_PPV_ARGS(&m_device)
            ));
    }

    // Describe and create the command queue.
    D3D12_COMMAND_QUEUE_DESC queueDesc = {};
    queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
    queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;

    ThrowIfFailed(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_commandQueue)));
    NAME_D3D12_OBJECT(m_commandQueue);

    // Describe and create the swap chain.
    DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
    swapChainDesc.BufferCount = FrameCount;
    swapChainDesc.Width = m_width;
    swapChainDesc.Height = m_height;
    swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;

    ComPtr<IDXGISwapChain1> swapChain;
    ThrowIfFailed(factory->CreateSwapChainForHwnd(
        m_commandQueue.Get(),        // Swap chain needs the queue so that it can force a flush on it.
        Win32Application::GetHwnd(),
        &swapChainDesc,
        nullptr,
        nullptr,
        &swapChain
        ));

    // This sample does not support fullscreen transitions.
    ThrowIfFailed(factory->MakeWindowAssociation(Win32Application::GetHwnd(), DXGI_MWA_NO_ALT_ENTER));

    ThrowIfFailed(swapChain.As(&m_swapChain));
    m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();
    m_swapChainEvent = m_swapChain->GetFrameLatencyWaitableObject();

    // Create descriptor heaps.
    {
        // Describe and create a render target view (RTV) descriptor heap.
        D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
        rtvHeapDesc.NumDescriptors = FrameCount + 1;    // A descriptor for each frame + 1 intermediate render target.
        rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
        rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
        ThrowIfFailed(m_device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_rtvHeap)));

        // Describe and create a shader resource view (SRV) descriptor heap.
        D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {};
        srvHeapDesc.NumDescriptors = 1;
        srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
        srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
        ThrowIfFailed(m_device->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&m_srvHeap)));
        NAME_D3D12_OBJECT(m_srvHeap);

        m_rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
        m_srvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
    }

    // Create frame resources.
    {
        CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart());

        // Create RTVs and a command allocator for each frame.
        for (UINT n = 0; n < FrameCount; n++)
        {
            ThrowIfFailed(m_swapChain->GetBuffer(n, IID_PPV_ARGS(&m_renderTargets[n])));
            m_device->CreateRenderTargetView(m_renderTargets[n].Get(), nullptr, rtvHandle);
            rtvHandle.Offset(1, m_rtvDescriptorSize);

            NAME_D3D12_OBJECT_INDEXED(m_renderTargets, n);

            ThrowIfFailed(m_device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&m_commandAllocators[n])));
        }

        D3D12_RESOURCE_DESC renderTargetDesc = m_renderTargets[0]->GetDesc();

        D3D12_CLEAR_VALUE clearValue = {};
        memcpy(clearValue.Color, IntermediateClearColor, sizeof(IntermediateClearColor));
        clearValue.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

        // Create an intermediate render target that is the same dimensions as the swap chain.
        ThrowIfFailed(m_device->CreateCommittedResource(
            &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
            D3D12_HEAP_FLAG_NONE,
            &renderTargetDesc,
            D3D12_RESOURCE_STATE_RENDER_TARGET,
            &clearValue,
            IID_PPV_ARGS(&m_intermediateRenderTarget)));

        NAME_D3D12_OBJECT(m_intermediateRenderTarget);

        m_device->CreateRenderTargetView(m_intermediateRenderTarget.Get(), nullptr, rtvHandle);
        rtvHandle.Offset(1, m_rtvDescriptorSize);

        // Create a SRV of the intermediate render target.
        D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
        srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
        srvDesc.Format = renderTargetDesc.Format;
        srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
        srvDesc.Texture2D.MipLevels = 1;

        CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(m_srvHeap->GetCPUDescriptorHandleForHeapStart());
        m_device->CreateShaderResourceView(m_intermediateRenderTarget.Get(), &srvDesc, srvHandle);
    }
}

void D3D12PipelineStateCache::LoadAssets()
{
    // Create the root signature.
    {
        D3D12_FEATURE_DATA_ROOT_SIGNATURE featureData = {};

        // This is the highest version the sample supports. If CheckFeatureSupport succeeds, the HighestVersion returned will not be greater than this.
        featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1;

        if (FAILED(m_device->CheckFeatureSupport(D3D12_FEATURE_ROOT_SIGNATURE, &featureData, sizeof(featureData))))
        {
            featureData.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_0;
        }

        // We don't modify the SRV in the command list after SetGraphicsRootDescriptorTable
        // is executed on the GPU so we can use the default range behavior:
        // D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE
        CD3DX12_DESCRIPTOR_RANGE1 ranges[RootParametersCount];
        ranges[RootParameterSRV].Init(D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 1, 0);

        CD3DX12_ROOT_PARAMETER1 rootParameters[RootParametersCount];
        rootParameters[RootParameterUberShaderCB].InitAsConstantBufferView(0, 0, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, D3D12_SHADER_VISIBILITY_ALL);
        rootParameters[RootParameterCB].InitAsConstantBufferView(1, 0, D3D12_ROOT_DESCRIPTOR_FLAG_DATA_STATIC, D3D12_SHADER_VISIBILITY_ALL);
        rootParameters[RootParameterSRV].InitAsDescriptorTable(1, &ranges[RootParameterSRV], D3D12_SHADER_VISIBILITY_PIXEL);

        D3D12_STATIC_SAMPLER_DESC sampler = {};
        sampler.Filter = D3D12_FILTER_MIN_MAG_MIP_POINT;
        sampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
        sampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
        sampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_BORDER;
        sampler.MipLODBias = 0;
        sampler.MaxAnisotropy = 0;
        sampler.ComparisonFunc = D3D12_COMPARISON_FUNC_NEVER;
        sampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
        sampler.MinLOD = 0.0f;
        sampler.MaxLOD = 9999.0f;
        sampler.ShaderRegister = 0;
        sampler.RegisterSpace = 0;
        sampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL;

        CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC rootSignatureDesc;
        rootSignatureDesc.Init_1_1(_countof(rootParameters), rootParameters, 1, &sampler, D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT);

        ComPtr<ID3DBlob> signature;
        ComPtr<ID3DBlob> error;
        ThrowIfFailed(D3DX12SerializeVersionedRootSignature(&rootSignatureDesc, featureData.HighestVersion, &signature, &error));
        ThrowIfFailed(m_device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), IID_PPV_ARGS(&m_rootSignature)));
        NAME_D3D12_OBJECT(m_rootSignature);
    }

    // Create the command list.
    ThrowIfFailed(m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_commandAllocators[m_frameIndex].Get(), nullptr, IID_PPV_ARGS(&m_commandList)));
    NAME_D3D12_OBJECT(m_commandList);

    // Note: ComPtr's are CPU objects but this resource needs to stay in scope until
    // the command list that references it has finished executing on the GPU.
    // We will flush the GPU at the end of this method to ensure the resource is not
    // prematurely destroyed.
    ComPtr<ID3D12Resource> vertexIndexBufferUpload;

    // Vertex and Index Buffer.
    {
        const VertexPositionColor cubeVertices[] = {
            { { -1.0f, 1.0f, -1.0f, 1.0f }, { GetRandomColor(),GetRandomColor(), GetRandomColor() } },    // Back Top Left
            { { 1.0f, 1.0f, -1.0f, 1.0f }, { GetRandomColor(), GetRandomColor(), GetRandomColor() } },    // Back Top Right
            { { 1.0f, 1.0f, 1.0f, 1.0f }, { GetRandomColor(), GetRandomColor(), GetRandomColor() } },    // Front Top Right
            { { -1.0f, 1.0f, 1.0f, 1.0f }, { GetRandomColor(), GetRandomColor(), GetRandomColor() } },    // Front Top Left

            { { -1.0f, -1.0f, -1.0f, 1.0f }, { GetRandomColor(),GetRandomColor(), GetRandomColor() } },    // Back Bottom Left
            { { 1.0f, -1.0f, -1.0f, 1.0f }, { GetRandomColor(),GetRandomColor(), GetRandomColor() } },    // Back Bottom Right
            { { 1.0f, -1.0f, 1.0f, 1.0f }, { GetRandomColor(),GetRandomColor(), GetRandomColor() } },    // Front Bottom Right
            { { -1.0f, -1.0f, 1.0f, 1.0f }, { GetRandomColor(),GetRandomColor(), GetRandomColor() } },    // Front Bottom Left
        };

        const UINT cubeIndices[] =
        {
            0, 1, 3,
            1, 2, 3,

            3, 2, 7,
            6, 7, 2,

            2, 1, 6,
            5, 6, 1,

            1, 0, 5,
            4, 5, 0,

            0, 3, 4,
            7, 4, 3,

            7, 6, 4,
            5, 4, 6,
        };

        static const VertexPositionUV quadVertices[] =
        {
            { { -1.0f, -1.0f, 0.0f, 1.0f }, { 0.0f, 1.0f } },    // Bottom Left
            { { -1.0f, 1.0f, 0.0f, 1.0f }, { 0.0f, 0.0f } },    // Top Left
            { { 1.0f, -1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f } },    // Bottom Right
            { { 1.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, 0.0f } },        // Top Right
        };

        const UINT vertexIndexBufferSize = sizeof(cubeIndices) + sizeof(cubeVertices) + sizeof(quadVertices);

        ThrowIfFailed(m_device->CreateCommittedResource(
            &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
            D3D12_HEAP_FLAG_NONE,
            &CD3DX12_RESOURCE_DESC::Buffer(vertexIndexBufferSize),
            D3D12_RESOURCE_STATE_COPY_DEST,
            nullptr,
            IID_PPV_ARGS(&m_vertexIndexBuffer)));

        ThrowIfFailed(m_device->CreateCommittedResource(
            &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD),
            D3D12_HEAP_FLAG_NONE,
            &CD3DX12_RESOURCE_DESC::Buffer(vertexIndexBufferSize),
            D3D12_RESOURCE_STATE_GENERIC_READ,
            nullptr,
            IID_PPV_ARGS(&vertexIndexBufferUpload)));

        NAME_D3D12_OBJECT(m_vertexIndexBuffer);

        UINT8* mappedUploadHeap = nullptr;
        CD3DX12_RANGE readRange(0, 0);        // We do not intend to read from this resource on the CPU.
        ThrowIfFailed(vertexIndexBufferUpload->Map(0, &readRange, reinterpret_cast<void**>(&mappedUploadHeap)));

        // Fill in part of the upload heap with our index and vertex data.
        UINT8* heapLocation = static_cast<UINT8*>(mappedUploadHeap);
        memcpy(heapLocation, cubeVertices, sizeof(cubeVertices));
        heapLocation += sizeof(cubeVertices);
        memcpy(heapLocation, cubeIndices, sizeof(cubeIndices));
        heapLocation += sizeof(cubeIndices);
        memcpy(heapLocation, quadVertices, sizeof(quadVertices));

        // Pack the vertices and indices into their destination by copying from the upload heap.
        m_commandList->CopyBufferRegion(m_vertexIndexBuffer.Get(), 0, vertexIndexBufferUpload.Get(), 0, vertexIndexBufferSize);
        m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_vertexIndexBuffer.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER | D3D12_RESOURCE_STATE_INDEX_BUFFER));

        // Create the index and vertex buffer views.
        m_cubeVbv.BufferLocation = m_vertexIndexBuffer.Get()->GetGPUVirtualAddress();
        m_cubeVbv.SizeInBytes = sizeof(cubeVertices);
        m_cubeVbv.StrideInBytes = sizeof(VertexPositionColor);

        m_cubeIbv.BufferLocation = m_cubeVbv.BufferLocation + sizeof(cubeVertices);
        m_cubeIbv.SizeInBytes = sizeof(cubeIndices);
        m_cubeIbv.Format = DXGI_FORMAT_R32_UINT;

        m_quadVbv.BufferLocation = m_cubeIbv.BufferLocation + sizeof(cubeIndices);
        m_quadVbv.SizeInBytes = sizeof(quadVertices);
        m_quadVbv.StrideInBytes = sizeof(VertexPositionUV);
    }

    // Create the constant buffer.
    m_dynamicCB.Init(m_device.Get());

    // Close the command list and execute it to begin the vertex/index buffer copy
    // into the default heap.
    ThrowIfFailed(m_commandList->Close());
    ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
    m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

    // Create synchronization objects and wait until assets have been uploaded to the GPU.
    {
        ThrowIfFailed(m_device->CreateFence(m_fenceValues[m_frameIndex], D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&m_fence)));
        m_fenceValues[m_frameIndex]++;

        // Create an event handle to use for frame synchronization.
        m_fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
        if (m_fenceEvent == nullptr)
        {
            ThrowIfFailed(HRESULT_FROM_WIN32(GetLastError()));
        }

        // Wait for the command list to execute; we are reusing the same command
        // list in our main loop but for now, we just want to wait for setup to
        // complete before continuing.
        WaitForGpu();
    }

    m_psoLibrary.Build(m_device.Get(), m_rootSignature.Get());
    UpdateWindowTextPso();
}

// Update frame-based values.
void D3D12PipelineStateCache::OnUpdate()
{
    // Wait for the previous Present to complete.
    WaitForSingleObjectEx(m_swapChainEvent, 100, FALSE);

    m_timer.Tick(NULL);
    m_camera.Update(static_cast<float>(m_timer.GetElapsedSeconds()));
}

// Render the scene.
void D3D12PipelineStateCache::OnRender()
{
    PIXBeginEvent(m_commandQueue.Get(), 0, L"Render");

    // Record all the commands we need to render the scene into the command list.
    PopulateCommandList();

    // Execute the command list.
    ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() };
    m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

    PIXEndEvent(m_commandQueue.Get());

    // Present the frame.
    ThrowIfFailed(m_swapChain->Present(1, 0));

    m_drawIndex = 0;
    m_psoLibrary.EndFrame();

    MoveToNextFrame();
}

void D3D12PipelineStateCache::OnDestroy()
{
    // Ensure that the GPU is no longer referencing resources that are about to be
    // cleaned up by the destructor.
    WaitForGpu();

    CloseHandle(m_fenceEvent);
}

void D3D12PipelineStateCache::OnKeyDown(UINT8 key)
{
    m_camera.OnKeyDown(key);
}

void D3D12PipelineStateCache::OnKeyUp(UINT8 key)
{
    m_camera.OnKeyUp(key);

    switch (key)
    {
    case 'C':
        WaitForGpu();
        m_psoLibrary.ClearPSOCache();
        m_psoLibrary.Build(m_device.Get(), m_rootSignature.Get());
        break;

    case 'U':
        m_psoLibrary.ToggleUberShader();
        break;

    case 'L':
        m_psoLibrary.ToggleDiskLibrary();
        break;

    case 'M':
        m_psoLibrary.SwitchPSOCachingMechanism();
        break;

    case '1':
        ToggleEffect(PostBlit);
        break;

    case '2':
        ToggleEffect(PostInvert);
        break;

    case '3':
        ToggleEffect(PostGrayScale);
        break;

    case '4':
        ToggleEffect(PostEdgeDetect);
        break;

    case '5':
        ToggleEffect(PostBlur);
        break;

    case '6':
        ToggleEffect(PostWarp);
        break;

    case '7':
        ToggleEffect(PostPixelate);
        break;

    case '8':
        ToggleEffect(PostDistort);
        break;

    case '9':
        ToggleEffect(PostWave);
        break;

    default:
        break;
    }

    UpdateWindowTextPso();
}

// Fill the command list with all the render commands and dependent state.
void D3D12PipelineStateCache::PopulateCommandList()
{
    // Command list allocators can only be reset when the associated
    // command lists have finished execution on the GPU; apps should use
    // fences to determine GPU execution progress.
    ThrowIfFailed(m_commandAllocators[m_frameIndex]->Reset());

    // However, when ExecuteCommandList() is called on a particular command
    // list, that command list can then be reset at any time and must be before
    // re-recording.
    ThrowIfFailed(m_commandList->Reset(m_commandAllocators[m_frameIndex].Get(), nullptr));

    // Set necessary state.
    m_commandList->SetGraphicsRootSignature(m_rootSignature.Get());

    ID3D12DescriptorHeap* ppHeaps[] = { m_srvHeap.Get() };
    m_commandList->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps);

    m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    m_commandList->RSSetViewports(1, &m_viewport);
    m_commandList->RSSetScissorRects(1, &m_scissorRect);

    CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_rtvDescriptorSize);
    CD3DX12_CPU_DESCRIPTOR_HANDLE intermediateRtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart(), FrameCount, m_rtvDescriptorSize);
    CD3DX12_GPU_DESCRIPTOR_HANDLE srvHandle(m_srvHeap->GetGPUDescriptorHandleForHeapStart());

    m_commandList->OMSetRenderTargets(1, &intermediateRtvHandle, FALSE, nullptr);

    // Record commands.
    m_commandList->ClearRenderTargetView(intermediateRtvHandle, IntermediateClearColor, 0, nullptr);

    // Draw the scene as normal into the intermediate buffer.
    PIXBeginEvent(m_commandList.Get(), 0, L"Draw cube");
    {
        static float rot = 0.0f;
        DrawConstantBuffer* drawCB = (DrawConstantBuffer*)m_dynamicCB.GetMappedMemory(m_drawIndex, m_frameIndex);
        drawCB->worldViewProjection = XMMatrixTranspose(XMMatrixRotationY(rot) * XMMatrixRotationX(-rot) * m_camera.GetViewMatrix() * m_projectionMatrix);

        rot += 0.01f;

        m_commandList->IASetVertexBuffers(0, 1, &m_cubeVbv);
        m_commandList->IASetIndexBuffer(&m_cubeIbv);
        m_psoLibrary.SetPipelineState(m_device.Get(), m_rootSignature.Get(), m_commandList.Get(), BaseNormal3DRender, m_frameIndex);

        m_commandList->SetGraphicsRootConstantBufferView(RootParameterCB, m_dynamicCB.GetGpuVirtualAddress(m_drawIndex, m_frameIndex));
        m_commandList->DrawIndexedInstanced(36, 1, 0, 0, 0);
        m_drawIndex++;
    }
    PIXEndEvent(m_commandList.Get());

    // Set up the state for a fullscreen quad.
    m_commandList->IASetVertexBuffers(0, 1, &m_quadVbv);
    m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);

    // Indicate that the back buffer will be used as a render target and the
    // intermediate render target will be used as a SRV.
    D3D12_RESOURCE_BARRIER barriers[] = {
        CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET),
        CD3DX12_RESOURCE_BARRIER::Transition(m_intermediateRenderTarget.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
    };

    m_commandList->ResourceBarrier(_countof(barriers), barriers);
    m_commandList->SetGraphicsRootDescriptorTable(RootParameterSRV, m_srvHeap->GetGPUDescriptorHandleForHeapStart());

    const float black[] = { 0.0f, 0.0f, 0.0f, 0.0f };
    m_commandList->ClearRenderTargetView(rtvHandle, black, 0, nullptr);
    m_commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);

    // Draw some quads using the rendered scene with some effect shaders.
    PIXBeginEvent(m_commandList.Get(), 0, L"Post-processing");
    {
        UINT quadCount = 0;
        static const UINT quadsX = 3;
        static const UINT quadsY = 3;

        // Cycle through all of the effects.
        for (UINT i = PostBlit; i < EffectPipelineTypeCount; i++)
        {
            if (m_enabledEffects[i])
            {
                CD3DX12_VIEWPORT viewport(
                    (quadCount % quadsX) * (m_viewport.Width / quadsX),
                    (quadCount / quadsY) * (m_viewport.Height / quadsY),
                    m_viewport.Width / quadsX,
                    m_viewport.Height / quadsY);

                PIXBeginEvent(m_commandList.Get(), 0, g_cEffectNames[i]);
                m_commandList->RSSetViewports(1, &viewport);
                m_psoLibrary.SetPipelineState(m_device.Get(), m_rootSignature.Get(), m_commandList.Get(), static_cast<EffectPipelineType>(i), m_frameIndex);
                m_commandList->DrawInstanced(4, 1, 0, 0);
                PIXEndEvent(m_commandList.Get());
            }

            quadCount++;
        }
    }
    PIXEndEvent(m_commandList.Get());

    // Revert resource states back to original values.
    barriers[0].Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
    barriers[0].Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
    barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE;
    barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;

    m_commandList->ResourceBarrier(_countof(barriers), barriers);

    ThrowIfFailed(m_commandList->Close());
}

void D3D12PipelineStateCache::ToggleEffect(EffectPipelineType type)
{
    if (m_enabledEffects[type])
    {
        // Wait until all frames using the shader are rendered before destroying
        // the shader.
        WaitForGpu();

        m_psoLibrary.DestroyShader(type);
    }

    m_enabledEffects[type] = !m_enabledEffects[type];
}

void D3D12PipelineStateCache::UpdateWindowTextPso()
{
    std::wstringstream stringStream;
    stringStream << L"  [Use Uber Shader: ";
    stringStream << (m_psoLibrary.UberShadersEnabled() ? L"true]" : L"false]");
    stringStream << L"   [Use DiskCache: ";

    if (m_psoLibrary.DiskCacheEnabled())
    {
        stringStream << L"true, ";
        switch (m_psoLibrary.GetPSOCachingMechanism())
        {
        case PSOCachingMechanism::CachedBlobs:
                stringStream << L"CachedBlobs]";
                break;
        case PSOCachingMechanism::PipelineLibraries:
            stringStream << L"PipelineLibraries]";
            break;
        }
    }
    else
    {
        stringStream <<  L"false]";
    }

    SetCustomWindowText(stringStream.str().c_str());
}

// Wait for pending GPU work to complete.
void D3D12PipelineStateCache::WaitForGpu()
{
    // Schedule a Signal command in the queue.
    ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), m_fenceValues[m_frameIndex]));

    // Wait until the fence has been processed.
    ThrowIfFailed(m_fence->SetEventOnCompletion(m_fenceValues[m_frameIndex], m_fenceEvent));
    WaitForSingleObjectEx(m_fenceEvent, INFINITE, FALSE);

    // Increment the fence value for the current frame.
    m_fenceValues[m_frameIndex]++;
}

// Prepare to render the next frame.
void D3D12PipelineStateCache::MoveToNextFrame()
{
    // Schedule a Signal command in the queue.
    const UINT64 currentFenceValue = m_fenceValues[m_frameIndex];
    ThrowIfFailed(m_commandQueue->Signal(m_fence.Get(), currentFenceValue));

    // Update the frame index.
    m_frameIndex = m_swapChain->GetCurrentBackBufferIndex();

    // If the next frame is not ready to be rendered yet, wait until it is ready.
    if (m_fence->GetCompletedValue() < m_fenceValues[m_frameIndex])
    {
        ThrowIfFailed(m_fence->SetEventOnCompletion(m_fenceValues[m_frameIndex], m_fenceEvent));
        WaitForSingleObjectEx(m_fenceEvent, INFINITE, FALSE);
    }

    // Set the fence value for the next frame.
    m_fenceValues[m_frameIndex] = currentFenceValue + 1;
}


text:
namespace blink {

class CanvasContextCreationAttributesCore;
class CanvasResourceProvider;
class ImageBitmap;
#if defined(SUPPORT_WEBGL2_COMPUTE_CONTEXT)
class
    OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrWebGL2ComputeRenderingContextOrImageBitmapRenderingContext;
typedef OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrWebGL2ComputeRenderingContextOrImageBitmapRenderingContext
    OffscreenRenderingContext;
#else
class
    OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext;
typedef OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext
    OffscreenRenderingContext;
#endif

class CORE_EXPORT OffscreenCanvas final
    : public EventTargetWithInlineData,
      public ImageBitmapSource,
      public CanvasRenderingContextHost,
      public CanvasResourceDispatcherClient {
  DEFINE_WRAPPERTYPEINFO();
  USING_GARBAGE_COLLECTED_MIXIN(OffscreenCanvas);
  USING_PRE_FINALIZER(OffscreenCanvas, Dispose);

 public:
  static OffscreenCanvas* Create(ExecutionContext*,
                                 unsigned width,
                                 unsigned height);

  OffscreenCanvas(ExecutionContext*, const IntSize&);
  ~OffscreenCanvas() override;
  void Dispose();

  bool IsOffscreenCanvas() const override { return true; }
  // IDL attributes
  unsigned width() const { return size_.Width(); }
  unsigned height() const { return size_.Height(); }
  void setWidth(unsigned);
  void setHeight(unsigned);

  // CanvasResourceDispatcherClient
  bool BeginFrame() override;
  void SetFilterQualityInResource(SkFilterQuality filter_quality) override;

  // API Methods
  ImageBitmap* transferToImageBitmap(ScriptState*, ExceptionState&);

  const IntSize& Size() const override { return size_; }
  void SetSize(const IntSize&);
  void RecordTransfer();

  void SetPlaceholderCanvasId(DOMNodeId canvas_id);
  void DeregisterFromAnimationFrameProvider();
  DOMNodeId PlaceholderCanvasId() const { return placeholder_canvas_id_; }
  bool HasPlaceholderCanvas() const;
  bool IsNeutered() const override { return is_neutered_; }
  void SetNeutered();
  CanvasRenderingContext* GetCanvasRenderingContext(
      ExecutionContext*,
      const String&,
      const CanvasContextCreationAttributesCore&);

  static void RegisterRenderingContextFactory(
      std::unique_ptr<CanvasRenderingContextFactory>);

  bool OriginClean() const override;
  void SetOriginTainted() override { origin_clean_ = false; }
  // TODO(crbug.com/630356): apply the flag to WebGL context as well
  void SetDisableReadingFromCanvasTrue() {
    disable_reading_from_canvas_ = true;
  }

  CanvasResourceProvider* GetOrCreateResourceProvider();

  void SetFrameSinkId(uint32_t client_id, uint32_t sink_id) {
    client_id_ = client_id;
    sink_id_ = sink_id;
  }
  uint32_t ClientId() const { return client_id_; }
  uint32_t SinkId() const { return sink_id_; }

  void SetFilterQuality(const SkFilterQuality& quality) {
    filter_quality_ = quality;
  }

  void AllowHighPerformancePowerPreference() {
    allow_high_performance_power_preference_ = true;
  }

  // CanvasRenderingContextHost implementation.
  void PreFinalizeFrame() override {}
  void PostFinalizeFrame() override {}
  void DetachContext() override { context_ = nullptr; }
  CanvasRenderingContext* RenderingContext() const override { return context_; }

  bool PushFrameIfNeeded();
  bool PushFrame(scoped_refptr<CanvasResource> frame,
                 const SkIRect& damage_rect) override;
  void DidDraw(const FloatRect&) override;
  void DidDraw() override;
  void Commit(scoped_refptr<CanvasResource> bitmap_image,
              const SkIRect& damage_rect) override;
  bool ShouldAccelerate2dContext() const override;
  unsigned GetMSAASampleCountFor2dContext() const override { return 0; }
  CanvasResourceDispatcher* GetOrCreateResourceDispatcher() override;

  // Partial CanvasResourceHost implementation
  void NotifyGpuContextLost() override {}
  void SetNeedsCompositingUpdate() override {}
  // TODO(fserb): Merge this with HTMLCanvasElement::UpdateMemoryUsage
  void UpdateMemoryUsage() override;
  SkFilterQuality FilterQuality() const override { return filter_quality_; }

  // EventTarget implementation
  const AtomicString& InterfaceName() const final {
    return event_target_names::kOffscreenCanvas;
  }
  ExecutionContext* GetExecutionContext() const override {
    return execution_context_.Get();
  }

  ExecutionContext* GetTopExecutionContext() const override {
    return execution_context_.Get();
  }

  const KURL& GetExecutionContextUrl() const override {
    return GetExecutionContext()->Url();
  }

  // ImageBitmapSource implementation
  IntSize BitmapSourceSize() const final;
  ScriptPromise CreateImageBitmap(ScriptState*,
                                  base::Optional<IntRect>,
                                  const ImageBitmapOptions*,
                                  ExceptionState&) final;

  // CanvasImageSource implementation
  scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*,
                                               AccelerationHint,
                                               const FloatSize&) final;
  bool WouldTaintOrigin() const final { return !origin_clean_; }
  FloatSize ElementSize(const FloatSize& default_object_size,
                        const RespectImageOrientationEnum) const final {
    return FloatSize(width(), height());
  }
  bool IsOpaque() const final;
  bool IsAccelerated() const final;

  DispatchEventResult HostDispatchEvent(Event* event) override {
    return DispatchEvent(*event);
  }

  bool IsWebGL1Enabled() const override { return true; }
  bool IsWebGL2Enabled() const override { return true; }
  bool IsWebGLBlocked() const override { return false; }

  FontSelector* GetFontSelector() override;

  void Trace(Visitor*) override;

  class ScopedInsideWorkerRAF {
    STACK_ALLOCATED();

   public:
    ScopedInsideWorkerRAF(const viz::BeginFrameArgs& args)
        : abort_raf_(false), begin_frame_args_(args) {}

    bool AddOffscreenCanvas(OffscreenCanvas* canvas) {
      DCHECK(!abort_raf_);
      DCHECK(!canvas->inside_worker_raf_);
      if (canvas->GetOrCreateResourceDispatcher()) {
        // If we are blocked with too many frames, we must stop.
        if (canvas->GetOrCreateResourceDispatcher()
                ->HasTooManyPendingFrames()) {
          abort_raf_ = true;
          return false;
        }
      }

      canvas->inside_worker_raf_ = true;
      canvases_.push_back(canvas);
      return true;
    }

    ~ScopedInsideWorkerRAF() {
      for (auto canvas : canvases_) {
        DCHECK(canvas->inside_worker_raf_);
        canvas->inside_worker_raf_ = false;
        // If we have skipped raf, don't push frames.
        if (abort_raf_)
          continue;
        if (canvas->GetOrCreateResourceDispatcher()) {
          canvas->GetOrCreateResourceDispatcher()->ReplaceBeginFrameAck(
              begin_frame_args_);
        }
        canvas->PushFrameIfNeeded();
      }
    }

   private:
    bool abort_raf_;
    const viz::BeginFrameArgs& begin_frame_args_;
    HeapVector<Member<OffscreenCanvas>> canvases_;
  };

 private:
  int32_t memory_usage_ = 0;

  friend class OffscreenCanvasTest;
  using ContextFactoryVector =
      Vector<std::unique_ptr<CanvasRenderingContextFactory>>;
  static ContextFactoryVector& RenderingContextFactories();
  static CanvasRenderingContextFactory* GetRenderingContextFactory(int);

  Member<CanvasRenderingContext> context_;
  WeakMember<ExecutionContext> execution_context_;

  DOMNodeId placeholder_canvas_id_ = kInvalidDOMNodeId;

  IntSize size_;
  bool is_neutered_ = false;
  bool origin_clean_ = true;
  bool disable_reading_from_canvas_ = false;

  std::unique_ptr<CanvasResourceDispatcher> frame_dispatcher_;

  SkIRect current_frame_damage_rect_;

  bool needs_matrix_clip_restore_ = false;
  bool needs_push_frame_ = false;
  bool inside_worker_raf_ = false;

  SkFilterQuality filter_quality_ = kLow_SkFilterQuality;

  // An offscreen canvas should only prefer the high-performance GPU if it is
  // initialized by transferring control from an HTML canvas that is not
  // cross-origin.
  bool allow_high_performance_power_preference_ = false;

  // cc::FrameSinkId is broken into two integer components as this can be used
  // in transfer of OffscreenCanvas across threads
  // If this object is not created via
  // HTMLCanvasElement.transferControlToOffscreen(),
  // then the following members would remain as initialized zero values.
  uint32_t client_id_ = 0;
  uint32_t sink_id_ = 0;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_OFFSCREENCANVAS_OFFSCREEN_CANVAS_H_

redpajama_set_name: RedPajamaGithub


text:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="hr_HR">
<context>
    <name>design/ezodf/import</name>
    <message>
        <source>File:</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <source>Create or update the translation in:</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <source>Existing translations</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <source>New translations</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <source>Import in:</source>
        <translation type="unfinished"></translation>
    </message>
</context>
<context>
    <name>extension/ezodf</name>
    <message>
        <source>Upload file</source>
        <translation type="obsolete">Učitaj datoteku</translation>
    </message>
    <message>
        <source>Error</source>
        <translation>Greška</translation>
    </message>
    <message>
        <source>Export Object</source>
        <translation>Izvezi objekt</translation>
    </message>
    <message>
        <source>OpenOffice.org import</source>
        <translation>OpenOffice.org uvoz</translation>
    </message>
    <message>
        <source>OpenOffice.org export</source>
        <translation>OpenOffice.org izvoz</translation>
    </message>
    <message>
        <source>Document is now imported</source>
        <translation>Dokument se uvozi</translation>
    </message>
    <message>
        <source>The object was imported as: %class_name</source>
        <translation>Objekt je uvezen kao: %class_name</translation>
    </message>
    <message>
        <source>Document imported as</source>
        <translation>Dokument uvezen kao</translation>
    </message>
    <message>
        <source>Import another document</source>
        <translation>Uvezi drugi dokument</translation>
    </message>
    <message>
        <source>Import OpenOffice.org document</source>
        <translation>Uvezi OpenOffice.org dokument</translation>
    </message>
    <message>
        <source>Replace document</source>
        <translation>Zamijeni dokument</translation>
    </message>
    <message>
        <source>Import to</source>
        <translation>Uvezi u</translation>
    </message>
    <message>
        <source>Export eZ Publish content to OpenOffice.org</source>
        <translation>Izvezi eZ Publish sadržaj u OpenOffice.org</translation>
    </message>
    <message>
        <source>Here you can export any eZ Publish content object to an OpenOffice.org Writer document format.</source>
        <translation>Ovdje možete izvesti bilo koji eZ Publish objekt u OpenOffice.org Writer format dokumenta.</translation>
    </message>
    <message>
        <source>The images are placed in the media library and can be re-used.</source>
        <translation>Slike su smještene u biblioteku medija i mogu biti korištene više puta.</translation>
    </message>
    <message>
        <source>You can import OpenOffice.org Writer documents directly into eZ Publish from this page. You are
asked where to place the document and eZ Publish does the rest. The document is converted into
the appropriate class during the import, you get a notice about this after the import is done.
Images are placed in the media library so you can re-use them in other articles.</source>
        <translation>S ove stranice možete uvesti OpenOffice.org Writer direktno u eZ Publish Od vas će se tražiti
da odaberete lokaciju dokumenta i eZ Publish će odraditi ostatak. Dokument će biti konvertiran
u odgovarajuću klasu prilikom uvoza i bit ćete obavješteni o tome nakon što je uvoz završen.
Slike će biti smještene u biblioteku medija da ih možete koristiti u člancima.</translation>
    </message>
    <message>
        <source>The imported document is waiting for an approbation to be published.</source>
        <translation>Uvezeni dokument čeka na odobrenje za objavu.</translation>
    </message>
    <message>
        <source>Import document</source>
        <translation type="unfinished"></translation>
    </message>
</context>
<context>
    <name>extension/ezodf/browse</name>
    <message>
        <source>Choose document placement</source>
        <translation>Odaberite lokaciju dokumenta</translation>
    </message>
    <message>
        <source>Please choose the placement for the OpenOffice.org object.

    Select the placements and click the %buttonname button.
    Using the recent and bookmark items for quick placement is also possible.
    Click on placement names to change the browse listing.</source>
        <translation>Odaberite lokaciju za OpenOffice.org objekt.

    Odaberite lokacije i kliknite %buttonname tipku.
    Odabiranje lokacija je također moguće koristeći favorite.
    Kliknite na nazive lokacija da biste promijenili izlist.</translation>
    </message>
    <message>
        <source>Select</source>
        <translation>Odaberi</translation>
    </message>
</context>
<context>
    <name>extension/ezodf/export/error</name>
    <message>
        <source>Destination file format not supported</source>
        <translation>Odredišni format datoteke nije podržan</translation>
    </message>
    <message>
        <source>PDF conversion failed</source>
        <translation>Konverzija u PDF neuspješna</translation>
    </message>
    <message>
        <source>Word conversion failed</source>
        <translation>Konverzija u Word neuspješna</translation>
    </message>
    <message>
        <source>Unable to fetch node, or no read access</source>
        <translation>Nije moguće dohvatiti čvor ili ne postoje prava za čitanje</translation>
    </message>
    <message>
        <source>Unable to open file %1 on server side</source>
        <translation>Nije moguće otvoriti datoteku %1 na serveru</translation>
    </message>
</context>
<context>
    <name>extension/ezodf/import/error</name>
    <message>
        <source>File extension or type is not allowed.</source>
        <translation>Nastavak datoteke nije dozvoljen.</translation>
    </message>
    <message>
        <source>Could not parse XML.</source>
        <translation>Nije moguće parsirati XML.</translation>
    </message>
    <message>
        <source>Can not open socket. Please check if extension/ezodf/daemon.php is running.</source>
        <translation>Nije moguće otvoriti vezu. Provjerite je li pokrenut extension/ezodf/daemon.php.</translation>
    </message>
    <message>
        <source>Can not convert the given document.</source>
        <translation>Nije moguće konvertirati dokument.</translation>
    </message>
    <message>
        <source>Unable to call daemon. Fork can not create child process.</source>
        <translation>Nije moguće pozvati demon proces. Nije moguće stvoriti podprocese.</translation>
    </message>
    <message>
        <source>Daemon reported error.</source>
        <translation>Demon je prijavio grešku.</translation>
    </message>
    <message>
        <source>Unknown node.</source>
        <translation>Nepoznati čvor.</translation>
    </message>
    <message>
        <source>Access denied.</source>
        <translation>Pristup nije dozvoljen.</translation>
    </message>
    <message>
        <source>Error during import.</source>
        <translation>Greška prilikom uvoza.</translation>
    </message>
    <message>
        <source>Unknown content class specified in odf.ini:</source>
        <translation>Nepoznata klasa navedena u odf.ini:</translation>
    </message>
    <message>
        <source>Unknown error.</source>
        <translation>Nepoznata greška.</translation>
    </message>
    <message>
        <source>Filetype: </source>
        <translation>Vrsta datoteke: </translation>
    </message>
    <message>
        <source>Unable to fetch node with id </source>
        <translation>Nije moguće dohvatiti čvor s ID-em </translation>
    </message>
    <message>
        <source>Folder for images could not be created, access denied.</source>
        <translation>Nije moguće kreirati direktorij za slike jer nemate prava pristupa.</translation>
    </message>
    <message>
        <source>Document is not supported.</source>
        <translation>Dokument nije podržan.</translation>
    </message>
    <message>
        <source>Cannot import. File not found. Already imported?</source>
        <translation>Nije moguće uvesti datoteku jer nije pronađena. Možda je već uvezena?</translation>
    </message>
    <message>
        <source>Cannot import document, supplied placement nodeID is not valid.</source>
        <translation>Nije moguće uvesti dokument, dani ID lokacije nije ispravan.</translation>
    </message>
    <message>
        <source>Cannot store uploaded file, cannot import.</source>
        <translation>Uvoz nije moguć. Nije moguće pohraniti učitanu datoteku.</translation>
    </message>
</context>
<context>
    <name>extension/ezodf/popupmenu</name>
    <message>
        <source>Export PDF</source>
        <translation>Izvezi PDF</translation>
    </message>
    <message>
        <source>Export Word</source>
        <translation>Izvezi Word</translation>
    </message>
    <message>
        <source>OpenOffice.org</source>
        <translation>OpenOffice.org</translation>
    </message>
    <message>
        <source>Export OpenOffice</source>
        <translation>Izvezi OpenOffice</translation>
    </message>
    <message>
        <source>Import OpenOffice</source>
        <translation>Uvezi OpenOffice</translation>
    </message>
    <message>
        <source>Replace OpenOffice</source>
        <translation>Zamijeni OpenOffice</translation>
    </message>
</context>
</TS>


text:
package org.apache.flink.runtime.topology;

/** ID of a {@link Result}. */
public interface ResultID extends java.io.Serializable {}


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:text="拦截模式"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:layout_marginTop="25dp"
        android:gravity="center"
        android:textColor="@android:color/black" />

    <TextView
        android:id="@+id/label_control_choose"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="拦截黑名单"
        android:layout_marginTop="10dp"
        android:textSize="16sp"
        android:textColor="@color/bg_brown_type"
        android:gravity="center" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="30dp"
        android:gravity="center">

        <RadioButton
            android:id="@+id/mode_intercept_blacklist_but_whitelist"
            android:layout_width="70dp"
            android:gravity="center"
            android:button="@null"
            android:background="@drawable/mode_intercepet_no_whitelist"
            style="@style/ModeChooseButton"
            android:layout_height="70dp" />

        <RadioButton
            android:id="@+id/mode_intercept_all_but_whitelist"
            android:layout_width="70dp"
            android:gravity="center"
            android:button="@null"
            style="@style/ModeChooseButton"
            android:background="@drawable/mode_intercept_all_but_whitelist_selector"
            android:layout_height="70dp" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center"
        android:button="@null"
        android:layout_marginTop="20dp">

        <RadioButton
            android:id="@+id/mode_intercept_blacklist_all"
            android:layout_width="70dp"
            android:gravity="center"
            android:button="@null"
            style="@style/ModeChooseButton"
            android:background="@drawable/mode_intercept_blacklist_all_selector"
            android:layout_height="70dp" />

        <RadioButton
            android:id="@+id/mode_intercept_null"
            android:layout_width="70dp"
            android:button="@null"
            style="@style/ModeChooseButton"
            android:background="@drawable/mode_intercept_null_selector"
            android:gravity="center"
            android:layout_height="70dp" />
    </LinearLayout>

    <TextView
        android:id="@+id/list_intercept_already"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/translacute_half_rounded_rectangle_shape"
        android:layout_marginTop="30dp"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="30dp"
        android:padding="12dp"
        android:alpha="0.8"
        android:drawableRight="@drawable/ic_showmore"
        android:drawableLeft="@drawable/ic_blockednumber"
        android:drawablePadding="6dp"
        android:textColor="@color/black"
        android:gravity="center_vertical"
        android:text="已拦截号码" />

    <TextView
        android:id="@+id/list_intercept_add"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/translacute_half_rounded_rectangle_shape"
        android:layout_marginTop="15dp"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="30dp"
        android:padding="8dp"
        android:alpha="0.8"
        android:drawableRight="@drawable/ic_showmore"
        android:drawableLeft="@drawable/ic_menu_invite"
        android:drawablePadding="6dp"
        android:textColor="@color/black"
        android:gravity="center_vertical"
        android:text="添加号码" />

</LinearLayout>


text:
function getName(authData) {
    if (authData == null) {
        return undefined
    }
    switch (authData.provider) {
        case 'password':
            return authData.password.email.replace(/@.*/, '');
        case 'twitter':
            return authData.twitter.displayName;
        case 'facebook':
            return authData.facebook.displayName;
    }
}

function getNewUid(prefix) {
    if (typeof prefix === 'undefined') {
        prefix = "";
    } else {
        prefix = prefix + "-"
    }
    var length = 8;
    var uid = prefix + Math.random().toString(36).slice(-length);
    return uid
}

var getUrlVars = function () {
    var vars = {};
    var param = location.search.substring(1).split('&');
    for (var i = 0; i < param.length; i++) {
        var keySearch = param[i].search(/=/);
        var key = '';
        if (keySearch != -1) key = param[i].slice(0, keySearch);
        var val = param[i].slice(param[i].indexOf('=', 0) + 1);
        if (key != '') vars[key] = decodeURI(val);
    }
    return vars;
}

var date2str = function (date){
    var str = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate();
    return str
}

var getTodayString = function(){
    var currentDateTime = new Date();
    return date2str(currentDateTime);
}

var str2date = function (str){
    var devided = str.split("-");
    var year = devided[0];
    var month = devided[1];
    var day = devided[2];
    var date = new Date(year, month, day);
    return date
}

var getTodayTime = function(){
    var currentDateTime = new Date();
    var dateStr = currentDateTime.getFullYear()+"-"+(currentDateTime.getMonth()+1)+"-"+currentDateTime.getDate();
    var currentDate = str2date(dateStr);
    return currentDate.getTime();
}


text:
using FubuCore;
using FubuCore.Binding;
using FubuMVC.Core.Behaviors;
using FubuMVC.Core.Registration.Nodes;
using NUnit.Framework;
using Shouldly;
using StructureMap.Testing;

namespace FubuMVC.StructureMap3.Testing.Compliance
{
    [TestFixture]
    public class Setter_Injection_from_ObjectDef_Dependency
    {
        [Test]
        public void will_set_properties_that_are_explicitly_set_on_ObjectDef()
        {
            var node = Process.For<OutsideBehavior>();
            node.AddAfter(Process.For<InsideBehavior>());

            var def = node.As<IContainerModel>().ToObjectDef();

            var behavior = ContainerFacilitySource
                .BuildBehavior(new ServiceArguments(), def, x => { })
                .As<OutsideBehavior>();

            behavior.InsideBehavior.ShouldBeOfType<InsideBehavior>();
        }
    }

    public class OutsideBehavior : BasicBehavior
    {
        public OutsideBehavior() : base(PartialBehavior.Executes)
        {
        }
    }

    public class InsideBehavior : BasicBehavior
    {
        public InsideBehavior()
            : base(PartialBehavior.Executes)
        {
        }
    }
}


text:
package org.wso2.carbon.identity.oauth2.client.authentication;

import org.apache.axiom.util.base64.Base64Utils;
import org.apache.commons.lang.StringUtils;
import org.apache.oltu.oauth2.common.OAuth;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ClientAuthUtil {

    protected String test = "test";

    public static Map<String, List<String>> getBodyContentWithClientAndSecret(String clientId, String secret) {

        Map<String, String> content = new HashMap<>();
        if (StringUtils.isNotEmpty(clientId)) {
            content.put(OAuth.OAUTH_CLIENT_ID, clientId);
        }
        if (StringUtils.isNotEmpty(secret)) {
            content.put(OAuth.OAUTH_CLIENT_SECRET, secret);
        }
        return getBodyContent(content);
    }

    public static Map<String, List<String>> getBodyContent(Map<String, String> contentStrings) {

        Map<String, List<String>> bodyContent = new HashMap<>();
        contentStrings.forEach((key, value) -> {
            List<String> valueList = new ArrayList<String>();
            valueList.add(value);
            bodyContent.put(key, valueList);
        });
        return bodyContent;
    }

    public static String getBase64EncodedBasicAuthHeader(String clientId, String secret, String extraParam) {

        if (StringUtils.isEmpty(clientId)) {
            return "Basic " + Base64Utils.encode((secret).getBytes());
        } else if (StringUtils.isEmpty(secret)) {
            return "Basic " + Base64Utils.encode((clientId).getBytes());
        }
        if (StringUtils.isNotEmpty(extraParam)) {
            return "Basic " + Base64Utils.encode((clientId + ":" + secret + ":" + extraParam).getBytes());
        }
        return "Basic " + Base64Utils.encode((clientId + ":" + secret).getBytes());
    }
}


text:
<?php

namespace Magento\Framework\App;

/**
 * A model for determining information about setup application
 */
class SetupInfo
{
    /**#@+
     * Initialization parameters for redirecting if the application is not installed
     */
    const PARAM_NOT_INSTALLED_URL_PATH = 'MAGE_NOT_INSTALLED_URL_PATH';
    const PARAM_NOT_INSTALLED_URL = 'MAGE_NOT_INSTALLED_URL';
    /**#@-*/

    /**
     * Default path relative to the project root
     */
    const DEFAULT_PATH = 'setup';

    /**
     * Environment variables
     *
     * @var array
     */
    private $server;

    /**
     * Current document root directory
     *
     * @var string
     */
    private $docRoot;

    /**
     * Project root directory
     *
     * @var string
     */
    private $projectRoot;

    /**
     * Constructor
     *
     * @param array $server
     * @param string $projectRoot
     * @throws \InvalidArgumentException
     */
    public function __construct($server, $projectRoot = '')
    {
        $this->server = $server;
        if (empty($server['DOCUMENT_ROOT'])) {
            throw new \InvalidArgumentException('DOCUMENT_ROOT variable is unavailable.');
        }
        $this->docRoot = str_replace('\\', '/', $server['DOCUMENT_ROOT']);
        $this->projectRoot = $projectRoot ?: $this->detectProjectRoot();
        $this->projectRoot = str_replace('\\', '/', $this->projectRoot);
    }

    /**
     * Automatically detects project root from current environment
     *
     * Assumptions:
     * if the current setup application relative path is at the end of script path, then it is setup application
     * otherwise it is the "main" application
     *
     * @return mixed
     * @throws \InvalidArgumentException
     */
    private function detectProjectRoot()
    {
        if (empty($this->server['SCRIPT_FILENAME'])) {
            throw new \InvalidArgumentException('Project root cannot be automatically detected.');
        }
        $haystack = str_replace('\\', '/', dirname($this->server['SCRIPT_FILENAME']));
        $needle = '/' . $this->getPath();
        $isSetupApp = preg_match('/^(.+?)' . preg_quote($needle, '/') . '$/', $haystack, $matches);
        if ($isSetupApp) {
            return $matches[1];
        }
        return $haystack;
    }

    /**
     * Gets setup application URL
     *
     * @return string
     */
    public function getUrl()
    {
        if (isset($this->server[self::PARAM_NOT_INSTALLED_URL])) {
            return $this->server[self::PARAM_NOT_INSTALLED_URL];
        }
        return Request\Http::getDistroBaseUrlPath($this->server) . $this->getPath() . '/';
    }

    /**
     * Gets the "main" application URL
     *
     * @return string
     */
    public function getProjectUrl()
    {
        $isProjectInDocRoot = false !== strpos($this->projectRoot . '/', $this->docRoot . '/');
        if (!$isProjectInDocRoot || empty($this->server['HTTP_HOST'])) {
            return '';
        }
        return 'http://' . $this->server['HTTP_HOST'] . substr($this->projectRoot . '/', strlen($this->docRoot));
    }

    /**
     * Gets setup application directory path in the filesystem
     *
     * @param string $projectRoot
     * @return string
     */
    public function getDir($projectRoot)
    {
        return rtrim($projectRoot, '/') . '/' . $this->getPath();
    }

    /**
     * Checks if the setup application is available in current document root
     *
     * @return bool
     */
    public function isAvailable()
    {
        $setupDir = $this->getDir($this->projectRoot);
        $isSubDir = false !== strpos($setupDir . '/', $this->docRoot . '/');
        return $isSubDir && realpath($setupDir);
    }

    /**
     * Gets relative path to setup application
     *
     * @return string
     */
    private function getPath()
    {
        if (isset($this->server[self::PARAM_NOT_INSTALLED_URL_PATH])) {
            return trim($this->server[self::PARAM_NOT_INSTALLED_URL_PATH], '/');
        }
        return self::DEFAULT_PATH;
    }
}


text:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[RequireComponent(typeof(RigidbodyArcade))]
[RequireComponent(typeof(PointColliderArcade))]
public class Projectile : MonoBehaviour
{
  public ProjectileManager Manager;

  private Transform mTransform;
  private RigidbodyArcade mRigidBody;
  private ColliderArcade mCollider;
  private float mTime;

  void Start()
  {
    Manager.Add(this);
    gameObject.SetActive(false);
    mTransform = transform;
    mRigidBody = GetComponent<RigidbodyArcade>();
    mCollider = mRigidBody.colliderArcade;
  }

  void FixedUpdate()
  {
    mTime += Time.fixedDeltaTime;
    if (mTime > 0.5f)
    {
      gameObject.SetActive(false);
      Manager.Add(this);
    }
  }

  public void Reuse(Vector2 position, Vector2 velocity)
  {
    Manager.Remove(this);
    gameObject.SetActive(true);
    mTransform = transform;
    mRigidBody = GetComponent<RigidbodyArcade>();
    mCollider = mRigidBody.colliderArcade;
    mTime = 0.0f;

    mRigidBody.lastPosition = position;
    mRigidBody.velocity = velocity;
    mTransform.position = position;
  }

}


text:
'use strict';
const Base = require('../base');

module.exports = Base.extend({
  initializing() {
    this.option('skip-install');
  },

  prompting() {
    this._setPrompt(this.async());
  },

  writing() {
    let json = this._packageJSON(require('./templates/package.json'));
    this._write('package.json', JSON.stringify(json, null, 2));
    this._write('README.md', `
# ${this.props.projectName}

## License

[MIT](http://${this.props.userName}.mit-License.org/)
`);

    this._copy('_gitignore', '.gitignore');
    this._copy('gulpfile.js');
    this._copy('webpack.config.js');
    this._copy('src/client.js');
    this._copy('src/styles/main.css');
    this._copy('src/styles/_hello.css');
    this._copy('public/index.html');
    this._copy('test/index.js');
  },

  install() {
    if (!this.options['skip-install']) {
      this.npmInstall();
    }
  }
});


text:
<?php

namespace Taller\BookBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class BookEditType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title')
            ->add('author')
            ->add('summary')
            ->add('edition_date', 'birthday')
            ->add('image', 'file', array('required' => false, 'data_class' => null))
        ;
    }

    public function getName()
    {
        return 'taller_bookbundle_booktype';
    }
}


text:
package linkedin;

import java.util.List;

public class DepthSum {

    /*
     * Given a nested list of integers, returns the sum of all integers in the
     * list weighted by their depth For example, given the list {{1,1},2,{1,1}}
     * the function should return 10 (four 1's at depth 2, one 2 at depth 1)
     * Given the list {1,{4,{6}}} the function should return 27 (one 1 at depth
     * 1, one 4 at depth 2, and one 6 at depth 3)
     */

    public interface NestedInteger {
        /**
         * @return true if this NestedInteger holds a single integer, rather
         * than a nested list
         */
        boolean isInteger();

        /**
         * @return the single integer that this NestedInteger holds, if it holds
         * a single integer Return null if this NestedInteger holds a
         * nested list
         */
        Integer getInteger();

        /**
         * @return the nested list that this NestedInteger holds, if it holds a
         * nested list Return null if this NestedInteger holds a single
         * integer
         */
        List<NestedInteger> getList();
    }

    public int depthSum(List<NestedInteger> input) { // ur implementation here}
        int finalSum = 0;
        for (NestedInteger nestedInteger : input) {
            finalSum += depthSumInternal(nestedInteger, 1);
        }
        return finalSum;
    }

    private int depthSumInternal(NestedInteger input, int level) {
        int returnSum = 0;
        if (input.isInteger())
            return level * input.getInteger();
        for (NestedInteger childInput : input.getList()) {
            int childLevel = level + 1;
            returnSum += depthSumInternal(childInput, childLevel);
        }
        return returnSum;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}


text:
var mongoose = require('mongoose');

function testUtils () {

  var self = this;

  self.clearDB = function () {

    for (var i in mongoose.connection.collections) {
      mongoose.connection.collections[i].remove();
    }

  }

  return testUtils();
}


text:
package cz.metacentrum.perun.core.impl.modules.attributes;

import cz.metacentrum.perun.core.api.Attribute;
import cz.metacentrum.perun.core.api.AttributeDefinition;
import cz.metacentrum.perun.core.api.AttributesManager;
import cz.metacentrum.perun.core.api.Facility;
import cz.metacentrum.perun.core.api.User;
import cz.metacentrum.perun.core.api.exceptions.AttributeNotExistsException;
import cz.metacentrum.perun.core.api.exceptions.ConsistencyErrorException;
import cz.metacentrum.perun.core.api.exceptions.InternalErrorException;
import cz.metacentrum.perun.core.api.exceptions.WrongAttributeAssignmentException;
import cz.metacentrum.perun.core.api.exceptions.WrongAttributeValueException;
import cz.metacentrum.perun.core.api.exceptions.WrongReferenceAttributeValueException;
import cz.metacentrum.perun.core.impl.PerunSessionImpl;
import cz.metacentrum.perun.core.implApi.modules.attributes.UserFacilityAttributesModuleAbstract;
import cz.metacentrum.perun.core.implApi.modules.attributes.UserFacilityAttributesModuleImplApi;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author Slavek Licehammer <glory@ics.muni.cz>
 */
public class urn_perun_user_facility_attribute_def_def_shell_passwd_scp extends UserFacilityAttributesModuleAbstract implements UserFacilityAttributesModuleImplApi {

	private static final Pattern pattern = Pattern.compile("^(/[-_.a-zA-Z0-9]+)+$");

	@Override
	public void checkAttributeSyntax(PerunSessionImpl sess, User user, Facility facility, Attribute attribute) throws WrongAttributeValueException {
		String shell = attribute.valueAsString();

		if(shell == null) return;
		Matcher matcher = pattern.matcher(shell);
		if(!matcher.matches()) throw new WrongAttributeValueException(attribute, "Wrong format. ^(/[-_.A-z0-9]+)+$ expected");
	}

	@Override
	public void checkAttributeSemantics(PerunSessionImpl sess, User user, Facility facility, Attribute attribute) throws WrongReferenceAttributeValueException {
		if (attribute.valueAsString() == null) throw new WrongReferenceAttributeValueException(attribute, "Value can't be null");
	}

	@Override
	public Attribute fillAttribute(PerunSessionImpl sess, User user, Facility facility, AttributeDefinition attributeDefinition) throws WrongAttributeAssignmentException {
		Attribute attribute = new Attribute(attributeDefinition);
		try {
			Attribute shellOnFacilityAttribute = sess.getPerunBl().getAttributesManagerBl().getAttribute(sess, facility, AttributesManager.NS_FACILITY_ATTR_DEF + ":" + attributeDefinition.getFriendlyName());
			attribute.setValue(shellOnFacilityAttribute.getValue());
			return attribute;
		} catch(AttributeNotExistsException ex) {
			throw new ConsistencyErrorException(ex);
		}
	}

	@Override
	public AttributeDefinition getAttributeDefinition() {
		AttributeDefinition attr = new AttributeDefinition();
		attr.setNamespace(AttributesManager.NS_USER_FACILITY_ATTR_DEF);
		attr.setFriendlyName("shell_passwd_scp");
		attr.setDisplayName("Shell for passwd_scp");
		attr.setType(String.class.getName());
		attr.setDescription("Shell password.");
		return attr;
	}
}


text:
using UnityEngine;
using System.Collections;

public class LogicExplodingFloor : MonoBehaviour
{
	void OnGUI()
	{
        if(LogicGlobalFracturing.HelpVisible == false)
        {
            return;
        }

	      // Draw global instructions

        LogicGlobalFracturing.GlobalGUI();

        // Draw instructions

        GUILayout.Label("This scene shows a floor with:");
        GUILayout.Label("-BSP fracturing");
        GUILayout.Label("-Moving explosion source with radius");
        GUILayout.Label("");

        if(GUILayout.Button("Restart"))
        {
            UnityEngine.SceneManagement.SceneManager.LoadScene("02 Sample Scene - Exploding Floor");
        }
	}
}


text:
<?php

require_once dirname( dirname( dirname( __FILE__ ) ) ) . DIRECTORY_SEPARATOR . 'phpunit_bootstrap.php';

class system_classes_TagTest extends PHPUnit_Framework_TestCase
{
	private $text = 'Test Tag';
	private $slug;
	private $tag;

	public function setup()
	{
		$this->slug = Utils::slugify( $this->text );
		$this->tag = new Tag( array( 'tag_text' => $this->text, 'tag_slug' => $this->slug ) );
	}

	public function teardown()
	{
		unset( $this->tag );
	}

	public function test_construct_tag()
	{
		$params = array(
			'tag_slug' => $this->slug,
			'tag_text' => $this->text
		);
		$t = new Tag($params);

		$this->assertType('Tag', $t);
		$this->assertEquals($t->tag_slug, $this->slug );
		$this->assertEquals($t->tag_text, $this->text );
	}

	public function test_create_tag()
	{
		$t = Tag::create( array( 'tag_text' => $this->text, 'tag_slug' => $this->slug ) );
		$this->assertType( 'Tag', $t );
		$this->assertEquals( $t->tag_slug, $this->slug );
		$this->assertEquals( $t->tag_text, $this->text );
		$t->delete();
	}

	/**
	 * @todo assertType() fails
	 */
	public function test_insert_tag()
	{
		$count = count( Tags::get() );
		$res = $this->tag->insert();
		if ( $res ) {
			$this->assertType( 'Tag', $res );
			$this->assertEquals( $count + 1, count( Tags::get() ) );
			$t = Tag::get( $this->text );
			$this->assertType( 'Tag', $t );
			$this->assertEquals( $t->tag_text, $this->text );
			$t->delete();
		}
		else {
			$this->assertEquals( $res, FALSE );
		}

	}

	public function test_update_tag()
	{

		$this->tag->insert();
		$t = Tag::get( $this->tag->tag_text );
		$t->tag_text = 'Updated Test Tag';
		$t->update();
		$new_tag = Tag::get( $this->tag->tag_slug );
		$this->assertEquals( $new_tag->tag, $t->tag_text );
		$t->delete();
	}

	public function test_delete_tag()
	{
		$count = count( Tags::get() );
		$t = $this->tag->insert();
		$this->assertEquals( $count + 1, count( Tags::get() ) );
		$t->delete();
		$this->assertEquals( $count, count( Tags::get() ) );
	}

	public function test_get_tag()
	{
		$this->tag->insert();
		$t = Tag::get( $this->text );
		$this->assertEquals( $t->tag_text, $this->tag->tag_text );
		$t->delete();
	}

	public function test_attach_to_post_tag()
	{

        $this->markTestIncomplete(
          'This test has not been implemented yet.'
        );
	}

	public function test_detach_from_post_tag()
	{

        $this->markTestIncomplete(
          'This test has not been implemented yet.'
        );
	}

}
?>


text:
package models;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import com.avaje.ebean.Ebean;

import play.data.validation.Constraints.Required;
import play.db.ebean.Model;

/**
 * Repräsentiert ein laufendes Spiel
 *
 * @author justus.markert
 *
 */
@Entity
public class Game extends Model {

	/**
	 *
	 */
	private static final long serialVersionUID = 4975452788426314864L;

	/**
	 * Interne Id
	 */
	@Id
	long id;

	/**
	 * Das benutzte Spielfeld
	 */
	@Required
	@ManyToOne
	public Playground playground;

	/**
	 * Die Teilnehmenden Spieler und ihr Forschritt im Spiel
	 */
    @ManyToMany(cascade=CascadeType.ALL)
	public List<PlayerGameStatus> playerGameStatus = new ArrayList<PlayerGameStatus>();

	/**
	 * Standard C'tor
	 *
	 * @param playground
	 */
	public Game(Playground playground) {

		this.playground = playground;
	}

	/**
	 * Play-Definition eines Finders. Der Zugriff findet dann über die
	 * public-Methoden statt.
	 */
	private static Finder<String, Game> find = new Finder<String, Game>(
			String.class, Game.class);

	/**
	 * Gib mir alle vorhandenen Spiele
	 *
	 * @return List<Game>
	 */
	public static List<Game> findByAll() {

		return Ebean.find(Game.class).fetch("playerGameStatus")
				.fetch("playground").findList();
	}

	/**
	 * Füge einen Spieler hinzu.
	 *
	 * @param playerGameStatus
	 */
	public void addPlayer(Player player) {

		PlayerGameStatus playerGameStatus = new PlayerGameStatus(player);
		// setze currentPoint auf Startpunkt etc.
		playerGameStatus.save();
		this.playerGameStatus.add(playerGameStatus);
	}
}