A structure context manager to facilitate updating structure contents. On context enter, a structure is created and populated from the specified memory address. All changes to structure content are written back to memory on context exit. If the structure content has not chan
(cls, mem: QlMemoryManager, address: int)
| 137 | @classmethod |
| 138 | @contextmanager |
| 139 | def ref(cls, mem: QlMemoryManager, address: int): |
| 140 | """A structure context manager to facilitate updating structure contents. |
| 141 | |
| 142 | On context enter, a structure is created and populated from the specified memory |
| 143 | address. All changes to structure content are written back to memory on context |
| 144 | exit. If the structure content has not changed, no memory writes occur. |
| 145 | |
| 146 | Args: |
| 147 | mem : memory manager instance |
| 148 | address : bind address |
| 149 | |
| 150 | Example: |
| 151 | >>> class Point(BaseStruct): |
| 152 | ... _fields_ = [ |
| 153 | ... ('x', ctypes.c_uint32), |
| 154 | ... ('y', ctypes.c_uint32) |
| 155 | ... ] |
| 156 | |
| 157 | >>> # bind a Point structure to address `ptr` |
| 158 | >>> with Point.ref(ql.mem, ptr) as p: |
| 159 | ... p.x = 10 |
| 160 | ... p.y = 20 |
| 161 | >>> # p data has changed and will be written back to `ptr` |
| 162 | |
| 163 | >>> # bind a Point structure to address `ptr` |
| 164 | >>> with Point.ref(ql.mem, ptr) as p: |
| 165 | ... print(f'saved coordinates: {p.x}, {p.y}') |
| 166 | >>> # p data has not changed and nothing will be written back |
| 167 | """ |
| 168 | |
| 169 | instance = cls.load_from(mem, address) |
| 170 | orig_data = hash(bytes(instance)) |
| 171 | |
| 172 | try: |
| 173 | yield instance |
| 174 | finally: |
| 175 | curr_data = hash(bytes(instance)) |
| 176 | |
| 177 | if curr_data != orig_data: |
| 178 | instance.save_to(mem, address) |
| 179 | |
| 180 | @classmethod |
| 181 | def sizeof(cls) -> int: |