Git Product home page Git Product logo

ktx's People

Contributors

crykn avatar cypherdare avatar czyzby avatar deviodesign avatar divelix avatar dwursteisen avatar elect86 avatar fejd avatar focuspo1nt avatar jakewilson avatar jcornaz avatar jkly avatar kali-dali avatar kanpov avatar keturn avatar kotcrab avatar kvonspiczak avatar maltaisn avatar manabreak avatar megamiun avatar mmilenkov avatar mrplow442 avatar nukesz avatar proorange avatar pylvain avatar quillraven avatar sreich avatar tomgrill avatar vrudas avatar yhslai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ktx's Issues

Explore Kotlin 1.1 features

  • Builder scoping DSL could greatly improve Scene2D and VisUI building APIs. #44 #46
  • Builder scoping DSL for Skin building methods. #45
  • Type aliases for LibGDX collections could help avoiding collisions with Kotlin classes (Array, for example), as well as providing class names consistent with the factory methods.
  • Coroutines could be potentially used for asset loading and delegating tasks to main loop (similarly to official Swing utilities library). #41 #47
  • Some properties might be inlined (especially extensions).

Actor.onKeyUp() and Actor.onKeyDown() extension functions

onKey() is all fine and well, but it has a couple of downsides.

  • It only supports letter/number keys - you can't e.g. bind Esc to close a menu.
  • Holding down a key will continuously fire events instead of just one, on the initial key-down.
  • Doesn't detect key releases.

The proposed functions would bind an InputListener with the onKeyDown() or onKeyUp() methods overriden.

Logging utilities

  • Global logging methods.
  • Logger implementation.
  • Unit tests.

Thanks to inline functions, Kotlin can make it possible to use nearly-zero overhead logging mechanism that does not rely on varargs to provide string templates. The existing solution is - unfortunately - not compatible with LibGDX logging.

Merging LibGDX utilities from Ore Infinium

  • Common LibGDX interfaces adapters.
  • Math extensions.
  • ktx-graphics? Utilities for Batch and ShaderProgram in ktx-app.

i'm gonna find some time to push some of my helper functions from my game upwards into here so other people can benefit from my headaches.

some of them are rather useful, some of them are useless even for me ( experiments ๐Ÿ˜‰ )

see here https://github.com/sreich/ore-infinium/blob/master/core/src/com/ore/infinium/util/LibgdxExtensions.kt

i also have artemis ones that would be useful(delegate system initters and some other things), but i'll push that to the backburner because i want to see where i go with those

mostly the interface ones of libgdx, but there's a few others that might be useful to someone other than my crazy self, we'll have to see

the interfaces exist because if you have to inherit from it or create an object of it, it's waaay easier. since libgdx doesn't use default interface java keyword, meaning you have to implement everything. it also gives guarantees on nullability which i found annoying for some of them (like Actor? but turns out it's never not null, so my kotlin wrappers give you that info back) and so on.

i'm sure i'll find ones in the future as i'm working and move them upwards where it makes sense.

there's also a couple in here https://github.com/sreich/ore-infinium/blob/master/core/src/com/ore/infinium/util/KotlinExtensions.kt (obvs ignore the ones that are clearly useless. mutableListOfNulls actually made it into stdlib in a form recently, i believe)

ones of interest are probably

  • interfaces
  • random.nextint(range)
    *shaderprogram.use {}
    *Texture.flipx, flipy
    ...

any thoughts? care to take a glance and call out ones you think others might find useful, or use my best judgement and give a PR awaiting feedback on it?

Actors extensions

  • Actor extension methods for common listeners.
  • Actor.isShown()
  • Operators overloading for adding actors to stages and groups.
  • Actions chaining methods (then?) which automatically create action sequences.
  • Operators overloading for actions.
  • Unit tests.
    • Actors.
    • Listeners.
    • Actions.

improving scene2d label,textbutton property notation for setting text

this is something that's been bothering me...

so you know how kotlin transforms get/set methods from java into property accessors. well, one place this screws up is in label and textbutton of scene2d.

label.text = "test" // won't work, can't assign string to stringbuilder

this exists because label has getText():StringBuilder, and setText(String)..which is a bit strange of an api to begin with.

in other words, from what i've seen, your only way of setting text is:

label.setText("")

the only workaround i could think of is something like this...(both textbutton and label are affected, not sure what else..haven't looked

private var Label.label: String
    get() = text.toString()
    set(str) = setText(str)
private var TextButton.label: String
    get() = text.toString()
    set(str) = setText(str)

got any better ideas? i really don't like the method syntax, property syntax is much more straightforward esp when everything else uses it (consistency). i have yet to find other properties that have similar problems.

KTX tools module

An equivalent to gdx-tools that could automate some KTX-related operations. Potential candidates:

  • Conversion of .properties files to type-safe i18n enums from ktx-i18n.
  • Conversion of skin .json definition to type-safe builders from ktx-style.
  • Generating type-safe ktx-style builders from an existing Skin instance.
  • Extraction of texture region names from .atlas files, which could be saved as a type-safe enum. Useful for both ktx-style builders and general TextureAtlas usage.

Could be implemented as standalone library or Gradle plugin. Or both. The first approach seems the most flexible.

@kotcrab

Scene2D support

  • Interfaces and abstract bases.
    • KWidget (for all parental widgets)
    • KTable (for Table-extending widgets)
    • KTree (for widgets operating on Tree.Node instances)
    • KGroup (for regular WidgetGroup actors)
  • Factory methods of root actors.
    • Table-based (Table, Window, Dialog, ButtonGroup wrapper)
    • Tree
    • WidgetGroup-based (most other parental actors)
  • Kotlin type-safe builders for Scene2D widgets.
    • Non-parental actors.
      • Actor (should we even support this one?)
      • Image
      • Label
      • List (it's not exactly parental, a simple text adding extension method should be enough)
      • ProgressBar
      • SelectBox (similarly to list)
      • Slider
      • TextArea
      • TextField
      • Touchpad
    • Parental actors.
      • ButtonGroup
      • Button
      • CheckBox
      • Container
      • Dialog
      • HorizontalGroup
      • ImageButton
      • ImageTextButton
      • ScrollPane
      • SplitPane
      • Stack
      • Table
      • TextButton
      • Tree (hierarchies should be supported somehow, each actor in a tree hierarchy might be a node)
      • VerticalGroup
      • Window
    • Special-case actors.
      • TextTooltip
      • Tooltip
  • README - overview of the supported features.
    • Guide.
    • Usage examples.
    • Misc.
  • Units tests.

Release 1.9.6-b3

  • Upload to Maven Central.
  • Create a new GitHub release.
  • Extract library version to a separate file.


The next planned release aims to clean up tests code style, remove deprecated utilities and add support for Box2D and coroutines-based asset loading.

Application utilities module

  • ApplicationAdapter equivalent.
  • Game/Screen equivalent. This turns out more opinionated than it should be, it basically forces the developer to use Scene2D - preventing from basing everything on an entity system or using a different screen transition tool.
  • LetterboxingViewport.
  • Documentation (README, guide, usage examples).
  • Unit tests.

LibGDX default ApplicationListener implementations are pretty basic and often force the user to set up boilerplate code like screen clearing or fixed rendering time step manually. This is desired for some advanced users, but most would like to focus on the game logic itself. A more advanced ApplicationListener implementation that handles smooth view transitions and manages Stage with a SpriteBatch could be very useful.

Travis CI integration

  • Automatic snapshot uploads.
  • Pull request verification.
  • master branch testing.
  • Dokka documentation publishing.

Color utilities

  • color factory method with optional alpha defaulting to 1f.
  • Color.copy extension method, supporting optional values overriding.

clearscreen (glclear)

thinking clearscreen should instead have an optional arg for opacity. often times you want to set the opacity (fbos especially) and cannot do that. adding it as an optional arg should maintain BC (though i suppose that doesn't matter since ktx is not 1.0 yet)

Javadocs and Dokka documentation

Standard Gradle javadoc task fails to build a proper Javadoc archive. However, we can use Dokka to generate Javadocs from Kotlin sources. It would be nice to automatically generate Dokka documentation and post it with GitHub Pages using the gh-pages branch after every push to master.

Expose KotlinApplication#timeSinceLastRender to allow interpolation/extrapolation

KotlinApplication's implementation of fixed timestep doesn't take interpolation/extrapolation between frames into account. For example, if the fixedTimeStep is 0.05, but the first Gdx.graphics.rawDeltaTime is 0.08, then it only calls render(0.05) for one time. In the other words, it renders the state of the game at 0.05s, at the 0.08s of the real world.

It's not that bad, but we can at least let the user decide whether he wants interpolation/extrapolation for a smoother result.

Since KotlinApplication doesn't expose timeSinceLastRender, I have to copy&paste its code and implement my own ApplicationListener this way:

  override final fun render() {
    timeSinceLastRender = Math.min(timeSinceLastRender + Gdx.graphics.rawDeltaTime, maxDeltaTime)
    while (timeSinceLastRender >= fixedTimeStep) {
      timeSinceLastRender -= fixedTimeStep
      clearScreen(0f, 0f, 0f, 1f)
      update(fixedTimeStep)
    }
    smoothRender(timeSinceLastRender / fixedTimeStep) // Extrapolation
  }

Math support

  • Overloaded operators and simple factory methods.
    • Vector2.
    • Vector3.
    • Matrix3.
    • Matrix4.
  • Global methods for random numbers using MathUtil (?).

Add scoped cell and node accessors for table and tree children

  • cell inCell extension property returning Cell storing the actor. Usable only in scope of KTable parent.
  • node inNode extension property returning Node storing the actor. Usable only in scope of KTree parent.
  • cell extension method allowing to customize Cell storing the actor, returning the actor for fluent API. Usable only in scope of KTable parent.
  • node extension method allowing to customize Node storing the actor, returning the actor for fluent API. Usable only in scope of KTree parent.

Store actor's container using userObject API of Actor. Add scoped utility extension methods that allow to easily customize and access actor containers.

Assets support

  • Global AssetManager container.
  • Strongly-typed utility functions for easy asset loading.
  • AssetDescriptor building utilities.
  • Easy conversion of strings to FileHandle instances (an alternative to a rather obscure Gdx.files.internal and so on).
  • Disposable utilities.
  • Pool utilities.
  • Unit tests.
    • Disposable.
    • Pool.
    • Asset loading.
    • FileHandle.

Coroutines support

  • Add ktx-async module.
  • Implement coroutine context for LibGDX applications that executes tasks on the main rendering thread, using Gdx.app.postRunnable to resume coroutines executed on other threads.
  • Implement utility functions for asynchronous tasks based on coroutines executed on a configurable AsyncExecutor instance.
  • Add HttpRequest utilities based on coroutines.
  • Simplify LibGDX Timer API. Currently it does not support lambdas.
  • Add suspending delay method, which does not block the main rendering thread using LibGDX Timer.
  • skipFrame suspending method that resumes on the next frame using Gdx.app.postRunnable API.
  • Implement tasks cancellation.
  • Documentation with usage examples.

Implement ktx-async module with asynchronous operations utilities and Kotlin 1.1 coroutines support.

Static instances removal

  • I18n bundle - with idiomatic Kotlin NLS enums (see README file), the static nls methods are not as useful.
  • Dependency injection context - after full context initiation, context should not be accessed directly. Dynamically created instances should be accessible through injected providers.
  • Asset manager - with dependency injection from ktx-inject, static access to resources can be harmful and hide code dependencies. Fully loaded assets should be passed directly to the objects and functions that depend on them.

  • Add deprecation warnings to the mentioned instances and functions that rely on them.
  • Provide alternative utility methods for AssetManager usage, allowing the users to migrate to the new API before the next release.
  • Rewrite ktx-i18n documentation.
  • Rewrite ktx-inject documentation.

Most static variables are pretty much justified and optional to use. For example, you can still benefit from gdx-assets utilities without the global AssetManager, but most applications will want to use only a single one anyway.

I don't think the global Skin variable should be removed from ktx-scene2d though, as it greatly simplifies and improves readability of UI building methods.

@kotcrab @sreich @MrPlow442 I'd love to hear your thoughts on this.

I18n support

  • Global nls functions.
  • Utility I18NBundle container.
  • BundleLine interface, providing i18n support with zero boilerplate.
  • Unit tests.

ktx-tools gradle plugin buildsystem issues

i'm working on the gradle plugin which will end up running a code generator on whatever we want (my focus is on fonts, sounds, textures not in particular order).

i could use some help on this issue right now. if you check out my fork, https://github.com/sreich/ktx/tree/feature/ktx-tools

running install on ktx-tools fails..not sure why it's failing at that task though. once i get this building a "hello world" then i can begin work on it. i'm inexperienced in gradle, but had it working fine before combining it into ktx-tools.

:tools:dokkaZip
:tools:compileKotlin UP-TO-DATE
:tools:compileJava NO-SOURCE
:tools:copyMainKotlinClasses FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':tools:copyMainKotlinClasses'.
> kotlin.KotlinNullPointerException (no error message)

* Try:
Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':tools:copyMainKotlinClasses'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:84)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
	at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
	at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:88)
	at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:236)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.execute(DefaultTaskGraphExecuter.java:228)
	at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:61)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:228)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:215)
	at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:77)
	at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:58)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:32)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:113)
	at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
	at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
	at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
	at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
	at org.gradle.initialization.DefaultGradleLauncher$RunTasksAction.execute(DefaultGradleLauncher.java:256)
	at org.gradle.initialization.DefaultGradleLauncher$RunTasksAction.execute(DefaultGradleLauncher.java:253)
	at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
	at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:175)
	at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:119)
	at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:102)
	at org.gradle.launcher.exec.GradleBuildController.run(GradleBuildController.java:71)
	at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:50)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:43)
	at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:40)
	at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
	at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
	at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:75)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49)
	at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:49)
	at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:31)
	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:47)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
	at org.gradle.util.Swapper.swap(Swapper.java:38)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:46)
Caused by: kotlin.KotlinNullPointerException
	at org.jetbrains.kotlin.gradle.tasks.SyncOutputTask.siblingInJavaDir(SyncOutputTask.kt:162)
	at org.jetbrains.kotlin.gradle.tasks.SyncOutputTask.siblingInJavaDir$default(SyncOutputTask.kt:161)
	at org.jetbrains.kotlin.gradle.tasks.SyncOutputTask.processIncrementally(SyncOutputTask.kt:125)
	at org.jetbrains.kotlin.gradle.tasks.SyncOutputTask.access$processIncrementally(SyncOutputTask.kt:57)
	at org.jetbrains.kotlin.gradle.tasks.SyncOutputTask$execute$2.execute(SyncOutputTask.kt:93)
	at org.jetbrains.kotlin.gradle.tasks.SyncOutputTask$execute$2.execute(SyncOutputTask.kt:57)
	at org.gradle.api.internal.changedetection.changes.ChangesOnlyIncrementalTaskInputs.doOutOfDate(ChangesOnlyIncrementalTaskInputs.java:46)
	at org.gradle.api.internal.changedetection.changes.StatefulIncrementalTaskInputs.outOfDate(StatefulIncrementalTaskInputs.java:39)
	at org.gradle.api.internal.changedetection.changes.ChangesOnlyIncrementalTaskInputs.outOfDate(ChangesOnlyIncrementalTaskInputs.java:27)
	at org.jetbrains.kotlin.gradle.tasks.SyncOutputTask.execute(SyncOutputTask.kt:93)
	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$IncrementalTaskAction.doExecute(DefaultTaskClassInfoStore.java:163)
	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:134)
	at org.gradle.api.internal.project.taskfactory.DefaultTaskClassInfoStore$StandardTaskAction.execute(DefaultTaskClassInfoStore.java:123)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:95)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:76)
	... 78 more

Collections support

  • Array utilities: factory methods, extensions, Iterable/kotlin.Array conversions.
  • ObjectSet utilities: factory methods, extensions, Iterable/kotlin.Array conversions.
  • ObjectMap utilities.
    • Iterable/kotlin.Array conversions.
    • Factory methods.
    • Extension utility methods.
    • Support for map[key] = value operator.
  • List utilities.
    • PooledList implementation: PooledLinkedList done right.
  • Unit tests.
    • Arrays.
    • Sets.
    • Maps.
    • Lists.

VisUI support

  • Kotlin type-safe builders for VisUI widgets.
    • Non-parental actors.
      • Actor (maybe?)
      • VisImage
      • VisLabel
      • VisList
      • VisProgressBar
      • VisSelectBox
      • VisSlider
      • VisTextArea
        • HighlightTextArea
        • ScrollableTextArea
      • VisTextField
      • VisValidatableTextField
      • Touchpad
      • BusyBar
      • Separator
      • LinkLabel
    • Parental actors.
      • Button
      • VisCheckBox
      • VisRadioButton
      • VisDialog (just use VisWindow)
      • HorizontalGroup
      • HorizontalFlowGroup
      • VerticalGroup
      • VerticalFlowGroup
      • VisImageButton
      • VisImageTextButton
      • Stack
      • VisTable
      • VisTree
      • VisWindow
      • BasicColorPicker
      • ExtendedColorPicker
      • ToastTable
      • GridGroup
      • FloatingGroup
      • Spinner
    • Special-case classes.
      • ButtonGroup
      • Tooltip (the VisUI one)
      • MessageToast
      • MenuItem (parental but adding something to menu items is usually not done since it disrupts popup menu layout)
      • PopupMenu (parental but MenuItem must be added using its custom method)
      • ListView
      • DragPane / Draggable
      • FormValidator (not an actor but some API might be nice)
      • TabbedPane / Tab
      • ButtonBar
      • VisScrollPane (parental but standard addActor is not supported)
      • VisSplitPane (parental but standard addActor is not supported)
      • MultiSplitPane (parental but standard addActor is not supported)
      • Container (parental but supports only single child)
      • CollapsibleWidget (parental but supports only single child)
  • README - overview of the supported features.
  • Unit tests.

