Compare commits

...

3 commits

Author SHA1 Message Date
guerringuerrin
3922a7ee0a Prioritize least busy buildings for hotkey training commands
getTotalQueueTime(queue) calculates total remaining
queue time of a production building.
getBuildingsSortedByQueueTime(entities), sorts building selection
by their queued training time and filter invalid entities
Removes the resource availability guard from the Training selection
panel onPress handler to align mouse interaction with hotkey behavior
2026-05-27 10:29:08 -03:00
Vladislav Belov
1250ca1dac
Replaces FALLTHROUGH macro by attribute
Some checks failed
checkrefs / lfscheck (push) Has been cancelled
checkrefs / checkrefs (push) Has been cancelled
lint / cppcheck (push) Has been cancelled
lint / copyright (push) Has been cancelled
lint / jenkinsfiles (push) Has been cancelled
pre-commit / build (push) Has been cancelled
It was forgotten during removing the FALLTHROUGH macro in
b41ca5ad78.
2026-05-22 23:25:31 +02:00
Vladislav Belov
a0ecfbaa33
Skips UNIFORM buffers for GLES
Currently we don't support UNIFORM buffers for GLES.

Refs 54701868da
2026-05-22 23:14:30 +02:00
4 changed files with 48 additions and 10 deletions

View file

@ -1596,6 +1596,34 @@ function updateDefaultBatchSize()
g_BatchSize = getDefaultBatchTrainingSize();
}
/**
* Calculates the total remaining production queue time of a building.
*/
function getTotalQueueTime(queue)
{
return queue.reduce((sum, item) => sum + (item.timeRemaining ?? item.timeTotal ?? 0), 0);
}
/**
* Returns the given production building selection sorted by their current
* queued training time, from lowest to highest.
* Invalid entities or entities without a valid production queue are filtered out.
*/
function getBuildingsSortedByQueueTime(entities)
{
return entities.map(entity =>
{
const state = GetEntityState(entity);
const queue = state?.production?.queue;
if (!Array.isArray(queue))
return null;
return {
"entity": entity,
"totalQueueTime": getTotalQueueTime(queue)
};
}).filter(data => data !== null).sort((a, b) => a.totalQueueTime - b.totalQueueTime).map(building => building.entity);
}
/**
* Add the unit shown at position to the training queue for all entities in the selection.
* @param {number} position - The position of the template to train.
@ -1628,6 +1656,7 @@ function addTrainingToQueue(selection, trainEntType, playerState)
if (!decrement)
template = GetTemplateData(trainEntType);
// Batch training only possible if we can train at least 2 units.
if (Engine.HotkeyIsPressed("session.batchtrain") && (canBeAddedCount == undefined || canBeAddedCount > 1))
{
@ -1678,14 +1707,14 @@ function addTrainingToQueue(selection, trainEntType, playerState)
}
else
{
let buildingsForTraining = appropriateBuildings;
let sortedBuildingsForTraining = getBuildingsSortedByQueueTime(appropriateBuildings);
if (canBeAddedCount !== undefined)
buildingsForTraining = buildingsForTraining.slice(0, canBeAddedCount);
sortedBuildingsForTraining = sortedBuildingsForTraining.slice(0, canBeAddedCount);
Engine.PostNetworkCommand({
"type": "train",
"template": trainEntType,
"count": 1,
"entities": buildingsForTraining,
"entities": sortedBuildingsForTraining,
"pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
});
}
@ -1734,6 +1763,12 @@ function flushTrainingBatch()
{
const batchedSize = g_NumberOfBatches * getBatchTrainingSize();
const appropriateBuildings = getBuildingsWhichCanTrainEntity(g_BatchTrainingEntities, g_BatchTrainingType);
// Sort buildings by queued training time so that, if some training
// commands fail due to resource or entity limits, units are assigned
// to the least busy buildings first.
const sortedBuildings = getBuildingsSortedByQueueTime(appropriateBuildings);
// If training limits don't allow us to train batchedSize in each appropriate structure.
if (g_BatchTrainingEntityAllowedCount !== undefined &&
g_BatchTrainingEntityAllowedCount < batchedSize * appropriateBuildings.length)
@ -1742,7 +1777,7 @@ function flushTrainingBatch()
const buildingsCountToTrainFullBatch = Math.floor(g_BatchTrainingEntityAllowedCount / batchedSize);
Engine.PostNetworkCommand({
"type": "train",
"entities": appropriateBuildings.slice(0, buildingsCountToTrainFullBatch),
"entities": sortedBuildings.slice(0, buildingsCountToTrainFullBatch),
"template": g_BatchTrainingType,
"count": batchedSize,
"pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
@ -1753,7 +1788,7 @@ function flushTrainingBatch()
if (remainer)
Engine.PostNetworkCommand({
"type": "train",
"entities": [appropriateBuildings[buildingsCountToTrainFullBatch]],
"entities": [sortedBuildings[buildingsCountToTrainFullBatch]],
"template": g_BatchTrainingType,
"count": remainer,
"pushFront": Engine.HotkeyIsPressed("session.pushorderfront")
@ -1762,7 +1797,7 @@ function flushTrainingBatch()
else
Engine.PostNetworkCommand({
"type": "train",
"entities": appropriateBuildings,
"entities": sortedBuildings,
"template": g_BatchTrainingType,
"count": batchedSize,
"pushFront": Engine.HotkeyIsPressed("session.pushorderfront")

View file

@ -1035,8 +1035,7 @@ g_SelectionPanels.Training = {
data.button.onPress = function()
{
if (!neededResources)
addTrainingToQueue(unitIds, data.item, data.playerState);
addTrainingToQueue(unitIds, data.item, data.playerState);
};
const showTemplateFunc = () => { showTemplateDetails(data.item, data.playerState.civ); };

View file

@ -259,6 +259,10 @@ CDeviceCommandContext::CDeviceCommandContext(CDevice* device)
// Currently we don't support upload buffers for GL.
if (type == CBuffer::Type::UPLOAD)
continue;
#if CONFIG2_GLES
if (type == CBuffer::Type::UNIFORM)
continue;
#endif
const GLenum target = BufferTypeToGLTarget(type);
const GLuint handle = 0;
m_BoundBuffers[index].first = target;

View file

@ -213,8 +213,8 @@ std::unique_ptr<CTexture> CTexture::Create(
break;
#if CONFIG2_GLES
// GLES requires pixel type == UNSIGNED_SHORT or UNSIGNED_INT for depth.
case Format::D16_UNORM: FALLTHROUGH;
case Format::D24_UNORM: FALLTHROUGH;
case Format::D16_UNORM: [[fallthrough]];
case Format::D24_UNORM: [[fallthrough]];
case Format::D32_SFLOAT:
internalFormat = GL_DEPTH_COMPONENT;
pixelFormat = GL_DEPTH_COMPONENT;