Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce ISquidPanel that both the awt and gdx panels implement #81

Merged
merged 1 commit into from
Sep 30, 2015

Conversation

smelc
Copy link
Contributor

@smelc smelc commented Sep 30, 2015

  • ISquidPanel<T> is merely the extraction of the methods of SquidPanel, except that the type of colors is generic (T). This'll help users that want to maximize their codebase that is shared between awt and android.
  • I've added ICombinedPanel that shows how to lift ISquidPanel to have a panel that combines both a background and a foreground (a simpler SquidLayers).
  • I've also added IColoredString to have an abstraction of string where differents parts have different colors, that is supported by ISquidPanel.
  • I've left an interrogation in the gdx implementation of SquidPanel regarding ISquidPanel::refresh().

…anel implement. It is merely the extraction of the methods of SquidPanel, except that the type of colors is generic (ISquidPanel<T>). This'll help users that want to maximize their codebase that is shared between awt and android. Add ICombinedPanel that shows how to lift ISquidPanel to more expressive interfaces and added IColoredString to have an abstraction of string where differents parts have different colors, that is supported by ISquidPanel. Left an interrogation in the gdx implementation of SquidPanel regarding ISquidPanel::refresh().
@tommyettinger
Copy link
Member

I didn't realize how impressive this was by just scanning the summary; IColoredString is a great idea and so is the shared interface in general. I think refresh only makes sense with Swing's update-when-there's-input approach, as far as I can tell. The GDX version of refresh can be a no-op without problems, since any GDX visuals needs to be passed a Batch that does the actual rendering. With that in mind, I'm not sure how much can be abstracted between the two, since just having this:

ISquidPanel<Color> panel = new squidpony.squidgrid.gui.gdx.SquidPanel();
//is there any way to be used for display without casting back to GDX SquidPanel ?
(squidpony.squidgrid.gui.gdx.SquidPanel)(panel).draw(batch, 1F);

Would mean the code becomes platform-specific rather quickly. Still, if rendering is isolated to one chunk of code, the interface should be handy. It's my opinion that there isn't much reason to use Swing other than slightly smaller game filesizes for distribution and slightly less code needed to get started, since the GDX version has all the features Swing does and more but isn't snail-paced when the user presses too many keys or you try to add animations.

This is unrelated to the PR, but you mentioned GDX being used on Android. I'm concerned about the GDX class SquidInput and what it means for Android (it won't work, currently). SquidInput is meant to handle complex user input, like modifier keys or caps lock and modifier keys simultaneously, and caps lock is tricky to query in a cross-platform way. LWJGL, which LibGDX uses for display on desktop, uses AWT to do it, and LibGDX doesn't provide any way to find the state of caps lock on android (not sure if it makes sense there either). I can get rid of the check for caps lock and treat it as if shift-pressed means capital-letters every time, regardless of caps lock, and then it should work on android. I might post an issue about this for feedback.

Merging. I may make some changes, but you did some rather excellent cleanup and added some nice abstractions here.

tommyettinger added a commit that referenced this pull request Sep 30, 2015
Introduce ISquidPanel<T> that both the awt and gdx panels implement, introduce IColoredString to have a cross-platform way of handling colorful text, ICombinedPanel introduced as a partial SquidLayers interface
@tommyettinger tommyettinger merged commit 3aab321 into yellowstonegames:master Sep 30, 2015
@smelc
Copy link
Contributor Author

smelc commented Oct 1, 2015