INCOMPATIBLE with ktx-scene2d to avoid collisions. Similarly named methods (for example, textButton) might return different widgets in each library.

Coroutines-based asset manager

Asynchronous asset loading based on coroutines would both benefit simplify the API usage - it would look as if assets are loaded synchronously - as well as the asset manager internal implementation.


It would be possible to turn this pseudocode example:

fun create() {
  assetManager.apply {
     load<String>("my.txt") // Returns nothing. :C
     load<Texture>("logo.png")
     load<String>("other.txt")
     load<I18NBundle>("i18n.properties")
     // Schedule loading of other assets.
  }
}

fun render() {
  if (assetManager.update()) {
    // Assets loaded!
    finishLoading()
  }
  updateProgressLabel(assetManager.progress)
}

fun finishLoading() {
   assetManager.apply {
     myText = get<String>("my.txt")
     logo = get<Texture>("logo.png")
     otherText = get<String>("other.txt")
     bundle = get<I18NBundle>("i18n.properties")
     // Extract other assets.
  }
  goToNextView()
}

...into this pseudocode example:

fun create() {
  assetManager.apply {
     // Each call suspends and resumes on the rendering thread,
     // never blocking the rendering process.
     myText = load<String>("my.txt")
     logo = load<Texture>("logo.png")
     otherText = load<String>("other.txt")
     bundle = load<I18NBundle>("i18n.properties")
  }
  // Resumes after all assets are loaded:
  goToNextView()
}

