diasurgical/DevilutionX

Make custom iterators for activ entity lists

Aperta

#2586 aperta il 12 ago 2021

 (6 commenti) (0 reazioni) (0 assegnatari)C++ (743 fork)batch import
good first issuehelp wanted

Metriche repository

Star
 (7255 stelle)
Metriche merge PR
 (Merge medio 2g 12h) (15 PR mergiate in 30 g)

Descrizione

There are a lot of loops that we are not able to convert to ranges as they only loop over the active entities rather then all entities.

	for (int i = 0; i < ActiveMissileCount; i++) {
		int mx = ActiveMissiles[i];
		if (Missiles[mx]._mitype == MIS_TOWN && missile._misource == id)
			Missiles[mx]._mirange = 0;
	}

This also means that we will still be indexing in to the global array at least once.

To solve this we can create custom iterators:

	for (auto missile : ActiveMissileIterator) {
		if (missile._mitype == MIS_TOWN && missile._misource == id)
			missile._mirange = 0;
	}

https://internalpointers.com/post/writing-custom-iterators-modern-cpp

Some times it may also be useful with iterators that can take a custom range:

	int start = gbIsMultiplayer ? 3 : 2;
	int end = gbIsHellfire ? 10 : 8;
	for (auto healitem : ItemIterator(&Healitems[start], &Healitems[end])) {
		healitem._iCreateInfo = lvl | CF_HEALER;
		healitem._iIdentified = true;
		healitem._iStatFlag = StoreStatOk(&healitem[i]);
	}

This issue builds on the changes done in https://github.com/diasurgical/devilutionX/issues/2435 but does not strictly require it.

Guida contributor