Thank you for merging this. I do not use gdx yet in my roguelike since I'm getting started and did not take the time to install gdx properly (but I need to do it, since a game for a small screen is pretty different from a desktop game..). Hence, if gdx.SquidPanel.draw(Batch, ..) is the main drawing entry point, then well the abstraction does not help (but hey maybe we can build an abstraction of Batch on the awt side ?). But even if draw(Batch, ..) is the main entry point, there are still two advantages to the interface, that maybe do not directly come to mind:

  • I witnessed that, to have an awt/gdx independent game, you need to abstract away the type of color for which the interface helps. Initially, the dependency on java.awt.Color was spreading pretty far in my roguelike. Then I came up with the interface and it helped me track where I refer to the type of color. Now my design is:

    An abstract Game class (in the 'core' Eclipse project), that is awt/gdx independent, hence only knows ISquidPanel; but does quite a lot of stuff. Game takes as parameter the type of colors. I just require that type to be an implementation of IColor (an interface of mine, to be able to retrieve a color's components) and I manage the colors (i.e. build concrete instances) using a dedicated factory, that builds instances of my subclass of java.awt.Color (I need a subclass to implement IColor).

    Then I have a concrete class called AWTGame (in a different Eclipse project, that authorizes depending on awt) that subclasses Game and manages awt dependent stuff: the JFrame and provides the color factory (roughly: a function IColor -> my subclass of java.awt.Color).

    The handling of key events and mouse is similar: an awt/gdx independent interface in the 'core' project, implemented in the 'awt' project.

  • Another use of ISquidPanel is that I can simulate layers of panels with offsets. For example, to display the inventory of the rogue, I simulate the inventory as a small (i.e. smaller than the map) ISquidPanel. To draw, the simulated panel just writes to the underlying (large) panel by offsetting all coordinates by the top left position of the inventory and checks that clients do not try to write outside the simulated panel. I'll provide this one in a next PR if it seems general enough for a library.

@SquidPony
Copy link
Collaborator

For me the choice of Swing was made not because of the roguelike grid
building but rather because of the ease of other UI elements around the
grid panel. Given that roguelike in general continue to be mostly single
grid screen games, maybe dropping Swing support in favor of libgdx would be
a good idea at this point.

I know one of the things that halted progress on libjcsi back in the day
was the increasing cost of supporting two very different backends with the
same interface.
On Oct 1, 2015 6:36 AM, "smelc" notifications@github.com wrote:

Thank you for merging this. I do not use gdx yet in my roguelike since I'm
getting started and did not take the time to install gdx properly (but I
need to do it, since a game for a small screen is pretty different from a
desktop game..). Hence, if gdx.SquidPanel.draw(Batch, ..) is the main
drawing entry point, then well the abstraction does not help (but hey maybe
we can build an abstraction of Batch on the awt side ?). But even if draw(Batch,
..) is the main entry point, there are still two advantages to the
interface, that maybe do not directly come to mind:

I witnessed that, to have an awt/gdx independent game, you need to
abstract away the type of color for which the interface helps.
Initially, the dependency on java.awt.Color was spreading pretty far in my
roguelike. Then I came up with the interface and it helped me track where I
refer to the type of color. Now my design is:

An abstract Game class (in the 'core' Eclipse project), that is
awt/gdx independent, hence only knows ISquidPanel; but does quite a lot of
stuff. Game takes as parameter the type of colors. I just require that
type to be an implementation of IColor (an interface of mine, to be
able to retrieve a color's components) and I manage the colors (i.e. build
concrete instances) using a dedicated factory, that builds instances of my
subclass of java.awt.Color (I need a subclass to implement IColor).

Then I have a concrete class called AWTGame (in a different Eclipse
project, that authorizes depending on awt) that subclasses Game and
manages awt dependent stuff: the JFrame and provides the color factory
(roughly: a function IColor -> my subclass of java.awt.Color).

The handling of key events and mouse is similar: an awt/gdx
independent interface in the 'core' project, implemented in the 'awt'
project.

Another use of ISquidPanel is that I can simulate layers of panels
with offsets. For example, to display the inventory of the rogue, I
simulate the inventory as a small (i.e. smaller than the map) ISquidPanel.
To draw, the simulated panel just writes to the underlying (large) panel by
offsetting all coordinates by the top left position of the inventory and
checks that clients do not try to write outside the simulated panel. I'll
provide this one in a next PR if it seems general enough for a library.


Reply to this email directly or view it on GitHub
#81 (comment).

@davidbecker
Copy link
Contributor

I'm very much for dropping support for Swing in favor of LibGDX as the preferred/"blessed" display stack. The last few people that commented on any issue seems to not use Swing, but LibGDX (not sure what @devilbuddy is using/is planning to use on android)

@devilbuddy
Copy link

I've written my own custom renderer based on the tilemap renderer from libgdx

@tommyettinger
Copy link
Member

Personally, I feel like the -util module has the most... utility, for the most games, even just on its own with a custom renderer. I don't think the text-based display code is critical for many uses of SquidLib, but for roguelikes I can certainly see the appeal. I think with the right instruction on where and how to start, a newcomer to SquidLib could set up a libGDX project as easily as a Swing one, and with scene2d.ui in libGDX, there's even less reason to cover both. I'm reluctant to make a major change like this without knowing more about who uses SquidLib, but since the consensus seems to be toward dropping Swing support (and because Swing is drastically slower to render and to respond to input than GDX), I'm in favor as well. I think dropping SquidLib for Swing should probably be during the 3.0 release frame; everyone's 2.x code is breaking with the Point-to-Coord changes anyway, so they might as well upgrade to a faster/better/more-responsive renderer at the same time. The API is certainly fairly close for everything but animations and images (and the aforementioned render() taking a Batch, which may be possible to push into the constructor), so I'm not too worried except for the few (or maybe more than a few) people who haven't been using a dependency manager like Maven or Gradle with SquidLib.

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.

5 participants