fun render() {
  updateProgressLabel(assetManager.statusMessage)
}

@kotcrab Thoughts on this? Should we include coroutines in ktx-assets, add the new manager to ktx-async (general LibGDX asynchronous operations utilities and basic coroutines support) or create a separate module?

Release 1.9.4-b2

  • Upload to Maven Central.
  • Add to releases section.
  • Update gdx-setup.
  • Update change log.

Box2D utilities module

  • Review gdx-box2d-kotlin code.
  • Migrate gdx-box2d-kotlin to ktx-box2d module.
  • FixtureDef factory methods supporting different shapes.
  • earthGravity property.
  • World factory methods.
  • Documentation listing all extensions. Usage examples.
  • Provide an easy way to access built Fixture instances.
  • Improve FixtureDef.filter API.
  • Address FixtureDef.shape issue.
  • Add userData properties to extended body and fixture definitions.

@Jkly

Documentation improvements

  • Contributing guideline.
  • Links to related LibGDX articles.
  • Gradle/Maven dependencies info.

Basically, all KTX guides assume prior knowledge of LibGDX API. Some people are likely to get there because of Kotlin rather LibGDX. It would be nice to include some links to the original LibGDX APIs explanations that are being improved by each KTX module - for example, ktx-scene2d could link to Scene2D wiki article.

Also, there is no CONTRIBUTING.md file and Maven dependencies data in existing README files.

Update contribution guide

Contribution guide should contain a note about updating the changelog file and README of the modified project.

Math module implementation

Hi guys,

I am a little bit confused about the implementation of the math module.
Applying operators on vectors/matrices does not behave as expected since the result which gets returned is the left handed variable instead of a new vector/matrix.
For example:

val x = Vector2(1f, 1f)
val y = x * 2f

will get y the correct result and x won't be Vector2(1f, 1f) anymore but Vector2(2f, 2f), i.e. x == y is true.

To bypass that problem you would do something like this: val y = Vector2(x) * 2f so x keeps it's original values.

I understand that the operators are simple aliases for the Vector/Matrix methods and the gdx implementation does not return new instances for obvious performance reasons.

So do you think this problem could be solved with some kind of pooling to prevent performance issues?
I would appreciate at least some kind of flag, which can be set for the math module so new instances get returned by default.

-Trixt0r

Upload 1.9.4-b1 to Maven Central

  • Upload 1.9.4-b1 version to Maven Central.
  • Update info and add "shield" to README.md with current version.
  • Add zipped data to releases.

Refactoring Vis module

This is attempt to improve current Vis builder API. Current implementation when building actors that belong to Table-type widget will return Cell<Actor> which is convenient if you need to modify cell properties but most of the time you also need to get Actor itself which requires not so convenient .actor call.
New API will introduce .cell {} that will allow to modify Cell properties but still return Actor.

This requires to re-purpose Actor.userObject for storing Cell. However .cell {} syntax is only valid in UI builder, allowing user to re user field later. Also, fallback method searching actor hierarchy search would be implemented.

.cell {} syntax is only valid in current DSL block thanks to two things:

  • only parental Actors that will put Cell instance in Actor.userObject provide API to call .cell{} (thanks to possibility to put extension methods in interface)
  • nested DSL blocks won't be able to call it thanks to @DslMarker annotation

This is simple subset of current API with those changes implemented. Notice that there is only one WidgetFactory interface for both Table-type and standard WidgetGroup actors. Usage of @DslMarker requires to extend all widget classes such as VisLabel, that was not needed before.

