예제 #1
0
    OverlappedWindow::OverlappedWindow() 
    {
        auto pimpl = std::make_unique<Pimpl>();

            //
            //      ---<>--- Register window class ---<>---
            //

        Windows::WNDCLASSEX wc;
        XlZeroMemory(wc);
        XlSetMemory(&wc, 0, sizeof(wc));

        auto windowClassName = Conversion::Convert<std::string>(CurrentModule::GetInstance().HashId());

        wc.cbSize           = sizeof(wc);
        wc.style            = CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
        wc.lpfnWndProc      = (::WNDPROC)&WndProc;
        wc.cbClsExtra       = 0;
        wc.cbWndExtra       = 0;
        wc.hInstance        = CurrentModule::GetInstance().Handle();
        wc.hIcon            = ::LoadIcon(nullptr, IDI_INFORMATION);
        wc.hCursor          = ::LoadCursor(nullptr, IDC_ARROW); 
        wc.hbrBackground    = (HBRUSH)nullptr;
        wc.lpszMenuName     = 0;
        wc.lpszClassName    = windowClassName.c_str();
        wc.hIconSm          = NULL;

            //       (Ignore class registration failure errors)
        (*Windows::Fn_RegisterClassEx)(&wc);

            //
            //      ---<>--- Create the window itself ---<>---
            //
        DWORD windowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME;
        DWORD windowStyleEx = 0;
        pimpl->_hwnd = (*Windows::Fn_CreateWindowEx)(
            windowStyleEx, windowClassName.c_str(), 
            NULL, windowStyle, 
            32, 32, 1280, 720, 
            NULL, NULL, CurrentModule::GetInstance().HInstance(), NULL);

        if (!pimpl->_hwnd || pimpl->_hwnd == INVALID_HANDLE_VALUE) {
            Throw(std::exception( "Failure during windows construction" ));        // (note that a window class can be leaked by this.. But, who cares?)
        }

        SetWindowLongPtr(pimpl->_hwnd, GWLP_USERDATA, (LONG_PTR)pimpl.get());
        ShowWindow(pimpl->_hwnd, SW_SHOWNORMAL);

            //  Create input translator -- used to translate between windows messages
            //  and the cross platform input-handling interface
        pimpl->_inputTranslator = std::make_shared<InputTranslator>();

        _pimpl = std::move(pimpl);
    }
예제 #2
0
    DynamicArray<uint8>  MeshDatabase::BuildNativeVertexBuffer(const NativeVBLayout& outputLayout) const
    {
            //
            //      Write the data into the vertex buffer
            //
        auto size = outputLayout._vertexStride * _unifiedVertexCount;
        auto finalVertexBuffer = std::make_unique<uint8[]>(size);
        XlSetMemory(finalVertexBuffer.get(), 0, size);

        for (unsigned elementIndex = 0; elementIndex <_streams.size(); ++elementIndex) {
            const auto& nativeElement     = outputLayout._elements[elementIndex];
            const auto& stream            = _streams[elementIndex];
            WriteStream(
                stream, PtrAdd(finalVertexBuffer.get(), nativeElement._alignedByteOffset),
                nativeElement._nativeFormat, outputLayout._vertexStride,
                size - nativeElement._alignedByteOffset);
        }

        return DynamicArray<uint8>(std::move(finalVertexBuffer), size);
    }
예제 #3
0
    void AsyncLoadOperation::Enqueue(const ResChar filename[], CompletionThreadPool& pool)
    {
        assert(!_hasBeenQueued);
        _hasBeenQueued = true;
        XlCopyString(_filename, filename);

            // We will hold an extra reference to this object
            // during the queueing processing and while the background
            // load is occurring.
            //
            // Before the file open is started, it will be just a 
            // weak reference. If all client references are destroyed
            // before we open the file, then we will cancel.
            // However, once the file has been opened we need to
            // hold a strong reference at least until the read has
            // completed

        std::weak_ptr<AsyncLoadOperation> weakToThis = shared_from_this();
        pool.Enqueue(
            [weakToThis]()
            {
                auto thisOp = weakToThis.lock();
                    // if all other references to this object have been released
                    // then the weak_ptr::lock() will fail, and we can consider
                    // it a cancel
                if (!thisOp) return;

                    // if we got to this point, we cannot cancel until the load
                    // level read operation has been completed
                auto h = CreateFile(
                    thisOp->_filename, GENERIC_READ, FILE_SHARE_READ,
                    nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,
                    nullptr);

                if (h == INVALID_HANDLE_VALUE) {
                        // failed to load the file -- probably because it's missing
                    thisOp->SetState(::Assets::AssetState::Invalid);
                    return;
                }
                    
                auto fileSize = GetFileSize(h, nullptr);
                if (!fileSize || fileSize == INVALID_FILE_SIZE) {
                    thisOp->SetState(::Assets::AssetState::Invalid);
                    CloseHandle(h);
                    return;
                }

                thisOp->_buffer.reset((uint8*)XlMemAlign(fileSize, 16));
                thisOp->_bufferLength = fileSize;

                thisOp->_overlapped = std::make_unique<SpecialOverlapped>();
                XlSetMemory(thisOp->_overlapped.get(), 0, sizeof(OVERLAPPED));
                thisOp->_overlapped->_fileHandle = INVALID_HANDLE_VALUE;
                thisOp->_overlapped->_returnPointer = thisOp;

                auto readResult = ReadFileEx(
                    h, thisOp->_buffer.get(), fileSize, 
                    thisOp->_overlapped.get(), &SpecialOverlapped::CompletionRoutine);
                if (!readResult) {
                    CloseHandle(h);
                    thisOp->SetState(::Assets::AssetState::Invalid);
                    thisOp->_overlapped->_returnPointer.reset();
                    return;
                }

                thisOp->_overlapped->_fileHandle = h;

                // execution will pass to AsyncLoadOperation::CompletionRoutine, which
                // will complete the load operation
            });
    }