void PublicHubsFrame::updateList()
{
	//CLockRedraw<> l_lock_draw(m_ctrlHubs);
	m_ctrlHubs.DeleteAllItems();
	users = 0;
	visibleHubs = 0;
	
	double size = -1;
	FilterModes mode = NONE;
	
	int sel = ctrlFilterSel.GetCurSel();
	
	bool doSizeCompare = parseFilter(mode, size);
	
	auto cnt = m_ctrlHubs.GetItemCount();
	for (auto i = m_hubs.cbegin(); i != m_hubs.cend(); ++i)
	{
		if (matchFilter(*i, sel, doSizeCompare, mode, size))
		{
			TStringList l;
			l.resize(COLUMN_LAST);
			l[COLUMN_NAME] = Text::toT(i->getName());
			string l_description = i->getDescription();
			boost::replace_all(l_description, ".px.", "");
			l[COLUMN_DESCRIPTION] = Text::toT(l_description);
			l[COLUMN_USERS] = Util::toStringW(i->getUsers());
			l[COLUMN_SERVER] = Text::toT(i->getServer());
			l[COLUMN_COUNTRY] = Text::toT(i->getCountry()); // !SMT!-IP
			l[COLUMN_SHARED] = Util::formatBytesW(i->getShared());
			l[COLUMN_MINSHARE] = Util::formatBytesW(i->getMinShare());
			l[COLUMN_MINSLOTS] = Util::toStringW(i->getMinSlots());
			l[COLUMN_MAXHUBS] = Util::toStringW(i->getMaxHubs());
			l[COLUMN_MAXUSERS] = Util::toStringW(i->getMaxUsers());
			l[COLUMN_RELIABILITY] = Util::toStringW(i->getReliability());
			l[COLUMN_RATING] = Text::toT(i->getRating());
			const auto l_country = i->getCountry();
			dcassert(!l_country.empty());
			const auto l_index_country = WinUtil::getFlagIndexByName(l_country.c_str());
			//const auto l_index =
			m_ctrlHubs.insert(cnt++, l, l_index_country); // !SMT!-IP
			
			/*
			LVITEM lvItem = { 0 };
			        lvItem.mask = LVIF_IMAGE;
			        lvItem.iItem = l_index;
			        lvItem.iImage = isOnline(i->getServer()) ? 0 : 1;
			        m_ctrlHubs.SetItem(&lvItem);
			*/
			visibleHubs++;
			users += i->getUsers();
		}
	}
	
	m_ctrlHubs.resort();
	
	updateStatus();
}
Exemple #2
0
bool AFK_VapourCell::build3DList(
    unsigned int threadId,
    const AFK_KeyedCell& cell,
    AFK_3DList& list,
    const AFK_ShapeSizes& sSizes,
    AFK_VAPOUR_CELL_CACHE *cache) const
{
    /* Add the local vapour to the list. */
    list.extend<FeatureArray, CubeArray>(features, cubes);

    /* If this isn't the top level cell... */
    if (cell.c.coord.v[3] < (sSizes.skeletonFlagGridDim * SHAPE_CELL_MAX_DISTANCE))
    {
        /* Pull the parent cell from the cache, and
         * include its list too
         */
        AFK_KeyedCell parentCell = cell.parent(sSizes.subdivisionFactor);
        auto parentVapourCellClaim = cache->getAndClaim(threadId, parentCell, AFK_CL_SHARED);
        if (parentVapourCellClaim.isValid())
            return parentVapourCellClaim.getShared().build3DList(threadId, parentCell, list, sSizes, cache);
        else return false;
    }
    else return true;
}
void AFK_LandscapeDisplayQueue::draw(
    unsigned int threadId,
    AFK_ShaderProgram *shaderProgram,
    AFK_Jigsaw *jigsaw,
    AFK_LANDSCAPE_CACHE *cache,
    const AFK_TerrainBaseTile *baseTile,
    const AFK_LandscapeSizes& lSizes)
{
    /* First, check there's anything to draw at all ... */
#if COPY_TO_GL_CULLING
    bool allChecked = false;
    std::vector<bool> checked;
    checked.reserve(queue.size());
    for (unsigned int i = 0; i < queue.size(); ++i) checked.push_back(false);

    do
    {
        allChecked = true;
        for (unsigned int i = 0; i < queue.size(); ++i)
        {
            if (checked[i]) continue;

            auto entry = cache->get(threadId, landscapeTiles[i]);
            if (entry)
            {
                auto claim = entry->claimable.claimInplace(threadId, AFK_CL_SHARED);
                if (claim.isValid())
                {
                    if (claim.getShared().realCellWithinYBounds(queue[i].cellCoord))
                    {
                        /* I do want to draw this tile. */
                        culledQueue.push_back(queue[i]);
                    }

                    /* If I got here, the tile has been checked successfully. */
                    checked[i] = true;
                }
                else
                {
                    /* want to retry */
                    allChecked = false;
                }
            }
            else
            {
                /* Ignore, this one shouldn't be drawn */
                checked[i] = true;
            }
        }

        if (!allChecked) std::this_thread::yield(); /* Give things a chance */
    } while (!allChecked);

    size_t instanceCount = culledQueue.size();
#else
    size_t instanceCount = queue.size();
#endif
    if (instanceCount == 0) return;

    /* Check I've initialised the various locations in the
     * shader program that I need
     */
    if (!jigsawPiecePitchLocation)
    {
        jigsawPiecePitchLocation = glGetUniformLocation(shaderProgram->program, "JigsawPiecePitch");
        jigsawYDispTexSamplerLocation = glGetUniformLocation(shaderProgram->program, "JigsawYDispTex");
        jigsawColourTexSamplerLocation = glGetUniformLocation(shaderProgram->program, "JigsawColourTex");
        jigsawNormalTexSamplerLocation = glGetUniformLocation(shaderProgram->program, "JigsawNormalTex");
        displayTBOSamplerLocation = glGetUniformLocation(shaderProgram->program, "DisplayTBO");
    }

    /* Fill out ye olde uniform variable with the jigsaw
     * piece pitch.
     */
    Vec2<float> jigsawPiecePitchST = jigsaw->getPiecePitchST();
    glUniform2fv(jigsawPiecePitchLocation, 1, &jigsawPiecePitchST.v[0]);

    /* The first texture is the jigsaw Y-displacement */
    glActiveTexture(GL_TEXTURE0);
    jigsaw->bindTexture(0);
    glUniform1i(jigsawYDispTexSamplerLocation, 0);

    /* The second texture is the jigsaw colour */
    glActiveTexture(GL_TEXTURE1);
    jigsaw->bindTexture(1);
    glUniform1i(jigsawColourTexSamplerLocation, 1);

    /* The third texture is the jigsaw normal */
    glActiveTexture(GL_TEXTURE2);
    jigsaw->bindTexture(2);
    glUniform1i(jigsawNormalTexSamplerLocation, 2);

    /* The fourth texture is the landscape display texbuf,
     * which explains to the vertex shader which tile it's
     * drawing and where in the jigsaw to look.
     */
    glActiveTexture(GL_TEXTURE3);
    if (!buf) glGenBuffers(1, &buf);
    glBindBuffer(GL_TEXTURE_BUFFER, buf);
    glBufferData(
        GL_TEXTURE_BUFFER,
#if COPY_TO_GL_CULLING
        culledQueue.size() * sizeof(AFK_LandscapeDisplayUnit),
        &culledQueue[0],
#else
        queue.size() * sizeof(AFK_LandscapeDisplayUnit),
        &queue[0],
#endif
        GL_STREAM_DRAW);
    glTexBuffer(
        GL_TEXTURE_BUFFER,
        GL_RGBA32F,
        buf);
    AFK_GLCHK("landscape display queue texBuffer")
    glUniform1i(displayTBOSamplerLocation, 3);

#if AFK_GL_DEBUG
    shaderProgram->Validate();
#endif

    baseTile->draw(instanceCount);

    glBindTexture(GL_TEXTURE_2D, 0);
    glBindTexture(GL_TEXTURE_BUFFER, 0);
}
Exemple #4
0
bool AFK_World::generateClaimedWorldCell(
    AFK_WORLD_CACHE::Claim& claim,
    unsigned int threadId,
    const struct AFK_WorldWorkParam::World& param,
    const struct AFK_WorldWorkThreadLocal& threadLocal,
    AFK_WorldWorkQueue& queue)
{
    const AFK_Cell& cell                = param.cell;
    const Vec3<float>& viewerLocation   = threadLocal.viewerLocation;
    const AFK_Camera& camera            = threadLocal.camera;

    bool entirelyVisible                = ((param.flags & AFK_WCG_FLAG_ENTIRELY_VISIBLE) != 0);
    bool renderTerrain                  = ((param.flags & AFK_WCG_FLAG_TERRAIN_RENDER) != 0);
    bool resume                         = ((param.flags & AFK_WCG_FLAG_RESUME) != 0);

    bool retval = true;

    AFK_WorldCell& worldCell = claim.get();
    worldCell.bind(cell, minCellSize);

    /* Check for visibility. */
    bool someVisible = entirelyVisible;
    bool allVisible = entirelyVisible;

    if (!entirelyVisible) worldCell.testVisibility(camera, someVisible, allVisible);
    if (!someVisible && !renderTerrain)
    {
        cellsInvisible.fetch_add(1);
    }
    else /* if (cell.coord.v[1] == 0) */
    {
        bool needsResume = false;
        std::vector<AFK_Tile> missingTiles;

        /* We display geometry at a cell if its detail pitch is at the
         * target detail pitch, or if it's already the smallest
         * possible cell.
         * Note that the smallest possible cell is 2.  I can't go to 1,
         * because it will preclude landscape half-tiles (which would
         * be at +/- 0.5).
         */
        bool display = (cell.coord.v[3] == 2 ||
            worldCell.testDetailPitch(threadLocal.detailPitch, camera, viewerLocation));

        /* Find the tile where any landscape at this cell would be
         * homed
         */
        AFK_Tile tile = afk_tile(cell);

        /* I'm going to want this in a moment.
         */
        float landscapeTileUpperYBound = FLT_MAX;

        /* We always at least touch the landscape.  Higher detailed
         * landscape tiles are dependent on lower detailed ones for their
         * terrain description.
         */
        auto landscapeClaim = landscapeCache->insertAndClaim(threadId, tile, AFK_CL_BLOCK | AFK_CL_UPGRADE);
        if (landscapeClaim.isValid())
        {
            landscapeTileUpperYBound = landscapeClaim.getShared().getYBoundUpper();
        
            if (!landscapeClaim.getShared().hasTerrainDescriptor() ||
                ((renderTerrain || display) && landscapeClaim.getShared().artworkState(landscapeJigsaws) != AFK_LANDSCAPE_TILE_HAS_ARTWORK))
            {
                /* In order to generate this tile we need to upgrade
                 * our claim if we can.
                 */
                if (landscapeClaim.upgrade())
                {
                    AFK_LandscapeTile& landscapeTile = landscapeClaim.get();
                    if (checkClaimedLandscapeTile(tile, landscapeTile, display))
                        needsResume = generateLandscapeArtwork(tile, landscapeTile, threadId, missingTiles);
        
                    if (!needsResume && display)
                        displayLandscapeTile(cell, tile, landscapeTile, threadId);
                }
                else
                {
                    needsResume = true;
                }
            }
            else if (display)
            {
                displayLandscapeTile(cell, tile, landscapeClaim.getShared(), threadId);
            }
        }
        else
        {
            needsResume = true;
        }

        /* If I need a resume for the landscape tile, push it in */
        if (needsResume)
        {
            /* Because I'm doing a resume, I need to account for it in the
             * remaining volume counter
             */
            volumeLeftToEnumerate.fetch_add(CUBE(cell.coord.v[3]));

            AFK_WorldWorkQueue::WorkItem resumeItem;
            resumeItem.func = afk_generateWorldCells;
            resumeItem.param.world = param;
            resumeItem.param.world.flags |= AFK_WCG_FLAG_RESUME;
            if (param.dependency) param.dependency->retain();

            /* If we have missing tiles, that resume needs to be a
             * dependency of those missing tiles:
             */
            if (!missingTiles.empty())
            {
                AFK_WorldWorkParam::Dependency *dep = new AFK_WorldWorkParam::Dependency(resumeItem);
                dep->retain(missingTiles.size());

                for (auto m : missingTiles)
                {
                    volumeLeftToEnumerate.fetch_add(CUBE(m.coord.v[2]));

                    AFK_WorldWorkQueue::WorkItem missingItem;
                    missingItem.func = afk_generateWorldCells;
                    missingItem.param.world.cell        = afk_cell(m, 0);
                    missingItem.param.world.flags       = AFK_WCG_FLAG_ENTIRELY_VISIBLE | AFK_WCG_FLAG_TERRAIN_RENDER;
                    missingItem.param.world.dependency  = dep;
                    queue.push(missingItem);
                }

                tilesResumed.fetch_add(missingTiles.size());
            }
            else
            {
                /* We enqueue the resume directly */
                queue.push(resumeItem);
            }

            tilesResumed.fetch_add(1);
        }

        if (!resume && !renderTerrain)
        {
            /* Now that I've done all that, I can get to the
             * business of handling the entities within the cell.
             * Firstly, so long as it's above the landscape, give it
             * some starting entities if it hasn't got them
             * already.
             */
        
            if (worldCell.getRealCoord().v[1] >= landscapeTileUpperYBound)
            {
                /* TODO: This RNG will make the same set of entities every
                 * time the cell is re-displayed.  This is fine for probably
                 * static, landscape decoration type objects.  But I'm also
                 * going to want to have transient objects popping into
                 * existence, and those should be done with a different,
                 * long-period RNG that I retain (in thread local storage),
                 * perhaps a Mersenne Twister.
                 */
                AFK_Boost_Taus88_RNG staticRng;
                staticRng.seed(cell.rngSeed());
                int startingEntityCount = worldCell.getStartingEntitiesWanted(
                    staticRng, entitySparseness);
        
                for (int e = 0; e < startingEntityCount; ++e)
                {
                    int shapeKey = worldCell.getStartingEntityShapeKey(staticRng);
                    generateStartingEntity(shapeKey, worldCell, threadId, staticRng);
                }
            }
        
            for (int eI = 0; eI < worldCell.getEntityCount(); ++eI)
            {
                AFK_Entity& e = worldCell.getEntityAt(eI);
                if (e.notProcessedYet(afk_core.computingFrame))
                {
                    /* Account for this shape in the volume left to enumerate */
                    volumeLeftToEnumerate.fetch_add(CUBE(SHAPE_CELL_MAX_DISTANCE));

                    /* Make sure everything I need in that shape
                     * has been computed ...
                     */
                    AFK_WorldWorkQueue::WorkItem shapeCellItem;
                    shapeCellItem.func                          = afk_generateEntity;
                    shapeCellItem.param.shape.cell              = afk_keyedCell(afk_vec4<int64_t>(
                                                                    0, 0, 0, SHAPE_CELL_MAX_DISTANCE), e.shapeKey);
                    shapeCellItem.param.shape.transformation    = e.getTransformation();
                    shapeCellItem.param.shape.flags             = 0;
        
#if AFK_SHAPE_ENUM_DEBUG
                    shapeCellItem.param.shape.asedWorldCell     = cell;
                    shapeCellItem.param.shape.asedCounter       = eI;
                    AFK_DEBUG_PRINTL("ASED: Enqueued entity: worldCell=" << cell << ", entity counter=" << eI)
#endif
        
                    shapeCellItem.param.shape.dependency        = nullptr;
                    queue.push(shapeCellItem);
            
                    entitiesQueued.fetch_add(1);
                }
            }
        }

        /* We don't need this any more */
        claim.release();

        /* If the terrain here was at too coarse a resolution to
         * be displayable, recurse through the subcells
         */
        if (!display && !renderTerrain && someVisible && !resume)
        {
            /* I'm about to enumerate this cell's volume in subcells */
            volumeLeftToEnumerate.fetch_add(CUBE(cell.coord.v[3]));

            size_t subcellsSize = CUBE(subdivisionFactor);
            AFK_Cell *subcells = new AFK_Cell[subcellsSize]; /* TODO avoid heap thrashing somehow.  Maybe make it an iterator */
            unsigned int subcellsCount = cell.subdivide(subcells, subcellsSize, subdivisionFactor);
            assert(subcellsCount == subcellsSize);

            for (unsigned int i = 0; i < subcellsCount; ++i)
            {
                AFK_WorldWorkQueue::WorkItem subcellItem;
                subcellItem.func                     = afk_generateWorldCells;
                subcellItem.param.world.cell         = subcells[i];
                subcellItem.param.world.flags        = (allVisible ? AFK_WCG_FLAG_ENTIRELY_VISIBLE : 0);
                subcellItem.param.world.dependency   = nullptr;
                queue.push(subcellItem);
            }

            delete[] subcells;
        }
    }

    return retval;
}
Exemple #5
0
int afk_testChainLink()
{
    boost::random::random_device rdev;
    int64_t rngSeed = (static_cast<int64_t>(rdev()) |
        (static_cast<int64_t>(rdev())) << 32);

    const int iterations = 40000;
    const int maxChainLength = static_cast<int>(sqrt(iterations));
    const int threads = 24;

    std::shared_ptr<AFK_BasicLinkFactory<AFK_ClaimableChainLinkTestLink> > linkFactory =
        std::make_shared<AFK_BasicLinkFactory<AFK_ClaimableChainLinkTestLink> >();
    AFK_ChainLinkTestChain *testChain = new AFK_ChainLinkTestChain(linkFactory);

    std::deque<std::thread> workers;

    afk_clock::time_point startTime, endTime;
    startTime = afk_clock::now();
    assert(threads < 31);
    for (int i = 0; i < threads; ++i)
    {
        workers.push_back(std::thread(
            afk_testChainLink_worker,
            i + 1,
            rngSeed,
            iterations,
            maxChainLength,
            testChain
            ));
    }

    for (auto workerIt = workers.begin(); workerIt != workers.end(); ++workerIt)
    {
        workerIt->join();
    }

    endTime = afk_clock::now();

    /* Verify that whole thing */
    int index = 0;
    int fails = 0;
    testChain->foreach([&index, &fails](std::shared_ptr<AFK_ClaimableChainLinkTestLink> link)
    {
        //afk_out << "verify test chain link: index " << index << ": ";

        auto claim = link->claim(1, AFK_CL_SPIN);
        //afk_out << claim.getShared();
        if (claim.getShared().verify(index))
        {
            //afk_out << " (verify ok)" << std::endl;
        }
        else
        {
            //afk_out << " (verify FAILED)" << std::endl;
            ++fails;
        }

        ++index;
    });

    afk_duration_mfl timeTaken = std::chrono::duration_cast<afk_duration_mfl>(endTime - startTime);
    afk_out << "Chain link test (" << iterations << " iterations, " << maxChainLength << " max chain length, " << threads << " threads) finished in " << timeTaken.count() << " millis" << std::endl;

    delete testChain;
    afk_out << "Chain link test finished with " << iterations << " iterations, " << fails << " fails." << std::endl;

    return fails;
}
Exemple #6
0
 void setOther(Instance *other){getShared()->other=other;}
Exemple #7
0
 void setSelf(Instance *self){getShared()->self=self;}
Exemple #8
0
 Instance *getOther(){return getShared()->other;}
Exemple #9
0
 Instance *getSelf(){return getShared()->self;}