inline fun table(init: KVisTable.() -> Unit): Table = actor(KVisTable(), init)

inline fun horizontalGroup(init: KHorizontalGroup.() -> Unit): KHorizontalGroup = actor(KHorizontalGroup(), init)

inline fun <T : Actor> actor(actor: T, init: T.() -> Unit): T {
    actor.init()
    return actor
}

@VisDslMarker
class KVisLabel(text: CharSequence, styleName: String) : VisLabel(text, styleName)

@VisDslMarker
class KVisTable : VisTable(false), WidgetFactory, CellAccessor {
    override fun <T : Actor> addActorToWidgetGroup(actor: T): T {
        val cell = add(actor)
        actor.userObject = cell
        return actor
    }
}

@VisDslMarker
class KHorizontalGroup : HorizontalGroup(), WidgetFactory {
    override fun <T : Actor> addActorToWidgetGroup(actor: T): T {
        addActor(actor)
        return actor
    }
}

interface CellAccessor {
    fun <T : Actor> T.cell(): Cell<T> {
        return this.userObject as Cell<T> //TODO fallback to actor hierarchy search
    }

    fun <T : Actor> T.cell(initCell: Cell<T>.() -> Unit): T {
        cell().initCell()
        return this
    }

    // Alternatively to above
    fun <T : Actor> T.cell(grow: Boolean, padding: Float = 0f /* other fields ...*/): T {
        if (grow) cell().grow()
        cell().pad(padding)
        return this
    }

    fun <T : Actor> T.row(): T {
        cell().row()
        return this
    }


    @Deprecated("Calls to cell() can't be nested", level = DeprecationLevel.ERROR)
    fun <T : Actor> Cell<T>.cell() {
    }

    @Deprecated("Calls to cell() can't be nested", level = DeprecationLevel.ERROR)
    fun <T : Actor> Cell<T>.cell(initCell: Cell<T>.() -> Unit) {
    }
}


interface WidgetFactory {
    fun label(text: String, styleName: String = DEFAULT_STYLE, init: KVisLabel.() -> Unit = {}): VisLabel
            = actor(KVisLabel(text, styleName), init)

    fun table(init: KVisTable.() -> Unit = {}): VisTable = actor(KVisTable(), init)

    fun horizontalGroup(init: KHorizontalGroup.() -> Unit = {}): HorizontalGroup = actor(KHorizontalGroup(), init)

    fun <T : Actor> actor(actor: T, init: T.() -> Unit): T {
        val result: T = addActorToWidgetGroup(actor)
        actor.init()
        return result
    }

    fun <T : Actor> addActorToWidgetGroup(actor: T): T
}

@DslMarker
annotation class VisDslMarker

Usage examples

fun createUI() {
    var extLabel: VisLabel? = null

    table {
        extLabel = label("A")
        val label: VisLabel = label("A") {
            setAlignment(Align.left)
            // cell {} // this is invalid because of DslMarker
        }
        val labelCell: Cell<VisLabel> = label("A").cell() // get cell explicitly
        val label2: VisLabel = label("A").cell { growX() } // modify some values of cell but still get actor
        val label4: VisLabel = label("A").cell(grow = true, padding = 2f) // alternative way to modify cell properties

        horizontalGroup {
            // both invalid because of DslMarker
            // label2.cell()
            // label("A").cell()
        }
    }

    horizontalGroup {
        val label: VisLabel = label("A")
        //label("A").cell() // invalid, IDE won't suggest cell here
    }

    // invalid, IDE won't suggest cell here
    //extLabel.cell()
    //extLabel.cell { growX() }
}

@czyzby Any thoughts, do you see any shortcomings of this approach?

Skin utilities module

  • Type-safe builders for Scene2D widgets styles.
  • Utility functions that make accessing and modifying Skin assets easier.
  • Unit tests.

ktx-style would a type-safe alternative to constructing Scene2D styles with error-prone JSON files.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.