FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
pythonnative/src/pythonnative/mutations.py at main · andevsr/pythonnative · GitHub
andevsr
pythonnative
Repository navigation
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
pythonnative
/
src
/
pythonnative
/
mutations.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
121 lines (91 loc) · 3.74 KB
Breadcrumbs
pythonnative
/
src
/
pythonnative
/
mutations.py
Copy path
File metadata and controls
121 lines (91 loc) · 3.74 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"""Batched mutation protocol between the reconciler and native backends.
The reconciler no longer talks to the native layer one call at a time.
Instead, every commit pass produces an ordered list of small mutation
ops referencing integer **tags** (stable per-view identifiers), and the
whole list is applied in a single
[`apply_mutations`][pythonnative.native_views.NativeViewRegistry.apply_mutations]
call. This mirrors React Native's Fabric mounting layer: the diff phase
is pure, and the native side sees one coherent transaction per commit.
Why tags instead of view objects?
- The diff phase runs *before* any native view exists, so ops cannot
reference views directly.
- Tags give the native side a stable identity to key its own view
registry, event routing, and animation bookkeeping on.
- A flat list of `(op, tag, payload)` tuples is trivially serializable,
which keeps the door open for applying mutations from a background
thread or through a single JNI/ObjC crossing in the future.
Op ordering rules (the reconciler guarantees these):
1. A `CreateOp` for a tag precedes any other op referencing that tag.
2. `InsertOp` ops appear after both the parent and child exist.
3. `DestroyOp` ops are emitted children-first; handlers detach the view
from its parent as part of destruction.
4. `SetFrameOp` ops are only emitted for frames that actually changed
since the last layout pass (frame diffing).
"""
from
dataclasses
import
dataclass
,
field
from
typing
import
Any
,
Dict
,
Tuple
,
Union
__all__
=
[
"CreateOp"
,
"UpdateOp"
,
"InsertOp"
,
"DestroyOp"
,
"SetFrameOp"
,
"Mutation"
,
]
@
dataclass
(
frozen
=
True
)
class
CreateOp
:
"""Create a native view for ``tag`` of element type ``type_name``.
Attributes:
tag: Unique integer identity assigned by the reconciler.
type_name: Element type name (e.g. ``"Text"``).
props: Initial *clean* props; callables have already been
routed to the [`EventRegistry`][pythonnative.events.EventRegistry]
and replaced by the ``_pn_events`` name set.
"""
tag
:
int
type_name
:
str
props
:
Dict
[
str
,
Any
]
=
field
(
default_factory
=
dict
)
@
dataclass
(
frozen
=
True
)
class
UpdateOp
:
"""Apply ``changed_props`` to the view registered under ``tag``.
Removed props are signaled with a value of ``None``, matching the
pre-existing handler contract.
"""
tag
:
int
changed_props
:
Dict
[
str
,
Any
]
=
field
(
default_factory
=
dict
)
@
dataclass
(
frozen
=
True
)
class
InsertOp
:
"""Ensure the child view sits at ``index`` inside the parent view.
Handlers must treat this as *move-aware*: if the child is already
attached to the parent at a different position, it is moved rather
than duplicated. ``index`` is clamped by handlers to the current
child count.
"""
parent_tag
:
int
child_tag
:
int
index
:
int
@
dataclass
(
frozen
=
True
)
class
DestroyOp
:
"""Release the native view registered under ``tag``.
The registry drops its tag record and calls the handler's
``destroy`` hook so platform resources (listeners, timers, image
loads) can be released eagerly instead of waiting for GC.
"""
tag
:
int
@
dataclass
(
frozen
=
True
)
class
SetFrameOp
:
"""Position and size the view registered under ``tag``.
Coordinates are points relative to the parent's content origin,
exactly as computed by the layout engine.
"""
tag
:
int
x
:
float
y
:
float
width
:
float
height
:
float
@
property
def
frame
(
self
)
->
Tuple
[
float
,
float
,
float
,
float
]:
"""Return ``(x, y, width, height)`` as a tuple."""
return
(
self
.
x
,
self
.
y
,
self
.
width
,
self
.
height
)
Mutation
=
Union
[
CreateOp
,
UpdateOp
,
InsertOp
,
DestroyOp
,
SetFrameOp
]
"""Union of every op type carried by a commit transaction."""
Back
|
FazBrowse Home
|
New Git URL