Optimized jsexport by tailored resolv lib.

This commit is contained in:
genxium
2022-12-25 18:44:29 +08:00
parent 9ffcc6fbd8
commit 8139a00939
24 changed files with 2265 additions and 126 deletions

View File

@@ -3,3 +3,5 @@ GopherJs is supposed to be run by `go run`.
If on-the-fly compilation is needed, run `gopherjs serve jsexport` and then visit `http://localhost:8080/jsexport.js` -- if 404 not found is responded, run `gopherjs build` to check syntax errors.
See the `Makefile` for more options.
Kindly note that the sources of the greate opensource projects [resolv](https://github.com/SolarLune/resolv) and [vector](https://github.com/quartercastle/vector) are copied and modified here to reduce the size of generated js codes, i.e. standard libs `fmt`, `error`, `pb`(including standard libs `sync` and `reflect`) are deliberately avoided from scratch.

View File

@@ -1,8 +1,7 @@
package battle
import (
"github.com/kvartborg/vector"
"github.com/solarlune/resolv"
"resolv"
"math"
)
@@ -61,7 +60,7 @@ type SatResult struct {
OverlapY float64
AContainedInB bool
BContainedInA bool
Axis vector.Vector
Axis resolv.Vector
}
func CalcPushbacks(oldDx, oldDy float64, playerShape, barrierShape *resolv.ConvexPolygon) (bool, float64, float64, *SatResult) {
@@ -77,7 +76,7 @@ func CalcPushbacks(oldDx, oldDy float64, playerShape, barrierShape *resolv.Conve
OverlapY: 0,
AContainedInB: true,
BContainedInA: true,
Axis: vector.Vector{0, 0},
Axis: resolv.Vector{0, 0},
}
if overlapped := isPolygonPairOverlapped(playerShape, barrierShape, overlapResult); overlapped {
pushbackX, pushbackY := overlapResult.Overlap*overlapResult.OverlapX, overlapResult.Overlap*overlapResult.OverlapY
@@ -116,7 +115,7 @@ func isPolygonPairOverlapped(a, b *resolv.ConvexPolygon, result *SatResult) bool
return true
}
func isPolygonPairSeparatedByDir(a, b *resolv.ConvexPolygon, e vector.Vector, result *SatResult) bool {
func isPolygonPairSeparatedByDir(a, b *resolv.ConvexPolygon, e resolv.Vector, result *SatResult) bool {
/*
[WARNING] This function is deliberately made private, it shouldn't be used alone (i.e. not along the norms of a polygon), otherwise the pushbacks calculated would be meaningless.

View File

@@ -30,9 +30,6 @@ type PlayerDownsync struct {
MaxHp int32
CharacterState int32
InAir bool
Name string
DisplayName string
Avatar string
}
type InputFrameDecoded struct {
@@ -80,5 +77,4 @@ type RoomDownsyncFrame struct {
MeleeBullets []*MeleeBullet
BackendUnconfirmedMask uint64
ShouldForceResync bool
Players map[int32]*PlayerDownsync
}

View File

@@ -4,10 +4,9 @@ go 1.18
require (
github.com/gopherjs/gopherjs v1.18.0-beta1
github.com/solarlune/resolv v0.5.1
resolv v0.0.0
)
require (
github.com/kvartborg/vector v0.0.0-20200419093813-2cba0cabb4f0 // indirect
replace (
resolv => ../resolv_tailored
)

View File

@@ -1,23 +1,2 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gopherjs/gopherjs v1.18.0-beta1 h1:IbykhVEq4SAjwyBRuNHl0aOO6w6IqgL3RUdMhoBo4mY=
github.com/gopherjs/gopherjs v1.18.0-beta1/go.mod h1:6UY8PXRnu51MqjYCCY4toG0S5GeH5uVJ3qDxIsa+kqo=
github.com/kvartborg/vector v0.0.0-20200419093813-2cba0cabb4f0 h1:v8lWpj5957KtDMKu+xQtlu6G3ZoZR6Tn9bsfZCRG5Xw=
github.com/kvartborg/vector v0.0.0-20200419093813-2cba0cabb4f0/go.mod h1:GAX7tMJqXx9fB1BrsTWPOXy6IBRX+J461BffVPAdpwo=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/solarlune/resolv v0.5.1 h1:Ul6PAs/zaxiMUOEYz1Z6VeUj5k3CDcWMvSh+kivybDY=
github.com/solarlune/resolv v0.5.1/go.mod h1:HjM2f/0NoVjVdZsi26GtugX5aFbA62COEFEXkOhveRw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=

View File

@@ -1,18 +0,0 @@
<html>
<head>
<script src="jsexport.js"></script>
</head>
<script>
var minStep = 8;
var space = gopkgs.NewCollisionSpaceJs(2048, 2048, 8, 8);
var snapIntoPlatformOverlap = 0.1;
var spaceOffsetX = 0;
var spaceOffsetY = 0;
var a = gopkgs.GenerateRectColliderJs(189, 497, 48, 48, snapIntoPlatformOverlap, snapIntoPlatformOverlap, snapIntoPlatformOverlap, snapIntoPlatformOverlap, spaceOffsetX, spaceOffsetY, "Player");
space.Add(a);
var b = gopkgs.GenerateRectColliderJs(189, 504, 48, 48, snapIntoPlatformOverlap, snapIntoPlatformOverlap, snapIntoPlatformOverlap, snapIntoPlatformOverlap, spaceOffsetX, spaceOffsetY, "Player");
space.Add(b);
var collision = gopkgs.CheckCollisionJs(a, 0, 0);
console.log(collision);
</script>
</html>

View File

@@ -1,8 +1,8 @@
package main
import (
"resolv"
"github.com/gopherjs/gopherjs/js"
"github.com/solarlune/resolv"
. "jsexport/battle"
)
@@ -51,6 +51,7 @@ func NewPlayerDownsyncJs(id, virtualGridX, virtualGridY, dirX, dirY, velX, velY,
}
func NewRoomDownsyncFrameJs(id int32, playersArr []*PlayerDownsync, meleeBullets []*MeleeBullet) *js.Object {
// [WARNING] Avoid using "pb.RoomDownsyncFrame" here, in practive "MakeFullWrapper" doesn't expose the public fields for a "protobuf struct" as expected and requires helper functions like "GetCollisionSpaceObjsJs".
return js.MakeFullWrapper(&RoomDownsyncFrame{
Id: id,
PlayersArr: playersArr,
@@ -59,6 +60,7 @@ func NewRoomDownsyncFrameJs(id int32, playersArr []*PlayerDownsync, meleeBullets
}
func GetCollisionSpaceObjsJs(space *resolv.Space) []*js.Object {
// [WARNING] We couldn't just use the existing method "space.Objects()" to access them in JavaScript, there'd a stackoverflow error
objs := space.Objects()
ret := make([]*js.Object, 0, len(objs))
for _, obj := range objs {
@@ -67,15 +69,6 @@ func GetCollisionSpaceObjsJs(space *resolv.Space) []*js.Object {
return ret
}
func GetPlayersArrJs(rdf *RoomDownsyncFrame) []*js.Object {
// We couldn't just use the existing getters or field names to access non-primitive fields in Js
ret := make([]*js.Object, 0, len(rdf.PlayersArr))
for _, player := range rdf.PlayersArr {
ret = append(ret, js.MakeFullWrapper(player))
}
return ret
}
func GenerateRectColliderJs(wx, wy, w, h, topPadding, bottomPadding, leftPadding, rightPadding, spaceOffsetX, spaceOffsetY float64, data interface{}, tag string) *js.Object {
/*
[WARNING] It's important to note that we don't need "js.MakeFullWrapper" for a call sequence as follows.
@@ -96,12 +89,6 @@ func GenerateConvexPolygonColliderJs(unalignedSrc *Polygon2D, spaceOffsetX, spac
return js.MakeFullWrapper(GenerateConvexPolygonCollider(unalignedSrc, spaceOffsetX, spaceOffsetY, data, tag))
}
func CheckCollisionJs(obj *resolv.Object, dx, dy float64) *js.Object {
// TODO: Support multiple tags in the future
// Unfortunately I couldn't find a way to just call "var a = GenerateRectColliderJs(...); space.Add(a); a.Check(...)" to get the collision result, the unwrapped method will result in stack overflow. Need a better solution later.
return js.MakeFullWrapper(obj.Check(dx, dy))
}
func ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs(delayedInputList, delayedInputListForPrevRenderFrame []uint64, currRenderFrame *RoomDownsyncFrame, collisionSys *resolv.Space, collisionSysMap map[int32]*resolv.Object, gravityX, gravityY, jumpingInitVelY, inputDelayFrames, inputScaleFrames int32, collisionSpaceOffsetX, collisionSpaceOffsetY, snapIntoPlatformOverlap, snapIntoPlatformThreshold, worldToVirtualGridRatio, virtualGridToWorldRatio float64) *js.Object {
// We need access to all fields of RoomDownsyncFrame for displaying in frontend
return js.MakeFullWrapper(ApplyInputFrameDownsyncDynamicsOnSingleRenderFrame(delayedInputList, delayedInputListForPrevRenderFrame, currRenderFrame, collisionSys, collisionSysMap, gravityX, gravityY, jumpingInitVelY, inputDelayFrames, inputScaleFrames, collisionSpaceOffsetX, collisionSpaceOffsetY, snapIntoPlatformOverlap, snapIntoPlatformThreshold, worldToVirtualGridRatio, virtualGridToWorldRatio))
@@ -117,11 +104,9 @@ func main() {
"NewCollisionSpaceJs": NewCollisionSpaceJs,
"GenerateRectColliderJs": GenerateRectColliderJs,
"GenerateConvexPolygonColliderJs": GenerateConvexPolygonColliderJs,
"GetPlayersArrJs": GetPlayersArrJs,
"GetCollisionSpaceObjsJs": GetCollisionSpaceObjsJs,
"ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs": ApplyInputFrameDownsyncDynamicsOnSingleRenderFrameJs,
"WorldToPolygonColliderBLPos": WorldToPolygonColliderBLPos, // No need to wrap primitive return types
"PolygonColliderBLToWorldPos": PolygonColliderBLToWorldPos,
"CheckCollisionJs": CheckCollisionJs,
})
}