private void ReplacePageFIFO(Page newPage)
        {
            // Узнаем информацию о Page, которую будем заменять
            PageInfo oldPageInfo = _addedPagesInfo[0];

            _addedPagesInfo.RemoveAt(0);

            // Находим её Frame Number в Оперативной Памяти
            int frameNumber = _pageTables[oldPageInfo.ProcessID].FindFrameNumber(oldPageInfo.PageNumber);

            // Заменяем Frame в Оперативной Памяти
            Page oldPage = _physicalMemory.SwapPages(newPage, frameNumber);

            // Вставляем "вынутую" из Оперативной Памяти Page куда-нибудь в Виртуальную Память
            _virtualMemory.InsertPage(oldPage);

            // Указываем в таблице для процесса вынутой Page, что теперь она находится НЕ в Оперативной Памяти
            _pageTables[oldPageInfo.ProcessID].ChangeFrameNumberForPageNumber(oldPageInfo.PageNumber, -1);

            // Указываем в таблице для процесса вставленной Page её адрес в Оперативной Памяти
            _pageTables[newPage.ProcessID].ChangeFrameNumberForPageNumber(newPage.PageNumber, frameNumber);

            _addedPagesInfo.Add(
                new PageInfo()
            {
                ProcessID = newPage.ProcessID, PageNumber = newPage.PageNumber
            });
            PageReplacedEvent?.Invoke(oldPageInfo.ProcessID, oldPageInfo.PageNumber, newPage.ProcessID, newPage.PageNumber);

            PageFaultHandledEvent?.Invoke(true, frameNumber, newPage.ProcessID, newPage.PageNumber);
            PageTableAnswerEvent?.Invoke(frameNumber, newPage.ProcessID, newPage.PageNumber);
        }
        private Page HandlePageFault(int processID, int pageNumber)
        {
            Page askedPage = _virtualMemory.ExtractPage(processID, pageNumber);

            if (_physicalMemory.IsFull)
            {
                ReplacePageFIFO(askedPage);
            }
            else
            {
                int newFrameNumber = _physicalMemory.InsertPage(askedPage);
                _pageTables[processID].ChangeFrameNumberForPageNumber(pageNumber, newFrameNumber);

                _addedPagesInfo.Add(
                    new PageInfo()
                {
                    ProcessID = processID, PageNumber = pageNumber
                });

                PageFaultHandledEvent?.Invoke(false, newFrameNumber, processID, pageNumber);
                PageTableAnswerEvent?.Invoke(newFrameNumber, processID, pageNumber);
            }

            return(askedPage);
        }
        public Page GetPage(int processID, int pageNumber)
        {
            PageTableRequestEvent?.Invoke(processID, pageNumber);

            int frameNumber = _pageTables[processID].FindFrameNumber(pageNumber);

            if (frameNumber != -1)
            {
                PageTableAnswerEvent?.Invoke(frameNumber, processID, pageNumber);
                return(_physicalMemory.GetPage(frameNumber));
            }
            else
            {
                PageFaultOccuredEvent?.Invoke(processID, pageNumber);
                return(HandlePageFault(processID, pageNumber));
            }
        }