Skip to content

Add partial combined SDL2 and ncurses build#1329

Merged
cxxxr merged 7 commits intolem-project:mainfrom
frejanordsiek:combined-sdl2-ncurses-build
Mar 23, 2024
Merged

Add partial combined SDL2 and ncurses build#1329
cxxxr merged 7 commits intolem-project:mainfrom
frejanordsiek:combined-sdl2-ncurses-build

Conversation

@frejanordsiek
Copy link
Contributor

This adds a partial combined SDL2 and ncurses build to address #1327 . The changes add a -i,--interface INTERFACE option to specify the desired interface: sdl2 or ncurses (case-insensitive). If whatever is given is not available, the logic goes down the existing chain of finding a default implementation.

But, there are a few issues with this merge request, which are:

  1. It doesn't auto-detect whether lem is run from a tty or not and (default on a tty should probably be ncurses, but elsewhere it might make sense for it to be SDL2). This is part of why this is a "partial" solution.
  2. It is a bit of a hack. Again, "partial" solution
  3. The choice of command line argument might not be the best
  4. My Common Lisp is really rusty (haven't used it in about 6-7 years) and the indentation and choice of functions might not be the best.

src/lem.lisp Outdated
filename)))
((member arg '("-i" "--interface") :test #'equal)
(let ((interface (pop args)))
(unless (and interface (/= 0 (array-total-size interface)))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are you looking for plusp and length for strings?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Those would work. I chose array-total-size since it only handles arrays (which strings are), but it does hurt readability and the performance loss from the type check when checking arguments is so close to zero that it is basically irrelevant. As for plusp, that would also work. Mainly make it more clear.

I've changed to them in the latest commits.

src/lem.lisp Outdated
((member arg '("-i" "--interface") :test #'equal)
(let ((interface (pop args)))
(unless (and interface (/= 0 (array-total-size interface)))
(error "Please, specify an interface to use."))
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think erroring here is cool. I'd rather have a default.

Also an error throws a backtrace right? A simple message to the user might have been nicer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. I've changed it to printing a string to stderr in a new commit.

src/lem.lisp Outdated
(unless (and interface (/= 0 (array-total-size interface)))
(error "Please, specify an interface to use."))
(setf (command-line-arguments-interface parsed-args)
(intern (string-upcase interface) "KEYWORD"))))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Also alexandria:make-keyword (with the string upcase)

Interns the string designated by NAME in the KEYWORD package.

but if this works it works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I switched it to alexandria:make-keyword in a commit I just pushed to make it more clear what is happening to someone skimming the code fast.

…nt a message to stderr if an interface argument isn't given or it has zero length rather than erroring.
…ocessing in src/lem.lisp to using alexandria:make-keyword.
@frejanordsiek
Copy link
Contributor Author

Bringing the discussion of the command line argument in #1327 over here.

Right now, the -i INTERFACE or --interface INTERFACE argument scheme is a bit unwieldy. The one advantage it has is that it can handle any number of interfaces, where as switches can only handle 2 very easily

Emacs uses -nw (short for --no-window-system) as its one switch.

Of course, it would be nice to make it autodetect if it is on a tty and default to using ncurses then and default to SDL2 if it isn't, but I am not sure how to do that. ncurses doesn't seem to have any function to detect this. Nor does SDL2. My best guess is to try (interactive-stream-p *standard-input*).

…n is interactive (probably a terminal) and SDL2 otherwise.
@frejanordsiek
Copy link
Contributor Author

OK, I had a "duh" moment and figured out why my attempts at using (interactive-stream-p *standard-input*) were failing so badly. I just made a new commit that defaults the interface to ncurses if stdin is interactive (probably a terminal) and sdl2 if it isn't (probably launched from a Desktop app launcher or file browser).

@frejanordsiek
Copy link
Contributor Author

A potentially simpler scheme for the command line arguments could be

  • -nw / --no-window-system from Emacs for any terminal interface (ncurses is the only one right now)
  • -gw / --graphical-window for any graphical interface (sdl2 is the only one right now)
  • -i INTERFACE / --interface INTERFACE for explicitly picking an interface by name (might be important if there is every more than one terminal and/or graphics interface).

How does this sound?

@vindarel
Copy link
Collaborator

mmh I find "-nw" not so explicit. What about

  • --nogui defaults to ncurses
  • --gui -> SDL2
  • and -i

but wait, simply:

  • --ncurses
  • --sdl or --sdl2
  • -i

@frejanordsiek
Copy link
Contributor Author

mmh I find "-nw" not so explicit. What about

* `--nogui` defaults to ncurses

* `--gui` -> SDL2

* and -i

but wait, simply:

* `--ncurses`

* `--sdl` or `--sdl2`

* -i

Why not both?

  • --ncurses for using ncurses
  • --sdl and --sdl2 for using sdl2
  • --nogui for using whatever terminal interface is available (in case anything beyond ncurses is added)
  • --gui for using whatever GUI interface is available (in case anything beyond sdl2 is added)
  • -i / --interface for specifying interface by name with a single option.

@frejanordsiek
Copy link
Contributor Author

I added them.

@cxxxr
Copy link
Member

cxxxr commented Mar 19, 2024

Thank you for the great PR.
I think it is generally good, but I would like to avoid unnecessarily adding more command line options.
I think "-i" "--interface" is sufficient, do we need to add other options?

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.

3 participants