Skip to content

Commit ce83d02

Browse files
Merge pull request #13 from SethMorrowSoftware/codex/conduct-project-audit-and-document-findings
Harden native handle lifecycle, add validations, register chain segments, and improve kit input handling
2 parents 99ef69b + 47c1d92 commit ce83d02

6 files changed

Lines changed: 680 additions & 112 deletions

File tree

audit.md

Lines changed: 270 additions & 0 deletions
Large diffs are not rendered by default.

examples/box2dxt-contraption-builder.livecodescript

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -264,21 +264,37 @@ end b2kClear
264264
-- =====================================================================
265265
-- Configuration
266266
-- =====================================================================
267+
function b2kNumberOr pValue, pDefault
268+
if pValue is empty then return pDefault
269+
if pValue is not a number then return pDefault
270+
return pValue
271+
end b2kNumberOr
272+
273+
function b2kClamp pValue, pLo, pHi
274+
local tValue
275+
put b2kNumberOr(pValue, pLo) into tValue
276+
if tValue < pLo then put pLo into tValue
277+
if tValue > pHi then put pHi into tValue
278+
return tValue
279+
end b2kClamp
280+
267281
command b2kSetScale pPixelsPerMetre
268-
put pPixelsPerMetre into sScale
282+
put b2kClamp(pPixelsPerMetre, 1, 10000) into sScale
269283
end b2kSetScale
270284

271285
command b2kSetOrigin pScreenX, pScreenY
272-
put pScreenX into sOriginX
273-
put pScreenY into sOriginY
286+
put b2kNumberOr(pScreenX, sOriginX) into sOriginX
287+
put b2kNumberOr(pScreenY, sOriginY) into sOriginY
274288
end b2kSetOrigin
275289

276290
command b2kSetGravity pGx, pGy
291+
put b2kNumberOr(pGx, 0) into pGx
292+
put b2kNumberOr(pGy, -10) into pGy
277293
if sWorld is not empty then b2SetGravity sWorld, pGx, pGy
278294
end b2kSetGravity
279295

280296
command b2kSetSubsteps pN
281-
put pN into sSub
297+
put round(b2kClamp(pN, 1, 64)) into sSub
282298
end b2kSetSubsteps
283299

284300
-- World toggles: island sleeping (saves CPU) and continuous collision (CCD,
@@ -343,6 +359,7 @@ command b2kAddBox pControl, pDynamic
343359
else put 0 into tType
344360
put ((the width of pControl) / 2) / sScale into tHw
345361
put ((the height of pControl) / 2) / sScale into tHh
362+
if tHw <= 0 or tHh <= 0 then return 0
346363
put b2kToWorldX(item 1 of the loc of pControl) into tWx
347364
put b2kToWorldY(item 2 of the loc of pControl) into tWy
348365
put (word 1 of tRef is "graphic") into tGraphic
@@ -376,6 +393,7 @@ command b2kAddBall pControl, pDynamic
376393
if pDynamic then put 2 into tType
377394
else put 0 into tType
378395
put ((the width of pControl) / 2) / sScale into tRad
396+
if tRad <= 0 then return 0
379397
put b2kToWorldX(item 1 of the loc of pControl) into tWx
380398
put b2kToWorldY(item 2 of the loc of pControl) into tWy
381399
put b2NewBody(sWorld, tType, tWx, tWy, 0, false, false) into tBody
@@ -400,6 +418,7 @@ command b2kAddCapsule pControl, pDynamic
400418
else put 0 into tType
401419
put (the width of pControl) / sScale into tWm
402420
put (the height of pControl) / sScale into tHm
421+
if tWm <= 0 or tHm <= 0 then return 0
403422
put (tWm >= tHm) into tHoriz
404423
if tHoriz then
405424
put tHm / 2 into tR
@@ -486,7 +505,11 @@ end b2kRegister
486505
command b2kSpawnBox pScreenX, pScreenY, pW, pH, pColor
487506
local tName, tRef
488507
if pW is empty then put 40 into pW
508+
put b2kClamp(pW, 1, 10000) into pW
489509
if pH is empty then put pW into pH
510+
put b2kClamp(pH, 1, 10000) into pH
511+
put b2kNumberOr(pScreenX, sOriginX) into pScreenX
512+
put b2kNumberOr(pScreenY, sOriginY) into pScreenY
490513
put "b2kspawn_" & the milliseconds & "_" & random(1000000) into tName
491514
create graphic (tName)
492515
put the long id of graphic (tName) into tRef
@@ -505,6 +528,9 @@ end b2kSpawnBox
505528
command b2kSpawnBall pScreenX, pScreenY, pDiameter, pColor
506529
local tName, tRef
507530
if pDiameter is empty then put 40 into pDiameter
531+
put b2kClamp(pDiameter, 1, 10000) into pDiameter
532+
put b2kNumberOr(pScreenX, sOriginX) into pScreenX
533+
put b2kNumberOr(pScreenY, sOriginY) into pScreenY
508534
put "b2kspawn_" & the milliseconds & "_" & random(1000000) into tName
509535
create graphic (tName)
510536
put the long id of graphic (tName) into tRef
@@ -526,6 +552,10 @@ command b2kSpawnCapsule pScreenX, pScreenY, pLength, pThickness, pColor
526552
local tName, tRef
527553
if pLength is empty then put 80 into pLength
528554
if pThickness is empty then put 40 into pThickness
555+
put b2kClamp(pLength, 1, 10000) into pLength
556+
put b2kClamp(pThickness, 1, 10000) into pThickness
557+
put b2kNumberOr(pScreenX, sOriginX) into pScreenX
558+
put b2kNumberOr(pScreenY, sOriginY) into pScreenY
529559
put "b2kspawn_" & the milliseconds & "_" & random(1000000) into tName
530560
create graphic (tName)
531561
put the long id of graphic (tName) into tRef
@@ -552,18 +582,21 @@ end b2kSpawnCapsule
552582
command b2kSetBounce pControl, pRestitution
553583
local s
554584
put sShapeH[the long id of pControl] into s
585+
put b2kClamp(pRestitution, 0, 2) into pRestitution
555586
if s is not empty then b2SetShapeRestitution s, pRestitution
556587
end b2kSetBounce
557588

558589
command b2kSetFriction pControl, pFriction
559590
local s
560591
put sShapeH[the long id of pControl] into s
592+
put b2kClamp(pFriction, 0, 10) into pFriction
561593
if s is not empty then b2SetShapeFriction s, pFriction
562594
end b2kSetFriction
563595

564596
command b2kSetDensity pControl, pDensity
565597
local s
566598
put sShapeH[the long id of pControl] into s
599+
put b2kClamp(pDensity, 0, 10000) into pDensity
567600
if s is not empty then b2SetShapeDensity s, pDensity
568601
end b2kSetDensity
569602

@@ -585,12 +618,20 @@ command b2kReshape pControl, pShape
585618
switch pShape
586619
case "ball"
587620
put ((the width of pControl) / 2) / sScale into tR
621+
if tR <= 0 then
622+
put tOld into sShapeH[tRef]
623+
exit b2kReshape
624+
end if
588625
put b2AddCircle(tBody, 0, 0, tR, 1.0, 0.4, 0.4) into sShapeH[tRef]
589626
put tR into sRad[tRef]
590627
break
591628
case "capsule"
592629
put (the width of pControl) / sScale into tWm
593630
put (the height of pControl) / sScale into tHm
631+
if tWm <= 0 or tHm <= 0 then
632+
put tOld into sShapeH[tRef]
633+
exit b2kReshape
634+
end if
594635
put (tWm >= tHm) into tHoriz
595636
if tHoriz then
596637
put tHm / 2 into tR
@@ -628,6 +669,10 @@ command b2kReshape pControl, pShape
628669
default
629670
put ((the width of pControl) / 2) / sScale into tHw
630671
put ((the height of pControl) / 2) / sScale into tHh
672+
if tHw <= 0 or tHh <= 0 then
673+
put tOld into sShapeH[tRef]
674+
exit b2kReshape
675+
end if
631676
put b2AddBox(tBody, tHw, tHh, 1.0, 0.4, 0.2) into sShapeH[tRef]
632677
if sRender[tRef] is "poly" then
633678
put ("-" & tHw) & "," & ("-" & tHh) & cr & tHw & "," & ("-" & tHh) & cr \
@@ -1498,7 +1543,7 @@ command b2kRelease
14981543
end b2kRelease
14991544

15001545
-- =====================================================================
1501-
-- The loop (fixed timestep, generation-guarded, screen-locked sync)
1546+
-- The loop (fixed timestep, generation-guarded; sync locks only rendering)
15021547
-- =====================================================================
15031548
on b2kStep pGen
15041549
if not sRunning then exit b2kStep
@@ -1518,12 +1563,10 @@ on b2kStep pGen
15181563
if sDragging then
15191564
b2MouseSetTarget sDragJoint, b2kToWorldX(the mouseH), b2kToWorldY(the mouseV)
15201565
end if
1521-
lock screen
1522-
b2kSync
1523-
b2kDispatchContacts
1566+
b2kSync -- locks screen internally for render updates only
1567+
b2kDispatchContacts -- user handlers run after the screen is unlocked
15241568
b2kDispatchSensors
15251569
if sFrameObj is not empty then dispatch "b2kFrame" to sFrameObj
1526-
unlock screen -- one redraw per frame: sync + events + app drawing
15271570
end if
15281571
send ("b2kStep " & sGen) to me in 16 milliseconds
15291572
end b2kStep
@@ -1535,12 +1578,10 @@ command b2kStepOnce
15351578
if sDragging then
15361579
b2MouseSetTarget sDragJoint, b2kToWorldX(the mouseH), b2kToWorldY(the mouseV)
15371580
end if
1538-
lock screen
15391581
b2kSync
15401582
b2kDispatchContacts
15411583
b2kDispatchSensors
15421584
if sFrameObj is not empty then dispatch "b2kFrame" to sFrameObj
1543-
unlock screen
15441585
end b2kStepOnce
15451586

15461587
command b2kSync

examples/box2dxt-demo.livecodescript

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -254,21 +254,37 @@ end b2kClear
254254
-- =====================================================================
255255
-- Configuration
256256
-- =====================================================================
257+
function b2kNumberOr pValue, pDefault
258+
if pValue is empty then return pDefault
259+
if pValue is not a number then return pDefault
260+
return pValue
261+
end b2kNumberOr
262+
263+
function b2kClamp pValue, pLo, pHi
264+
local tValue
265+
put b2kNumberOr(pValue, pLo) into tValue
266+
if tValue < pLo then put pLo into tValue
267+
if tValue > pHi then put pHi into tValue
268+
return tValue
269+
end b2kClamp
270+
257271
command b2kSetScale pPixelsPerMetre
258-
put pPixelsPerMetre into sScale
272+
put b2kClamp(pPixelsPerMetre, 1, 10000) into sScale
259273
end b2kSetScale
260274

261275
command b2kSetOrigin pScreenX, pScreenY
262-
put pScreenX into sOriginX
263-
put pScreenY into sOriginY
276+
put b2kNumberOr(pScreenX, sOriginX) into sOriginX
277+
put b2kNumberOr(pScreenY, sOriginY) into sOriginY
264278
end b2kSetOrigin
265279

266280
command b2kSetGravity pGx, pGy
281+
put b2kNumberOr(pGx, 0) into pGx
282+
put b2kNumberOr(pGy, -10) into pGy
267283
if sWorld is not empty then b2SetGravity sWorld, pGx, pGy
268284
end b2kSetGravity
269285

270286
command b2kSetSubsteps pN
271-
put pN into sSub
287+
put round(b2kClamp(pN, 1, 64)) into sSub
272288
end b2kSetSubsteps
273289

274290
-- World toggles: island sleeping (saves CPU) and continuous collision (CCD,
@@ -333,6 +349,7 @@ command b2kAddBox pControl, pDynamic
333349
else put 0 into tType
334350
put ((the width of pControl) / 2) / sScale into tHw
335351
put ((the height of pControl) / 2) / sScale into tHh
352+
if tHw <= 0 or tHh <= 0 then return 0
336353
put b2kToWorldX(item 1 of the loc of pControl) into tWx
337354
put b2kToWorldY(item 2 of the loc of pControl) into tWy
338355
put (word 1 of tRef is "graphic") into tGraphic
@@ -366,6 +383,7 @@ command b2kAddBall pControl, pDynamic
366383
if pDynamic then put 2 into tType
367384
else put 0 into tType
368385
put ((the width of pControl) / 2) / sScale into tRad
386+
if tRad <= 0 then return 0
369387
put b2kToWorldX(item 1 of the loc of pControl) into tWx
370388
put b2kToWorldY(item 2 of the loc of pControl) into tWy
371389
put b2NewBody(sWorld, tType, tWx, tWy, 0, false, false) into tBody
@@ -390,6 +408,7 @@ command b2kAddCapsule pControl, pDynamic
390408
else put 0 into tType
391409
put (the width of pControl) / sScale into tWm
392410
put (the height of pControl) / sScale into tHm
411+
if tWm <= 0 or tHm <= 0 then return 0
393412
put (tWm >= tHm) into tHoriz
394413
if tHoriz then
395414
put tHm / 2 into tR
@@ -476,7 +495,11 @@ end b2kRegister
476495
command b2kSpawnBox pScreenX, pScreenY, pW, pH, pColor
477496
local tName, tRef
478497
if pW is empty then put 40 into pW
498+
put b2kClamp(pW, 1, 10000) into pW
479499
if pH is empty then put pW into pH
500+
put b2kClamp(pH, 1, 10000) into pH
501+
put b2kNumberOr(pScreenX, sOriginX) into pScreenX
502+
put b2kNumberOr(pScreenY, sOriginY) into pScreenY
480503
put "b2kspawn_" & the milliseconds & "_" & random(1000000) into tName
481504
create graphic (tName)
482505
put the long id of graphic (tName) into tRef
@@ -495,6 +518,9 @@ end b2kSpawnBox
495518
command b2kSpawnBall pScreenX, pScreenY, pDiameter, pColor
496519
local tName, tRef
497520
if pDiameter is empty then put 40 into pDiameter
521+
put b2kClamp(pDiameter, 1, 10000) into pDiameter
522+
put b2kNumberOr(pScreenX, sOriginX) into pScreenX
523+
put b2kNumberOr(pScreenY, sOriginY) into pScreenY
498524
put "b2kspawn_" & the milliseconds & "_" & random(1000000) into tName
499525
create graphic (tName)
500526
put the long id of graphic (tName) into tRef
@@ -516,6 +542,10 @@ command b2kSpawnCapsule pScreenX, pScreenY, pLength, pThickness, pColor
516542
local tName, tRef
517543
if pLength is empty then put 80 into pLength
518544
if pThickness is empty then put 40 into pThickness
545+
put b2kClamp(pLength, 1, 10000) into pLength
546+
put b2kClamp(pThickness, 1, 10000) into pThickness
547+
put b2kNumberOr(pScreenX, sOriginX) into pScreenX
548+
put b2kNumberOr(pScreenY, sOriginY) into pScreenY
519549
put "b2kspawn_" & the milliseconds & "_" & random(1000000) into tName
520550
create graphic (tName)
521551
put the long id of graphic (tName) into tRef
@@ -542,18 +572,21 @@ end b2kSpawnCapsule
542572
command b2kSetBounce pControl, pRestitution
543573
local s
544574
put sShapeH[the long id of pControl] into s
575+
put b2kClamp(pRestitution, 0, 2) into pRestitution
545576
if s is not empty then b2SetShapeRestitution s, pRestitution
546577
end b2kSetBounce
547578

548579
command b2kSetFriction pControl, pFriction
549580
local s
550581
put sShapeH[the long id of pControl] into s
582+
put b2kClamp(pFriction, 0, 10) into pFriction
551583
if s is not empty then b2SetShapeFriction s, pFriction
552584
end b2kSetFriction
553585

554586
command b2kSetDensity pControl, pDensity
555587
local s
556588
put sShapeH[the long id of pControl] into s
589+
put b2kClamp(pDensity, 0, 10000) into pDensity
557590
if s is not empty then b2SetShapeDensity s, pDensity
558591
end b2kSetDensity
559592

@@ -575,12 +608,20 @@ command b2kReshape pControl, pShape
575608
switch pShape
576609
case "ball"
577610
put ((the width of pControl) / 2) / sScale into tR
611+
if tR <= 0 then
612+
put tOld into sShapeH[tRef]
613+
exit b2kReshape
614+
end if
578615
put b2AddCircle(tBody, 0, 0, tR, 1.0, 0.4, 0.4) into sShapeH[tRef]
579616
put tR into sRad[tRef]
580617
break
581618
case "capsule"
582619
put (the width of pControl) / sScale into tWm
583620
put (the height of pControl) / sScale into tHm
621+
if tWm <= 0 or tHm <= 0 then
622+
put tOld into sShapeH[tRef]
623+
exit b2kReshape
624+
end if
584625
put (tWm >= tHm) into tHoriz
585626
if tHoriz then
586627
put tHm / 2 into tR
@@ -618,6 +659,10 @@ command b2kReshape pControl, pShape
618659
default
619660
put ((the width of pControl) / 2) / sScale into tHw
620661
put ((the height of pControl) / 2) / sScale into tHh
662+
if tHw <= 0 or tHh <= 0 then
663+
put tOld into sShapeH[tRef]
664+
exit b2kReshape
665+
end if
621666
put b2AddBox(tBody, tHw, tHh, 1.0, 0.4, 0.2) into sShapeH[tRef]
622667
if sRender[tRef] is "poly" then
623668
put ("-" & tHw) & "," & ("-" & tHh) & cr & tHw & "," & ("-" & tHh) & cr \
@@ -1488,7 +1533,7 @@ command b2kRelease
14881533
end b2kRelease
14891534

14901535
-- =====================================================================
1491-
-- The loop (fixed timestep, generation-guarded, screen-locked sync)
1536+
-- The loop (fixed timestep, generation-guarded; sync locks only rendering)
14921537
-- =====================================================================
14931538
on b2kStep pGen
14941539
if not sRunning then exit b2kStep
@@ -1508,12 +1553,10 @@ on b2kStep pGen
15081553
if sDragging then
15091554
b2MouseSetTarget sDragJoint, b2kToWorldX(the mouseH), b2kToWorldY(the mouseV)
15101555
end if
1511-
lock screen
1512-
b2kSync
1513-
b2kDispatchContacts
1556+
b2kSync -- locks screen internally for render updates only
1557+
b2kDispatchContacts -- user handlers run after the screen is unlocked
15141558
b2kDispatchSensors
15151559
if sFrameObj is not empty then dispatch "b2kFrame" to sFrameObj
1516-
unlock screen -- one redraw per frame: sync + events + app drawing
15171560
end if
15181561
send ("b2kStep " & sGen) to me in 16 milliseconds
15191562
end b2kStep
@@ -1525,12 +1568,10 @@ command b2kStepOnce
15251568
if sDragging then
15261569
b2MouseSetTarget sDragJoint, b2kToWorldX(the mouseH), b2kToWorldY(the mouseV)
15271570
end if
1528-
lock screen
15291571
b2kSync
15301572
b2kDispatchContacts
15311573
b2kDispatchSensors
15321574
if sFrameObj is not empty then dispatch "b2kFrame" to sFrameObj
1533-
unlock screen
15341575
end b2kStepOnce
15351576

15361577
command b2kSync

0 commit comments

Comments
 (0)