What's inside?
Architectural Overview of the LUWRAIN Core
The LUWRAIN core is a highly modular, event-driven framework designed specifically for creating accessible applications for blind users. Instead of relying on a traditional graphical user interface (GUI) and an external screen reader, LUWRAIN integrates speech, auditory icons, and braille directly into the application lifecycle and UI rendering pipeline.
The architecture can be divided into several key subsystems:
The Event-Driven Execution Model
At the heart of the system is the org.luwrain.core.Base class and its concrete implementation, the org.luwrain.core.Core class.
LUWRAIN operates on a single-threaded event loop model to ensure thread safety for UI and accessibility state modifications.
The org.luwrain.core.EventQueue provides a thread-safe mechanism for enqueuing events using standard Java synchronization (wait() and notify()).
protected void eventLoop(StopCondition stopCondition)
{
requireNonNull(stopCondition, "stopCondition can't be null");
while(stopCondition.continueEventLoop())
{
try {
this.announcement = null;
this.eventResponse = null;
final Event event = eventQueue.pickEvent();
if (event == null)
continue;
onEvent(event);
event.markAsProcessed();
// ... processing responses and announcements
}
catch(Throwable e) { /* ... */ }
}
}
The EventDispatching class acts as a router.
It intercepts events and delegates them based on their type:
RunnableEventandCallableEvent: Safely executes arbitrary code in the main thread.InputEvent: Represents user keystrokes. It checks for global hotkeys via theGlobalKeysregistry before passing the event to the activeArea.SystemEvent: Represents internal state changes (e.g., idle state, font size changes) or broadcasts to all applications.
Application and Tiling Window Management
Unlike traditional operating systems that use overlapping windows, LUWRAIN uses a text-based tiling window manager paradigm. The screen is divided into non-overlapping rectangular sections called "Areas".
-
AppManager: Maintains the lifecycle of launched applications (Application). It keeps track of the active application, the desktop app, and a stack of opened popups. It ensures that events are routed to the correct app. -
TilesManager: Constructs a logical tree ofTileobjects based on theAreaLayoutof the active application. Layouts are predefined (e.g.,SINGLE,LEFT_RIGHT,TOP_BOTTOM,LEFT_TOP_BOTTOM). It also handles the injection of popups into the layout tree (top, bottom, left, or right). -
WindowManager: Responsible for translating the logicalTilestree into physical screen coordinates. It calculates the X, Y, width, and height of eachAreausing a recursive algorithm that divides the available screen space.private void calculateGeomImpl(Tiles windows, Object obj, int left, int top, int right, int bottom) { // ... base cases for leaves ... if (windows.getOrientation(obj) == Tiles.Orientation.VERT) { // Calculates vertical split for TOP_BOTTOM layouts int range1 = (range / (leafCount1 + leafCount2)) * leafCount1; calculateGeomImpl(windows, obj1, left, top, right, top + range1 - 1); calculateGeomImpl(windows, obj2, left, top + range1 + 1, right, bottom); interaction.drawHorizontalLine(left, right, top + range1); return; } // ... horizontal splitting logic ... }
The Interaction Layer
The org.luwrain.core.Interaction interface abstracts the underlying operating system's console or graphical window.
It provides low-level primitives for rendering a text-based grid.
The WindowManager uses this interface to draw text, clear rectangles, and draw vertical/horizontal divider lines between areas.
It also manages a "hot point" (cursor position) which is crucial for braille displays and screen tracking.
public interface Interaction
{
// ... initialization and parameters ...
void startDrawSession();
void clearRect(int left, int top, int right, int bottom);
void drawText(int x, int y, String text);
void endDrawSession();
void setHotPoint(int x, int y);
void drawVerticalLine(int top, int bottom, int x);
void drawHorizontalLine(int left, int right, int y);
}
Extensibility and Object Registry
LUWRAIN is designed to be highly extensible without modifying the core code.
ExtensionsManager: Discovers and loads Java plugins using the standardServiceLoaderAPI. It also scans specific directories to load JavaScript extensions, wrapping them in aScriptExtension.ObjRegistry: Acts as a central repository for objects provided by extensions. When an extension is loaded, it can register global commands, background workers (Worker), shortcuts (Shortcut), and property providers.
Integrated Accessibility Subsystems
Because LUWRAIN does not use an external screen reader, accessibility is deeply woven into the architecture:
- Audio Spatial Awareness: When switching applications, the
EventDispatchingclass analyzes theAreaLayoutand plays specific sound icons (e.g.,Sounds.AREA_LAYOUT_DOUBLEorSounds.AREA_LAYOUT_TRIPLE) via thesoundManager. This gives the blind user an immediate auditory understanding of how the screen is divided. - Contextual Speech: The
Corehandles announcements (AnnouncementType.APPorAnnouncementType.AREA) automatically when the focus changes. If a user presses a key that is not processed by the activeArea, the system immediately plays anINACCESSIBLEsound icon. - Background Sounds: The
Areasclass queries the activeAreavia anAreaQueryto determine if a specific background sound should be played to indicate the current environment or context.