Skip to content

Commit

Permalink
Merge pull request #300 from lightning-js/dev
Browse files Browse the repository at this point in the history
Release 1.21.0
  • Loading branch information
michielvandergeest authored Feb 27, 2025
2 parents f4c2fe6 + aad1356 commit 46a6882
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 38 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## v1.21.0

_27 feb 2025_

- Added functionality for keeping query params when navigating back in the router
- Exposed more info in reactive router state
- Added `range`-attribute to for-loop
- Fixed issue when setting `alpha` to truthy or false values
- Upgraded to renderer v2.13.0

## v1.20.1

_14 feb 2025_
Expand Down
51 changes: 51 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -799,8 +799,59 @@ declare module '@lightningjs/blits' {
* and cleaned up
*
* Defaults to `200` (mb)
* @deprecated
* Deprecated: use `gpuMemory` launch setting instead
*/
gpuMemoryLimit?: number,
/**
* Configures the gpu memory settings used by the renderer
*/
gpuMemory: {
/**
* Maximum GPU memory threshold (in `mb`) after which
* the renderer will immediately start cleaning up textures to free
* up graphical memory
*
* When setting to `0`, texture memory management is disabled
*
* @default `200`
*/
max: number,
/**
* Target threshold of GPU memory usage, defined as a fraction of
* the max threshold. The renderer will attempt to keep memory
* usage below this target by cleaning up non-renderable textures
*
* @default `0.8`
*/
target: 0.8,
/**
* Interval at which regular texture cleanups occur (in `ms`)
*
* @default `5000`
*/
cleanupInterval: 5000,
/**
* Baseline GPU memory usage of the App (in `mb`), without rendering any
* textures. This value will be used as a basis when calculating
* the total memory usage towards the max and target memory
* usage
*
* @default `25`
*/
baseline: 25,
/**
* Whether or not the max threshold should be considered
* as a strict number that can not be exceeded in any way
*
* When set to `true`, new textures won't be created when the
* max threshold has been reached, until agressive texture cleanup
* has brought the memory back down
*
* @default false
*/
strict: false,
},
/**
* Defines which mode the renderer should operate in: `webgl` or `canvas`
*
Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lightningjs/blits",
"version": "1.20.1",
"version": "1.21.0",
"description": "Blits: The Lightning 3 App Development Framework",
"bin": "bin/index.js",
"exports": {
Expand Down Expand Up @@ -52,7 +52,7 @@
},
"dependencies": {
"@lightningjs/msdf-generator": "^1.1.1",
"@lightningjs/renderer": "^2.12.1"
"@lightningjs/renderer": "^2.13.0"
},
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion src/engines/L3/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ const propsTransformer = {
}
},
set alpha(v) {
if (this.raw['show'] === undefined || this.raw['show'] === true) {
if (this.raw['show'] === undefined || this.raw['show'] == true) {
this.props['alpha'] = v
}
},
Expand Down
25 changes: 22 additions & 3 deletions src/engines/L3/launch.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,27 @@ const textRenderEngines = (settings) => {
if (renderMode === 'canvas') return [CanvasTextRenderer]
}

const textureMemorySettings = (settings) => {
const gpuMemory = {
...{
max: 200,
target: 0.8,
cleanupInterval: 5000,
baseline: 25,
strict: false,
},
...('gpuMemory' in settings === true ? settings.gpuMemory : {}),
}

return {
criticalThreshold: gpuMemory.max * 1024 * 1024, // convert from mb to bytes
targetThresholdLevel: gpuMemory.target,
cleanupInterval: gpuMemory.cleanupInterval,
baselineMemoryAllocation: gpuMemory.baseline * 1024 * 1024, // convert from mb to bytes
doNotExceedCriticalThreshold: gpuMemory.strict,
}
}

export default (App, target, settings = {}) => {
renderer = new RendererMain(
{
Expand All @@ -62,13 +83,11 @@ export default (App, target, settings = {}) => {
clearColor: (settings.canvasColor && colors.normalize(settings.canvasColor)) || 0x00000000,
inspector: settings.inspector === true ? Inspector : undefined,
boundsMargin: settings.viewportMargin || 0,
// gpu memory limit, converted from mb to bytes - defaults to 200mb
txMemByteThreshold:
'gpuMemoryLimit' in settings ? settings.gpuMemoryLimit * 1024 * 1024 : 200 * 1024 * 1024,
renderEngine: renderEngine(settings),
fontEngines: textRenderEngines(settings),
canvas: settings.canvas,
textureProcessingTimeLimit: settings.textureProcessingTimeLimit,
textureMemory: textureMemorySettings(settings),
},
target
)
Expand Down
24 changes: 22 additions & 2 deletions src/lib/codegenerator/generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ const generateComponentCode = function (
const generateForLoopCode = function (templateObject, parent) {
const forLoop = templateObject[':for']
delete templateObject[':for']
const range = templateObject['range'] || templateObject[':range'] || '{}'
delete templateObject['range']
delete templateObject[':range']

const key = templateObject['key']
const forKey = interpolate(key, 'scope.')
Expand Down Expand Up @@ -340,10 +343,19 @@ const generateForLoopCode = function (templateObject, parent) {

ctx.renderCode.push(`
const created${forStartCounter} = []
let from${forStartCounter}
let to${forStartCounter}
const forloop${forStartCounter} = (collection = [], elms, created) => {
const rawCollection = getRaw(collection)
const keys = new Set()
let l = rawCollection.length
const range = ${interpolate(range)} || {}
from${forStartCounter} = range['from'] || 0
to${forStartCounter} = 'to' in range ? range['to'] : rawCollection.length
while(l--) {
const ${item} = rawCollection[l]
`)
Expand All @@ -354,7 +366,9 @@ const generateForLoopCode = function (templateObject, parent) {
`)
}
ctx.renderCode.push(`
keys.add('' + ${interpolate(key, '') || 'l'})
if(l < to${forStartCounter} && l >= from${forStartCounter}) {
keys.add('' + ${interpolate(key, '') || 'l'})
}
}
`)

Expand All @@ -368,6 +382,7 @@ const generateForLoopCode = function (templateObject, parent) {
const length = rawCollection.length
const effects = []
for(let __index = 0; __index < length; __index++) {
if(__index < from${forStartCounter} || __index >= to${forStartCounter}) continue
const scope = Object.create(component)
parent = ${parent}
scope['${item}'] = rawCollection[__index]
Expand Down Expand Up @@ -488,6 +503,10 @@ const generateForLoopCode = function (templateObject, parent) {
effectKey = effectKey.match(/[^.]+$/)[0]
}

// get the reference to range from and to
const effectKeysRegex = /\$([^,} ]+)/g
const effectKeys = [...range.matchAll(effectKeysRegex)].map((match) => `'${match[1]}'`)

ctx.renderCode.push(`
let forEffects${forStartCounter}
effect(() => {
Expand All @@ -497,7 +516,7 @@ const generateForLoopCode = function (templateObject, parent) {
result[2],
':for'
)}, elms, created${forStartCounter})
}, '${effectKey}' )
}, ['${effectKey}', ${effectKeys.join(',')}] )
`)

outerScopeEffects.forEach((effect) => {
Expand All @@ -520,6 +539,7 @@ const generateForLoopCode = function (templateObject, parent) {
effect(() => {
void ${refs.join(', ')}
for(let __index = 0; __index < ${interpolate(result[2])}.length; __index++) {
if(__index < from${forStartCounter} || __index >= to${forStartCounter}) continue
const scope = {}
scope['${index}'] = __index
scope['${item}'] = ${interpolate(result[2])}[__index]
Expand Down
8 changes: 5 additions & 3 deletions src/lib/reactivity/effect.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ export const track = (target, key, global = false) => {
if (paused) {
return
}
if (currentKey !== null && key !== currentKey) {
return
}
// note: nesting the conditions like this seems to perform better ¯\_(ツ)_/¯
if (Array.isArray(currentKey) === true) {
if (currentKey.includes(key) === false) return
} else if (currentKey !== null && key !== currentKey) return

let effectsMap = objectMap.get(target)
if (!effectsMap) {
effectsMap = new Map()
Expand Down
12 changes: 8 additions & 4 deletions src/lib/reactivity/reactive.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,14 @@ const reactiveProxy = (original, _parent = null, _key, global) => {
const rawValue = getRaw(value)

let result = true
const isEqual =
Array.isArray(rawValue) === true
? deepEqualArray(oldRawValue, rawValue)
: oldRawValue === rawValue
let isEqual = false

// We need to check that the oldRawValue is also an array before we do the deep equal check
if (Array.isArray(rawValue) === true && Array.isArray(oldRawValue) === true) {
isEqual = deepEqualArray(oldRawValue, rawValue)
} else if (oldRawValue === rawValue) {
isEqual = true
}

if (isEqual === false) {
if (typeof value === 'object') {
Expand Down
Loading

0 comments on commit 46a6882

Please sign in to comment.