@rbxts/replecs 0.1.0-alpha9 → 0.2.0-cdtest.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@
2
2
  --!optimize 2
3
3
 
4
4
  local jecs = require "../jecs"
5
+ local customid = require "./customid"
5
6
  local common = require "./common"
6
7
 
7
8
  type World = jecs.World
@@ -14,11 +15,6 @@ export type Cursor = {
14
15
 
15
16
  local ECS_NAME = jecs.Name
16
17
  local CHILD_OF = jecs.ChildOf
17
- local WILDCARD = jecs.Wildcard
18
-
19
- function PAIR(first: Entity, second: Entity): Entity
20
- return jecs.pair(first, second)
21
- end
22
18
 
23
19
  local utils = {}
24
20
 
@@ -139,6 +135,20 @@ function cursor.writei32(c: Cursor, value: number)
139
135
  c.offset += 4
140
136
  end
141
137
 
138
+ function cursor.write_span(c: Cursor, value: number, span: number)
139
+ if span <= 0xFF then
140
+ cursor.writeu8(c, value)
141
+ elseif span <= 0xFFFF then
142
+ cursor.writeu16(c, value)
143
+ elseif span <= 0xFFFFFF then
144
+ cursor.writeu24(c, value)
145
+ elseif span <= 0xFFFFFFFF then
146
+ cursor.writeu32(c, value)
147
+ else
148
+ error "span too large"
149
+ end
150
+ end
151
+
142
152
  function cursor.read_buffer(c: Cursor, len: number)
143
153
  local retrieved = buffer.create(len)
144
154
  buffer.copy(retrieved, 0, c.buffer, c.offset - len, len)
@@ -175,6 +185,20 @@ function cursor.readu40(c: Cursor): number
175
185
  return one + two * 256
176
186
  end
177
187
 
188
+ function cursor.read_span(c: Cursor, span: number): number
189
+ if span <= 0xFF then
190
+ return cursor.readu8(c)
191
+ elseif span <= 0xFFFF then
192
+ return cursor.readu16(c)
193
+ elseif span <= 0xFFFFFF then
194
+ return cursor.readu24(c)
195
+ elseif span <= 0xFFFFFFFF then
196
+ return cursor.readu32(c)
197
+ else
198
+ error "span too large"
199
+ end
200
+ end
201
+
178
202
  function cursor.readi8(c: Cursor): number
179
203
  c.offset -= 1
180
204
  return buffer.readi8(c.buffer, c.offset)
@@ -550,11 +574,14 @@ function bitmask.tostring(self: Bitmask): string
550
574
  end
551
575
 
552
576
  table.clear(BYTES)
577
+ local str = ""
553
578
  for i = 0, highest_entry do
554
- table.insert(BYTES, buffer.readu32(buf, i * BYTES_PER_ENTRY))
579
+ str = str .. tobinary(buffer.readu32(buf, i * BYTES_PER_ENTRY))
580
+ --table.insert(BYTES, buffer.readu32(buf, i * BYTES_PER_ENTRY))
555
581
  end
556
582
 
557
- return table.concat(BYTES, "-")
583
+ --return table.concat(BYTES, "-")
584
+ return str
558
585
  end
559
586
 
560
587
  utils.bitmask = {
@@ -562,47 +589,173 @@ utils.bitmask = {
562
589
  from_set = bitmask.from_set,
563
590
  }
564
591
 
565
- function utils.create_shared_lookup(world: World, components: common.Components)
566
- local shared: common.Shared = {
567
- lookup = {
568
- ["jecs.ChildOf"] = CHILD_OF,
569
- },
592
+ function utils.create_shared_lookup<T>(lookup: { [string]: T }): common.SharedInfo<T>
593
+ local keys = {}
594
+ local indexes = {}
595
+ local members = {}
596
+
597
+ for name in lookup do
598
+ table.insert(keys, name)
599
+ end
600
+ table.sort(keys)
601
+
602
+ for index, name in keys do
603
+ local member = lookup[name]
604
+ members[member] = index
605
+ indexes[index] = member
606
+ end
607
+
608
+ return {
609
+ lookup = lookup,
610
+ keys = keys,
611
+ indexes = indexes,
612
+ members = members,
613
+ }
614
+ end
615
+
616
+ function utils.resolved_shared(
617
+ world: World,
618
+ components: common.Components,
619
+ registered_custom_ids: { [customid.CustomId]: boolean }
620
+ ): common.Shared
621
+ local shared = {
570
622
  serdes = {},
571
623
  bytespan = {},
572
- ids = {},
573
- components = {},
624
+ } :: common.Shared
625
+
626
+ local components_lookup: { [string]: jecs.Entity } = {
627
+ ["jecs.ChildOf"] = CHILD_OF,
574
628
  }
629
+ local custom_ids_lookup = {}
575
630
 
576
631
  for component, name in world:query(ECS_NAME):with(components.shared):iter() do
577
- shared.lookup[name] = component
632
+ components_lookup[name] = component
633
+ end
634
+
635
+ for custom in registered_custom_ids do
636
+ custom_ids_lookup[custom.identifier] = custom
578
637
  end
579
638
 
580
639
  for component, serdes in world:query(components.serdes):with(components.shared, ECS_NAME):iter() do
581
640
  shared.serdes[component] = serdes
582
641
  end
583
642
 
584
- for component, bytespan in world:query(components.bytespan):with(components.shared, ECS_NAME):iter() do
585
- shared.bytespan[component] = bytespan
643
+ shared.components = utils.create_shared_lookup(components_lookup)
644
+ shared.custom_ids = utils.create_shared_lookup(custom_ids_lookup)
645
+
646
+ return shared
647
+ end
648
+
649
+ function utils.generate_handshake(world: World, shared: common.Shared): common.HandshakeInfo
650
+ local component_to_name: { [Entity]: string } = {}
651
+ local handshake: common.HandshakeInfo = {
652
+ components = {},
653
+ custom_ids = {},
654
+ serdes = {},
655
+ }
656
+
657
+ for component_name, component in shared.components.lookup do
658
+ handshake.components[component_name] = true
659
+ component_to_name[component] = component_name
586
660
  end
587
661
 
588
- local keys = {}
589
- local component_ids = {}
590
- local id_components = {}
662
+ for custom_id in shared.custom_ids.lookup do
663
+ handshake.custom_ids[custom_id] = true
664
+ end
591
665
 
592
- for name in shared.lookup do
593
- table.insert(keys, name)
666
+ for component, serdes in shared.serdes do
667
+ local name = component_to_name[component]
668
+ if not name then
669
+ utils.logwarn(`found serdes for component {utils.logcomponent(world, component)} was not shared`)
670
+ continue
671
+ end
672
+
673
+ handshake.serdes[name] = {
674
+ includes_variants = serdes.includes_variants,
675
+ bytespan = serdes.bytespan,
676
+ }
677
+ end
678
+
679
+ return handshake
680
+ end
681
+
682
+ function utils.verify_handshake(
683
+ world: World,
684
+ shared: common.Shared,
685
+ handshake: common.HandshakeInfo,
686
+ handshake_side: string,
687
+ verify_side: string
688
+ ): (boolean, string?)
689
+ local component_to_name: { [Entity]: string } = {}
690
+
691
+ for component_name in handshake.components do
692
+ if not shared.components.lookup[component_name] then
693
+ return false, `missing shared component "{component_name}" in {verify_side}`
694
+ end
695
+ end
696
+ for component_name, component in shared.components.lookup do
697
+ if not handshake.components[component_name] then
698
+ return false, `missing shared component "{component_name}" in {handshake_side}`
699
+ end
700
+ component_to_name[component] = component_name
594
701
  end
595
- table.sort(keys)
596
702
 
597
- for id, name in keys do
598
- local component = shared.lookup[name]
599
- component_ids[shared.lookup[name]] = id
600
- id_components[id] = component
703
+ for custom_id in handshake.custom_ids do
704
+ if not shared.custom_ids.lookup[custom_id] then
705
+ return false, `missing custom id "{custom_id}" in {verify_side}`
706
+ end
707
+ end
708
+ for custom_id in shared.custom_ids.lookup do
709
+ if not handshake.custom_ids[custom_id] then
710
+ return false, `missing custom id "{custom_id}" in {handshake_side}`
711
+ end
601
712
  end
602
713
 
603
- shared.ids = component_ids
604
- shared.components = id_components
605
- return shared
714
+ for component_name, serdes_info in handshake.serdes do
715
+ local component = shared.components.lookup[component_name]
716
+ if not component then
717
+ warn(`{handshake_side} registered a serdes for "{component_name}" that {verify_side} doesn't have`)
718
+ continue
719
+ end
720
+
721
+ local serdes = shared.serdes[component]
722
+ if not serdes then
723
+ return false, `missing serdes for component "{component_name}" in {verify_side}`
724
+ end
725
+
726
+ if (serdes_info.includes_variants or false) ~= (serdes.includes_variants or false) then
727
+ return false,
728
+ `mismatched includes_variants for component "{component_name}": ({serdes_info.includes_variants} ~= {serdes.includes_variants})`
729
+ end
730
+ if serdes_info.bytespan ~= serdes.bytespan then
731
+ return false,
732
+ `mismatched bytespan for component "{component_name}": ({serdes_info.bytespan} ~= {serdes.bytespan})`
733
+ end
734
+ end
735
+ for component in shared.serdes do
736
+ local component_name = component_to_name[component]
737
+ if not component_name then
738
+ utils.logwarn(`found serdes for component {utils.logcomponent(world, component)} was not shared`)
739
+ continue
740
+ end
741
+
742
+ if not handshake.serdes[component_name] then
743
+ warn(`{verify_side} registered a serdes for "{component_name}" that {handshake_side} doesn't have`)
744
+ end
745
+ end
746
+
747
+ return true, nil
748
+ end
749
+
750
+ function utils.is_client_valid(player: any): boolean
751
+ if game then
752
+ if typeof(player) == "Instance" then
753
+ return player.ClassName == "Player" and player:IsDescendantOf(game:GetService "Players")
754
+ else
755
+ return false
756
+ end
757
+ end
758
+ return true
606
759
  end
607
760
 
608
761
  function utils.vlq_span(length: number): number
@@ -0,0 +1 @@
1
+ return "0.2.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/replecs",
3
- "version": "0.1.0-alpha9",
3
+ "version": "0.2.0-cdtest.2",
4
4
  "description": "Replication library for Jecs",
5
5
  "main": "out/init.lua",
6
6
  "types": "out/index.d.ts",
@@ -21,8 +21,7 @@
21
21
  "scripts": {
22
22
  "serve": "rojo sourcemap serve.project.json -o sourcemap.json --watch && rojo serve serve.project.json",
23
23
  "build": "rbxtsc",
24
- "watch": "rbxtsc -w",
25
- "prepublishOnly": "npm run build"
24
+ "watch": "rbxtsc -w"
26
25
  },
27
26
  "repository": {
28
27
  "type": "git",
@@ -1 +0,0 @@
1
- export type FilterGroup = {}