12
12
T = TypeVar ("T" )
13
13
14
14
15
+ # TODO: docs (copy from rust, probably)
16
+ # TODO: the fact that this thing is nor interned and is recomputed/realloc'd for each
17
+ # log call is pretty shit? then again I guess this is just as true for the arrow datatypes we
18
+ # keep passing around... and the same is true for rust... (i think cpp caches all of this?)
19
+ class ComponentDescriptor :
20
+ def __init__ (
21
+ self ,
22
+ component_name : str ,
23
+ * ,
24
+ archetype_name : str | None = None ,
25
+ archetype_field_name : str | None = None ,
26
+ ) -> None :
27
+ self .archetype_name = archetype_name
28
+ self .archetype_field_name = archetype_field_name
29
+ self .component_name = component_name
30
+
31
+ def __str__ (self ) -> str :
32
+ archetype_name = self .archetype_name
33
+ archetype_field_name = self .archetype_field_name
34
+ component_name = self .component_name
35
+
36
+ if archetype_name is not None and archetype_field_name is None :
37
+ return f"{ archetype_name } :{ component_name } "
38
+ elif archetype_name is None and archetype_field_name is not None :
39
+ return f"{ component_name } #{ archetype_field_name } "
40
+ elif archetype_name is not None and archetype_field_name is not None :
41
+ return f"{ archetype_name } :{ component_name } #{ archetype_field_name } "
42
+
43
+ return component_name
44
+
45
+
46
+ # TODO: Protocol are duck typed
15
47
class ComponentBatchLike (Protocol ):
16
48
"""Describes interface for objects that can be converted to batch of rerun Components."""
17
49
50
+ # TODO: uh... this needs to be the complete opposite
51
+ # def component_name(self) -> str:
52
+ # """
53
+ # The fully-qualified name of this component batch, e.g. `rerun.components.Position2D`.
54
+ #
55
+ # This is a trivial but useful helper for `self.descriptor().component_name`.
56
+ #
57
+ # The default implementation already does the right thing. Do not override unless you know
58
+ # what you're doing.
59
+ # `Self::name()` must exactly match the value returned by `self.descriptor().component_name`,
60
+ # or undefined behavior ensues.
61
+ # """
62
+ # return self.component_descriptor().component_name
63
+ #
64
+ # def component_descriptor(self) -> ComponentDescriptor:
65
+ # """Returns the complete descriptor of the component."""
66
+ # ...
67
+
68
+ # TODO: in python we probably dont need component_name at all anymore though?
69
+ # TODO: for the static type checker...
18
70
def component_name (self ) -> str :
19
71
"""Returns the name of the component."""
20
72
...
21
73
74
+ def component_descriptor (self ) -> ComponentDescriptor :
75
+ """Returns the complete descriptor of the component."""
76
+ return ComponentDescriptor (self .component_name ())
77
+
22
78
def as_arrow_array (self ) -> pa .Array :
23
79
"""Returns a `pyarrow.Array` of the component data."""
24
80
...
25
81
26
82
83
+ class DescribedComponentBatch (ComponentBatchLike ):
84
+ """A `ComponentBatchLike` object with its associated `ComponentDescriptor`."""
85
+
86
+ # TODO: don't do this noob
87
+ # _descriptor: ComponentDescriptor
88
+ # _batch: ComponentBatchLike
89
+
90
+ def __init__ (self , batch : ComponentBatchLike , descriptor : ComponentDescriptor ):
91
+ self ._batch = batch
92
+ self ._descriptor = descriptor
93
+
94
+ def component_name (self ) -> str :
95
+ """Returns the name of the component."""
96
+ return self ._batch .component_name ()
97
+
98
+ def component_descriptor (self ) -> ComponentDescriptor :
99
+ """Returns the complete descriptor of the component."""
100
+ return self ._descriptor
101
+
102
+ def as_arrow_array (self ) -> pa .Array :
103
+ """Returns a `pyarrow.Array` of the component data."""
104
+ return self ._batch .as_arrow_array ()
105
+
106
+
27
107
class AsComponents (Protocol ):
28
108
"""
29
109
Describes interface for interpreting an object as a bundle of Components.
@@ -43,6 +123,8 @@ def as_component_batches(self) -> Iterable[ComponentBatchLike]:
43
123
...
44
124
45
125
126
+ # TODO: same as `Archetype(rr.AsComponents)`
127
+ # TODO:
46
128
@define
47
129
class Archetype :
48
130
"""Base class for all archetypes."""
@@ -107,11 +189,17 @@ def as_component_batches(self) -> Iterable[ComponentBatchLike]:
107
189
# TODO(#3381): Depending on what we decide
108
190
# to do with optional components, we may need to make this instead call `_empty_pa_array`
109
191
if comp is not None :
110
- yield comp
192
+ descr = ComponentDescriptor (
193
+ comp .component_name (),
194
+ archetype_name = self .archetype_name (),
195
+ archetype_field_name = fld .name ,
196
+ )
197
+ yield DescribedComponentBatch (comp , descr )
111
198
112
199
__repr__ = __str__
113
200
114
201
202
+ # TODO: basically that's the equivalent of Rust's Loggable right now
115
203
class BaseBatch (Generic [T ]):
116
204
_ARROW_DATATYPE : pa .DataType | None = None
117
205
"""The pyarrow type of this batch."""
@@ -268,6 +356,14 @@ def component_name(self) -> str:
268
356
"""
269
357
return self .component_batch .component_name ()
270
358
359
+ def component_descriptor (self ) -> ComponentDescriptor :
360
+ """
361
+ Returns the complete descriptor of the component.
362
+
363
+ Part of the `ComponentBatchLike` logging interface.
364
+ """
365
+ return self .component_batch .component_descriptor ()
366
+
271
367
def as_arrow_array (self ) -> pa .Array :
272
368
"""
273
369
The component as an arrow batch.
@@ -279,6 +375,7 @@ def as_arrow_array(self) -> pa.Array:
279
375
return pa .ListArray .from_arrays (offsets , array )
280
376
281
377
378
+ # TODO: okay what about this? does this need a descriptor?
282
379
class ComponentBatchMixin (ComponentBatchLike ):
283
380
def component_name (self ) -> str :
284
381
"""
@@ -308,6 +405,7 @@ def partition(self, lengths: npt.ArrayLike) -> ComponentColumn:
308
405
return ComponentColumn (self , lengths )
309
406
310
407
408
+ # TODO: okay what about this? does this need a descriptor????????????
311
409
class ComponentMixin (ComponentBatchLike ):
312
410
"""
313
411
Makes components adhere to the ComponentBatchLike interface.
0 commit comments