@rbxts/replecs 0.1.0-alpha9-test5 → 0.2.0-cdtest.1

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)
@@ -531,10 +555,14 @@ local function tobinary(n: number): string
531
555
  return string.rep("0", 8 - #result) .. result
532
556
  end
533
557
 
558
+ local BYTES = table.create(6)
559
+
534
560
  function bitmask.tostring(self: Bitmask): string
561
+ local buf = self.buffer
562
+
535
563
  local highest_entry = -1
536
564
  for i = self.entries - 1, 0, -1 do
537
- local value = bitmask.read(self, i)
565
+ local value = buffer.readu32(buf, i * BYTES_PER_ENTRY)
538
566
  if value ~= 0 then
539
567
  highest_entry = i
540
568
  break
@@ -545,11 +573,14 @@ function bitmask.tostring(self: Bitmask): string
545
573
  return ""
546
574
  end
547
575
 
576
+ table.clear(BYTES)
548
577
  local str = ""
549
578
  for i = 0, highest_entry do
550
- local value = bitmask.read(self, i)
551
- str ..= tobinary(value)
579
+ str = str .. tobinary(buffer.readu32(buf, i * BYTES_PER_ENTRY))
580
+ --table.insert(BYTES, buffer.readu32(buf, i * BYTES_PER_ENTRY))
552
581
  end
582
+
583
+ --return table.concat(BYTES, "-")
553
584
  return str
554
585
  end
555
586
 
@@ -558,47 +589,173 @@ utils.bitmask = {
558
589
  from_set = bitmask.from_set,
559
590
  }
560
591
 
561
- function utils.create_shared_lookup(world: World, components: common.Components)
562
- local shared: common.Shared = {
563
- lookup = {
564
- ["jecs.ChildOf"] = CHILD_OF,
565
- },
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 = {
566
622
  serdes = {},
567
623
  bytespan = {},
568
- ids = {},
569
- components = {},
624
+ } :: common.Shared
625
+
626
+ local components_lookup: { [string]: jecs.Entity } = {
627
+ ["jecs.ChildOf"] = CHILD_OF,
570
628
  }
629
+ local custom_ids_lookup = {}
571
630
 
572
631
  for component, name in world:query(ECS_NAME):with(components.shared):iter() do
573
- 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
574
637
  end
575
638
 
576
639
  for component, serdes in world:query(components.serdes):with(components.shared, ECS_NAME):iter() do
577
640
  shared.serdes[component] = serdes
578
641
  end
579
642
 
580
- for component, bytespan in world:query(components.bytespan):with(components.shared, ECS_NAME):iter() do
581
- 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
660
+ end
661
+
662
+ for custom_id in shared.custom_ids.lookup do
663
+ handshake.custom_ids[custom_id] = true
582
664
  end
583
665
 
584
- local keys = {}
585
- local component_ids = {}
586
- local id_components = {}
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
587
672
 
588
- for name in shared.lookup do
589
- table.insert(keys, name)
673
+ handshake.serdes[name] = {
674
+ includes_variants = serdes.includes_variants,
675
+ bytespan = serdes.bytespan,
676
+ }
590
677
  end
591
- table.sort(keys)
592
678
 
593
- for id, name in keys do
594
- local component = shared.lookup[name]
595
- component_ids[shared.lookup[name]] = id
596
- id_components[id] = component
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
597
701
  end
598
702
 
599
- shared.ids = component_ids
600
- shared.components = id_components
601
- return shared
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
712
+ end
713
+
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
602
759
  end
603
760
 
604
761
  function utils.vlq_span(length: number): number
@@ -0,0 +1,2 @@
1
+ -- Automatically generated
2
+ return ""
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rbxts/replecs",
3
- "version": "0.1.0-alpha9-test5",
3
+ "version": "0.2.0-cdtest.1",
4
4
  "description": "Replication library for Jecs",
5
5
  "main": "out/init.lua",
6
6
  "types": "out/index.d.ts",
@@ -1 +0,0 @@
1
- export type FilterGroup = {}