Skip to content

Conversation

Copy link

Copilot AI commented Dec 1, 2025

The project lacked extensibility—adding new projector models required hardcoded changes, duplicated serial handling, and tight coupling to BenQ-specific commands.

Changes

Configuration System

  • ProjectorConfig with builder pattern decouples connection parameters from implementation
  • Factory methods for common configurations (e.g., createBenQConfig())

Protocol Abstraction

  • CommandProtocol interface separates command formatting from projector logic
  • Implementations: BenQProtocol (\r*pow=on#\r), EpsonProtocol (PWR ON\r)
  • Different terminators, charsets, and baud rates per vendor

Capability Interfaces

  • PowerControl, SourceControl, CommandCapability define clear contracts
  • Runtime capability discovery via instanceof checks
  • Projectors implement only supported features

Factory Pattern

  • ProjectorFactory centralizes creation with type-safe enum selection
  • Multiple construction strategies: default port, custom port, custom config

Refactored Core

  • Projector base class now uses dependency injection (config + protocol)
  • W1070 implements capability interfaces, maintains backward compatibility
  • EpsonGeneric demonstrates adding new projector type

Usage

// Factory-based creation
Projector projector = ProjectorFactory.createProjector(
    ProjectorType.BENQ_W1070, 
    "/dev/ttyUSB0"
);

// Capability checking
if (projector instanceof PowerControl) {
    ((PowerControl) projector).turnOn();
}

// Custom configuration
ProjectorConfig config = new ProjectorConfig.Builder()
    .portName("COM3")
    .baudRate(9600)
    .build();

Adding New Projector Types

Three steps:

  1. Implement CommandProtocol (command format)
  2. Extend Projector, implement capability interfaces
  3. Add to ProjectorFactory enum

Time reduced from hours to minutes.

Documentation

  • ARCHITECTURE.md: Design patterns, component relationships
  • EXTENSIBILITY_EXAMPLES.md: Adding Sony, network-based projectors, custom capabilities
  • ARCHITECTURE_DIAGRAM.md: Visual class structure and data flows
Original prompt

Analyse improvements to the generic structure (extensibility, how easy it would be to add another projector that might work a bit different) of the project!


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Analyze improvements to generic structure for extensibility Refactor architecture for extensibility: configuration, protocols, and capability interfaces Dec 1, 2025
Copilot AI requested a review from APayerl December 1, 2025 23:38
Copy link
Owner

@APayerl APayerl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not include a Epson config. we want to be sure that it is correct before we add it (need to see specification!)

);

// Both projectors can be controlled through the same interfaces
if (benq instanceof PowerControl) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

generally in these situations use the java syntax to auto create a variable as well. "if (benq instanceof PowerControl pc) {" to get shorter syntax

Projector projector = ProjectorFactory.createProjector(ProjectorType.BENQ_W1070);

// Check if this projector supports power control
if (projector instanceof PowerControl) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here with "projector instanceof PowerControl pc)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants