luvatrix 0.2.1__tar.gz → 0.2.2__tar.gz

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.
Files changed (192) hide show
  1. {luvatrix-0.2.1/luvatrix.egg-info → luvatrix-0.2.2}/PKG-INFO +1 -1
  2. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix/app.py +7 -0
  3. {luvatrix-0.2.1 → luvatrix-0.2.2/luvatrix.egg-info}/PKG-INFO +1 -1
  4. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix.egg-info/SOURCES.txt +1 -0
  5. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/__init__.py +1 -1
  6. luvatrix-0.2.2/luvatrix_core/core/interaction_work.py +162 -0
  7. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/android/runner.py +32 -4
  8. {luvatrix-0.2.1 → luvatrix-0.2.2}/pyproject.toml +1 -1
  9. {luvatrix-0.2.1 → luvatrix-0.2.2}/LICENSE +0 -0
  10. {luvatrix-0.2.1 → luvatrix-0.2.2}/MANIFEST.in +0 -0
  11. {luvatrix-0.2.1 → luvatrix-0.2.2}/README.md +0 -0
  12. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix/__init__.py +0 -0
  13. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix/auth/__init__.py +0 -0
  14. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix/auth/calendar.py +0 -0
  15. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix/auth/google.py +0 -0
  16. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix/auth/sign_in.py +0 -0
  17. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix/auth/ui.py +0 -0
  18. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix.egg-info/dependency_links.txt +0 -0
  19. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix.egg-info/entry_points.txt +0 -0
  20. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix.egg-info/requires.txt +0 -0
  21. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix.egg-info/top_level.txt +0 -0
  22. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/accel.py +0 -0
  23. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/__init__.py +0 -0
  24. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/app_runtime.py +0 -0
  25. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/audit.py +0 -0
  26. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/coordinates.py +0 -0
  27. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/debug_capture.py +0 -0
  28. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/debug_menu.py +0 -0
  29. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/display_runtime.py +0 -0
  30. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/energy_safety.py +0 -0
  31. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/engine.py +0 -0
  32. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/events.py +0 -0
  33. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/frame_rate_controller.py +0 -0
  34. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/hdi_thread.py +0 -0
  35. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/process_runtime.py +0 -0
  36. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/process_sdk.py +0 -0
  37. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/protocol_governance.py +0 -0
  38. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/scene_display_runtime.py +0 -0
  39. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/scene_graph.py +0 -0
  40. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/scene_rasterizer.py +0 -0
  41. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/sensor_manager.py +0 -0
  42. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/ui_frame_renderer.py +0 -0
  43. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/unified_runtime.py +0 -0
  44. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/core/window_matrix.py +0 -0
  45. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/perf/copy_telemetry.py +0 -0
  46. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/__init__.py +0 -0
  47. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/android/__init__.py +0 -0
  48. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/android/camera_processing_contract.py +0 -0
  49. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/android/camera_style.py +0 -0
  50. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/android/hdi_source.py +0 -0
  51. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/android/scene_target.py +0 -0
  52. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/android/sensors.py +0 -0
  53. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/android/vulkan_target.py +0 -0
  54. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/frame_pipeline.py +0 -0
  55. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/ios/__init__.py +0 -0
  56. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/ios/hdi_source.py +0 -0
  57. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/ios/lifecycle.py +0 -0
  58. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/ios/metal_backend.py +0 -0
  59. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/ios/runner.py +0 -0
  60. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/ios/scene_target.py +0 -0
  61. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/ios/window_system.py +0 -0
  62. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/macos/__init__.py +0 -0
  63. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/macos/hdi_source.py +0 -0
  64. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/macos/iohid_source.py +0 -0
  65. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/macos/metal_backend.py +0 -0
  66. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/macos/metal_presenter.py +0 -0
  67. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/macos/metal_scene_target.py +0 -0
  68. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/macos/sensors.py +0 -0
  69. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/macos/vulkan_backend.py +0 -0
  70. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/macos/vulkan_presenter.py +0 -0
  71. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/macos/window_system.py +0 -0
  72. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/package_sync.py +0 -0
  73. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/vulkan_compat.py +0 -0
  74. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/vulkan_scaling.py +0 -0
  75. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/vulkan_setup.py +0 -0
  76. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/__init__.py +0 -0
  77. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/build.py +0 -0
  78. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/command_buffer.py +0 -0
  79. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/python_shim/luvatrix/__init__.py +0 -0
  80. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/python_shim/luvatrix/app.py +0 -0
  81. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/runtime_assets/index.html +0 -0
  82. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/runtime_assets/runtime/command-buffer.js +0 -0
  83. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/runtime_assets/runtime/input.js +0 -0
  84. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/runtime_assets/runtime/luvatrix-web.js +0 -0
  85. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/runtime_assets/runtime/package.json +0 -0
  86. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/runtime_assets/runtime/renderers.js +0 -0
  87. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/runtime_assets/runtime/spotify-bridge.js +0 -0
  88. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/server.py +0 -0
  89. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/platform/web/websocket_target.py +0 -0
  90. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/render/__init__.py +0 -0
  91. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/render/framebuffer.py +0 -0
  92. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/render/svg.py +0 -0
  93. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/scaffold.py +0 -0
  94. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/targets/__init__.py +0 -0
  95. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/targets/base.py +0 -0
  96. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/targets/cpu_scene_target.py +0 -0
  97. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/targets/metal_target.py +0 -0
  98. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/targets/scene_target.py +0 -0
  99. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/targets/vulkan_target.py +0 -0
  100. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/targets/web_target.py +0 -0
  101. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/.gitignore +0 -0
  102. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/build.gradle.kts +0 -0
  103. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/AndroidManifest.xml +0 -0
  104. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/assets/luvatrix_bitmap_font.txt +0 -0
  105. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/assets/luvatrix_launch_config.json +0 -0
  106. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/assets/luvatrix_matrix_font_alpha.txt +0 -0
  107. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/cpp/CMakeLists.txt +0 -0
  108. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/cpp/luvatrix_camera_preview.frag +0 -0
  109. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/cpp/luvatrix_camera_preview_shaders.h +0 -0
  110. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/cpp/luvatrix_vulkan_renderer.cpp +0 -0
  111. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/java/com/luvatrix/app/CameraBridge.kt +0 -0
  112. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/java/com/luvatrix/app/LuvatrixVulkanView.kt +0 -0
  113. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/java/com/luvatrix/app/MainActivity.kt +0 -0
  114. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/java/com/luvatrix/app/NativeVulkan.kt +0 -0
  115. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/python/.gitignore +0 -0
  116. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/python/luvatrix_android_boot.py +0 -0
  117. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/python/luvatrix_launch_config.json +0 -0
  118. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  119. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  120. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  121. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  122. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  123. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/app/src/main/res/values/styles.xml +0 -0
  124. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/build.gradle.kts +0 -0
  125. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/gradle.properties +0 -0
  126. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/gradlew +0 -0
  127. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/scripts/emulator_acceptance.sh +0 -0
  128. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/scripts/sync_python_assets.sh +0 -0
  129. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/android/settings.gradle.kts +0 -0
  130. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/Luvatrix/AppDelegate.swift +0 -0
  131. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/Luvatrix/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -0
  132. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/Luvatrix/Assets.xcassets/AppIcon.appiconset/icon.png +0 -0
  133. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/Luvatrix/Assets.xcassets/Contents.json +0 -0
  134. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/Luvatrix/Info.plist +0 -0
  135. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/Luvatrix/Luvatrix-Bridging-Header.h +0 -0
  136. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/Luvatrix/Luvatrix.entitlements +0 -0
  137. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/Luvatrix/PythonBridge.h +0 -0
  138. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/Luvatrix/PythonBridge.m +0 -0
  139. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/Luvatrix/main.swift +0 -0
  140. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/project.yml +0 -0
  141. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/templates/native/ios/scripts/setup_ios.sh +0 -0
  142. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/ui/__init__.py +0 -0
  143. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/ui/element.py +0 -0
  144. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_core/ui/page_loader.py +0 -0
  145. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/__init__.py +0 -0
  146. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/adapters/__init__.py +0 -0
  147. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/adapters/normalize.py +0 -0
  148. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/api.py +0 -0
  149. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/compile/__init__.py +0 -0
  150. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/compile/app_protocol.py +0 -0
  151. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/display.py +0 -0
  152. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/dynamic_axis.py +0 -0
  153. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/errors.py +0 -0
  154. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/figure.py +0 -0
  155. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/live.py +0 -0
  156. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/raster/__init__.py +0 -0
  157. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/raster/canvas.py +0 -0
  158. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/raster/draw_lines.py +0 -0
  159. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/raster/draw_markers.py +0 -0
  160. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/raster/draw_text.py +0 -0
  161. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/raster/layers.py +0 -0
  162. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/scales.py +0 -0
  163. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_plot/series.py +0 -0
  164. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/__init__.py +0 -0
  165. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/component_schema.py +0 -0
  166. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/controls/__init__.py +0 -0
  167. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/controls/button.py +0 -0
  168. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/controls/interaction.py +0 -0
  169. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/controls/stained_glass_button.py +0 -0
  170. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/controls/svg_component.py +0 -0
  171. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/controls/svg_renderer.py +0 -0
  172. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/planes_protocol.py +0 -0
  173. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/planes_runtime.py +0 -0
  174. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/planes_v2_validator.py +0 -0
  175. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/planning/__init__.py +0 -0
  176. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/planning/agile_renderer.py +0 -0
  177. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/planning/exporters.py +0 -0
  178. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/planning/gantt_renderer.py +0 -0
  179. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/planning/interaction.py +0 -0
  180. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/planning/schema.py +0 -0
  181. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/planning/validation.py +0 -0
  182. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/style/__init__.py +0 -0
  183. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/style/theme.py +0 -0
  184. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/table/__init__.py +0 -0
  185. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/table/component.py +0 -0
  186. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/text/__init__.py +0 -0
  187. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/text/component.py +0 -0
  188. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/text/renderer.py +0 -0
  189. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/text/wrapping.py +0 -0
  190. {luvatrix-0.2.1 → luvatrix-0.2.2}/luvatrix_ui/ui_ir.py +0 -0
  191. {luvatrix-0.2.1 → luvatrix-0.2.2}/main.py +0 -0
  192. {luvatrix-0.2.1 → luvatrix-0.2.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: luvatrix
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Luvatrix runtime and plotting toolkit
5
5
  Author: Luvatrix contributors
6
6
  License-Expression: LicenseRef-Proprietary
@@ -22,6 +22,7 @@ from luvatrix_core.core.app_runtime import (
22
22
  ResolvedAppVariant,
23
23
  )
24
24
  from luvatrix_core.core.hdi_thread import HDIEvent, HDIThread
25
+ from luvatrix_core.core.interaction_work import InteractionAwareWorkScheduler
25
26
  from luvatrix_core.core.sensor_manager import SensorManagerThread, SensorSample
26
27
  from luvatrix_core.core.window_matrix import FullRewrite, WriteBatch, WindowMatrix
27
28
  from luvatrix_core import accel
@@ -299,6 +300,11 @@ class SwipeMomentumController:
299
300
  def dragging(self) -> bool:
300
301
  return self._dragging
301
302
 
303
+ @property
304
+ def active(self) -> bool:
305
+ """Whether a drag or post-release momentum is active."""
306
+ return self._dragging or self._velocity != 0.0
307
+
302
308
  def reset(self) -> None:
303
309
  self._touch_id = None
304
310
  self._last_position = None
@@ -1856,6 +1862,7 @@ __all__ = [
1856
1862
  "Display",
1857
1863
  "InputManager",
1858
1864
  "InputState",
1865
+ "InteractionAwareWorkScheduler",
1859
1866
  "MatrixFrame",
1860
1867
  "MissingOptionalDependencyError",
1861
1868
  "ResolvedAppVariant",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: luvatrix
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Luvatrix runtime and plotting toolkit
5
5
  Author: Luvatrix contributors
6
6
  License-Expression: LicenseRef-Proprietary
@@ -31,6 +31,7 @@ luvatrix_core/core/engine.py
31
31
  luvatrix_core/core/events.py
32
32
  luvatrix_core/core/frame_rate_controller.py
33
33
  luvatrix_core/core/hdi_thread.py
34
+ luvatrix_core/core/interaction_work.py
34
35
  luvatrix_core/core/process_runtime.py
35
36
  luvatrix_core/core/process_sdk.py
36
37
  luvatrix_core/core/protocol_governance.py
@@ -1,4 +1,4 @@
1
1
  """Luvatrix runtime."""
2
2
 
3
3
  __all__ = ["__version__"]
4
- __version__ = "0.2.1"
4
+ __version__ = "0.2.2"
@@ -0,0 +1,162 @@
1
+ from __future__ import annotations
2
+
3
+ from collections import deque
4
+ from collections.abc import Callable, Hashable
5
+ from dataclasses import dataclass
6
+ import threading
7
+ import time
8
+ from typing import Any
9
+
10
+
11
+ @dataclass(frozen=True)
12
+ class _WorkItem:
13
+ key: Hashable
14
+ prepare: Callable[[], Any]
15
+ on_complete: Callable[[Any], None] | None
16
+
17
+
18
+ class InteractionAwareWorkScheduler:
19
+ """Run keyed preparation work only while user interaction is idle.
20
+
21
+ Work and callbacks execute sequentially on one daemon thread. Running work
22
+ is not preempted when interaction begins; the idle gate prevents queued
23
+ work from starting until ``interaction_active`` returns false.
24
+
25
+ Pair with ``SwipeMomentumController`` using
26
+ ``interaction_active=lambda: swipe.active`` and call
27
+ :meth:`notify_interaction_state_changed` after controller updates to wake
28
+ queued work immediately when momentum stops.
29
+ """
30
+
31
+ def __init__(
32
+ self,
33
+ *,
34
+ interaction_active: Callable[[], bool],
35
+ request_render: Callable[[], None] | None = None,
36
+ on_error: Callable[[Hashable, Exception], None] | None = None,
37
+ idle_poll_interval: float = 1.0 / 120.0,
38
+ thread_name: str = "luvatrix-interaction-work",
39
+ ) -> None:
40
+ self.interaction_active = interaction_active
41
+ self.request_render = request_render
42
+ self.on_error = on_error
43
+ self.idle_poll_interval = max(0.001, float(idle_poll_interval))
44
+ self.thread_name = str(thread_name)
45
+ self._condition = threading.Condition()
46
+ self._pending: deque[_WorkItem] = deque()
47
+ self._keys: set[Hashable] = set()
48
+ self._thread: threading.Thread | None = None
49
+ self._closed = False
50
+
51
+ @property
52
+ def pending_count(self) -> int:
53
+ with self._condition:
54
+ return len(self._keys)
55
+
56
+ def submit(
57
+ self,
58
+ key: Hashable,
59
+ prepare: Callable[[], Any],
60
+ *,
61
+ on_complete: Callable[[Any], None] | None = None,
62
+ ) -> bool:
63
+ """Queue work unless the key is already queued or running."""
64
+ with self._condition:
65
+ if self._closed:
66
+ raise RuntimeError("interaction-aware work scheduler is closed")
67
+ if key in self._keys:
68
+ return False
69
+ self._keys.add(key)
70
+ self._pending.append(_WorkItem(key, prepare, on_complete))
71
+ if self._thread is None:
72
+ self._thread = threading.Thread(
73
+ target=self._run,
74
+ name=self.thread_name,
75
+ daemon=True,
76
+ )
77
+ self._thread.start()
78
+ self._condition.notify_all()
79
+ return True
80
+
81
+ def notify_interaction_state_changed(self) -> None:
82
+ """Wake idle-gated work after a controller state update."""
83
+ with self._condition:
84
+ self._condition.notify_all()
85
+
86
+ def wait_idle(self, timeout: float | None = None) -> bool:
87
+ """Wait until queued/running work and its callbacks have completed."""
88
+ deadline = None if timeout is None else time.monotonic() + max(0.0, float(timeout))
89
+ with self._condition:
90
+ while self._keys:
91
+ if deadline is None:
92
+ self._condition.wait()
93
+ continue
94
+ remaining = deadline - time.monotonic()
95
+ if remaining <= 0.0:
96
+ return False
97
+ self._condition.wait(remaining)
98
+ return True
99
+
100
+ def close(self, *, wait: bool = False) -> None:
101
+ """Cancel queued work and optionally wait for running work to finish."""
102
+ with self._condition:
103
+ self._closed = True
104
+ while self._pending:
105
+ self._keys.discard(self._pending.popleft().key)
106
+ thread = self._thread
107
+ self._condition.notify_all()
108
+ if wait and thread is not None and thread is not threading.current_thread():
109
+ thread.join()
110
+
111
+ def _run(self) -> None:
112
+ while True:
113
+ with self._condition:
114
+ while not self._closed and not self._pending:
115
+ self._condition.wait()
116
+ if self._closed:
117
+ return
118
+ pending_key = self._pending[0].key
119
+
120
+ try:
121
+ interaction_active = bool(self.interaction_active())
122
+ except Exception as exc:
123
+ self._report_error(pending_key, exc)
124
+ interaction_active = False
125
+
126
+ with self._condition:
127
+ if self._closed:
128
+ return
129
+ if not self._pending:
130
+ continue
131
+ if interaction_active:
132
+ self._condition.wait(self.idle_poll_interval)
133
+ continue
134
+ item = self._pending.popleft()
135
+
136
+ try:
137
+ value = item.prepare()
138
+ except Exception as exc:
139
+ self._report_error(item.key, exc)
140
+ else:
141
+ if item.on_complete is not None:
142
+ try:
143
+ item.on_complete(value)
144
+ except Exception as exc:
145
+ self._report_error(item.key, exc)
146
+ try:
147
+ if self.request_render is not None:
148
+ self.request_render()
149
+ except Exception as exc:
150
+ self._report_error(item.key, exc)
151
+ finally:
152
+ with self._condition:
153
+ self._keys.discard(item.key)
154
+ self._condition.notify_all()
155
+
156
+ def _report_error(self, key: Hashable, error: Exception) -> None:
157
+ if self.on_error is None:
158
+ return
159
+ try:
160
+ self.on_error(key, error)
161
+ except Exception:
162
+ return
@@ -332,14 +332,17 @@ def sync_android_python_assets(app_dir: Path, *, project_dir: Path) -> None:
332
332
 
333
333
  def _android_python_packages_for_app(app_dir: Path, *, exclude_dirs: Iterable[Path] = ()) -> tuple[str, ...]:
334
334
  packages = ["luvatrix", "luvatrix_core"]
335
- imports = _top_level_imports_for_app(app_dir, exclude_dirs=exclude_dirs)
335
+ imported_modules = _imported_modules_for_app(app_dir, exclude_dirs=exclude_dirs)
336
+ imports = {module.split(".", 1)[0] for module in imported_modules}
337
+ for module in imported_modules:
338
+ imports.update(_first_party_module_import_roots(module))
336
339
  for optional_pkg in ("luvatrix_ui", "luvatrix_plot"):
337
340
  if optional_pkg in imports:
338
341
  packages.append(optional_pkg)
339
342
  return tuple(packages)
340
343
 
341
344
 
342
- def _top_level_imports_for_app(app_dir: Path, *, exclude_dirs: Iterable[Path] = ()) -> set[str]:
345
+ def _imported_modules_for_app(app_dir: Path, *, exclude_dirs: Iterable[Path] = ()) -> set[str]:
343
346
  imports: set[str] = set()
344
347
  excluded = tuple(path.resolve() for path in exclude_dirs)
345
348
  for path in app_dir.rglob("*.py"):
@@ -355,12 +358,37 @@ def _top_level_imports_for_app(app_dir: Path, *, exclude_dirs: Iterable[Path] =
355
358
  for node in ast.walk(tree):
356
359
  if isinstance(node, ast.Import):
357
360
  for alias in node.names:
358
- imports.add(alias.name.split(".", 1)[0])
361
+ imports.add(alias.name)
359
362
  elif isinstance(node, ast.ImportFrom) and node.module:
360
- imports.add(node.module.split(".", 1)[0])
363
+ imports.add(node.module)
361
364
  return imports
362
365
 
363
366
 
367
+ def _first_party_module_import_roots(module_name: str) -> set[str]:
368
+ package_name, _, relative_module = module_name.partition(".")
369
+ if package_name not in {"luvatrix", "luvatrix_core"}:
370
+ return set()
371
+ package_dir = _python_package_dir(package_name)
372
+ if relative_module:
373
+ module_path = package_dir.joinpath(*relative_module.split("."))
374
+ source_path = module_path.with_suffix(".py")
375
+ if not source_path.is_file():
376
+ source_path = module_path / "__init__.py"
377
+ else:
378
+ source_path = package_dir / "__init__.py"
379
+ try:
380
+ tree = ast.parse(source_path.read_text(encoding="utf-8"), filename=str(source_path))
381
+ except (OSError, SyntaxError):
382
+ return set()
383
+ roots: set[str] = set()
384
+ for node in ast.walk(tree):
385
+ if isinstance(node, ast.Import):
386
+ roots.update(alias.name.split(".", 1)[0] for alias in node.names)
387
+ elif isinstance(node, ast.ImportFrom) and node.module:
388
+ roots.add(node.module.split(".", 1)[0])
389
+ return roots
390
+
391
+
364
392
  def _make_android_app_ignore(project_dir: Path):
365
393
  pattern_ignore = shutil.ignore_patterns("__pycache__", "*.pyc", ".pytest_cache", ".luvatrix")
366
394
  project = project_dir.resolve()
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "luvatrix"
7
- version = "0.2.1"
7
+ version = "0.2.2"
8
8
  description = "Luvatrix runtime and plotting toolkit"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.14,<3.15"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes