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); }
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); }
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 }); }