bool INIFile::writeINIFile( void ) { if ( !isDirty() ) return true; // if ( invalid ) // return false; FILE *inf; // here we need to stat the file to see if it has changed // - but what do we do if it has? We should have loaded // it VERY recently if ( ( inf = fopen( loadedFileName.c_str(), "wt" ) ) == 0 ) return false; for ( std::vector <IniSectionPtr>::iterator thisSect = sections.begin(); thisSect != sections.end(); thisSect++ ) { const std::string sname = ( *thisSect ) ->name; if ( ( *thisSect ) ->isValidSection() ) fprintf( inf, "[%s]\n", sname.c_str() ); for ( std::vector <IniEntryPtr>::iterator this_entry = ( *thisSect ) ->entries.begin(); this_entry != ( *thisSect ) ->entries.end(); this_entry++ ) { const std::string name = ( *this_entry ) ->name; const std::string val = ( *this_entry ) ->getValue(); if ( ( *this_entry ) ->isValidEntry() ) fprintf( inf, "%s=%s\n", name.c_str(), val.c_str() ); else fprintf( inf, "%s\n", val.c_str() ); // treat as annotation } } fclose( inf ); setClean(); // now stat the file so we can check for changes checkStat(); return true; }
void Form::update(float elapsedTime) { if (isDirty()) { updateBounds(); // Cache themed attributes for performance. _skin = getSkin(_state); _opacity = getOpacity(_state); GP_ASSERT(_layout); if (_scroll != SCROLL_NONE) { updateScroll(); } else { _layout->update(this, Vector2::zero()); } } }
void Form::draw() { // If this form has a node then it's a 3D form. The contents will be rendered // into a framebuffer which will be used to texture a quad. The quad will be // given the same dimensions as the form and must be transformed appropriately // by the user, unless they call setQuad() themselves. // On the other hand, if this form has not been set on a node it will render // directly to the display. if (_node) { // Check whether this form has changed since the last call to draw() // and if so, render into the framebuffer. if (isDirty()) { _frameBuffer->bind(); Game* game = Game::getInstance(); Rectangle prevViewport = game->getViewport(); game->setViewport(Rectangle(_bounds.x, _bounds.y, _bounds.width, _bounds.height)); draw(_theme->getSpriteBatch(), _clip); // Rebind the default framebuffer and game viewport. FrameBuffer::bindDefault(); // restore the previous game viewport game->setViewport(prevViewport); } _quad->draw(); } else { draw(_theme->getSpriteBatch(), _clip); } }
void vmsAppSettingsStore::SaveSettingsToFile(LPCSTR pszFile) { if (!isDirty()) return; HANDLE hFile = CreateFile (pszFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL); if (hFile == INVALID_HANDLE_VALUE) return; try { DWORD dwRequiredSize = 0; DWORD dw = 0; getStateBuffer(0, &dwRequiredSize, false); if (dwRequiredSize == 0) return; std::auto_ptr<BYTE> apbtBufferGuard( new BYTE[dwRequiredSize] ); LPBYTE pbtBuffer = apbtBufferGuard.get(); if (pbtBuffer == 0) return; memset(pbtBuffer, 0, dwRequiredSize); getStateBuffer(pbtBuffer, &dwRequiredSize, true); if (FALSE == WriteFile (hFile, pbtBuffer, dwRequiredSize, &dw, NULL) || dw != dwRequiredSize) { CloseHandle (hFile); return; } CloseHandle (hFile); onStateSavedSuccessfully(); } catch (...) { } }
void OctreeElement::printDebugDetails(const char* label) const { unsigned char childBits = 0; for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { OctreeElement* childAt = getChildAtIndex(i); if (childAt) { setAtBit(childBits,i); } } QDebug elementDebug = qDebug().nospace(); QString resultString; resultString.sprintf("%s - Voxel at corner=(%f,%f,%f) size=%f\n isLeaf=%s isDirty=%s shouldRender=%s\n children=", label, (double)_cube.getCorner().x, (double)_cube.getCorner().y, (double)_cube.getCorner().z, (double)_cube.getScale(), debug::valueOf(isLeaf()), debug::valueOf(isDirty()), debug::valueOf(getShouldRender())); elementDebug << resultString; outputBits(childBits, &elementDebug); qDebug("octalCode="); printOctalCode(getOctalCode()); }
void Himmel::update() { AbstractHimmel::update(); updateSeed(); if(isDirty()) { const t_aTime atime = t_aTime::fromTimeF(*getTime()); astro()->update(atime); osg::Vec3f sunv = astro()->getSunPosition(false); u_sun->set(sunv); osg::Vec3f sunrv = astro()->getSunPosition(true); u_sunr->set(sunrv); u_time->set(static_cast<float>(getTime()->getf())); if(m_starmap) m_starmap->update(*this); if(m_moon) { m_moon->update(*this); //m_moonGlare->update(*this); } if(m_stars) m_stars->update(*this); if(m_atmosphere) m_atmosphere->update(*this); if(m_highLayer) m_highLayer->update(*this); if(m_dubeLayer) m_dubeLayer->update(*this); dirty(false); } }
Vector<IntRect> Tile::updateBackBuffer() { if (m_buffer && !isDirty()) return Vector<IntRect>(); if (!m_backBuffer) { if (!m_buffer) { m_backBuffer = new QPixmap(m_backingStore->m_tileSize.width(), m_backingStore->m_tileSize.height()); m_backBuffer->fill(m_backingStore->m_client->tiledBackingStoreBackgroundColor()); } else { // Currently all buffers are updated synchronously at the same time so there is no real need // to have separate back and front buffers. Just use the existing buffer. m_backBuffer = m_buffer; m_buffer = 0; } } QVector<QRect> dirtyRects = m_dirtyRegion->rects(); *m_dirtyRegion = QRegion(); QPainter painter(m_backBuffer); GraphicsContext context(&painter); context.translate(-m_rect.x(), -m_rect.y()); Vector<IntRect> updatedRects; int size = dirtyRects.size(); for (int n = 0; n < size; ++n) { context.save(); IntRect rect = dirtyRects[n]; updatedRects.append(rect); context.clip(FloatRect(rect)); context.scale(FloatSize(m_backingStore->m_contentsScale, m_backingStore->m_contentsScale)); m_backingStore->m_client->tiledBackingStorePaint(&context, m_backingStore->mapToContents(rect)); context.restore(); } return updatedRects; }
int TableItem_t::getSerializeSize(const TableConfig* config, bool dirty, bool only_primary) { int len = 0; for (int i = 0; i < config->column_num; i++){ if (only_primary && !config->isPrimary(i)) {continue;} if (dirty && !isDirty(i) && !config->isPrimary(i)) {continue;} switch (config->types[i]) { case OBJECT_INT32: len += 7; break; case OBJECT_STRING: len += (7 + get<std::string>(config, i).length()); break; case OBJECT_INT64: len += 11; break; case OBJECT_UINT64: len += 11; break; case OBJECT_UINT32: len += 7; break; case OBJECT_BOOL: len += 4; break; case OBJECT_UINT8: len += 4; break; case OBJECT_INT8: len += 4; break; case OBJECT_UINT16: len += 5; break; case OBJECT_INT16: len += 5; break; case OBJECT_FLOAT: len += 7; break; case OBJECT_DOUBLE: len += 11; break; } } return len; }
/*! Removes \a count rows starting at \a row. Since this model does not support hierarchical structures, \a parent must be an invalid model index. When the edit strategy is OnManualSubmit, deletion of rows from the database is delayed until submitAll() is called. For OnFieldChange and OnRowChange, only one row may be deleted at a time and only if no other row has a cached change. Deletions are submitted immediately to the database. The model retains a blank row for successfully deleted row until refreshed with select(). After failed deletion, the operation is not reverted in the model. The application may resubmit or revert. Inserted but not yet successfully submitted rows in the range to be removed are immediately removed from the model. Before a row is deleted from the database, the beforeDelete() signal is emitted. If row < 0 or row + count > rowCount(), no action is taken and false is returned. Returns \c true if all rows could be removed; otherwise returns \c false. Detailed database error information can be retrieved using lastError(). \sa removeColumns(), insertRows() */ bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent) { Q_D(QSqlTableModel); if (parent.isValid() || row < 0 || count <= 0) return false; else if (row + count > rowCount()) return false; else if (!count) return true; if (d->strategy != OnManualSubmit) if (count > 1 || (d->cache.value(row).submitted() && isDirty())) return false; // Iterate backwards so we don't have to worry about removed rows causing // higher cache entries to shift downwards. for (int idx = row + count - 1; idx >= row; --idx) { QSqlTableModelPrivate::ModifiedRow& mrow = d->cache[idx]; if (mrow.op() == QSqlTableModelPrivate::Insert) { revertRow(idx); } else { if (mrow.op() == QSqlTableModelPrivate::None) mrow = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Delete, QSqlQueryModel::record(idx)); else mrow.setOp(QSqlTableModelPrivate::Delete); if (d->strategy == OnManualSubmit) emit headerDataChanged(Qt::Vertical, idx, idx); } } if (d->strategy != OnManualSubmit) return submit(); return true; }
/** Refreshes the current value of the SystemSettings which holds the aircraft type Note: The default behavior of ConfigTaskWidget is bypassed. Therefore no automatic synchronization of UAV Objects to UI is done. */ void ConfigVehicleTypeWidget::refreshWidgetsValues(UAVObject *o) { Q_UNUSED(o); if (!allObjectsUpdated()) { return; } bool dirty = isDirty(); // Get the Airframe type from the system settings: UAVDataObject *system = dynamic_cast<UAVDataObject *>(getObjectManager()->getObject(QString("SystemSettings"))); Q_ASSERT(system); UAVObjectField *field = system->getField(QString("AirframeType")); Q_ASSERT(field); // At this stage, we will need to have some hardcoded settings in this code, this // is not ideal, but there you go. QString frameType = field->getValue().toString(); qDebug() << "ConfigVehicleTypeWidget::refreshWidgetsValues - frame type:" << frameType; QString category = frameCategory(frameType); setComboCurrentIndex(m_aircraft->aircraftType, m_aircraft->aircraftType->findText(category)); VehicleConfig *vehicleConfig = getVehicleConfigWidget(category); if (vehicleConfig) { vehicleConfig->refreshWidgetsValues(frameType); } updateFeedForwardUI(); setDirty(dirty); qDebug() << "ConfigVehicleTypeWidget::refreshWidgetsValues - end"; }
/*! Inserts \a count empty rows at position \a row. Note that \a parent must be invalid, since this model does not support parent-child relations. For edit strategies OnFieldChange and OnRowChange, only one row may be inserted at a time and the model may not contain other cached changes. The primeInsert() signal will be emitted for each new row. Connect to it if you want to initialize the new row with default values. Does not submit rows, regardless of edit strategy. Returns \c false if the parameters are out of bounds or the row cannot be inserted; otherwise returns \c true. \sa primeInsert(), insertRecord() */ bool QSqlTableModel::insertRows(int row, int count, const QModelIndex &parent) { Q_D(QSqlTableModel); if (row < 0 || count <= 0 || row > rowCount() || parent.isValid()) return false; if (d->strategy != OnManualSubmit) if (count != 1 || isDirty()) return false; d->busyInsertingRows = true; beginInsertRows(parent, row, row + count - 1); if (d->strategy != OnManualSubmit) d->cache.empty(); if (!d->cache.isEmpty()) { QMap<int, QSqlTableModelPrivate::ModifiedRow>::Iterator it = d->cache.end(); while (it != d->cache.begin() && (--it).key() >= row) { int oldKey = it.key(); const QSqlTableModelPrivate::ModifiedRow oldValue = it.value(); d->cache.erase(it); it = d->cache.insert(oldKey + count, oldValue); } } for (int i = 0; i < count; ++i) { d->cache[row + i] = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Insert, d->rec); emit primeInsert(row + i, d->cache[row + i].recRef()); } endInsertRows(); d->busyInsertingRows = false; return true; }
bool C4FoWBeam::MergeRight(int32_t x, int32_t y) { // Note: Right-merging is the most common and most important optimization. // This procedure will probably be *hammered* as a result. Worth inlining? assert(!isDirty()); assert(isRight(x, y)); // Calculate error. Note that simply summing up errors is not correct, // strictly speaking (as new and old error surfaces might overlap). Still, // this is quite elaborate already, no need to make it even more int32_t iErr = getDoubleTriangleSurface( getLeftEndX(), iLeftEndY, getRightEndX(), iRightEndY, x, y); if (iError + iErr > C4FoWMergeThreshold) return false; // Move right endpoint. iRightX = x; iRightY = y; iRightEndY = y; iError += iErr; return true; }
void Sprite::updateTransform(void) { CCASSERT(_batchNode, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode"); // recalculate matrix only if it is dirty if( isDirty() ) { // If it is not visible, or one of its ancestors is not visible, then do nothing: if( !_visible || ( _parent && _parent != _batchNode && static_cast<Sprite*>(_parent)->_shouldBeHidden) ) { _quad.br.vertices = _quad.tl.vertices = _quad.tr.vertices = _quad.bl.vertices = Vertex3F(0,0,0); _shouldBeHidden = true; } else { _shouldBeHidden = false; if( ! _parent || _parent == _batchNode ) { _transformToBatch = getNodeToParentTransform(); } else { CCASSERT( dynamic_cast<Sprite*>(_parent), "Logic error in Sprite. Parent must be a Sprite"); kmMat4 nodeToParent = getNodeToParentTransform(); kmMat4 parentTransform = static_cast<Sprite*>(_parent)->_transformToBatch; kmMat4Multiply(&_transformToBatch, &parentTransform, &nodeToParent); } // // calculate the Quad based on the Affine Matrix // Size size = _rect.size; float x1 = _offsetPosition.x; float y1 = _offsetPosition.y; float x2 = x1 + size.width; float y2 = y1 + size.height; float x = _transformToBatch.mat[12]; float y = _transformToBatch.mat[13]; float cr = _transformToBatch.mat[0]; float sr = _transformToBatch.mat[1]; float cr2 = _transformToBatch.mat[5]; float sr2 = -_transformToBatch.mat[4]; float ax = x1 * cr - y1 * sr2 + x; float ay = x1 * sr + y1 * cr2 + y; float bx = x2 * cr - y1 * sr2 + x; float by = x2 * sr + y1 * cr2 + y; float cx = x2 * cr - y2 * sr2 + x; float cy = x2 * sr + y2 * cr2 + y; float dx = x1 * cr - y2 * sr2 + x; float dy = x1 * sr + y2 * cr2 + y; _quad.bl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(ax), RENDER_IN_SUBPIXEL(ay), _positionZ ); _quad.br.vertices = Vertex3F( RENDER_IN_SUBPIXEL(bx), RENDER_IN_SUBPIXEL(by), _positionZ ); _quad.tl.vertices = Vertex3F( RENDER_IN_SUBPIXEL(dx), RENDER_IN_SUBPIXEL(dy), _positionZ ); _quad.tr.vertices = Vertex3F( RENDER_IN_SUBPIXEL(cx), RENDER_IN_SUBPIXEL(cy), _positionZ ); } // MARMALADE CHANGE: ADDED CHECK FOR nullptr, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS if (_textureAtlas) { _textureAtlas->updateQuad(&_quad, _atlasIndex); } _recursiveDirty = false; setDirty(false); } // MARMALADE CHANGED // recursively iterate over children /* if( _hasChildren ) { // MARMALADE: CHANGED TO USE Node* // NOTE THAT WE HAVE ALSO DEFINED virtual Node::updateTransform() arrayMakeObjectsPerformSelector(_children, updateTransform, Sprite*); }*/ Node::updateTransform(); }
Vector3f Frame::getPos(void) { if( isDirty() ) synchronizeSafe(); return wrap( dxPos( <M ) ); }
Matrix4f Frame::getLTM(void) { if( isDirty() ) synchronizeSafe(); return wrap( LTM ); }
libember::glow::GlowStreamCollection* StreamConverter::create(libember::glow::GlowStreamCollection* root, gadget::StreamManager const& manager) { typedef std::vector<gadget::Parameter*> ParameterCollection; std::map<int, std::unique_ptr<ParameterCollection> > dic; { auto it = std::begin(manager); auto const last= std::end(manager); for (; it != last; ++it) { auto& parameter = *it; auto const identifier = parameter->streamIdentifier(); if (dic.find(identifier) == std::end(dic)) { dic[identifier] = std::unique_ptr<ParameterCollection>(new ParameterCollection()); } dic[identifier]->push_back(parameter); } } { for(auto& pair : dic) { auto& streams = *pair.second; auto const identifier = pair.first; auto const size = streams.size(); if (size == 1 && streams.front()->hasStreamDescriptor() == false) { auto parameter = streams.front(); if (parameter->isSubscribed() && parameter->isDirty()) { auto entry = SingleStreamEntryFactory::create(parameter); root->insert(entry); } } else if (size >= 1) { auto const first = std::begin(streams); auto const last = std::end(streams); auto const result = std::max_element(first, last, [](decltype(*first) max, decltype(*first) cur) -> bool { if (max->hasStreamDescriptor() && cur->hasStreamDescriptor()) { return cur->streamDescriptor()->offset() > max->streamDescriptor()->offset(); } else if (max->hasStreamDescriptor()) { return false; } else if (cur->hasStreamDescriptor()) { return true; } return false; }); auto const isSubscribed = std::any_of(first, last, [](decltype(*first) stream) -> bool { return stream->isSubscribed() && stream->isDirty(); }); if (result != last && isSubscribed) { auto descriptor = (*result)->streamDescriptor(); auto const format = descriptor->format(); auto const offset = descriptor->offset(); auto const size = offset + format.size(); auto buffer = std::vector<unsigned char>(size, 0x00); for(auto parameter : streams) { encode(parameter, std::begin(buffer), std::end(buffer)); parameter->clearDirtyState(); } root->insert(identifier, std::begin(buffer), std::end(buffer)); } } } } return root; }
/** This upload the results from texture image to the graphics card */ void cwImageTexture::updateData() { if(!isDirty()) { return; } if(DeleteTexture) { deleteGLTexture(); TextureDirty = false; return; } if(TextureUploadTask == nullptr) { TextureDirty = false; return; } if(TextureUploadTask->isRunning()) { return; } QList<QPair<QByteArray, QSize> > mipmaps = TextureUploadTask->mipmaps(); ScaleTexCoords = TextureUploadTask->scaleTexCoords(); if(mipmaps.empty()) { return; } QSize firstLevel = mipmaps.first().second; if(!cwTextureUploadTask::isDivisibleBy4(firstLevel)) { qDebug() << "Trying to upload an image that isn't divisible by 4. This will crash ANGLE on windows." << LOCATION; TextureDirty = false; return; } //Load the data into opengl bind(); //Get the max texture size GLint maxTextureSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); int trueMipmapLevel = 0; for(int mipmapLevel = 0; mipmapLevel < mipmaps.size(); mipmapLevel++) { //Get the mipmap data QPair<QByteArray, QSize> image = mipmaps.at(mipmapLevel); QByteArray imageData = image.first; QSize size = image.second; if(size.width() < maxTextureSize && size.height() < maxTextureSize) { glCompressedTexImage2D(GL_TEXTURE_2D, trueMipmapLevel, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, size.width(), size.height(), 0, imageData.size(), imageData.data()); trueMipmapLevel++; #ifdef Q_OS_WIN //Only upload one texture, because some intel cards, don't support npot dxt1 copression, so we just used nearest //FIXME: ADD to rendering settings! break; #endif //Q_OS_WIN } } release(); deleteLoadNoteTask(); TextureDirty = false; }
QRegion QSGAbstractSoftwareRenderer::optimizeRenderList() { // Iterate through the renderlist from front to back // Objective is to update the dirty status and rects. for (auto i = m_renderableNodes.rbegin(); i != m_renderableNodes.rend(); ++i) { auto node = *i; if (!m_dirtyRegion.isEmpty()) { // See if the current dirty regions apply to the current node node->addDirtyRegion(m_dirtyRegion, true); } if (!m_obscuredRegion.isEmpty()) { // Don't try to paint things that are covered by opaque objects node->subtractDirtyRegion(m_obscuredRegion); } // Keep up with obscured regions if (node->isOpaque()) { m_obscuredRegion += node->boundingRectMin(); } if (node->isDirty()) { // Don't paint things outside of the rendering area if (!m_background->rect().toRect().contains(node->boundingRectMax(), /*proper*/ true)) { // Some part(s) of node is(are) outside of the rendering area QRegion renderArea(m_background->rect().toRect()); QRegion outsideRegions = node->dirtyRegion().subtracted(renderArea); if (!outsideRegions.isEmpty()) node->subtractDirtyRegion(outsideRegions); } // Get the dirty region's to pass to the next nodes if (node->isOpaque()) { // if isOpaque, subtract node's dirty rect from m_dirtyRegion m_dirtyRegion -= node->boundingRectMin(); } else { // if isAlpha, add node's dirty rect to m_dirtyRegion m_dirtyRegion += node->dirtyRegion(); } // if previousDirtyRegion has content outside of boundingRect add to m_dirtyRegion QRegion prevDirty = node->previousDirtyRegion(); if (!prevDirty.isNull()) m_dirtyRegion += prevDirty; } } if (m_obscuredRegion.contains(m_background->rect().toAlignedRect())) { m_isOpaque = true; } else { m_isOpaque = false; } // Empty dirtyRegion (for second pass) m_dirtyRegion = QRegion(); m_obscuredRegion = QRegion(); // Iterate through the renderlist from back to front // Objective is to make sure all non-opaque items are painted when an item under them is dirty for (auto j = m_renderableNodes.begin(); j != m_renderableNodes.end(); ++j) { auto node = *j; if (!node->isOpaque() && !m_dirtyRegion.isEmpty()) { // Only blended nodes need to be updated node->addDirtyRegion(m_dirtyRegion, true); } m_dirtyRegion += node->dirtyRegion(); } QRegion updateRegion = m_dirtyRegion; // Empty dirtyRegion m_dirtyRegion = QRegion(); m_obscuredRegion = QRegion(); return updateRegion; }
void Sprite::updateTransform() { CCASSERT(_batchNode, "updateTransform is only valid when Sprite is being rendered using an SpriteBatchNode"); // recalculate matrix only if it is dirty if( isDirty() ) { // If it is not visible, or one of its ancestors is not visible, then do nothing: if( !_visible || ( _parent && _parent != _batchNode && static_cast<Sprite*>(_parent)->_shouldBeHidden) ) { _quad.br.vertices.setZero(); _quad.tl.vertices.setZero(); _quad.tr.vertices.setZero(); _quad.bl.vertices.setZero(); _shouldBeHidden = true; } else { _shouldBeHidden = false; if( ! _parent || _parent == _batchNode ) { _transformToBatch = getNodeToParentTransform(); } else { CCASSERT( dynamic_cast<Sprite*>(_parent), "Logic error in Sprite. Parent must be a Sprite"); const Mat4 &nodeToParent = getNodeToParentTransform(); Mat4 &parentTransform = static_cast<Sprite*>(_parent)->_transformToBatch; _transformToBatch = parentTransform * nodeToParent; } // // calculate the Quad based on the Affine Matrix // Size &size = _rect.size; float x1 = _offsetPosition.x; float y1 = _offsetPosition.y; float x2 = x1 + size.width; float y2 = y1 + size.height; float x = _transformToBatch.m[12]; float y = _transformToBatch.m[13]; float cr = _transformToBatch.m[0]; float sr = _transformToBatch.m[1]; float cr2 = _transformToBatch.m[5]; float sr2 = -_transformToBatch.m[4]; float ax = x1 * cr - y1 * sr2 + x; float ay = x1 * sr + y1 * cr2 + y; float bx = x2 * cr - y1 * sr2 + x; float by = x2 * sr + y1 * cr2 + y; float cx = x2 * cr - y2 * sr2 + x; float cy = x2 * sr + y2 * cr2 + y; float dx = x1 * cr - y2 * sr2 + x; float dy = x1 * sr + y2 * cr2 + y; _quad.bl.vertices.set(SPRITE_RENDER_IN_SUBPIXEL(ax), SPRITE_RENDER_IN_SUBPIXEL(ay), _positionZ); _quad.br.vertices.set(SPRITE_RENDER_IN_SUBPIXEL(bx), SPRITE_RENDER_IN_SUBPIXEL(by), _positionZ); _quad.tl.vertices.set(SPRITE_RENDER_IN_SUBPIXEL(dx), SPRITE_RENDER_IN_SUBPIXEL(dy), _positionZ); _quad.tr.vertices.set(SPRITE_RENDER_IN_SUBPIXEL(cx), SPRITE_RENDER_IN_SUBPIXEL(cy), _positionZ); setTextureCoords(_rect); } // MARMALADE CHANGE: ADDED CHECK FOR nullptr, TO PERMIT SPRITES WITH NO BATCH NODE / TEXTURE ATLAS if (_textureAtlas) { _textureAtlas->updateQuad(&_quad, _atlasIndex); } _recursiveDirty = false; setDirty(false); } Node::updateTransform(); }
// Determine if a note is dirty given a guid bool NoteTable::isDirty(QString guid) { qint32 lid = getLid(guid); return isDirty(lid); }
// Determine if a note is dirty given a guid bool NoteTable::isDirty(string guid) { QString g(QString::fromStdString(guid)); return isDirty(g); }
//---------------------------------------------------------------------------------------- void MaterialEditorPrefsEditor::setDirty() { emit isDirty(); }
BOOL vmsDownloadsGroupsMgr::SaveToDisk() { fsString strFile = fsGetDataFilePath ("groups.sav"); if (!isDirty()) return TRUE; HANDLE hFile = CreateFile (strFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, NULL); if (hFile == INVALID_HANDLE_VALUE) return FALSE; vmsDownloadsGroupsFileHdr hdr; DWORD dw; if (FALSE == WriteFile (hFile, &hdr, sizeof (hdr), &dw, NULL)) { CloseHandle (hFile); return FALSE; } DWORD dwRequiredSize = 0; getStateBuffer(0, &dwRequiredSize, false); if (dwRequiredSize == 0) return FALSE; std::auto_ptr<BYTE> apbtBufferGuard( new BYTE[dwRequiredSize] ); LPBYTE pbtBuffer = apbtBufferGuard.get(); if (pbtBuffer == 0) return FALSE; memset(pbtBuffer, 0, dwRequiredSize); getStateBuffer(pbtBuffer, &dwRequiredSize, true); if (FALSE == WriteFile (hFile, pbtBuffer, dwRequiredSize, &dw, NULL) || dw != dwRequiredSize) { CloseHandle (hFile); return FALSE; } CloseHandle (hFile); onStateSavedSuccessfully(); return TRUE; }
bool Cluster::update() { if (!Node::update()) return false; if (!isDirty(this, 40)) return true; boost::timer t1; cv::Mat in = getImage("in"); if (in.empty()) return false; const bool use_manhat = getSignal("manhat") > 0.5; float max_space_dist = (in.cols*in.cols + in.rows*in.rows); if (use_manhat) max_space_dist = (in.cols + in.rows); cv::Mat out = in.clone(); /* if (has_initted) { has_initted = true; } */ const float margin = getSignal("margin"); const float upper = 1.0 + margin; const float lower = 1.0 - margin; const float dist_weight = getSignal("dist_weight"); int num = getSignal("num"); // 1 just tracks the average color of the image if (num < 1) num = 1; // TBD arbitrary maximum if (num > 10) num = 10; const int old_size = clusters.size(); clusters.resize(num); std::vector<cluster_center> nc; nc.resize(clusters.size()); for (int k = 0; k < nc.size(); k++) { initCluster(nc[k], in.cols, in.rows); if (k >= old_size) { initCluster(clusters[k], in.cols, in.rows, true); LOG(INFO) << k << " " << old_size << " " << nc.size() << ", " << clusters[k].x; } } const bool wrap = getSignal("wrap") > 0.5; const int wd = in.cols; const int ht = in.rows; for (int y = 0; y < in.rows; ++y) { for (int x = 0; x < in.cols; ++x) { cv::Vec4b src2 = in.at<cv::Vec4b> (y,x); float dist = max_space_dist; int dist_ind = 0; // search through all clusters for nearest one for (int k = 0; k < clusters.size(); k++) { struct cluster_center cc = clusters[k]; int x2 = x; int y2 = y; if (wrap) { float dx = cc.x - x2; float dy = cc.y - y2; if (dx + wd < -dx) x2 -= wd; else if ( -(dx - wd) < dx) x2 += wd; if (dy + ht < - y2) y2 -= ht; else if ( -(dy - ht) < dy) y2 += ht; } // There might be an inevitable amount of oscillation in wrap mode where // points that might be within range in multiple directions // will flip-flop between them. // could try to smooth motion of colors and centers const float span_x = (cc.max_x - cc.min_x)*(upper)+10; const float span_y = (cc.max_y - cc.min_y)*upper; const int mid_x = (cc.max_x + cc.min_x)/2; const int mid_y = (cc.max_y + cc.min_y)/2; if ((x2 < mid_x + span_x/2) && (x2 > mid_x - span_x/2) && (y2 < mid_y + span_y/2) && (y2 > mid_y - span_y/2)) { const float kdist = find_dist( src2.val[0], src2.val[1], src2.val[2], x2, y2, cc.rgb.val[0], cc.rgb.val[1], cc.rgb.val[2], cc.x, cc.y, max_space_dist, dist_weight, use_manhat); //in.cols, in.rows); //, //wrap); //, inst->color_weight); // store the closest match if (kdist < dist) { dist = kdist; dist_ind = k; } } } // clusters // update min maxes if (x > nc[dist_ind].max_x) nc[dist_ind].max_x = x; if (x < nc[dist_ind].min_x) nc[dist_ind].min_x = x; if (y > nc[dist_ind].max_y) nc[dist_ind].max_y = y; if (y < nc[dist_ind].min_y) nc[dist_ind].min_y = y; nc[dist_ind].aggr_x += x; nc[dist_ind].aggr_y += y; nc[dist_ind].aggr_r += src2.val[0]; nc[dist_ind].aggr_g += src2.val[1]; nc[dist_ind].aggr_b += src2.val[2]; nc[dist_ind].numpix += 1.0; // use the old cluster center color out.at<cv::Vec4b>(y,x) = clusters[dist_ind].rgb; // TBD optionally provide a scaled image that encodes distance from centers //out.at<cv::Vec4b>(y,x) = cv::Vec4b(dist*1024, dist*512, // dist*256, 0); // clusters[dist_ind].rgb.val[2],0); }} // xy loop throug input image setImage("out", out); //setSignal("num", nc.size()); /// update cluster_centers for (int k = 0; k < nc.size(); k++) { if (nc[k].numpix > 0) { nc[k].x = (int) (nc[k].aggr_x/nc[k].numpix); nc[k].y = (int) (nc[k].aggr_y/nc[k].numpix); nc[k].rgb = cv::Vec4b( (unsigned char) (nc[k].aggr_r/nc[k].numpix), (unsigned char) (nc[k].aggr_g/nc[k].numpix), (unsigned char) (nc[k].aggr_b/nc[k].numpix), 0 ); } setSignal("x" + boost::lexical_cast<std::string>(k), nc[k].x); setSignal("y" + boost::lexical_cast<std::string>(k), nc[k].y); if (false) { setSignal("mnx" + boost::lexical_cast<std::string>(k), nc[k].min_x); setSignal("mny" + boost::lexical_cast<std::string>(k), nc[k].min_y); setSignal("mxx" + boost::lexical_cast<std::string>(k), nc[k].max_x); setSignal("mxy" + boost::lexical_cast<std::string>(k), nc[k].max_y); } setSignal("r" + boost::lexical_cast<std::string>(k), nc[k].rgb.val[0]); setSignal("g" + boost::lexical_cast<std::string>(k), nc[k].rgb.val[1]); setSignal("b" + boost::lexical_cast<std::string>(k), nc[k].rgb.val[2]); setSignal("p" + boost::lexical_cast<std::string>(k), nc[k].numpix); } clusters = nc; //setSignal("time", t1.elapsed()); }
void LLPanelClassifiedEdit::onChange() { enableVerbs(isDirty()); }
//run the aging simulation void simulateAging(bit32 numFrames, const char *fileName, bit32 refresh) { struct agingFrame *frames; //memory frames struct memRef *memList, *curr; //pointer to the current memory reference bit32 *pageTable; //page table bit32 numRefs = 0, numFaults = 0, numWrites = 0; //stat counters bit32 i, pageNo; //current page number and loop control bit32 usedFrames = 0; //used frames - for compulsory misses //set up page table and ensure all bits are 0 pageTable = (bit32 *) malloc(NUM_PAGES * sizeof(bit32)); memset(pageTable, 0, sizeof(bit32) * NUM_PAGES); //set up the memory frames frames = (struct agingFrame *) malloc(numFrames * sizeof(struct agingFrame)); for(i = 0; i < numFrames; i++) { frames[i].pageNo = ZERO; frames[i].age = 0; } //read the file in and store the references and future uses of the references readFile(&memList, fileName); curr = memList; while(curr != NULL) { //if we have hit the end of the refresh period, shift the ref bit in to the age of each frame //also unreference each frame if(numRefs % refresh == 0) { for(i = 0; i < numFrames; i++) { frames[i].age = frames[i].age >> 1; if(isRef(pageTable, frames[i].pageNo)) { frames[i].age = frames[i].age | AGING_REF; } pageTable[frames[i].pageNo] = pageTable[frames[i].pageNo] & CLEAR_REF; } } pageNo = getPageNumber(curr->reference); if(isValid(pageTable, pageNo)) { //page already already valid/in a frame - hit pageHitSetBits(pageTable, pageNo, curr->mode); //set appropriate bits printf("%i\thit\n", numRefs + 1); } else { //page is not in frame yet - miss numFaults++; //compulsory miss - will only happen numFrames times if(usedFrames < numFrames) { frames[usedFrames].pageNo = pageNo; //store the page number in the frame //update the page table entry placePageInFrame(pageTable, pageNo, usedFrames, curr->mode); //map current page to frame usedFrames++; printf("%i\tpage fault - no eviction\n", numRefs + 1); } else { //capacity miss - frames are full and page is not in a frame - will need to evict bit32 oldestFrame = 0; unsigned short int min = NINE_BITS; for(i = 0; i < numFrames; i++) { //find the oldest frame unsigned short int age = frames[i].age; if(isRef(pageTable, frames[i].pageNo)) { //if page is referenced, shift on the 9th bit age = age | AGING_REF; } if(age < min) { oldestFrame = i; min = age; } } //ends for //evict the oldest frame if(isDirty(pageTable, frames[oldestFrame].pageNo)) { numWrites++; printf("%i\tpage fault - evict dirty\n", numRefs + 1); } else { printf("%i\tpage fault - evict clean\n", numRefs + 1); } evictPage(pageTable, frames[oldestFrame].pageNo); frames[oldestFrame].pageNo = pageNo; //store the page number in the frame //update the page table entry placePageInFrame(pageTable, pageNo, oldestFrame, curr->mode); //map current page to frame } } //increment number of references and move to next reference numRefs++; curr = curr->next; } //print stats printf("\nAging\n"); printf("Number of frames:\t%i\n", numFrames); printf("Total memory accesses:\t%i\n", numRefs); printf("Total page faults:\t%i\n", numFaults); printf("Total writes to disk:\t%i\n\n", numWrites); //clean up memory free(frames); }
//run the clock simulation void simulateClock(bit32 numFrames, const char *fileName) { struct clockFrame *frames, *currFrame; //pointers to the frame list and the current frame bit32 *pageTable; //page table struct memRef *memList, *currRef; //pointer to current memory reference bit32 numFaults = 0, numWrites = 0, numRefs = 0; //stat counters bit32 usedFrames = 0, pageNo, i; //number of used frames, loop counter //set up page table and ensure all bits are 0 pageTable = (bit32 *) malloc(NUM_PAGES * sizeof(bit32)); memset(pageTable, 0, sizeof(bit32) * NUM_PAGES); //set up the frame clock for(i = 0; i < numFrames; i++) { struct clockFrame *temp = (struct clockFrame *) malloc(sizeof(struct clockFrame)); temp->frameNo = i; temp->pageNo = ZERO; temp->next = NULL; if(i == 0) { frames = temp; //if its the first time through, we've created the first frame } else { currFrame->next = temp; //if it's not the first, temp frame should be pointed to by previous frame } currFrame = temp; //update curr } currFrame->next = frames; currFrame = frames; //read the file in and store the references and future uses of the references readFile(&memList, fileName); currRef = memList; while(currRef != NULL) { pageNo = getPageNumber(currRef->reference); if(isValid(pageTable, pageNo)) { //page already valid/in a frame - hit pageHitSetBits(pageTable, pageNo, currRef->mode); //set appropriate bits printf("%i\thit\n", numRefs + 1); } else { //page is not in a frame yet - miss numFaults++; if(usedFrames < numFrames) { //compulsory miss - add the page to the next frame currFrame->pageNo = pageNo; currFrame = currFrame->next; placePageInFrame(pageTable, pageNo, currFrame->frameNo, currRef->mode); //map current page to frame usedFrames++; printf("%i\tpage fault - no eviction\n", numRefs + 1); } else { //capacity miss - frames are full and page is not in a frame - will need to evict //find an unreferenced page, clearing referenced pages along the way while(isRef(pageTable, currFrame->pageNo)) { pageTable[currFrame->pageNo] = pageTable[currFrame->pageNo] & CLEAR_REF; currFrame = currFrame->next; } //currFrame now points to an unreferenced page - evict the frame if(isDirty(pageTable, currFrame->pageNo)) { numWrites++; printf("%i\tpage fault - evict dirty\n", numRefs + 1); } else { printf("%i\tpage fault - evict clean\n", numRefs + 1); } evictPage(pageTable, currFrame->pageNo); currFrame->pageNo = pageNo; //store the page number in the frame placePageInFrame(pageTable, pageNo, currFrame->frameNo, currRef->mode); //map current page to frame //move curr to the next frame currFrame = currFrame->next; } } //increment number of references and move to next reference numRefs++; currRef = currRef->next; } //print stats printf("\nClock\n"); printf("Number of frames:\t%i\n", numFrames); printf("Total memory accesses:\t%i\n", numRefs); printf("Total page faults:\t%i\n", numFaults); printf("Total writes to disk:\t%i\n\n", numWrites); //clean up memory currFrame = frames; for(i = 0; i < numFrames; i++) { frames = currFrame->next; free(currFrame); currFrame = frames; } } //ends clock simulation
void Form::update(float elapsedTime) { if (isDirty()) { _clearBounds.set(_absoluteClipBounds); // Calculate the clipped bounds. float x = 0; float y = 0; float width = _bounds.width; float height = _bounds.height; Rectangle clip(0, 0, _bounds.width, _bounds.height); float clipX2 = clip.x + clip.width; float x2 = clip.x + x + width; if (x2 > clipX2) width -= x2 - clipX2; float clipY2 = clip.y + clip.height; float y2 = clip.y + y + height; if (y2 > clipY2) height -= y2 - clipY2; if (x < 0) { width += x; x = -x; } else { x = 0; } if (y < 0) { height += y; y = -y; } else { y = 0; } _clipBounds.set(x, y, width, height); // Calculate the absolute bounds. x = 0; y = 0; _absoluteBounds.set(x, y, _bounds.width, _bounds.height); // Calculate the absolute viewport bounds. Absolute bounds minus border and padding. const Theme::Border& border = getBorder(_state); const Theme::Padding& padding = getPadding(); x += border.left + padding.left; y += border.top + padding.top; width = _bounds.width - border.left - padding.left - border.right - padding.right; height = _bounds.height - border.top - padding.top - border.bottom - padding.bottom; _viewportBounds.set(x, y, width, height); // Calculate the clip area. Absolute bounds, minus border and padding, clipped to the parent container's clip area. clipX2 = clip.x + clip.width; x2 = x + width; if (x2 > clipX2) width = clipX2 - x; clipY2 = clip.y + clip.height; y2 = y + height; if (y2 > clipY2) height = clipY2 - y; if (x < clip.x) { float dx = clip.x - x; width -= dx; x = clip.x; } if (y < clip.y) { float dy = clip.y - y; height -= dy; y = clip.y; } _viewportClipBounds.set(x, y, width, height); _absoluteClipBounds.set(x - border.left - padding.left, y - border.top - padding.top, width + border.left + padding.left + border.right + padding.right, height + border.top + padding.top + border.bottom + padding.bottom); if (_clearBounds.isEmpty()) { _clearBounds.set(_absoluteClipBounds); } // Cache themed attributes for performance. _skin = getSkin(_state); _opacity = getOpacity(_state); // Get scrollbar images and diminish clipping bounds to make room for scrollbars. if ((_scroll & SCROLL_HORIZONTAL) == SCROLL_HORIZONTAL) { _scrollBarLeftCap = getImage("scrollBarLeftCap", _state); _scrollBarHorizontal = getImage("horizontalScrollBar", _state); _scrollBarRightCap = getImage("scrollBarRightCap", _state); _viewportClipBounds.height -= _scrollBarHorizontal->getRegion().height; } if ((_scroll & SCROLL_VERTICAL) == SCROLL_VERTICAL) { _scrollBarTopCap = getImage("scrollBarTopCap", _state); _scrollBarVertical = getImage("verticalScrollBar", _state); _scrollBarBottomCap = getImage("scrollBarBottomCap", _state); _viewportClipBounds.width -= _scrollBarVertical->getRegion().width; } GP_ASSERT(_layout); if (_scroll != SCROLL_NONE) updateScroll(); else _layout->update(this, Vector2::zero()); } }
//run the OPT algorithm simulation void simulateOpt(bit32 numFrames, const char *fileName) { struct memRef *memList, *curr; //list of memory references bit32 *pageTable; //page table struct nextUse **future; //array of nextUse structures struct nextUse *tempFuture; //used to deallocate nodes of future use bit32 numFaults = 0, numWrites = 0, numRefs = 0; //stat counters struct optFrame *frames; //frame structure bit32 i, pageNo, frameNo, usedFrames = 0; //loop control, page number, frame number, and number of used frames //set up page table and ensure all bits are 0 pageTable = (bit32 *) malloc(NUM_PAGES * sizeof(bit32)); memset(pageTable, 0, sizeof(bit32) * NUM_PAGES); //set up the future array future = (struct nextUse **) malloc(sizeof(struct nextUse *) * NUM_PAGES); for(i = 0; i < NUM_PAGES; i++) { struct nextUse *temp = (struct nextUse *) malloc(sizeof(struct nextUse)); temp->time = MAX_UINT; temp->next = NULL; temp->tail = NULL; *(future + i) = temp; } //read the file in and store the references and future uses of the references readOptFile(&memList, future, fileName); //set up memory frames frames = (struct optFrame *) malloc(sizeof(struct optFrame) * numFrames); for(i = 0; i < numFrames; i++) { frames[i].pageNo = MAX_UINT; frames[i].next = *(future + i); } curr = memList; while(curr != NULL) { pageNo = getPageNumber(curr->reference); if(isValid(pageTable, pageNo)) { //page already already valid/in a frame - hit pageHitSetBits(pageTable, pageNo, curr->mode); //set appropriate bits frameNo = getFrameNumber(pageTable, pageNo); //get the frame number for this page tempFuture = future[pageNo]; //store current use for deallocation future[pageNo] = future[pageNo]->next; //move the next use down one frames[frameNo].next = future[pageNo]; //update the future array with next use of this page free(tempFuture); //deallocate printf("%i\thit\n", numRefs + 1); } else { //page is not in a frame yet - miss numFaults++; //compulsory miss - will only happen numFrames times if(usedFrames < numFrames) { frames[usedFrames].pageNo = pageNo; //store the page number in the frame tempFuture = future[pageNo]; //store current use for deallocation future[pageNo] = future[pageNo]->next; //move the next use of this page down frames[usedFrames].next = future[pageNo]; //update the link to future use in the frame table free(tempFuture); //deallocate the current use placePageInFrame(pageTable, pageNo, usedFrames, curr->mode); //map current page to frame usedFrames++; printf("%i\tpage fault - no eviction\n", numRefs + 1); } else { //capacity miss - evict page not used until furthest in future bit32 furthest = 0; //index of the page with the furthest future use bit32 ptIndex; //page number of the page used furthest in the future i = 0; if(frames[i].next == NULL) { //there is not future use of this page - we were lucky, can avoid loop furthest = i; } else { for(i = 1; i < numFrames; i++) { if(frames[i].next == NULL) { //there is no future use of this page - can safely remove furthest = i; //printf("\tNULL FOUND: furthest = %i", furthest); i = numFrames; //exit loop } else { //find the furthest future use of a page if(frames[i].next->time > frames[furthest].next->time) { furthest = i; } } } } //evict page in frame[furthest] - page used furthest in future ptIndex = frames[furthest].pageNo; if(isDirty(pageTable, ptIndex)) { numWrites++; printf("%i\tpage fault - evict dirty\n", numRefs + 1); } else { printf("%i\tpage fault - evict clean\n", numRefs + 1); } evictPage(pageTable, ptIndex); frames[furthest].pageNo = pageNo; //store the page number in the frame tempFuture = future[pageNo]; //store current use for deallocation future[pageNo] = future[pageNo]->next; //move future use down to next use frames[furthest].next = future[pageNo]; //update the frames reference to the future table free(tempFuture); //deallocate memory placePageInFrame(pageTable, pageNo, furthest, curr->mode); //map current page to frame } } //increment number of references and move to next reference numRefs++; curr = curr->next; } //print stats printf("\nNRU\n"); printf("Number of frames:\t%i\n", numFrames); printf("Total memory accesses:\t%i\n", numRefs); printf("Total page faults:\t%i\n", numFaults); printf("Total writes to disk:\t%i\n\n", numWrites); //clean up memory free(frames); free(future); }
//run the NRU algorithm simulation void simulateNRU(bit32 numFrames, const char *fileName, bit32 refresh) { bit32 *frames; //list of frames bit32 *pageTable; //page table bit32 numFaults = 0, numWrites = 0, numRefs = 0; //stat counters bit32 usedFrames = 0, pageNo, i; //number of frames used and the page number, loop counter struct memRef *memList, *curr; //pointer to current memory reference //set up page table and ensure all bits are 0 pageTable = (bit32 *) malloc(NUM_PAGES * sizeof(bit32)); memset(pageTable, 0, sizeof(bit32) * NUM_PAGES); //set up the memory frames frames = (bit32 *) malloc(numFrames * sizeof(bit32)); //seed the random number generator srand(time(NULL)); //read the file in and store the references and future uses of the references readFile(&memList, fileName); curr = memList; while(curr != NULL) { //if we've hit the refresh mark, mark all pages unreferenced if((numRefs % refresh) == 0) { for(i = 0; i < usedFrames; i++) { pageTable[frames[i]] = pageTable[frames[i]] & CLEAR_REF; } } pageNo = getPageNumber(curr->reference); if(isValid(pageTable, pageNo)) { //page already already valid/in a frame - hit pageHitSetBits(pageTable, pageNo, curr->mode); //set appropriate bits printf("%i\thit\n", numRefs + 1); } else { //page is not in a frame yet - miss numFaults++; //compulsory miss - will only happen numFrames times if(usedFrames < numFrames) { frames[usedFrames] = pageNo; //store the page number in the frame placePageInFrame(pageTable, pageNo, usedFrames, curr->mode); //map current page to frame usedFrames++; printf("%i\tpage fault - no eviction\n", numRefs + 1); } else { //capacity miss - frames are full and page is not in a frame - will need to evict bit32 frameToEvict = -1; bit32 *cleanUnref, *dirtyUnref, *cleanRef; //stores the indicies of each class of eviction candidate bit32 numCleanUnref = 0, numDirtyUnref = 0, numCleanRef = 0; //stores the number of candidates in each class //set up eviction candidate arrays cleanUnref = (bit32 *) malloc(sizeof(bit32) * numFrames); dirtyUnref = (bit32 *) malloc(sizeof(bit32) * numFrames); cleanRef = (bit32 *) malloc(sizeof(bit32) * numFrames); //find the number and place of each eviction candidate for(i = 0; i < numFrames; i++) { if(!isRef(pageTable, frames[i]) && !isDirty(pageTable, frames[i])) { //page in current frame is not referenced and not dirty cleanUnref[numCleanUnref] = i; numCleanUnref++; } else if(!isRef(pageTable, frames[i]) && isDirty(pageTable, frames[i])) { //page in current frame is not referenced, but is dirty - second best solution dirtyUnref[numDirtyUnref] = i; numDirtyUnref++; } else if(isRef(pageTable, frames[i]) && !isDirty(pageTable, frames[i])) { //page is referenced, but not dirty - third best solution cleanRef[numCleanRef] = i; numCleanRef++; } } if(numCleanUnref > 0) { //choose random number i = rand() % numCleanUnref; frameToEvict = cleanUnref[i]; } else if(numDirtyUnref > 0) { //choose random number i = rand() % numDirtyUnref; frameToEvict = dirtyUnref[i]; } else if(numCleanRef > 0) { //choose random number i = rand() % numCleanRef; frameToEvict = cleanRef[i]; } else { //all frames were referenced and dirty - choose any random frame frameToEvict = rand() % numFrames; } //free memory of arrays - frame to evict has been found free(cleanUnref); free(dirtyUnref); free(cleanRef); //evict the frame if(isDirty(pageTable, frames[frameToEvict])) { numWrites++; printf("%i\tpage fault - evict dirty\n", numRefs + 1); } else { printf("%i\tpage fault - evict clean\n", numRefs + 1); } evictPage(pageTable, frames[frameToEvict]); frames[frameToEvict] = pageNo; //store the page number in the frame placePageInFrame(pageTable, pageNo, frameToEvict, curr->mode); //map current page to frame } } //increment number of references and move to next reference numRefs++; curr = curr->next; } //ends while //print stats printf("\nNRU\n"); printf("Number of frames:\t%i\n", numFrames); printf("Total memory accesses:\t%i\n", numRefs); printf("Total page faults:\t%i\n", numFaults); printf("Total writes to disk:\t%i\n\n", numWrites); //clean up memory free(frames); } //ends NRU simulation