Full Code of SimulaVR/godot-haskell for AI

master cabc06451292 cached
788 files
11.0 MB
2.9M tokens
8 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (11,727K chars total). Download the full file to get everything.
Repository: SimulaVR/godot-haskell
Branch: master
Commit: cabc06451292
Files: 788
Total size: 11.0 MB

Directory structure:
gitextract_kt3cl1ny/

├── .gitignore
├── .gitmodules
├── .hlint.yaml
├── .travis.yml
├── .vscode/
│   └── tasks.json
├── LICENSE
├── README.md
├── Setup.hs
├── cbits/
│   └── util.h
├── classgen/
│   ├── README.md
│   ├── app-classgen/
│   │   └── Main.hs
│   ├── default.nix
│   ├── godot-haskell-classgen.cabal
│   ├── package.yaml
│   ├── release.nix
│   ├── src-classgen/
│   │   └── Classgen/
│   │       ├── Docs.hs
│   │       ├── Module.hs
│   │       ├── Spec.hs
│   │       └── Utils.hs
│   └── stack.yaml
├── default.nix
├── examples/
│   ├── dodge-the-creeps/
│   │   ├── .gitignore
│   │   ├── ChangeLog.md
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── Support.hs
│   │   ├── ffi/
│   │   │   ├── cbits/
│   │   │   │   └── flib.c
│   │   │   └── flib/
│   │   │       └── FLib.hs
│   │   ├── game/
│   │   │   ├── HUD.gdns
│   │   │   ├── HUD.tres
│   │   │   ├── HUD.tscn
│   │   │   ├── Main.gdns
│   │   │   ├── Main.tscn
│   │   │   ├── Mob.gdns
│   │   │   ├── Mob.tscn
│   │   │   ├── Player.gdns
│   │   │   ├── Player.tscn
│   │   │   ├── dodge_assets/
│   │   │   │   ├── art/
│   │   │   │   │   └── House In a Forest Loop.ogg
│   │   │   │   └── fonts/
│   │   │   │       ├── FONTLOG.txt
│   │   │   │       └── LICENSE.txt
│   │   │   ├── lib/
│   │   │   │   └── libmyproject.gdnlib
│   │   │   └── project.godot
│   │   ├── godot-haskell.nix
│   │   ├── hie.yaml
│   │   ├── myproject.cabal
│   │   ├── package.yaml
│   │   ├── pinned-nixpkgs.nix
│   │   ├── shell.nix
│   │   ├── src/
│   │   │   ├── Game/
│   │   │   │   ├── HUD.hs
│   │   │   │   ├── Main.hs
│   │   │   │   ├── Mob.hs
│   │   │   │   └── Player.hs
│   │   │   ├── Lib.hs
│   │   │   └── Project/
│   │   │       ├── Requirements.hs
│   │   │       ├── Scenes/
│   │   │       │   ├── HUD.hs
│   │   │       │   ├── Main.hs
│   │   │       │   ├── Mob.hs
│   │   │       │   └── Player.hs
│   │   │       ├── Scenes.hs
│   │   │       └── Support.hs
│   │   ├── stack-shell.nix
│   │   └── stack.yaml
│   ├── rss-reader/
│   │   ├── .gitignore
│   │   ├── ChangeLog.md
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── Support.hs
│   │   ├── ffi/
│   │   │   ├── cbits/
│   │   │   │   └── flib.c
│   │   │   └── flib/
│   │   │       └── FLib.hs
│   │   ├── game/
│   │   │   ├── Rss_reader.gdns
│   │   │   ├── Rss_reader.tscn
│   │   │   ├── export_presets.cfg
│   │   │   ├── lib/
│   │   │   │   └── libmyproject.gdnlib
│   │   │   └── project.godot
│   │   ├── godot-haskell.nix
│   │   ├── hie.yaml
│   │   ├── myproject.cabal
│   │   ├── package.yaml
│   │   ├── pinned-nixpkgs.nix
│   │   ├── shell.nix
│   │   ├── src/
│   │   │   ├── Game/
│   │   │   │   ├── RSSReader.hs
│   │   │   │   └── q
│   │   │   ├── Lib.hs
│   │   │   └── Project/
│   │   │       ├── Requirements.hs
│   │   │       ├── Scenes/
│   │   │       │   └── Rss_reader.hs
│   │   │       ├── Scenes.hs
│   │   │       └── Support.hs
│   │   ├── stack-shell.nix
│   │   └── stack.yaml
│   └── top-down-ten-minutes/
│       ├── .gitignore
│       ├── ChangeLog.md
│       ├── LICENSE
│       ├── Makefile
│       ├── README.md
│       ├── ffi/
│       │   ├── cbits/
│       │   │   └── flib.c
│       │   └── flib/
│       │       └── FLib.hs
│       ├── game/
│       │   ├── Bullet.gdns
│       │   ├── Bullet.tscn
│       │   ├── Enemy.gdns
│       │   ├── Enemy.tscn
│       │   ├── Explosion.tscn
│       │   ├── Player.gdns
│       │   ├── lib/
│       │   │   └── libtop-down-ten-minutes.gdnlib
│       │   ├── project.godot
│       │   ├── wall.tres
│       │   └── world.tscn
│       ├── godot-haskell.nix
│       ├── hie.yaml
│       ├── package.yaml
│       ├── pinned-nixpkgs.nix
│       ├── shell.nix
│       ├── src/
│       │   ├── Game/
│       │   │   └── World.hs
│       │   ├── Lib.hs
│       │   └── Project/
│       │       ├── Requirements.hs
│       │       ├── Scenes/
│       │       │   ├── Bullet.hs
│       │       │   ├── Enemy.hs
│       │       │   ├── Explosion.hs
│       │       │   └── World.hs
│       │       ├── Scenes.hs
│       │       └── Support.hs
│       ├── stack-shell.nix
│       ├── stack.yaml
│       └── top-down-ten-minutes.cabal
├── godot-haskell.cabal
├── hie.yaml
├── nix/
│   ├── pinned/
│   │   ├── all-hies.json
│   │   ├── default.nix
│   │   ├── hie.nix
│   │   └── nixpkgs.json
│   └── spacemacs-hie.nix
├── nixpkgs-version.json
├── package.yaml
├── pinned-nixpkgs.nix
├── project-generator/
│   └── Main.hs
├── release.nix
├── shell-spacemacs-hie.nix
├── shell.nix
├── src/
│   ├── Godot/
│   │   ├── Api/
│   │   │   └── Types.hs
│   │   ├── Api.hs
│   │   ├── Core/
│   │   │   ├── ARVRAnchor.hs
│   │   │   ├── ARVRCamera.hs
│   │   │   ├── ARVRController.hs
│   │   │   ├── ARVRInterface.hs
│   │   │   ├── ARVRInterfaceGDNative.hs
│   │   │   ├── ARVROrigin.hs
│   │   │   ├── ARVRPositionalTracker.hs
│   │   │   ├── ARVRServer.hs
│   │   │   ├── AStar.hs
│   │   │   ├── AStar2D.hs
│   │   │   ├── AcceptDialog.hs
│   │   │   ├── AnimatedSprite.hs
│   │   │   ├── AnimatedSprite3D.hs
│   │   │   ├── AnimatedTexture.hs
│   │   │   ├── Animation.hs
│   │   │   ├── AnimationNode.hs
│   │   │   ├── AnimationNodeAdd2.hs
│   │   │   ├── AnimationNodeAdd3.hs
│   │   │   ├── AnimationNodeAnimation.hs
│   │   │   ├── AnimationNodeBlend2.hs
│   │   │   ├── AnimationNodeBlend3.hs
│   │   │   ├── AnimationNodeBlendSpace1D.hs
│   │   │   ├── AnimationNodeBlendSpace2D.hs
│   │   │   ├── AnimationNodeBlendTree.hs
│   │   │   ├── AnimationNodeOneShot.hs
│   │   │   ├── AnimationNodeOutput.hs
│   │   │   ├── AnimationNodeStateMachine.hs
│   │   │   ├── AnimationNodeStateMachinePlayback.hs
│   │   │   ├── AnimationNodeStateMachineTransition.hs
│   │   │   ├── AnimationNodeTimeScale.hs
│   │   │   ├── AnimationNodeTimeSeek.hs
│   │   │   ├── AnimationNodeTransition.hs
│   │   │   ├── AnimationPlayer.hs
│   │   │   ├── AnimationRootNode.hs
│   │   │   ├── AnimationTree.hs
│   │   │   ├── AnimationTreePlayer.hs
│   │   │   ├── Area.hs
│   │   │   ├── Area2D.hs
│   │   │   ├── ArrayMesh.hs
│   │   │   ├── AtlasTexture.hs
│   │   │   ├── AudioBusLayout.hs
│   │   │   ├── AudioEffect.hs
│   │   │   ├── AudioEffectAmplify.hs
│   │   │   ├── AudioEffectBandLimitFilter.hs
│   │   │   ├── AudioEffectBandPassFilter.hs
│   │   │   ├── AudioEffectChorus.hs
│   │   │   ├── AudioEffectCompressor.hs
│   │   │   ├── AudioEffectDelay.hs
│   │   │   ├── AudioEffectDistortion.hs
│   │   │   ├── AudioEffectEQ.hs
│   │   │   ├── AudioEffectEQ10.hs
│   │   │   ├── AudioEffectEQ21.hs
│   │   │   ├── AudioEffectEQ6.hs
│   │   │   ├── AudioEffectFilter.hs
│   │   │   ├── AudioEffectHighPassFilter.hs
│   │   │   ├── AudioEffectHighShelfFilter.hs
│   │   │   ├── AudioEffectInstance.hs
│   │   │   ├── AudioEffectLimiter.hs
│   │   │   ├── AudioEffectLowPassFilter.hs
│   │   │   ├── AudioEffectLowShelfFilter.hs
│   │   │   ├── AudioEffectNotchFilter.hs
│   │   │   ├── AudioEffectPanner.hs
│   │   │   ├── AudioEffectPhaser.hs
│   │   │   ├── AudioEffectPitchShift.hs
│   │   │   ├── AudioEffectRecord.hs
│   │   │   ├── AudioEffectReverb.hs
│   │   │   ├── AudioEffectSpectrumAnalyzer.hs
│   │   │   ├── AudioEffectSpectrumAnalyzerInstance.hs
│   │   │   ├── AudioEffectStereoEnhance.hs
│   │   │   ├── AudioServer.hs
│   │   │   ├── AudioStream.hs
│   │   │   ├── AudioStreamGenerator.hs
│   │   │   ├── AudioStreamGeneratorPlayback.hs
│   │   │   ├── AudioStreamMicrophone.hs
│   │   │   ├── AudioStreamOGGVorbis.hs
│   │   │   ├── AudioStreamPlayback.hs
│   │   │   ├── AudioStreamPlaybackResampled.hs
│   │   │   ├── AudioStreamPlayer.hs
│   │   │   ├── AudioStreamPlayer2D.hs
│   │   │   ├── AudioStreamPlayer3D.hs
│   │   │   ├── AudioStreamRandomPitch.hs
│   │   │   ├── AudioStreamSample.hs
│   │   │   ├── BackBufferCopy.hs
│   │   │   ├── BakedLightmap.hs
│   │   │   ├── BakedLightmapData.hs
│   │   │   ├── BaseButton.hs
│   │   │   ├── BitMap.hs
│   │   │   ├── BitmapFont.hs
│   │   │   ├── Bone2D.hs
│   │   │   ├── BoneAttachment.hs
│   │   │   ├── BoxContainer.hs
│   │   │   ├── BoxShape.hs
│   │   │   ├── BulletPhysicsDirectBodyState.hs
│   │   │   ├── BulletPhysicsServer.hs
│   │   │   ├── Button.hs
│   │   │   ├── ButtonGroup.hs
│   │   │   ├── CPUParticles.hs
│   │   │   ├── CPUParticles2D.hs
│   │   │   ├── CSGBox.hs
│   │   │   ├── CSGCombiner.hs
│   │   │   ├── CSGCylinder.hs
│   │   │   ├── CSGMesh.hs
│   │   │   ├── CSGPolygon.hs
│   │   │   ├── CSGPrimitive.hs
│   │   │   ├── CSGShape.hs
│   │   │   ├── CSGSphere.hs
│   │   │   ├── CSGTorus.hs
│   │   │   ├── Camera.hs
│   │   │   ├── Camera2D.hs
│   │   │   ├── CameraFeed.hs
│   │   │   ├── CameraServer.hs
│   │   │   ├── CameraTexture.hs
│   │   │   ├── CanvasItem.hs
│   │   │   ├── CanvasItemMaterial.hs
│   │   │   ├── CanvasLayer.hs
│   │   │   ├── CanvasModulate.hs
│   │   │   ├── CapsuleMesh.hs
│   │   │   ├── CapsuleShape.hs
│   │   │   ├── CapsuleShape2D.hs
│   │   │   ├── CenterContainer.hs
│   │   │   ├── CharFXTransform.hs
│   │   │   ├── CheckBox.hs
│   │   │   ├── CheckButton.hs
│   │   │   ├── CircleShape2D.hs
│   │   │   ├── ClassDB.hs
│   │   │   ├── ClippedCamera.hs
│   │   │   ├── CollisionObject.hs
│   │   │   ├── CollisionObject2D.hs
│   │   │   ├── CollisionPolygon.hs
│   │   │   ├── CollisionPolygon2D.hs
│   │   │   ├── CollisionShape.hs
│   │   │   ├── CollisionShape2D.hs
│   │   │   ├── ColorPicker.hs
│   │   │   ├── ColorPickerButton.hs
│   │   │   ├── ColorRect.hs
│   │   │   ├── ConcavePolygonShape.hs
│   │   │   ├── ConcavePolygonShape2D.hs
│   │   │   ├── ConeTwistJoint.hs
│   │   │   ├── ConfigFile.hs
│   │   │   ├── ConfirmationDialog.hs
│   │   │   ├── Container.hs
│   │   │   ├── Control.hs
│   │   │   ├── ConvexPolygonShape.hs
│   │   │   ├── ConvexPolygonShape2D.hs
│   │   │   ├── Crypto.hs
│   │   │   ├── CryptoKey.hs
│   │   │   ├── CubeMap.hs
│   │   │   ├── CubeMesh.hs
│   │   │   ├── Curve.hs
│   │   │   ├── Curve2D.hs
│   │   │   ├── Curve3D.hs
│   │   │   ├── CurveTexture.hs
│   │   │   ├── CylinderMesh.hs
│   │   │   ├── CylinderShape.hs
│   │   │   ├── DampedSpringJoint2D.hs
│   │   │   ├── DirectionalLight.hs
│   │   │   ├── Directory.hs
│   │   │   ├── DynamicFont.hs
│   │   │   ├── DynamicFontData.hs
│   │   │   ├── EncodedObjectAsID.hs
│   │   │   ├── Engine.hs
│   │   │   ├── Environment.hs
│   │   │   ├── Expression.hs
│   │   │   ├── File.hs
│   │   │   ├── FileDialog.hs
│   │   │   ├── Font.hs
│   │   │   ├── FuncRef.hs
│   │   │   ├── GDNative.hs
│   │   │   ├── GDNativeLibrary.hs
│   │   │   ├── GDScript.hs
│   │   │   ├── GDScriptFunctionState.hs
│   │   │   ├── GIProbe.hs
│   │   │   ├── GIProbeData.hs
│   │   │   ├── Generic6DOFJoint.hs
│   │   │   ├── Geometry.hs
│   │   │   ├── GeometryInstance.hs
│   │   │   ├── GlobalConstants.hs
│   │   │   ├── Gradient.hs
│   │   │   ├── GradientTexture.hs
│   │   │   ├── GraphEdit.hs
│   │   │   ├── GraphNode.hs
│   │   │   ├── GridContainer.hs
│   │   │   ├── GridMap.hs
│   │   │   ├── GrooveJoint2D.hs
│   │   │   ├── HBoxContainer.hs
│   │   │   ├── HScrollBar.hs
│   │   │   ├── HSeparator.hs
│   │   │   ├── HSlider.hs
│   │   │   ├── HSplitContainer.hs
│   │   │   ├── HTTPClient.hs
│   │   │   ├── HTTPRequest.hs
│   │   │   ├── HashingContext.hs
│   │   │   ├── HeightMapShape.hs
│   │   │   ├── HingeJoint.hs
│   │   │   ├── IP.hs
│   │   │   ├── IP_Unix.hs
│   │   │   ├── Image.hs
│   │   │   ├── ImageTexture.hs
│   │   │   ├── ImmediateGeometry.hs
│   │   │   ├── Input.hs
│   │   │   ├── InputDefault.hs
│   │   │   ├── InputEvent.hs
│   │   │   ├── InputEventAction.hs
│   │   │   ├── InputEventGesture.hs
│   │   │   ├── InputEventJoypadButton.hs
│   │   │   ├── InputEventJoypadMotion.hs
│   │   │   ├── InputEventKey.hs
│   │   │   ├── InputEventMIDI.hs
│   │   │   ├── InputEventMagnifyGesture.hs
│   │   │   ├── InputEventMouse.hs
│   │   │   ├── InputEventMouseButton.hs
│   │   │   ├── InputEventMouseMotion.hs
│   │   │   ├── InputEventPanGesture.hs
│   │   │   ├── InputEventScreenDrag.hs
│   │   │   ├── InputEventScreenTouch.hs
│   │   │   ├── InputEventWithModifiers.hs
│   │   │   ├── InputMap.hs
│   │   │   ├── InstancePlaceholder.hs
│   │   │   ├── InterpolatedCamera.hs
│   │   │   ├── ItemList.hs
│   │   │   ├── JSON.hs
│   │   │   ├── JSONParseResult.hs
│   │   │   ├── JSONRPC.hs
│   │   │   ├── JavaClass.hs
│   │   │   ├── JavaClassWrapper.hs
│   │   │   ├── JavaScript.hs
│   │   │   ├── Joint.hs
│   │   │   ├── Joint2D.hs
│   │   │   ├── KinematicBody.hs
│   │   │   ├── KinematicBody2D.hs
│   │   │   ├── KinematicCollision.hs
│   │   │   ├── KinematicCollision2D.hs
│   │   │   ├── Label.hs
│   │   │   ├── LargeTexture.hs
│   │   │   ├── Light.hs
│   │   │   ├── Light2D.hs
│   │   │   ├── LightOccluder2D.hs
│   │   │   ├── Line2D.hs
│   │   │   ├── LineEdit.hs
│   │   │   ├── LineShape2D.hs
│   │   │   ├── LinkButton.hs
│   │   │   ├── Listener.hs
│   │   │   ├── MainLoop.hs
│   │   │   ├── MarginContainer.hs
│   │   │   ├── Marshalls.hs
│   │   │   ├── Material.hs
│   │   │   ├── MenuButton.hs
│   │   │   ├── Mesh.hs
│   │   │   ├── MeshDataTool.hs
│   │   │   ├── MeshInstance.hs
│   │   │   ├── MeshInstance2D.hs
│   │   │   ├── MeshLibrary.hs
│   │   │   ├── MeshTexture.hs
│   │   │   ├── MobileVRInterface.hs
│   │   │   ├── MultiMesh.hs
│   │   │   ├── MultiMeshInstance.hs
│   │   │   ├── MultiMeshInstance2D.hs
│   │   │   ├── MultiplayerAPI.hs
│   │   │   ├── MultiplayerPeerGDNative.hs
│   │   │   ├── Mutex.hs
│   │   │   ├── NativeScript.hs
│   │   │   ├── Navigation.hs
│   │   │   ├── Navigation2D.hs
│   │   │   ├── NavigationMesh.hs
│   │   │   ├── NavigationMeshInstance.hs
│   │   │   ├── NavigationPolygon.hs
│   │   │   ├── NavigationPolygonInstance.hs
│   │   │   ├── NetworkedMultiplayerENet.hs
│   │   │   ├── NetworkedMultiplayerPeer.hs
│   │   │   ├── NinePatchRect.hs
│   │   │   ├── Node.hs
│   │   │   ├── Node2D.hs
│   │   │   ├── NoiseTexture.hs
│   │   │   ├── OS.hs
│   │   │   ├── Object.hs
│   │   │   ├── OccluderPolygon2D.hs
│   │   │   ├── OmniLight.hs
│   │   │   ├── OpenSimplexNoise.hs
│   │   │   ├── OptionButton.hs
│   │   │   ├── PCKPacker.hs
│   │   │   ├── PHashTranslation.hs
│   │   │   ├── PackedDataContainer.hs
│   │   │   ├── PackedDataContainerRef.hs
│   │   │   ├── PackedScene.hs
│   │   │   ├── PacketPeer.hs
│   │   │   ├── PacketPeerGDNative.hs
│   │   │   ├── PacketPeerStream.hs
│   │   │   ├── PacketPeerUDP.hs
│   │   │   ├── Panel.hs
│   │   │   ├── PanelContainer.hs
│   │   │   ├── PanoramaSky.hs
│   │   │   ├── ParallaxBackground.hs
│   │   │   ├── ParallaxLayer.hs
│   │   │   ├── Particles.hs
│   │   │   ├── Particles2D.hs
│   │   │   ├── ParticlesMaterial.hs
│   │   │   ├── Path.hs
│   │   │   ├── Path2D.hs
│   │   │   ├── PathFollow.hs
│   │   │   ├── PathFollow2D.hs
│   │   │   ├── Performance.hs
│   │   │   ├── PhysicalBone.hs
│   │   │   ├── Physics2DDirectBodyState.hs
│   │   │   ├── Physics2DDirectBodyStateSW.hs
│   │   │   ├── Physics2DDirectSpaceState.hs
│   │   │   ├── Physics2DServer.hs
│   │   │   ├── Physics2DServerSW.hs
│   │   │   ├── Physics2DShapeQueryParameters.hs
│   │   │   ├── Physics2DShapeQueryResult.hs
│   │   │   ├── Physics2DTestMotionResult.hs
│   │   │   ├── PhysicsBody.hs
│   │   │   ├── PhysicsBody2D.hs
│   │   │   ├── PhysicsDirectBodyState.hs
│   │   │   ├── PhysicsDirectSpaceState.hs
│   │   │   ├── PhysicsMaterial.hs
│   │   │   ├── PhysicsServer.hs
│   │   │   ├── PhysicsShapeQueryParameters.hs
│   │   │   ├── PhysicsShapeQueryResult.hs
│   │   │   ├── PinJoint.hs
│   │   │   ├── PinJoint2D.hs
│   │   │   ├── PlaneMesh.hs
│   │   │   ├── PlaneShape.hs
│   │   │   ├── PluginScript.hs
│   │   │   ├── PointMesh.hs
│   │   │   ├── Polygon2D.hs
│   │   │   ├── PolygonPathFinder.hs
│   │   │   ├── Popup.hs
│   │   │   ├── PopupDialog.hs
│   │   │   ├── PopupMenu.hs
│   │   │   ├── PopupPanel.hs
│   │   │   ├── Position2D.hs
│   │   │   ├── Position3D.hs
│   │   │   ├── PrimitiveMesh.hs
│   │   │   ├── PrismMesh.hs
│   │   │   ├── ProceduralSky.hs
│   │   │   ├── ProgressBar.hs
│   │   │   ├── ProjectSettings.hs
│   │   │   ├── ProximityGroup.hs
│   │   │   ├── ProxyTexture.hs
│   │   │   ├── QuadMesh.hs
│   │   │   ├── RandomNumberGenerator.hs
│   │   │   ├── Range.hs
│   │   │   ├── RayCast.hs
│   │   │   ├── RayCast2D.hs
│   │   │   ├── RayShape.hs
│   │   │   ├── RayShape2D.hs
│   │   │   ├── RectangleShape2D.hs
│   │   │   ├── Reference.hs
│   │   │   ├── ReferenceRect.hs
│   │   │   ├── ReflectionProbe.hs
│   │   │   ├── RegEx.hs
│   │   │   ├── RegExMatch.hs
│   │   │   ├── RemoteTransform.hs
│   │   │   ├── RemoteTransform2D.hs
│   │   │   ├── Resource.hs
│   │   │   ├── ResourceFormatLoader.hs
│   │   │   ├── ResourceFormatLoaderCrypto.hs
│   │   │   ├── ResourceFormatSaver.hs
│   │   │   ├── ResourceFormatSaverCrypto.hs
│   │   │   ├── ResourceImporter.hs
│   │   │   ├── ResourceInteractiveLoader.hs
│   │   │   ├── ResourceLoader.hs
│   │   │   ├── ResourcePreloader.hs
│   │   │   ├── ResourceSaver.hs
│   │   │   ├── RichTextEffect.hs
│   │   │   ├── RichTextLabel.hs
│   │   │   ├── RigidBody.hs
│   │   │   ├── RigidBody2D.hs
│   │   │   ├── RootMotionView.hs
│   │   │   ├── SceneState.hs
│   │   │   ├── SceneTree.hs
│   │   │   ├── SceneTreeTimer.hs
│   │   │   ├── Script.hs
│   │   │   ├── ScrollBar.hs
│   │   │   ├── ScrollContainer.hs
│   │   │   ├── SegmentShape2D.hs
│   │   │   ├── Semaphore.hs
│   │   │   ├── Separator.hs
│   │   │   ├── Shader.hs
│   │   │   ├── ShaderMaterial.hs
│   │   │   ├── Shape.hs
│   │   │   ├── Shape2D.hs
│   │   │   ├── ShortCut.hs
│   │   │   ├── Skeleton.hs
│   │   │   ├── Skeleton2D.hs
│   │   │   ├── SkeletonIK.hs
│   │   │   ├── Skin.hs
│   │   │   ├── SkinReference.hs
│   │   │   ├── Sky.hs
│   │   │   ├── Slider.hs
│   │   │   ├── SliderJoint.hs
│   │   │   ├── SoftBody.hs
│   │   │   ├── Spatial.hs
│   │   │   ├── SpatialGizmo.hs
│   │   │   ├── SpatialMaterial.hs
│   │   │   ├── SpatialVelocityTracker.hs
│   │   │   ├── SphereMesh.hs
│   │   │   ├── SphereShape.hs
│   │   │   ├── SpinBox.hs
│   │   │   ├── SplitContainer.hs
│   │   │   ├── SpotLight.hs
│   │   │   ├── SpringArm.hs
│   │   │   ├── Sprite.hs
│   │   │   ├── Sprite3D.hs
│   │   │   ├── SpriteBase3D.hs
│   │   │   ├── SpriteFrames.hs
│   │   │   ├── StaticBody.hs
│   │   │   ├── StaticBody2D.hs
│   │   │   ├── StreamPeer.hs
│   │   │   ├── StreamPeerBuffer.hs
│   │   │   ├── StreamPeerGDNative.hs
│   │   │   ├── StreamPeerSSL.hs
│   │   │   ├── StreamPeerTCP.hs
│   │   │   ├── StreamTexture.hs
│   │   │   ├── StyleBox.hs
│   │   │   ├── StyleBoxEmpty.hs
│   │   │   ├── StyleBoxFlat.hs
│   │   │   ├── StyleBoxLine.hs
│   │   │   ├── StyleBoxTexture.hs
│   │   │   ├── SurfaceTool.hs
│   │   │   ├── TCP_Server.hs
│   │   │   ├── TabContainer.hs
│   │   │   ├── Tabs.hs
│   │   │   ├── TextEdit.hs
│   │   │   ├── TextFile.hs
│   │   │   ├── Texture.hs
│   │   │   ├── Texture3D.hs
│   │   │   ├── TextureArray.hs
│   │   │   ├── TextureButton.hs
│   │   │   ├── TextureLayered.hs
│   │   │   ├── TextureProgress.hs
│   │   │   ├── TextureRect.hs
│   │   │   ├── Theme.hs
│   │   │   ├── Thread.hs
│   │   │   ├── TileMap.hs
│   │   │   ├── TileSet.hs
│   │   │   ├── Timer.hs
│   │   │   ├── ToolButton.hs
│   │   │   ├── TouchScreenButton.hs
│   │   │   ├── Translation.hs
│   │   │   ├── TranslationServer.hs
│   │   │   ├── Tree.hs
│   │   │   ├── TreeItem.hs
│   │   │   ├── TriangleMesh.hs
│   │   │   ├── Tween.hs
│   │   │   ├── UPNP.hs
│   │   │   ├── UPNPDevice.hs
│   │   │   ├── UndoRedo.hs
│   │   │   ├── VBoxContainer.hs
│   │   │   ├── VScrollBar.hs
│   │   │   ├── VSeparator.hs
│   │   │   ├── VSlider.hs
│   │   │   ├── VSplitContainer.hs
│   │   │   ├── VehicleBody.hs
│   │   │   ├── VehicleWheel.hs
│   │   │   ├── VideoPlayer.hs
│   │   │   ├── VideoStream.hs
│   │   │   ├── VideoStreamGDNative.hs
│   │   │   ├── VideoStreamTheora.hs
│   │   │   ├── VideoStreamWebm.hs
│   │   │   ├── Viewport.hs
│   │   │   ├── ViewportContainer.hs
│   │   │   ├── ViewportTexture.hs
│   │   │   ├── VisibilityEnabler.hs
│   │   │   ├── VisibilityEnabler2D.hs
│   │   │   ├── VisibilityNotifier.hs
│   │   │   ├── VisibilityNotifier2D.hs
│   │   │   ├── VisualInstance.hs
│   │   │   ├── VisualScript.hs
│   │   │   ├── VisualScriptBasicTypeConstant.hs
│   │   │   ├── VisualScriptBuiltinFunc.hs
│   │   │   ├── VisualScriptClassConstant.hs
│   │   │   ├── VisualScriptComment.hs
│   │   │   ├── VisualScriptComposeArray.hs
│   │   │   ├── VisualScriptCondition.hs
│   │   │   ├── VisualScriptConstant.hs
│   │   │   ├── VisualScriptConstructor.hs
│   │   │   ├── VisualScriptCustomNode.hs
│   │   │   ├── VisualScriptDeconstruct.hs
│   │   │   ├── VisualScriptEmitSignal.hs
│   │   │   ├── VisualScriptEngineSingleton.hs
│   │   │   ├── VisualScriptExpression.hs
│   │   │   ├── VisualScriptFunction.hs
│   │   │   ├── VisualScriptFunctionCall.hs
│   │   │   ├── VisualScriptFunctionState.hs
│   │   │   ├── VisualScriptGlobalConstant.hs
│   │   │   ├── VisualScriptIndexGet.hs
│   │   │   ├── VisualScriptIndexSet.hs
│   │   │   ├── VisualScriptInputAction.hs
│   │   │   ├── VisualScriptIterator.hs
│   │   │   ├── VisualScriptLists.hs
│   │   │   ├── VisualScriptLocalVar.hs
│   │   │   ├── VisualScriptLocalVarSet.hs
│   │   │   ├── VisualScriptMathConstant.hs
│   │   │   ├── VisualScriptNode.hs
│   │   │   ├── VisualScriptOperator.hs
│   │   │   ├── VisualScriptPreload.hs
│   │   │   ├── VisualScriptPropertyGet.hs
│   │   │   ├── VisualScriptPropertySet.hs
│   │   │   ├── VisualScriptResourcePath.hs
│   │   │   ├── VisualScriptReturn.hs
│   │   │   ├── VisualScriptSceneNode.hs
│   │   │   ├── VisualScriptSceneTree.hs
│   │   │   ├── VisualScriptSelect.hs
│   │   │   ├── VisualScriptSelf.hs
│   │   │   ├── VisualScriptSequence.hs
│   │   │   ├── VisualScriptSubCall.hs
│   │   │   ├── VisualScriptSwitch.hs
│   │   │   ├── VisualScriptTypeCast.hs
│   │   │   ├── VisualScriptVariableGet.hs
│   │   │   ├── VisualScriptVariableSet.hs
│   │   │   ├── VisualScriptWhile.hs
│   │   │   ├── VisualScriptYield.hs
│   │   │   ├── VisualScriptYieldSignal.hs
│   │   │   ├── VisualServer.hs
│   │   │   ├── VisualShader.hs
│   │   │   ├── VisualShaderNode.hs
│   │   │   ├── VisualShaderNodeBooleanConstant.hs
│   │   │   ├── VisualShaderNodeBooleanUniform.hs
│   │   │   ├── VisualShaderNodeColorConstant.hs
│   │   │   ├── VisualShaderNodeColorFunc.hs
│   │   │   ├── VisualShaderNodeColorOp.hs
│   │   │   ├── VisualShaderNodeColorUniform.hs
│   │   │   ├── VisualShaderNodeCompare.hs
│   │   │   ├── VisualShaderNodeCubeMap.hs
│   │   │   ├── VisualShaderNodeCubeMapUniform.hs
│   │   │   ├── VisualShaderNodeCustom.hs
│   │   │   ├── VisualShaderNodeDeterminant.hs
│   │   │   ├── VisualShaderNodeDotProduct.hs
│   │   │   ├── VisualShaderNodeExpression.hs
│   │   │   ├── VisualShaderNodeFaceForward.hs
│   │   │   ├── VisualShaderNodeFresnel.hs
│   │   │   ├── VisualShaderNodeGlobalExpression.hs
│   │   │   ├── VisualShaderNodeGroupBase.hs
│   │   │   ├── VisualShaderNodeIf.hs
│   │   │   ├── VisualShaderNodeInput.hs
│   │   │   ├── VisualShaderNodeIs.hs
│   │   │   ├── VisualShaderNodeOuterProduct.hs
│   │   │   ├── VisualShaderNodeOutput.hs
│   │   │   ├── VisualShaderNodeScalarClamp.hs
│   │   │   ├── VisualShaderNodeScalarConstant.hs
│   │   │   ├── VisualShaderNodeScalarDerivativeFunc.hs
│   │   │   ├── VisualShaderNodeScalarFunc.hs
│   │   │   ├── VisualShaderNodeScalarInterp.hs
│   │   │   ├── VisualShaderNodeScalarOp.hs
│   │   │   ├── VisualShaderNodeScalarSmoothStep.hs
│   │   │   ├── VisualShaderNodeScalarSwitch.hs
│   │   │   ├── VisualShaderNodeScalarUniform.hs
│   │   │   ├── VisualShaderNodeSwitch.hs
│   │   │   ├── VisualShaderNodeTexture.hs
│   │   │   ├── VisualShaderNodeTextureUniform.hs
│   │   │   ├── VisualShaderNodeTextureUniformTriplanar.hs
│   │   │   ├── VisualShaderNodeTransformCompose.hs
│   │   │   ├── VisualShaderNodeTransformConstant.hs
│   │   │   ├── VisualShaderNodeTransformDecompose.hs
│   │   │   ├── VisualShaderNodeTransformFunc.hs
│   │   │   ├── VisualShaderNodeTransformMult.hs
│   │   │   ├── VisualShaderNodeTransformUniform.hs
│   │   │   ├── VisualShaderNodeTransformVecMult.hs
│   │   │   ├── VisualShaderNodeUniform.hs
│   │   │   ├── VisualShaderNodeVec3Constant.hs
│   │   │   ├── VisualShaderNodeVec3Uniform.hs
│   │   │   ├── VisualShaderNodeVectorClamp.hs
│   │   │   ├── VisualShaderNodeVectorCompose.hs
│   │   │   ├── VisualShaderNodeVectorDecompose.hs
│   │   │   ├── VisualShaderNodeVectorDerivativeFunc.hs
│   │   │   ├── VisualShaderNodeVectorDistance.hs
│   │   │   ├── VisualShaderNodeVectorFunc.hs
│   │   │   ├── VisualShaderNodeVectorInterp.hs
│   │   │   ├── VisualShaderNodeVectorLen.hs
│   │   │   ├── VisualShaderNodeVectorOp.hs
│   │   │   ├── VisualShaderNodeVectorRefract.hs
│   │   │   ├── VisualShaderNodeVectorScalarMix.hs
│   │   │   ├── VisualShaderNodeVectorScalarSmoothStep.hs
│   │   │   ├── VisualShaderNodeVectorScalarStep.hs
│   │   │   ├── VisualShaderNodeVectorSmoothStep.hs
│   │   │   ├── WeakRef.hs
│   │   │   ├── WebRTCDataChannel.hs
│   │   │   ├── WebRTCDataChannelGDNative.hs
│   │   │   ├── WebRTCMultiplayer.hs
│   │   │   ├── WebRTCPeerConnection.hs
│   │   │   ├── WebRTCPeerConnectionGDNative.hs
│   │   │   ├── WebSocketClient.hs
│   │   │   ├── WebSocketMultiplayerPeer.hs
│   │   │   ├── WebSocketPeer.hs
│   │   │   ├── WebSocketServer.hs
│   │   │   ├── WindowDialog.hs
│   │   │   ├── World.hs
│   │   │   ├── World2D.hs
│   │   │   ├── WorldEnvironment.hs
│   │   │   ├── X509Certificate.hs
│   │   │   ├── XMLParser.hs
│   │   │   └── YSort.hs
│   │   ├── Gdnative/
│   │   │   ├── Internal/
│   │   │   │   ├── Api.hs
│   │   │   │   ├── Gdnative.chs
│   │   │   │   ├── TH.hs
│   │   │   │   └── Types.hs
│   │   │   └── Internal.hs
│   │   ├── Gdnative.hs
│   │   ├── Internal/
│   │   │   └── Dispatch.hs
│   │   ├── Nativescript.hs
│   │   └── Tools/
│   │       ├── AnimationTrackEditPlugin.hs
│   │       ├── EditorExportPlugin.hs
│   │       ├── EditorFeatureProfile.hs
│   │       ├── EditorFileDialog.hs
│   │       ├── EditorFileSystem.hs
│   │       ├── EditorFileSystemDirectory.hs
│   │       ├── EditorImportPlugin.hs
│   │       ├── EditorInspector.hs
│   │       ├── EditorInspectorPlugin.hs
│   │       ├── EditorInterface.hs
│   │       ├── EditorNavigationMeshGenerator.hs
│   │       ├── EditorPlugin.hs
│   │       ├── EditorProperty.hs
│   │       ├── EditorResourceConversionPlugin.hs
│   │       ├── EditorResourcePreview.hs
│   │       ├── EditorResourcePreviewGenerator.hs
│   │       ├── EditorSceneImporter.hs
│   │       ├── EditorSceneImporterAssimp.hs
│   │       ├── EditorScenePostImport.hs
│   │       ├── EditorScript.hs
│   │       ├── EditorSelection.hs
│   │       ├── EditorSettings.hs
│   │       ├── EditorSpatialGizmo.hs
│   │       ├── EditorSpatialGizmoPlugin.hs
│   │       ├── EditorSpinSlider.hs
│   │       ├── EditorVCSInterface.hs
│   │       ├── ScriptCreateDialog.hs
│   │       ├── ScriptEditor.hs
│   │       └── VisualScriptEditor.hs
│   └── Godot.hs
├── src-generate/
│   ├── Generate.hs
│   ├── Spec.hs
│   ├── Types/
│   │   └── Internal.hs
│   └── Types.hs
├── stack-shell.nix
├── stack.yaml
├── template/
│   ├── README.md
│   ├── demo/
│   │   ├── Makefile
│   │   ├── ffi/
│   │   │   └── cbits/
│   │   │       └── flib.c
│   │   └── game/
│   │       ├── Main.gdns
│   │       ├── lib/
│   │       │   └── libdemo.gdnlib
│   │       └── project.godot
│   ├── godot-haskell.hsfiles
│   ├── mkdemo.sh
│   └── update-template.sh
└── update-nixpkgs.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
dist*
*.hi
*.o
.hsenv*
cabal-dev/
.stack-work/
.cabal-sandbox
cabal.sandbox.config
.DS_Store
*.dyn_o
*.dyn_hi
app/*.cpp
src/**/*.cpp
src/**/*.c
*.so
.ghc*
#*
.#*

doc/build/

# osvr_server
lighthousedb.json
lhr-*/

# emacs TAG file
TAGS


================================================
FILE: .gitmodules
================================================
[submodule "godot_headers"]
	path = godot_headers
	url = https://github.com/GodotNativeTools/godot_headers/
[submodule "haskell-src-exts-qq"]
	path = haskell-src-exts-qq
	url = https://github.com/KaneTW/haskell-src-exts-qq
[submodule "haskell-src-exts-sc"]
	path = haskell-src-exts-sc
	url = https://github.com/achirkin/haskell-src-exts-sc


================================================
FILE: .hlint.yaml
================================================
- ignore: { name: "Use camelCase" }
- ignore: { name: "Use newtype instead of data" }


================================================
FILE: .travis.yml
================================================
# https://docs.haskellstack.org/en/stable/travis_ci/

sudo: false
dist: bionic
language: generic
addons:
  apt:
    update: true

cache:
  directories:
  - $HOME/.stack
  - $TRAVIS_BUILD_DIR/.stack-work

before_install:
  - mkdir -p ~/.local/bin
  - export PATH=$HOME/.local/bin:$PATH
  - travis_retry curl -L https://get.haskellstack.org/stable/linux-x86_64.tar.gz | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'

install:
  - git submodule update --init --recursive
  - stack build
  - stack test


================================================
FILE: .vscode/tasks.json
================================================

{
  // Automatically created by phoityne-vscode extension.

  "version": "2.0.0",
  "presentation": {
    "reveal": "always",
    "panel": "new"
  },
  "tasks": [
    {
      // F7
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "label": "haskell build",
      "type": "shell",
      //"command": "cabal configure && cabal build"
      "command": "stack build"
    },
    {
      // F6
      "group": "build",
      "type": "shell",
      "label": "haskell clean & build",
      //"command": "cabal clean && cabal configure && cabal build"
      "command": "stack clean && stack build"
      //"command": "stack clean ; stack build"  // for powershell
    },
    {
      // F8
      "group": {
        "kind": "test",
        "isDefault": true
      },
      "type": "shell",
      "label": "haskell test",
      //"command": "cabal test"
      "command": "stack test"
    },
    {
      // F6
      "isBackground": true,
      "type": "shell",
      "label": "haskell watch",
      "command": "stack build --test --no-run-tests --file-watch"
    }
  ]
}


================================================
FILE: LICENSE
================================================
Copyright David Kraeutmann (c) 2018

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * Neither the name of David Kraeutmann nor the names of other
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

================================================
FILE: README.md
================================================
# godot-haskell

[![Build Status](https://travis-ci.org/SimulaVR/godot-haskell.svg?branch=master)](https://travis-ci.org/SimulaVR/godot-haskell)

Haskell bindings for the Godot game engine.

* Low-level (GDNative) in Godot.Gdnative
* Nativescript (binding classes/methods/etc) in Godot.Nativescript
* High-level (classes generated from the API ) in Godot.Api
* Access methods through Godot.Core

## Getting started with the examples

The easiest way to get started is to have a look at the demos included in the
[examples](https://github.com/SimulaVR/godot-haskell/tree/master/examples)
directory. First check out ["Dodge the
Creeps!"](https://github.com/SimulaVR/godot-haskell/tree/master/examples/dodge-the-creeps),
your first game from the [Godot
documentation](https://docs.godotengine.org/en/3.1/getting_started/step_by_step/your_first_game.html). Following
along with the documentation and the code should make everything understandable.

To build:
```bash
git clone --recursive https://github.com/SimulaVR/godot-haskell
stack install godot-haskell:exe:godot-haskell-project-generator
cd godot-haskell/examples/dodge-the-creeps
make
```

To make changes to the game, in two different terminals:
```bash
make stack-watch
make project-watch
```

The first command will constantly build Haskell code and copy the shared library
into the Godot project, demo. The second command will constantly scan the Godot
project and build Haskell code out of it.

Load up the game by importing `game/project.godot` into the editor, which you
can do from the commandline with `godot game/project.godot`. To run the game in
the editor press F5, stop it with F8.

### Understanding the examples

There are two parts to every project. `examples/dodge-the-creeps/game` which is
the Godot project and `examples/dodge-the-creeps/src` which are the Haskell
sources. When you run `cd examples/dodge-the-creeps && make stack` to build the
demo, it builds the project locally with `stack build` and then does a `cp` to
copy the resulting shared library into the right place in
`examples/dodge-the-creeps/game`. This way Godot will pick it up. If you just do
a `stack build` without copying, your shared library will never update and Godot
will run the old code.

You must regenerate `examples/dodge-the-creeps/src/Project` any time you modify
the Godot project. This directory contains the Godot project mirrored into
Haskell, just like @Servant@ provides you with API safety by declaring APIs in
Haskell. When you change the name of a node in Godot, this will update a Haskell
class instance, which will lead to a type error in your project. You can do this
with `stack exec godot-haskell-parse-game game src` which will watch your
project for changes.

## Known issues & inconveniences

* Script variables only appear in the editor when you reload it.
* No type safety for call and call_deferred.
* Every time you add a new node which needs a native script you need to manually
  select the library. It's tedious right now. This is the procedure for adding a
  new node backed by Haskell code: create the node, right click it, attach a
  script, select nativescript, the script will open in the editor, in the
  inspector find the Library subheading under NativeScript, click [empty], pick
  Load, the file picker will open, open lib, and select libmyproject.dnlib or
  whatever you've renamed the library to. That's it. Don't edit the empty file
  that's been opened. Now in Haskell, you can create a class with the same name
  as the Godot one and that inherits from the same type. See the demo. There is
  a ticket in Godot to automate this process :(

## Setting up your own project.

It's best to start with one of the existing examples, make a copy, and rename
the project. If you want to start another project use the stack template
`template/godot-haskell.hsroots` Alternatively, fetch it directly from git:

```bash
stack new myproject https://raw.githubusercontent.com/SimulaVR/godot-haskell/master/template/godot-haskell.hsfiles
```

## Changing Godot versions

You will need to regenerate the bindings if you switch Godot versions. At
present, these are generated for the version that corresponds to the
godot_headers submodule included here. This was 3.1 at the time of writing.

To regenerate bindings:

* Replace godot_headers with a version that corresponds to your
  install. Instructions are included there, but that generally means either
  checking out the corresponding files or rebuilding Godot.
* Check out a copy of the godot repo and make sure you're on the commit
  corresponding to your version of godot. You don't need to build this, but you
  probably will anyway. We need it because documentation files are not included
  in the api.json file found in godot_headers.
* Summarize the documentation xml files into a json file:

```bash
# Prerequisite
sudo apt-get install jq libcurl4-gnutls-dev # Or equivalent on you OS/Distro
cabal install xml-to-json

# Generate the JSON
xml-to-json godot-install-directory/doc/classes/*.xml | jq -n '[inputs]' &> godot_doc_classes.json
```

* Build the bindings themselves:

```bash
cd classgen
stack build
rm ../src/Godot/Core/* ../src/Godot/Tools/*
stack exec godot-haskell-classgen -- ../godot_headers/api.json ../godot_doc_classes.json ../
```

That's it! The rest of the bindings are fairly lightweight with few
dependencies, so you shouldn't see much breakage in the rest of the package.

If you want to get an idea of what the Haskell libraries are doing, set the
environment variable `HS_GODOT_DEBUG`.

## Questions

The primary method of contact is the SimulaVR [Discord server](https://discord.gg/V2NgzZt).
Mirrors are available at [![Gitter](https://badges.gitter.im/SimulaVR/Simula.svg)](https://gitter.im/SimulaVR/Simula?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) and in the SimulaVR channel at Matrix.

## Docs

Most of the API is documented but the lowest-level bindings, like GDNative
functions don't have documentation. They are quite intuitive to use though.


================================================
FILE: Setup.hs
================================================
import Distribution.Simple
main = defaultMain


================================================
FILE: cbits/util.h
================================================
#ifndef GODOT_HASKELL_UTIL_H__
#define GODOT_HASKELL_UTIL_H__

#include <gdnative/gdnative.h>

#endif /* GODOT_HASKELL_UTIL_H__ */


================================================
FILE: classgen/README.md
================================================
Generate bindings to the Godot API.

See the godot-haskell README.md for instructions on use


================================================
FILE: classgen/app-classgen/Main.hs
================================================
import Classgen.Module
import Classgen.Spec
import Control.Lens
import Control.Monad.State
import Data.Maybe (mapMaybe)
import Data.Aeson
import qualified Data.ByteString.Lazy as BL
import qualified Data.HashMap.Strict as HM
import Language.Haskell.Exts
import Language.Haskell.Exts.SimpleComments
import System.Directory
import System.Environment
import System.Exit
import System.FilePath
import Control.Applicative
import qualified Classgen.Docs as D
import qualified Data.HashMap.Strict as H
import qualified Data.Text as T

main :: IO ()
main = do
  args <- getArgs
  when (length args /= 3) $ do
    putStrLn "See the godot-haskell README.md for instructions"
    putStrLn "godot-haskell-classgen <api.json> <godot_doc_classes.json> <godot-haskell-root>"
    exitFailure
  api <- BL.readFile (args !! 0)
  let decodeErr x = either error id (eitherDecode x)
  let (Just classes) = decodeErr api :: Maybe GodotClasses
  doc <- BL.readFile (args !! 1)
  let (Just docs) = decodeErr doc :: Maybe D.GodotDocs
  let godotHaskellRootDir = args !! 2
  let docTable = D.toTable docs
  let state = execState (mapM_ (\cls -> addClass cls (H.lookup (cls ^. Classgen.Spec.name) docTable
                                                     <|> (T.stripPrefix "Godot_" (cls ^. Classgen.Spec.name)
                                                          >>= \r -> H.lookup r docTable)
                                                     <|> (T.stripPrefix "Godot" (cls ^. Classgen.Spec.name)
                                                          >>= \r -> H.lookup r docTable)
                                                     <|> (T.stripPrefix "_"  (cls ^. Classgen.Spec.name)
                                                          >>= \r -> H.lookup r docTable)
                                                     <|> (H.lookup  ("_" <> (cls ^. Classgen.Spec.name)) docTable)
                                                    ) classes) classes)
                        (ClassgenState mempty mempty mempty)
  writeModule godotHaskellRootDir $ godotApiTypes (state ^. tyDecls)
  mapM_ (writeModule godotHaskellRootDir) (HM.elems (state ^. modules))
  where
    godotApiTypes decls   = Module Nothing (Just
                                            $ ModuleHead Nothing (ModuleName Nothing "Godot.Api.Types") Nothing
                                            $ Just (classExports decls))
                            [LanguagePragma Nothing [Ident Nothing "DerivingStrategies"
                                                    ,Ident Nothing "GeneralizedNewtypeDeriving"
                                                    ,Ident Nothing "TypeFamilies"
                                                    ,Ident Nothing "TemplateHaskell"]]
                            classImports
                            (decls ++ mapMaybe fromNewtypeDerivingBase decls)
    classExports decls   = ExportSpecList Nothing $ tcHasBaseClass : mapMaybe fromNewtypeOnly decls
    tcHasBaseClass       = fmap (\_ -> Nothing) $ EThingWith () (EWildcard () 0) (UnQual () (Ident () "HasBaseClass")) []
    fromNewtypeOnly decl = case decl of
       DataDecl _ (NewType _) _ (DHead _ (Ident Nothing ntName)) _ _ ->
         Just $ EThingWith Nothing (EWildcard Nothing 0) (UnQual Nothing (Ident Nothing ntName)) []
       _ ->
         Nothing
    fromNewtypeDerivingBase decl = case decl of
       DataDecl _ (NewType _) _ (DHead _ (Ident Nothing ntName)) _ _ ->
         Just $ SpliceDecl Nothing (App Nothing (Var Nothing (UnQual Nothing (Ident Nothing "deriveBase")))
                                                 (TypQuote Nothing (UnQual Nothing (Ident Nothing ntName))))
       _ ->
         Nothing
    classImports = map (\n -> ImportDecl Nothing (ModuleName Nothing n) False False False Nothing Nothing Nothing)
      [ "Data.Coerce", "Foreign.C", "Godot.Internal.Dispatch", "Godot.Gdnative.Internal"]

writeModule :: FilePath -> Module (Maybe CodeComment) -> IO ()
writeModule godotHaskellRootDir mdl@(Module _ (Just (ModuleHead _ (ModuleName Nothing name) _ _)) _ _ _) = do
  let filepath = godotHaskellRootDir </> "src/" ++ map replaceDot name ++ ".hs"
  -- let out = prettyPrint mdl
  let out = uncurry exactPrint (ppWithComments mdl)
  createDirectoryIfMissing True (takeDirectory filepath)
  writeFile filepath out
  where
    replaceDot '.' = '/'
    replaceDot c = c


================================================
FILE: classgen/default.nix
================================================
{ mkDerivation, aeson, base, bytestring, c2hs, casing, containers
, directory, filepath, hpack
, lens, mtl, template-haskell, text, unordered-containers
, vector , stdenv, syb, callPackage, haskell, haskellPackages, fetchFromGitHub
}:
  let haskell-src-exts-custom = haskell.lib.dontCheck (haskellPackages.callPackage
        ({ mkDerivation, array, base, containers, directory, filepath
        , ghc-prim, happy, mtl, pretty, pretty-show, smallcheck, stdenv
        , tasty, tasty-golden, tasty-smallcheck
        }:
        mkDerivation {
          pname = "haskell-src-exts";
          version = "1.23.0";
          sha256 = "09048bhv7ajfsnjlzaz445yb65n2pc4l3yn7nmmrnkdy1f0gn2cm";
          libraryHaskellDepends = [ array base ghc-prim pretty ];
          libraryToolDepends = [ happy ];
          testHaskellDepends = [
            base containers directory filepath mtl pretty-show smallcheck tasty
            tasty-golden tasty-smallcheck
          ];
          doCheck = false;
          description = "Manipulating Haskell source: abstract syntax, lexer, parser, and pretty-printer";
          license = stdenv.lib.licenses.bsd3;
          hydraPlatforms = stdenv.lib.platforms.none;
       }) {});

      haskell-src-exts-qq = haskellPackages.callPackage (
        { mkDerivation, base, hspec, stdenv, syb, template-haskell
        }:
        mkDerivation {
          pname = "haskell-src-exts-qq";
          version = "0.8";
          src = fetchFromGitHub {
            owner = "KaneTW";
            repo = "haskell-src-exts-qq";
            rev = "a2d9071c9d6a627a253edfaaa64b6b67c9da3534";
            sha256 = "1cvk90zi16m3nnz52gxim9b8sm17356jrp756y95is6ky13l2h60";
          };
          libraryHaskellDepends = [
            base haskell-src-exts-custom haskell-src-meta-custom syb template-haskell
          ];
          testHaskellDepends = [ base haskell-src-exts-custom hspec ];
          description = "A quasiquoter for haskell-src-exts";
          license = stdenv.lib.licenses.bsd3;
          }) { };

  haskell-src-meta-custom = haskell.lib.dontCheck (haskellPackages.callPackage
        ({ mkDerivation, base, HUnit, pretty, stdenv, syb
        , template-haskell, test-framework, test-framework-hunit
        , th-orphans
        }:
        mkDerivation {
          pname = "haskell-src-meta";
          version = "0.8.5";
          sha256 = "1csqp3n7330rhia9msyw34z7qwwj64gdy5qlv8w4jbm49dap24ik";
          revision = "1";
          editedCabalFile = "00znr8mrlbyn0n1bw4c82rv82pq5ngkk7kw9cgk13pghf93hwwv7";
          libraryHaskellDepends = [
            base haskell-src-exts-custom pretty syb template-haskell th-orphans
          ];
          description = "Parse source to template-haskell abstract syntax";
          license = stdenv.lib.licenses.bsd3;
        }) {});
in 
mkDerivation {
  pname = "godot-haskell-classgen";
  version = "0.1.0.0";
  src = ./.;
  isLibrary = true;
  isExecutable = true;
  libraryHaskellDepends = [
    aeson base bytestring casing containers
    haskell-src-exts-qq lens mtl template-haskell text
    unordered-containers vector
  ];
  libraryToolDepends = [ c2hs hpack ];
  executableHaskellDepends = [
    aeson base bytestring casing containers directory filepath
    lens mtl template-haskell text
    unordered-containers vector
  ];
  executableToolDepends = [ c2hs ];
  prePatch = "hpack";
  homepage = "https://github.com/KaneTW/godot-haskell#readme";
  license = stdenv.lib.licenses.bsd3;
}


================================================
FILE: classgen/godot-haskell-classgen.cabal
================================================
cabal-version: 1.12

-- This file has been generated from package.yaml by hpack version 0.31.1.
--
-- see: https://github.com/sol/hpack
--
-- hash: 35a149339951f4c097aab1ae9ef0e3952109a1273b725ce775c4483b80c67fb6

name:           godot-haskell-classgen
version:        0.1.0.0
category:       Web
homepage:       https://github.com/KaneTW/godot-haskell#readme
bug-reports:    https://github.com/KaneTW/godot-haskell/issues
author:         David Kraeutmann
maintainer:     kane@kane.cx
copyright:      2018 David Kraeutmann
license:        BSD3
build-type:     Simple
extra-source-files:
    README.md

source-repository head
  type: git
  location: https://github.com/KaneTW/godot-haskell

library
  exposed-modules:
      Classgen.Docs
      Classgen.Module
      Classgen.Spec
      Classgen.Utils
  other-modules:
      Paths_godot_haskell_classgen
  hs-source-dirs:
      src-classgen
  default-extensions: FlexibleContexts FlexibleInstances ScopedTypeVariables TypeApplications StandaloneDeriving DerivingStrategies DefaultSignatures MultiParamTypeClasses FunctionalDependencies TypeFamilies TemplateHaskell TypeOperators TypeInType QuasiQuotes OverloadedStrings PatternSynonyms GeneralizedNewtypeDeriving
  include-dirs:
      godot_headers
      cbits
  build-tools:
      c2hs
  build-depends:
      aeson
    , base
    , bytestring
    , casing
    , containers
    , haskell-src-exts
    , haskell-src-exts-qq
    , haskell-src-exts-sc
    , lens
    , mtl
    , template-haskell
    , text
    , unordered-containers
    , vector
  default-language: Haskell2010

executable godot-haskell-classgen
  main-is: Main.hs
  other-modules:
      Paths_godot_haskell_classgen
  hs-source-dirs:
      app-classgen
  default-extensions: FlexibleContexts FlexibleInstances ScopedTypeVariables TypeApplications StandaloneDeriving DerivingStrategies DefaultSignatures MultiParamTypeClasses FunctionalDependencies TypeFamilies TemplateHaskell TypeOperators TypeInType QuasiQuotes OverloadedStrings PatternSynonyms GeneralizedNewtypeDeriving
  include-dirs:
      godot_headers
      cbits
  build-tools:
      c2hs
  build-depends:
      aeson
    , base
    , bytestring
    , casing
    , containers
    , directory
    , filepath
    , godot-haskell-classgen
    , haskell-src-exts
    , haskell-src-exts-sc
    , lens
    , mtl
    , template-haskell
    , text
    , unordered-containers
    , vector
  default-language: Haskell2010


================================================
FILE: classgen/package.yaml
================================================
name: godot-haskell-classgen
version: '0.1.0.0'
category: Web
author: David Kraeutmann
maintainer: kane@kane.cx
copyright: 2018 David Kraeutmann
license: BSD3
github: KaneTW/godot-haskell
extra-source-files:
- README.md

dependencies:
- base
- aeson
- bytestring
- template-haskell
- lens
- text
- casing
- vector
- containers
- unordered-containers
- mtl

build-tools:
- c2hs

include-dirs:
- godot_headers
- cbits

default-extensions:
- FlexibleContexts
- FlexibleInstances
- ScopedTypeVariables
- TypeApplications
- StandaloneDeriving
- DerivingStrategies
- DefaultSignatures
- MultiParamTypeClasses
- FunctionalDependencies
- TypeFamilies
- TemplateHaskell
- TypeOperators
- TypeInType
- QuasiQuotes
- OverloadedStrings
- PatternSynonyms
- GeneralizedNewtypeDeriving

library:
  source-dirs: src-classgen
  dependencies:
  - haskell-src-exts
  - haskell-src-exts-qq
  - haskell-src-exts-sc

executables:
  godot-haskell-classgen:
    main: Main.hs
    source-dirs: app-classgen
    dependencies:
      - godot-haskell-classgen
      - haskell-src-exts
      - haskell-src-exts-sc
      - directory
      - filepath



================================================
FILE: classgen/release.nix
================================================
let
  pkgs = import <nixpkgs> { };
in
  pkgs.haskellPackages.callPackage ./default.nix { }


================================================
FILE: classgen/src-classgen/Classgen/Docs.hs
================================================
{-# LANGUAGE TemplateHaskell, GeneralizedNewtypeDeriving, OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Classgen.Docs where

import Control.Applicative
import Control.Lens

import Data.Aeson
import Data.Aeson.TH
import Data.Monoid
import Data.Text (Text)
import qualified Data.Text as T
import Data.Vector (Vector)
import qualified Data.Vector as V
import Data.HashMap.Strict (HashMap)
import qualified Data.Set as S
import qualified Data.ByteString.Lazy as BL
import qualified Data.HashMap.Strict as H

import Text.Casing
import Classgen.Utils

-- | One of the two values that has been parsed from JSON
data AlternativeJSON a b
  = FirstJSON a
  | SecondJSON b
  deriving (Eq, Ord, Show)

instance (FromJSON a, FromJSON b) => FromJSON (AlternativeJSON a b) where
  parseJSON v = FirstJSON <$> parseJSON v <|> SecondJSON <$> parseJSON v

alternative1 :: AlternativeJSON a b -> a -> a
alternative1 (FirstJSON a) _ = a
alternative1 _             a = a

alt1 :: AlternativeJSON a b -> Maybe a
alt1 (FirstJSON a) = Just a
alt1 _ = Nothing

type GodotDocTable = HashMap Text GodotDocClass

type GodotDocs = Vector GodotDoc

newtype Ref a = Ref Text
  deriving (Show, Eq, FromJSON, ToJSON)

data GPrimType = VoidType | BoolType | IntType | FloatType
  deriving (Show, Eq)

instance FromJSON GPrimType where
  parseJSON = withText "primitive type" $ \t ->
    case t of
      "void" -> pure VoidType
      "bool" -> pure BoolType
      "int" -> pure IntType
      "float" -> pure FloatType
      _ -> fail $ "Unknown type" <> T.unpack t

data GType
  = PrimitiveType !GPrimType
  | CoreType !Text
  | CustomType !Text
  | EnumType !Text
  deriving (Show, Eq)

isCoreType t = t `S.member` S.fromList 
      [ "AABB",
        "Array",
        "Basis",
        "Color",
        "Dictionary",
        "GodotError",
        "NodePath",
        "Plane",
        "PoolByteArray",
        "PoolIntArray",
        "PoolRealArray",
        "PoolStringArray",
        "PoolVector2Array",
        "PoolVector3Array",
        "PoolColorArray",
        "Object",
        "Quat",
        "Rect2",
        "RID",
        "String",
        "Transform",
        "Transform2D",
        "Variant",
        "Vector2",
        "Vector3" ]

instance FromJSON GType where
  parseJSON v = PrimitiveType <$> parseJSON v
                <|> withText "type" (\t ->
                  if isCoreType t
                    then pure $ CoreType t
                    else if "enum." `T.isPrefixOf` t
                         then pure $ EnumType t
                         else pure $ CustomType t) v

data GodotDoc = GodotDoc {
  _gdClass :: !GodotDocClass
  } deriving (Show, Eq)

instance FromJSON GodotDoc where
  parseJSON (Object x) = GodotDoc <$> x .: "class"
  parseJSON _ = fail "Expected an Object"

data OptionalArray a = OptionalArray { unOption :: Vector a }
  deriving (Show, Eq)

instance FromJSON a => FromJSON (OptionalArray a) where
  parseJSON x@(Array _) = OptionalArray <$> parseJSON x
  parseJSON x = OptionalArray . V.singleton <$> parseJSON x

data GodotDocClass = GodotDocClass
  { _gdName :: !Text
  , _gdVersion :: !Text
  , _gdBrief_description :: !(AlternativeJSON Text Object)
  , _gdDescription ::  !(AlternativeJSON Text Object)
  , _gdCategory :: !(Maybe Text)
  , _gdInherits :: !(Maybe Text)
  , _gdMembers :: !(Maybe (HashMap Text (OptionalArray GodotProperty)))
  , _gdConstants :: !(HashMap Text (OptionalArray GodotConstant))
  , _gdSignals :: !(Maybe (HashMap Text (OptionalArray GodotSignal)))
  , _gdMethods :: !(HashMap Text (OptionalArray GodotMethod))
  } deriving (Show, Eq)

data GodotProperty = GodotProperty
  { _gpName :: !Text
  , _gcType :: !GType
  , _gcGetter :: !Text
  , _gcSetter :: !Text
  , _gcValue :: !(Maybe Text)
  } deriving (Show, Eq)

data GodotConstant = GodotConstant
  { _goName :: !Text
  , _goValue :: !Text
  , _goEnum :: !(Maybe Text)
  } deriving (Show, Eq)

data GodotSignal = GodotSignal
  { _gsName :: !Text
  , _gsDescription :: !(AlternativeJSON Text Object)
  , _gsArgument :: !(Maybe (OptionalArray GodotArgument))
  } deriving (Show, Eq)

data GodotArgument = GodotArgument
  { _gaName :: !Text
  , _gaType :: !GType
  , _gaIndex :: !Text
  , _gaDefault_ :: !(Maybe Text)
  } deriving (Show, Eq)

instance FromJSON GodotArgument where
  parseJSON (Object x) = GodotArgument <$> x .: "name" <*> x .: "type" <*> x .: "index" <*> x .:? "default"
  parseJSON _ = fail "Expected an Object"

data GodotMethod = GodotMethod
  { _gmName :: !Text
  , _gmDescription :: !(AlternativeJSON Text Object)
  , _gmReturn :: !(Maybe (HashMap Text GType))
  , _gmArgument :: !(Maybe (OptionalArray GodotArgument))
  } deriving (Show, Eq)

makeLensesWith fixedTypeFields ''GodotDoc
makeLensesWith fixedTypeFields ''GodotDocClass
makeLensesWith fixedTypeFields ''GodotProperty
makeLensesWith fixedTypeFields ''GodotSignal
makeLensesWith fixedTypeFields ''GodotArgument
makeLensesWith fixedTypeFields ''GodotMethod

toTable :: GodotDocs -> GodotDocTable
toTable = V.foldl' (\hm d -> H.insert (d ^. class' . name) (d ^. class') hm) H.empty 

makePrisms ''GType
makePrisms ''GPrimType

concat <$> mapM (deriveFromJSON defaultOptions { fieldLabelModifier = quietSnake . drop 3, omitNothingFields = True })
  [ ''GodotDocClass
  , ''GodotProperty
  , ''GodotConstant
  , ''GodotSignal
  , ''GodotMethod ]

convertDoc = T.replace "]" "@" . T.replace "[" "@"
           . T.replace "[/code]" "@" . T.replace "[code]" "@"
           . T.replace "[/codeblock]" "\n@\n" . T.replace "[codeblock]" "\n@\n"
           . T.replace "[b]" "__" . T.replace "[/b]" "__"
           . T.replace "[constant " "@"
           . T.replace "[member " "@"


================================================
FILE: classgen/src-classgen/Classgen/Module.hs
================================================
{-# LANGUAGE NoMonoLocalBinds, NoMonomorphismRestriction #-}
module Classgen.Module where

import Control.Lens hiding (index)
import Control.Applicative
import Control.Monad.State
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HM
import qualified Data.Vector as V
import Data.Text (Text)
import qualified Data.Text as T
import Data.Set (Set)
import qualified Data.Set as S
import qualified Language.Haskell.Exts as HS
import Language.Haskell.Exts.QQ
import Language.Haskell.Exts.SimpleComments
import Text.Casing
import Classgen.Spec
import qualified Classgen.Docs as D
import Data.Maybe
import Data.List

--TODO add singleton functions

data ClassgenState = ClassgenState
  { _csModules :: !(HashMap Text (HS.Module (Maybe CodeComment)))
  , _csMethods :: !(HashMap Text (Set Text))
  , _csTyDecls :: !([HS.Decl (Maybe CodeComment)])
  } deriving (Show, Eq) 

makeLensesWith abbreviatedFields ''ClassgenState

noComments l = fmap (\_ -> Nothing) l

addClass :: MonadState ClassgenState m => GodotClass -> Maybe D.GodotDocClass -> GodotClasses -> m ()
addClass cls mdoc allClasses = do
  methods <- mkMethods cls mdoc
  properties <- mkProperties cls mdoc
  signals <- mkSignals cls mdoc
  let dataType = if isCoreType (cls ^. name) then [] else mkDataType cls mdoc
  tyDecls <>= dataType
  let classDecls = nub $ (noComments <$> (mkConstants cls ++ mkEnums cls))
                 ++ signals ++ properties ++ methods
  modules %= HM.insert (mangleClass $ cls ^. name) (HS.Module Nothing
                                      (Just $ classModuleHead classDecls)
                                      [HS.LanguagePragma Nothing [HS.Ident Nothing "DerivingStrategies"
                                                                 ,HS.Ident Nothing "GeneralizedNewtypeDeriving"
                                                                 ,HS.Ident Nothing "TypeFamilies"
                                                                 ,HS.Ident Nothing "TypeOperators"
                                                                 ,HS.Ident Nothing "FlexibleContexts"
                                                                 ,HS.Ident Nothing "DataKinds"
                                                                 ,HS.Ident Nothing "MultiParamTypeClasses"]]
                                      (noComments <$> classImports)
                                      classDecls)
  where
    classImports = map (\n -> HS.ImportDecl () (HS.ModuleName () n) False False False Nothing Nothing Nothing)
      ([ "Data.Coerce", "Foreign.C", "Godot.Internal.Dispatch"
       , "qualified Data.Vector as V"
       , "Linear(V2(..),V3(..),M22)", "Data.Colour(withOpacity)", "Data.Colour.SRGB(sRGB)"
       , "System.IO.Unsafe", "Godot.Gdnative.Internal", "Godot.Api.Types"
       ] <> maybe [] (:[]) parentModuleImport)
    classModuleHead decls = HS.ModuleHead Nothing classModuleName Nothing $ Just (classExports decls)
    classModuleName = noComments $ HS.ModuleName () $ "Godot." ++ (pascal $ T.unpack (cls ^. apiType))
      ++ "." ++ (T.unpack $ mangleClass $ cls ^. name)
    parentModuleImport = case (cls ^. baseClass, V.find (\x -> cls ^. baseClass == x ^. name) allClasses) of
                         ("", Nothing) -> Nothing
                         (_, Nothing) -> error "Can't find base class"
                         (_, Just baseCls) -> Just $ "Godot." ++ (pascal $ T.unpack (baseCls ^. apiType))
                                                  ++ "." ++ (T.unpack $ mangleClass $ baseCls ^. name)
                                                  ++ "()"
    classExports decls = HS.ExportSpecList Nothing $
      mapMaybe (\decl -> case decl of
                   HS.TypeSig _ [name] (HS.TyCon _ (HS.Qual _ _ (HS.Ident _ "MethodBind"))) ->
                     Nothing
                   HS.TypeSig _ [name] (HS.TyCon _ (HS.UnQual _ (HS.Ident _ "MethodBind"))) ->
                     Nothing
                   HS.TypeSig _ [name] _ ->
                     Just $ HS.EVar Nothing (HS.Qual Nothing classModuleName name)
                   _ -> Nothing)
      decls

mkProperties :: MonadState ClassgenState m => GodotClass -> Maybe D.GodotDocClass -> m [HS.Decl (Maybe CodeComment)]
mkProperties cls mdoc = concat <$> mapM mkProperty (V.toList $ cls ^. properties)
  where
    mkProperty prop = do
      get <- mkGetter prop
      set <- mkSetter prop
      inst <- mkProp prop
      return (get ++ set ++ [inst])
    indexArg prop = if prop ^. index == -1 then
                 V.empty else
                 V.singleton (GodotArgument "param" (PrimitiveType IntType) Nothing)
    mkGetter prop             = mkMethod cls (GodotMethod (prop ^. getter)
                                              (gty prop) False False True False False False False
                                              (indexArg prop))
                                             (methodDoc (prop ^. getter) mdoc)
    mkSetter prop | T.null (prop ^. setter) = return []
                  | otherwise = mkMethod cls (GodotMethod (prop ^. setter)
                                              (PrimitiveType VoidType) False False False False False False False
                                              (indexArg prop <> V.singleton (GodotArgument (prop ^. name) (gty prop) Nothing)))
                                             (methodDoc (prop ^. setter) mdoc)
    gty prop = case (cls ^. name,prop ^. name) of
                              -- NB These are bugs in api.json
                              ("VisualScriptPropertySet","type_cache") -> CoreType "Dictionary" -- has int
                              ("PhysicsDirectBodyState","transform") -> CoreType "Transform" -- has transform2d
                              ("JSONParseResult","error") -> PrimitiveType IntType -- has Object
                              ("InputEventKey", "echo") -> PrimitiveType BoolType -- has int
                              ("GeometryInstance", "lod_max_distance") -> PrimitiveType FloatType -- has int
                              ("GeometryInstance", "lod_max_hysteresis") -> PrimitiveType FloatType -- has int
                              ("GeometryInstance", "lod_min_distance") -> PrimitiveType FloatType -- has int
                              ("GeometryInstance", "lod_min_hysteresis") -> PrimitiveType FloatType -- has int
                              ("Control", "margin_bottom") -> PrimitiveType FloatType -- has int
                              ("Control", "margin_top") -> PrimitiveType FloatType -- has int
                              ("Control", "margin_left") -> PrimitiveType FloatType -- has int
                              ("Control", "margin_right") -> PrimitiveType FloatType -- has int
                              ("Curve3D", "_data") -> CoreType "Dictionary" -- has int
                              ("Curve2D", "_data") -> CoreType "Dictionary" -- has int
                              ("Curve", "_data") -> CoreType "Array" -- has int
                              ("Polygon2D", "bones") -> CoreType "Array" -- has Bool
                              ("RichTextLabel", "custom_effects") -> CoreType "Array" -- has 17/17:RichTextEffect
                              ("AudioEffectPitchShift", "oversampling") -> PrimitiveType IntType -- has float
                              ("Area2D", "priority") -> PrimitiveType FloatType -- has int
                              ("Area", "priority") -> PrimitiveType FloatType -- has int
                              -- NB These seem to be too specific or generic in api.json
                              ("ARVRServer", "primary_interface") -> CustomType "ARVRInterface" -- has Object
                              ("AnimationTree", "tree_root") -> CustomType "AnimationNode" -- has AnimationRootNode
                              ("Camera2D", "custom_viewport") -> CustomType "Node" -- has Viewport
                              ("CanvasLayer", "custom_viewport") -> CustomType "Node" -- has Viewport
                              ("ConvexPolygonShape", "points") -> CustomType "PoolVector3Array" -- has Array
                              ("ParticlesMaterial","angle_curve") -> CoreType "Texture" -- has CurveTexture
                              ("ParticlesMaterial","angular_velocity_curve") -> CoreType "Texture" -- has CurveTexture
                              ("ParticlesMaterial","anim_offset_curve") -> CoreType "Texture" -- has CurveTexture
                              ("ParticlesMaterial","anim_speed_curve") -> CoreType "Texture" -- has CurveTexture
                              ("ParticlesMaterial","damping_curve") -> CoreType "Texture" -- has CurveTexture
                              ("ParticlesMaterial","hue_variation_curve") -> CoreType "Texture" -- has CurveTexture
                              ("ParticlesMaterial","linear_accel_curve") -> CoreType "Texture" -- has CurveTexture
                              ("ParticlesMaterial","orbit_velocity_curve") -> CoreType "Texture" -- has CurveTexture
                              ("ParticlesMaterial","radial_accel_curve") -> CoreType "Texture" -- has CurveTexture
                              ("ParticlesMaterial","scale_curve") -> CoreType "Texture" -- has CurveTexture
                              ("ParticlesMaterial","tangential_accel_curve") -> CoreType "Texture" -- has CurveTexture
                              ("ParticlesMaterial","color_ramp") -> CoreType "Texture" -- has GradientTexture
                              ("SceneTree","root") -> CoreType "Viewport" -- has Node
                              _ -> prop ^. type'
    mkProp prop = do
      pure $ noComments [dec|instance NodeProperty ((cty)) ((n)) ((ty)) ((ro)) where nodeProperty = ( $get , $set , Nothing) |]
      where cty = clsTy cls
            n = promotedString $ T.unpack $ prop ^. name
            ty = toHsType $ gty prop
            ro = if T.null (prop ^. setter) then
                   HS.TyPromoted () $ HS.PromotedCon () True $ HS.UnQual () $ HS.Ident () "True" else
                   HS.TyPromoted () $ HS.PromotedCon () True $ HS.UnQual () $ HS.Ident () "False"
            setname = toMethodName (prop ^. setter)
            getname = toMethodName (prop ^. getter)
            i :: String = show $ ((prop ^. index)::Int)
            get = if prop ^. index == -1 then
                    [hs|__getname__|] else
                    [hs|wrapIndexedGetter __i__ __getname__|]
            set = if prop ^. index == -1 || T.null (prop ^. setter) then
                    if T.null (prop ^. setter) then
                      [hs|()|] else
                      [hs|wrapDroppingSetter __setname__|]
                        else
                    [hs|wrapIndexedSetter __i__ __setname__|]

godotObjectTy :: HS.Type ()
godotObjectTy = HS.TyCon () $ HS.UnQual () $ HS.Ident () "Object"

sigCon :: HS.Exp ()
sigCon = HS.Con () $ HS.Qual () (HS.ModuleName () $ "Godot.Internal.Dispatch") $ HS.Ident () "Signal"

sigTy :: HS.Type ()
sigTy = HS.TyCon () $ HS.Qual () (HS.ModuleName () $ "Godot.Internal.Dispatch") $ HS.Ident () "Signal"

clsAsName :: GodotClass -> HS.Name ()
clsAsName cls = HS.Ident () (T.unpack $ mangleClass $ cls ^. name)

clsTy :: GodotClass -> HS.Type ()
clsTy = HS.TyCon () . HS.UnQual ()  . clsAsName

nameToTyCon = HS.TyCon () . HS.UnQual () . HS.Ident () . T.unpack

baseClsTy :: GodotClass -> HS.Type ()
baseClsTy cls = nameToTyCon (cls ^. baseClass)

intTy = HS.TyCon () . HS.UnQual () $ HS.name "Int"

promotedString s = HS.TyPromoted () (HS.PromotedString () s s)

promotedList l = HS.TyPromoted () (HS.PromotedList () True l)

mkDataType cls mdoc =
  [ HS.DataDecl (case mdoc of
                   Nothing -> Nothing
                   Just d -> case d ^. D.brief_description of
                              D.FirstJSON x -> preComment (T.unpack $
                                                          D.convertDoc $
                                                          x <> "\n" <> let desc = D.alternative1 (d ^. D.description) ""
                                                                       in case T.stripPrefix x desc of
                                                                            Nothing -> T.strip desc
                                                                            Just r -> r)
                              _ -> Nothing) (HS.NewType Nothing) Nothing 
    (noComments $ HS.DHead () $ clsAsName cls)
    [noComments $ HS.QualConDecl () Nothing Nothing $ HS.ConDecl () (clsAsName cls) [godotObjectTy]]
    [noComments $ HS.Deriving () (Just $ HS.DerivNewtype ()) [asVariantRule]]
  ] ++ if T.null (cls ^. baseClass) then [] else
  [ noComments
    $ [dec| instance HasBaseClass ((cty)) where
        type BaseClass ((cty)) = ((bty))
        super = coerce |] ]
  where
    asVariantRule = HS.IRule () Nothing Nothing $ HS.IHCon () (HS.UnQual () $ HS.Ident () "AsVariant")
    cty = clsTy cls
    bty = baseClsTy cls

mkSignals :: MonadState ClassgenState m => GodotClass -> Maybe D.GodotDocClass -> m [HS.Decl (Maybe CodeComment)]
mkSignals cls mdoc = return $ concatMap mkSignal (V.toList $ cls ^. signals)
  where
    signalDoc :: Text -> Maybe D.GodotDocClass -> Maybe CodeComment
    signalDoc name mdoc = do
      doc <- mdoc
      sigs <- D._gdSignals doc
      ss <- D.unOption <$> HM.lookup (T.pack "signal") sigs
      sdoc <- V.find (\e -> e ^. D.name == name) ss
      d <- D.alt1 $ sdoc ^. D.description
      preComment (T.unpack $ D.convertDoc d)
    argToHsType (GodotArgument _ ty _) = toHsType ty
    mkSignal sig 
      = let sigStr = T.unpack (sig ^. name)
            sigName = HS.Ident () ("sig_" ++ sigStr)
        in [ HS.TypeSig (signalDoc (sig ^. name) mdoc) [noComments $ sigName] (noComments $ HS.TyApp () sigTy (clsTy cls))
           , noComments $ HS.PatBind () (HS.PVar () sigName) (
               HS.UnGuardedRhs () $ HS.App () sigCon $ HS.Lit () $ HS.String () sigStr sigStr
           ) Nothing
           , let cty = clsTy cls
                 args = promotedList $ map argToHsType $ V.toList $ sig ^. arguments
                 st = promotedString sigStr
             in noComments [dec|instance NodeSignal ((cty)) ((st)) ((args))|]
           ]

mkConstants :: GodotClass -> [HS.Decl ()]
mkConstants cls = concatMap mkConstant (HM.toList $ cls ^. constants)
  where
    mkConstant (cname, cval)
      = let constName = HS.Ident () $ T.unpack ("_" <> cname)
        in [ HS.TypeSig ()  [constName] intTy
           , HS.FunBind () [HS.Match ()
                            constName
                            []
                            (HS.UnGuardedRhs () (HS.Lit () (HS.Int () (fromIntegral cval) (show cval))))
                            Nothing]
           ]

mkEnums cls = [] -- TODO Not sure what to do about these

methodDoc :: Text -> Maybe D.GodotDocClass -> Maybe CodeComment
methodDoc name mdoc = do
  doc <- mdoc
  (do
      ms <- D.unOption <$> HM.lookup (T.pack "method") (D._gdMethods doc)
      docm <- V.find (\e -> e ^. D.name == name) ms
      d <- D.alt1 $ docm ^. D.description 
      preComment (T.unpack $ D.convertDoc d))
    <|> (do
            mems <- D.unOption <$> (HM.lookup (T.pack "member") =<< D._gdMembers doc)
            doc <- V.find (\e -> e ^. D.getter == name || e ^. D.setter == name) mems
            d <- doc ^. D.value
            preComment (T.unpack $ D.convertDoc d))

mkMethods :: MonadState ClassgenState m => GodotClass -> Maybe D.GodotDocClass -> m [HS.Decl (Maybe CodeComment)]
mkMethods cls mdoc =
  concat <$> mapM (\m -> mkMethod cls m (methodDoc (m ^. name) mdoc))
             (V.toList $ cls ^. methods)

mkMethod :: MonadState ClassgenState m => GodotClass -> GodotMethod -> Maybe CodeComment -> m [HS.Decl (Maybe CodeComment)]
mkMethod cls method doc = do
  mtds <- use methods
  if (method ^. name) `S.member` (HM.lookupDefault mempty (cls ^. name) mtds)
    then return []
    else do
    methods %= HM.insertWith S.union (mangleClass $ cls ^. name) (S.singleton $ method ^. name)
    when (T.null $ method ^. name) $ error (show cls ++ "\n" ++ show method)
    return $ 
        [ noComments $ HS.InlineSig () False Nothing (HS.UnQual () clsMethodBindName)
        , HS.TypeSig doc [noComments $ clsMethodBindName]
                         (noComments $ HS.TyCon () (HS.UnQual () (HS.Ident () "MethodBind")))
        , noComments $ HS.PatBind () (HS.PVar () clsMethodBindName) clsMethodBindRhs Nothing
        , HS.TypeSig doc [HS.Ident Nothing $ methodName]
          (noComments [ty|(((clsName)) :< cls, Object :< cls) => cls -> ((methodSig))|])
        , noComments $ HS.FunBind () [HS.Match () (HS.Ident () $ methodName)
                        ((HS.PVar () (HS.Ident () "cls") : map (HS.PVar ()) argNames)
                         ++ if method ^. hasVarargs then
                            [HS.PVar () (HS.Ident () "varargs")] else
                            [])
                        runMethodRhs Nothing]
        , let cty = clsTy cls
              name = promotedString rawMethodName
              args = promotedList $ V.toList methodArgs
              ret = toHsType $ method ^. returnType
              mname = classModuleName <> "." <> methodName
          in noComments $
            [dec|instance NodeMethod ((cty)) ((name)) ((args)) (IO ((ret)) ) where nodeMethod = __mname__ |]
        ]
  where
    clsName = HS.TyCon () (HS.UnQual () (clsAsName cls))
    clsMethodBindName = HS.Ident () $ "bind" ++ (T.unpack $ mangleClass (cls ^. name)) ++ "_" ++ methodName
    clsMethodBindVar = HS.Var () $ HS.UnQual () clsMethodBindName
    clsMethodBindRhs = HS.UnGuardedRhs ()
      [hs| unsafePerformIO $ withCString $(HS.strE (T.unpack $ cls ^. name)) $
         \clsNamePtr -> withCString $(HS.strE rawMethodName) $
         \methodNamePtr -> godot_method_bind_get_method clsNamePtr methodNamePtr |]
    classModuleName = "Godot." ++ (pascal $ T.unpack (cls ^. apiType)) ++ "." ++ (T.unpack $ mangleClass $ cls ^. name)
    runMethodRhs = HS.UnGuardedRhs () $ HS.App () (
      HS.App ()
        (HS.Var () (HS.UnQual () (HS.Ident () "withVariantArray")))
        (let a = HS.List () $ zipWith (\a an -> wrapDefault a an) (V.toList $ method ^. arguments) argNames
        in if method ^. hasVarargs then
            [hs|$a ++ varargs|] else
            a))
      [hs|
        \(arrPtr, len) -> godot_method_bind_call $(clsMethodBindVar) (upcast cls) arrPtr len >>=
        \(err, res) -> throwIfErr err >> fromGodotVariant res |]

    wrapDefault (GodotArgument _ ty Nothing) v = mkToVariant v
    wrapDefault (GodotArgument _ ty (Just d)) v = mkDefault ty d (HS.Var () $ HS.UnQual () v)

    mkDefault :: GType -> Text -> HS.Exp () -> HS.Exp ()
    mkDefault (PrimitiveType IntType) d v = [hs|maybe (VariantInt (__dt__)) toVariant $v |]
      where dt = T.unpack d
    mkDefault (PrimitiveType FloatType) d v = [hs|maybe (VariantReal (__dt__)) toVariant $v |]
      where dt = T.unpack d
    mkDefault (PrimitiveType BoolType) d v = [hs|maybe (VariantBool __dt__) toVariant $v |]
      where dt = T.unpack d
    mkDefault (CoreType "Color") "1,1,1,1" v = [hs|defaultedVariant VariantColor (withOpacity (sRGB 1 1 1) 1) $v |]
    mkDefault (CoreType "Rect2") "(0, 0, 0, 0)" v = [hs|defaultedVariant VariantRect2 (V2 (V2 0 0) (V2 0 0)) $v |]
    mkDefault (CoreType "PoolStringArray") "[]" v = [hs|defaultedVariant VariantPoolStringArray V.empty $v |]
    mkDefault (CoreType "Dictionary") "{}" v = [hs|defaultedVariant VariantDictionary V.empty $v |]
    mkDefault (CoreType "PoolVector2Array") "[]" v = [hs|defaultedVariant VariantPoolVector2Array V.empty $v |]
    mkDefault (CoreType "PoolVector3Array") "[]" v = [hs|defaultedVariant VariantPoolVector3Array V.empty $v |]
    mkDefault (CoreType "PoolIntArray") "[]" v = [hs|defaultedVariant VariantPoolIntArray V.empty $v |]
    mkDefault (CoreType "PoolRealArray") "[]" v = [hs|defaultedVariant VariantPoolRealArray V.empty $v |]
    mkDefault (CoreType "PoolColorArray") "[PoolColorArray]" v = [hs|defaultedVariant VariantPoolColorArray V.empty $v |]
    mkDefault (CoreType "Array") "[]" v = [hs|defaultedVariant VariantArray V.empty $v |]
    mkDefault (CoreType "Vector2") "(-1, -1)" v = [hs|defaultedVariant VariantVector2 (V2 (-1) (-1)) $v |]
    mkDefault (CoreType "Vector2") "(0, 0)" v = [hs|defaultedVariant VariantVector2 (V2 0 0) $v |]
    mkDefault (CoreType "Vector3") "(0, 0, 0)" v = [hs|defaultedVariant VariantVector3 (V3 0 0 0) $v |]
    mkDefault (CoreType "Transform2D") "((1, 0), (0, 1), (0, 0))" v = [hs|defaultedVariant VariantTransform2d (TF2d (V2 1 0) (V2 0 1) (V2 0 0)) $v |]
    mkDefault (CoreType "Transform") "1, 0, 0, 0, 1, 0, 0, 0, 1 - 0, 0, 0" v = [hs|defaultedVariant VariantTransform (TF (V3 (V3 1 0 0) (V3 0 1 0) (V3 0 0 1)) (V3 0 0 0)) $v |]
    -- TODO Is this right?
    mkDefault (CoreType "RID") "[RID]" v = [hs|maybe VariantNil toVariant $v |]
    mkDefault (CoreType "String") d v = [hs|defaultedVariant VariantString __dt__ $v  |]
      where dt = "\"" <> T.unpack d <> "\""
    mkDefault _ "Null"          v = [hs|maybe VariantNil toVariant $v |]
    mkDefault _ "0"             v = [hs|maybe (VariantInt 0) toVariant $v |]
    mkDefault _ "1"             v = [hs|maybe (VariantInt 1) toVariant $v |]
    mkDefault _ "[Object:null]" v = [hs|maybe VariantNil toVariant $v |]
    mkDefault t d _ = error $ "Don't know how to make defaults for this type (" ++ show t ++ ") for value (" ++ show d ++ ")"

    mkToVariant = HS.App () (HS.Var () (HS.UnQual () (HS.Ident () "toVariant"))) . HS.Var () . HS.UnQual ()

    argNames = map (HS.Ident () . ("arg" ++) . show) [1..length (method ^. arguments)]

    methodSig = foldr (HS.TyFun ()) (HS.TyApp () [ty|IO|] (toHsType $ method ^. returnType)) methodArgs
    methodArgs = let args = fmap argToHsType (method ^. arguments)
                 in if method ^. hasVarargs then
                      args `V.snoc` [ty|[Variant 'GodotTy]|] else
                      args

    argToHsType (GodotArgument _ ty (Just _)) =
      HS.TyApp () (HS.TyCon () $ HS.UnQual () $ HS.Ident () "Maybe") $ toHsType ty
    argToHsType (GodotArgument _ ty _) = toHsType ty

    rawMethodName = T.unpack $ method ^. name
    methodName = toMethodName (method ^. name)

toMethodName name = T.unpack (case name of
                             "case" -> "case'"
                             "class" -> "class'"
                             "data" -> "data'"
                             "default" -> "default'"
                             "deriving" -> "deriving'"
                             "do" -> "do'"
                             "else" -> "else'"
                             "forall" -> "forall'"
                             "if" -> "if'"
                             "import" -> "import'"
                             "in" -> "in'"
                             "infix" -> "infix'"
                             "infixl" -> "infixl'"
                             "infixr" -> "infixr'"
                             "instance" -> "instance'"
                             "let" -> "let'"
                             "module" -> "module'"
                             "newtype" -> "newtype'"
                             "of" -> "of'"
                             "qualified" -> "qualified'"
                             "then" -> "then'"
                             "type" -> "type'"
                             "where" -> "where'"
                             "foreign" -> "foreign'"
                             "ccall" -> "ccall'"
                             "as" -> "as'"
                             "safe" -> "safe'"
                             "unsafe" -> "unsafe'"
                             x -> x)

mangleClass "String" = "GodotString"
mangleClass "Variant" = "GodotVariant"
mangleClass c = case T.stripPrefix "_" c of
                  Nothing -> c
                  Just x -> x

toHsType :: GType -> HS.Type ()
toHsType (PrimitiveType VoidType) = [ty| () |]
toHsType (PrimitiveType BoolType) = [ty| Bool |]
toHsType (PrimitiveType IntType) = [ty| Int |]
toHsType (PrimitiveType FloatType) = [ty| Float |]
toHsType (CoreType ty) = nameToTyCon $ renameType ty
  where
    renameType "RID" = "Rid"
    renameType "Transform2D" = "Transform2d"
    renameType "AABB" = "Aabb"
    renameType "String" = "GodotString"
    renameType "Variant" = "GodotVariant"
    renameType x = mangleClass x
-- NB: Are these bugs in api.json? Why is the type different from anywhere else?
toHsType (CustomType "SpatialMaterial,ShaderMaterial")    = nameToTyCon "Material"
toHsType (CustomType "ShaderMaterial,CanvasItemMaterial") = nameToTyCon "Material"
toHsType (CustomType "ShaderMaterial,SpatialMaterial")    = nameToTyCon "Material"
toHsType (CustomType "ShaderMaterial,ParticlesMaterial")  = nameToTyCon "Material"
toHsType (CustomType ty) = nameToTyCon ty
toHsType (EnumType _) = [ty| Int |]


================================================
FILE: classgen/src-classgen/Classgen/Spec.hs
================================================
{-# LANGUAGE TemplateHaskell, GeneralizedNewtypeDeriving, OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Classgen.Spec where

import Control.Applicative
import Control.Lens

import Data.Aeson
import Data.Aeson.TH
import Data.Monoid
import Data.Text (Text)
import qualified Data.Text as T
import Data.Vector (Vector)
import Data.HashMap.Strict (HashMap)
import qualified Data.Set as S

import Text.Casing
import Classgen.Utils

type GodotClasses = Vector GodotClass

newtype Ref a = Ref Text
  deriving (Show, Eq, FromJSON, ToJSON)

data GPrimType = VoidType | BoolType | IntType | FloatType
  deriving (Show, Eq)

instance FromJSON GPrimType where
  parseJSON = withText "primitive type" $ \t ->
    case t of
      "void" -> pure VoidType
      "bool" -> pure BoolType
      "int" -> pure IntType
      "float" -> pure FloatType
      _ -> fail $ "Unknown type" <> T.unpack t

data GType
  = PrimitiveType !GPrimType
  | CoreType !Text
  | CustomType !Text
  | EnumType !Text
  deriving (Show, Eq)

isCoreType t = t `S.member` S.fromList 
      [ "AABB",
        "Array",
        "Basis",
        "Color",
        "Dictionary",
        "GodotError",
        "NodePath",
        "Plane",
        "PoolByteArray",
        "PoolIntArray",
        "PoolRealArray",
        "PoolStringArray",
        "PoolVector2Array",
        "PoolVector3Array",
        "PoolColorArray",
        "Object",
        "Quat",
        "Rect2",
        "RID",
        "String",
        "Transform",
        "Transform2D",
        "Variant",
        "Vector2",
        "Vector3" ]

instance FromJSON GType where
  parseJSON v = PrimitiveType <$> parseJSON v
                <|> withText "type" (\t ->
                  if isCoreType t
                    then pure $ CoreType t
                    else if "enum." `T.isPrefixOf` t
                         then pure $ EnumType t
                         else pure $ CustomType t) v

data GodotClass = GodotClass
  { _gcName :: !Text
  , _gcBaseClass :: !Text
  , _gcApiType :: !Text
  , _gcSingleton ::  !Bool
  , _gcInstanciable :: !Bool
  , _gcIsReference :: !Bool
  , _gcConstants :: !(HashMap Text Int)
  , _gcProperties:: !(Vector GodotProperty)
  , _gcSignals :: !(Vector GodotSignal)
  , _gcMethods :: !(Vector GodotMethod)
  , _gcEnums :: !(Vector GodotEnum)
  } deriving (Show, Eq)

data GodotProperty = GodotProperty
  { _gpName :: !Text
  , _gcType :: !GType
  , _gcGetter :: !Text
  , _gcSetter :: !Text
  , _gcIndex :: !Int
  } deriving (Show, Eq)

data GodotSignal = GodotSignal
  { _gsName :: !Text
  , _gsArguments :: !(Vector GodotArgument)
  } deriving (Show, Eq)

data GodotArgument = GodotArgument
  { _gaName :: !Text
  , _gaType :: !GType
  , _gaDefaultValue :: !(Maybe Text)
  } deriving (Show, Eq)

instance FromJSON GodotArgument where
  parseJSON = withObject "argument" $ \v ->
    do
      hasDefault <- v .:? "has_default_value"
      maybeDefault <- case hasDefault of
        Just False -> pure Nothing
        _ -> Just <$> v .: "default_value"
      GodotArgument 
        <$> v .: "name"
        <*> v .: "type"
        <*> pure maybeDefault

data GodotMethod = GodotMethod
  { _gmName :: !Text
  , _gmReturnType :: !GType
  , _gmIsEditor :: !Bool
  , _gmIsNoscript :: !Bool
  , _gmIsConst :: !Bool
  , _gmIsReverse :: !Bool
  , _gmIsVirtual :: !Bool
  , _gmHasVarargs :: !Bool
  , _gmIsFromScript :: !Bool
  , _gmArguments :: !(Vector GodotArgument)
  } deriving (Show, Eq)

data GodotEnum = GodotEnum
  { _geName :: !GType
  , _geValues :: !(HashMap Text Int)
  } deriving (Show, Eq)

makeLensesWith fixedTypeFields ''GodotClass
makeLensesWith fixedTypeFields ''GodotProperty
makeLensesWith fixedTypeFields ''GodotSignal
makeLensesWith fixedTypeFields ''GodotArgument
makeLensesWith fixedTypeFields ''GodotMethod
makeLensesWith fixedTypeFields ''GodotEnum

makePrisms ''GType
makePrisms ''GPrimType

concat <$> mapM (deriveFromJSON defaultOptions { fieldLabelModifier = quietSnake . drop 3 })
  [ ''GodotClass
  , ''GodotProperty
  , ''GodotSignal
  , ''GodotMethod
  , ''GodotEnum ]


================================================
FILE: classgen/src-classgen/Classgen/Utils.hs
================================================
module Classgen.Utils where

import Control.Lens
import Language.Haskell.TH

fixedTypeFields :: LensRules
fixedTypeFields = defaultFieldRules & lensField .~ (\tyn fs f -> map fixDefName $ abbreviatedNamer tyn fs f)
    where
      fixDefName (TopName n) = TopName (fixName n)
      fixDefName (MethodName c n) = MethodName c (fixName n)
  
      fixName n = mkName $ case nameBase n of
        "type" -> "type'"
        "id" -> "id'"
        "class" -> "class'"
        s -> s


================================================
FILE: classgen/stack.yaml
================================================
# This file was automatically generated by 'stack init'
#
# Some commonly used options have been documented as comments in this file.
# For advanced use and comprehensive documentation of the format, please see:
# https://docs.haskellstack.org/en/stable/yaml_configuration/

# Resolver to choose a 'specific' stackage snapshot or a compiler version.
# A snapshot resolver dictates the compiler version and the set of packages
# to be used for project dependencies. For example:
#
# resolver: lts-3.5
# resolver: nightly-2015-09-21
# resolver: ghc-7.10.2
# resolver: ghcjs-0.1.0_ghc-7.10.2
# resolver:
#  name: custom-snapshot
#  location: "./custom-snapshot.yaml"
# resolver: lts-11.2
resolver: lts-15.4

# User packages to be built.
# Various formats can be used as shown in the example below.
#
# packages:
# - some-directory
# - https://example.com/foo/bar/baz-0.0.2.tar.gz
# - location:
#    git: https://github.com/commercialhaskell/stack.git
#    commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a
#   extra-dep: true
#  subdirs:
#  - auto-update
#  - wai
#
# A package marked 'extra-dep: true' will only be built if demanded by a
# non-dependency (i.e. a user package), and its test suites and benchmarks
# will not be run. This is useful for tweaking upstream packages.
packages:
- .
- ../haskell-src-exts-qq
- ../haskell-src-exts-sc

# Dependency packages to be pulled from upstream that are not in the resolver
# (e.g., acme-missiles-0.3)
extra-deps: []

# Override default flag values for local packages and extra-deps
# flags: {}

# Extra package databases containing global packages
# extra-package-dbs: []

# Control whether we use the GHC we find on the path
# system-ghc: true
#
# Require a specific version of stack, using version ranges
# require-stack-version: -any # Default
require-stack-version: ">=1.7"
#
# Override the architecture used by stack, especially useful on Windows
# arch: i386
# arch: x86_64
#
# Extra directories used by stack for building
# extra-include-dirs: [/path/to/dir]
# extra-lib-dirs: [/path/to/dir]
#
# Allow a newer minor version of GHC than the snapshot specifies
# compiler-check: newer-minor


================================================
FILE: default.nix
================================================
{ mkDerivation, aeson, ansi-wl-pprint, base, bytestring, c2hs
, casing, colour, containers, hpack, lens, linear, mtl, parsec
, parsers, stdenv, stm, template-haskell, text
, unordered-containers, vector, rsync, api-json ? null, lib, haskellPackages
}:
let godot-haskell-classgen = haskellPackages.callPackage ./classgen/default.nix { };
    modifyGodotApi = lib.optionalString (api-json != null) ''
cd classgen
echo "Running godot-haskell-classgen on path " ${api-json}
godot-haskell-classgen ${api-json}
cd ..
cp -r src src.bak
rsync -a classgen/src/ src/
''; in

mkDerivation {
  pname = "godot-haskell";
  version = "3.1.0.0";
  src = ./.;

  libraryHaskellDepends = [
    aeson ansi-wl-pprint base bytestring casing colour containers lens
    linear mtl parsec parsers stm template-haskell text
    unordered-containers vector
  ];
  libraryToolDepends = [ c2hs hpack rsync godot-haskell-classgen];
  doHaddock = false;
  preConfigure = ''
  hpack
  ${modifyGodotApi}
  '';
  homepage = "https://github.com/KaneTW/godot-haskell#readme";
  description = "Haskell bindings for the Godot game engine API";
  license = stdenv.lib.licenses.bsd3;
}

================================================
FILE: examples/dodge-the-creeps/.gitignore
================================================
dist*
*.hi
*.o
.stack-work/
.stack-work-devel/
*~
\#*
*.import
result




================================================
FILE: examples/dodge-the-creeps/ChangeLog.md
================================================
# Empty




================================================
FILE: examples/dodge-the-creeps/LICENSE
================================================
BSD 3-Clause License

Copyright (c) Andrei Barbu 2019
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



================================================
FILE: examples/dodge-the-creeps/Makefile
================================================
NAME = myproject
STACKLIBFILE = $(shell stack path --local-install-root)/lib/lib$(NAME).so
GODOTPROJECT = $(shell stack path --project-root)/game

all: stack
nix:
	nix-build shell.nix
	cp result/lib/ghc-*/lib$(NAME).so $(GODOTPROJECT)/lib
stack:
	stack build --fast --force-dirty
	cp $(STACKLIBFILE) $(GODOTPROJECT)/lib
stack-nix:
	stack --nix clean $(NAME)
	stack --nix build
	cp $(shell stack --nix path --local-install-root)/lib/lib$(NAME).so $(GODOTPROJECT)/lib
stack-run:
	stack build
	cp $(STACKLIBFILE) $(GODOTPROJECT)/lib
	godot -e --path ./game
stack-watch:
	stack build --file-watch --fast --exec "cp $(STACKLIBFILE) $(GODOTPROJECT)/lib"
project-watch:
	stack exec godot-haskell-project-generator game src
updatelib:
	cp $(STACKLIBFILE) $(GODOTPROJECT)/lib


================================================
FILE: examples/dodge-the-creeps/README.md
================================================
The official Godot demo from the manual: Dodge the Creeps.

Run with `make stack` then `godot game/project.godot` and press F5 to start, F8 to end.

Requires Godot 3.1


================================================
FILE: examples/dodge-the-creeps/Support.hs
================================================
{-# LANGUAGE FlexibleContexts, FunctionalDependencies, MultiParamTypeClasses, OverloadedLabels, UndecidableInstances,
  OverloadedStrings, TemplateHaskell, TypeApplications, TypeFamilies, DataKinds, TypeOperators, FlexibleInstances #-}

module Generated.Support where
import Godot
import GHC.TypeLits

class SceneNode (scene :: Symbol) (s :: Symbol) where
  type SceneNodeType scene s :: *
  type SceneNodeName scene s :: Symbol

class NodeInScheme (scene :: Symbol) (s :: Symbol) n | scene s -> n, n -> scene s


================================================
FILE: examples/dodge-the-creeps/ffi/cbits/flib.c
================================================
#include "HsFFI.h"

static void flib_init() __attribute__((constructor));
static void flib_init() {
  static char *argv[] = { "libGodotHaskellPlugin.so", 0 }, **argv_ = argv;
  static int argc = 1;
  hs_init(&argc, &argv_);
}

static void flib_fini() __attribute__((destructor));
static void flib_fini() {
  hs_exit();
}


================================================
FILE: examples/dodge-the-creeps/ffi/flib/FLib.hs
================================================
{-# LANGUAGE ForeignFunctionInterface #-}
module FLib where

import qualified Foreign
import           Foreign(nullPtr, Ptr,newForeignPtr_,castPtr)
import qualified Godot.Gdnative.Internal       as FFI
import           Godot.Gdnative
import           Godot.Nativescript
import           Lib
import qualified Data.Text as T
import qualified Data.Text.IO as T

godot_nativescript_init :: GdnativeHandle -> IO ()
godot_nativescript_init desc = do
  defaultExports desc
  exports desc
  putStrLn "Haskell NativeScript lib initialized"

foreign export ccall godot_nativescript_init :: GdnativeHandle -> IO ()


godot_gdnative_init :: FFI.GdnativeInitOptionsPtr -> IO ()
godot_gdnative_init opts = do
  Foreign.peek opts >>= FFI.initApiStructs

foreign export ccall godot_gdnative_init :: FFI.GdnativeInitOptionsPtr -> IO ()


godot_gdnative_terminate :: FFI.GdnativeTerminateOptionsPtr -> IO ()
godot_gdnative_terminate handle = pure ()

foreign export ccall godot_gdnative_terminate :: FFI.GdnativeTerminateOptionsPtr -> IO ()


================================================
FILE: examples/dodge-the-creeps/game/HUD.gdns
================================================
[gd_resource type="NativeScript" load_steps=2 format=2]

[ext_resource path="res://lib/libmyproject.gdnlib" type="GDNativeLibrary" id=1]

[resource]
resource_name = "HUD"
class_name = "HUD"
library = ExtResource( 1 )


================================================
FILE: examples/dodge-the-creeps/game/HUD.tres
================================================
[gd_resource type="DynamicFont" load_steps=2 format=2]

[ext_resource path="res://dodge_assets/fonts/Xolonium-Regular.ttf" type="DynamicFontData" id=1]

[resource]
size = 64
font_data = ExtResource( 1 )


================================================
FILE: examples/dodge-the-creeps/game/HUD.tscn
================================================
[gd_scene load_steps=5 format=2]

[ext_resource path="res://HUD.gdns" type="Script" id=1]
[ext_resource path="res://HUD.tres" type="DynamicFont" id=2]

[sub_resource type="InputEventAction" id=1]
action = "ui_select"

[sub_resource type="ShortCut" id=2]
shortcut = SubResource( 1 )

[node name="HUD" type="CanvasLayer"]
script = ExtResource( 1 )

[node name="ScoreLabel" type="Label" parent="."]
anchor_right = 1.0
margin_bottom = 78.0
custom_fonts/font = ExtResource( 2 )
text = "0"
align = 1
__meta__ = {
"_edit_use_anchors_": false
}

[node name="MessageLabel" type="Label" parent="."]
anchor_top = 0.5
anchor_right = 1.0
anchor_bottom = 0.5
margin_top = -79.5
margin_bottom = 79.5
custom_fonts/font = ExtResource( 2 )
text = "Dodge
the Creeps!"
align = 1

[node name="StartButton" type="Button" parent="."]
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
margin_left = -90.0
margin_top = -200.0
margin_right = 90.0
margin_bottom = -100.0
custom_fonts/font = ExtResource( 2 )
shortcut = SubResource( 2 )
text = "Start"
__meta__ = {
"_edit_use_anchors_": false
}

[node name="MessageTimer" type="Timer" parent="."]
wait_time = 2.0
one_shot = true
[connection signal="pressed" from="StartButton" to="." method="_on_StartButton_pressed"]
[connection signal="timeout" from="MessageTimer" to="." method="_on_MessageTimer_timeout"]


================================================
FILE: examples/dodge-the-creeps/game/Main.gdns
================================================
[gd_resource type="NativeScript" load_steps=2 format=2]

[ext_resource path="res://lib/libmyproject.gdnlib" type="GDNativeLibrary" id=1]

[resource]
class_name = "Main"
library = ExtResource( 1 )


================================================
FILE: examples/dodge-the-creeps/game/Main.tscn
================================================
[gd_scene load_steps=6 format=2]

[ext_resource path="res://Main.gdns" type="Script" id=1]
[ext_resource path="res://Mob.tscn" type="PackedScene" id=2]
[ext_resource path="res://Player.tscn" type="PackedScene" id=3]
[ext_resource path="res://HUD.tscn" type="PackedScene" id=4]

[sub_resource type="Curve2D" id=1]
_data = {
"points": PoolVector2Array( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 480, 0, 0, 0, 0, 0, 480, 720, 0, 0, 0, 0, 0, 720, 0, 0, 0, 0, 0, 0 )
}

[node name="Main" type="Node"]
script = ExtResource( 1 )
PackedScene = ExtResource( 2 )

[node name="ColorRect" type="ColorRect" parent="."]
margin_right = 480.0
margin_bottom = 720.0
color = Color( 0.229564, 0.339542, 0.394531, 1 )
__meta__ = {
"_edit_use_anchors_": false
}

[node name="Player" parent="." instance=ExtResource( 3 )]

[node name="MobTimer" type="Timer" parent="."]
wait_time = 0.5

[node name="ScoreTimer" type="Timer" parent="."]

[node name="StartTimer" type="Timer" parent="."]
wait_time = 2.0
one_shot = true

[node name="StartPosition" type="Position2D" parent="."]
position = Vector2( 240, 450 )

[node name="MobPath" type="Path2D" parent="."]
curve = SubResource( 1 )

[node name="MobSpawnLocation" type="PathFollow2D" parent="MobPath"]

[node name="HUD" parent="." instance=ExtResource( 4 )]
[connection signal="hit" from="Player" to="." method="game_over"]
[connection signal="timeout" from="MobTimer" to="." method="_on_MobTimer_timeout"]
[connection signal="timeout" from="ScoreTimer" to="." method="_on_ScoreTimer_timeout"]
[connection signal="timeout" from="StartTimer" to="." method="_on_StartTimer_timeout"]
[connection signal="start_game" from="HUD" to="." method="new_game"]


================================================
FILE: examples/dodge-the-creeps/game/Mob.gdns
================================================
[gd_resource type="NativeScript" load_steps=2 format=2]

[ext_resource path="res://lib/libmyproject.gdnlib" type="GDNativeLibrary" id=1]

[resource]
resource_name = "Mob"
class_name = "Mob"
library = ExtResource( 1 )


================================================
FILE: examples/dodge-the-creeps/game/Mob.tscn
================================================
[gd_scene load_steps=10 format=2]

[ext_resource path="res://Mob.gdns" type="Script" id=1]
[ext_resource path="res://dodge_assets/art/enemyFlyingAlt_1.png" type="Texture" id=2]
[ext_resource path="res://dodge_assets/art/enemyFlyingAlt_2.png" type="Texture" id=3]
[ext_resource path="res://dodge_assets/art/enemyWalking_1.png" type="Texture" id=4]
[ext_resource path="res://dodge_assets/art/enemyWalking_2.png" type="Texture" id=5]
[ext_resource path="res://dodge_assets/art/enemySwimming_1.png" type="Texture" id=6]
[ext_resource path="res://dodge_assets/art/enemySwimming_2.png" type="Texture" id=7]

[sub_resource type="SpriteFrames" id=1]
animations = [ {
"frames": [ ExtResource( 2 ), ExtResource( 3 ) ],
"loop": true,
"name": "fly",
"speed": 3.0
}, {
"frames": [ ExtResource( 4 ), ExtResource( 5 ) ],
"loop": true,
"name": "walk",
"speed": 4.0
}, {
"frames": [ ExtResource( 6 ), ExtResource( 7 ) ],
"loop": true,
"name": "swim",
"speed": 4.0
} ]

[sub_resource type="CapsuleShape2D" id=2]
radius = 36.0297
height = 27.5338

[node name="Mob" type="RigidBody2D"]
collision_mask = 0
gravity_scale = 0.0
script = ExtResource( 1 )
__meta__ = {
"_edit_group_": true
}

[node name="AnimatedSprite" type="AnimatedSprite" parent="."]
scale = Vector2( 0.75, 0.75 )
frames = SubResource( 1 )
animation = "swim"
frame = 1
playing = true

[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
rotation = 1.5708
shape = SubResource( 2 )

[node name="VisibilityNotifier2D" type="VisibilityNotifier2D" parent="."]
[connection signal="screen_exited" from="VisibilityNotifier2D" to="." method="_on_VisibilityNotifier2D_screen_exited"]


================================================
FILE: examples/dodge-the-creeps/game/Player.gdns
================================================
[gd_resource type="NativeScript" load_steps=2 format=2]

[ext_resource path="res://lib/libmyproject.gdnlib" type="GDNativeLibrary" id=1]

[resource]
resource_name = "Player"
class_name = "Player"
library = ExtResource( 1 )


================================================
FILE: examples/dodge-the-creeps/game/Player.tscn
================================================
[gd_scene load_steps=8 format=2]

[ext_resource path="res://Player.gdns" type="Script" id=1]
[ext_resource path="res://dodge_assets/art/playerGrey_walk1.png" type="Texture" id=2]
[ext_resource path="res://dodge_assets/art/playerGrey_walk2.png" type="Texture" id=3]
[ext_resource path="res://dodge_assets/art/playerGrey_up1.png" type="Texture" id=4]
[ext_resource path="res://dodge_assets/art/playerGrey_up2.png" type="Texture" id=5]

[sub_resource type="SpriteFrames" id=1]
animations = [ {
"frames": [ ExtResource( 2 ), ExtResource( 3 ) ],
"loop": true,
"name": "right",
"speed": 5.0
}, {
"frames": [ ExtResource( 4 ), ExtResource( 5 ) ],
"loop": true,
"name": "up",
"speed": 5.0
} ]

[sub_resource type="CapsuleShape2D" id=2]
radius = 26.892
height = 15.9045

[node name="Player" type="Area2D"]
script = ExtResource( 1 )
__meta__ = {
"_edit_group_": true
}

[node name="AnimatedSprite" type="AnimatedSprite" parent="."]
position = Vector2( 0, -1 )
scale = Vector2( 0.5, 0.5 )
frames = SubResource( 1 )
animation = "up"

[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource( 2 )
[connection signal="body_entered" from="." to="." method="_on_Player_body_entered"]


================================================
FILE: examples/dodge-the-creeps/game/dodge_assets/fonts/FONTLOG.txt
================================================
Please distribute this file along with the Xolonium fonts when possible.


Source

	Find the sourcefiles of Xolonium at
	<gitlab.com/sev/xolonium>


Credits

	Xolonium is created with FontForge <fontforge.org>,
	Inkscape <inkscape.org>, Python <python.org>, and
	FontTools <github.com/fonttools>.

	It originated as a custom font for the open-source
	game Xonotic <xonotic.org>. With many thanks to the
	Xonotic community for your support.


Supported OpenType features

	case  Provides case sensitive placement of punctuation,
	      brackets, and math symbols for uppercase text.
	frac  Replaces number/number sequences with diagonal fractions.
	      Numbers that touch a slash should not exceed 10 digits.
	kern  Provides kerning for Latin, Greek, and Cyrillic scripts.
	locl  Dutch: Replaces j with a stressed version if it follows í.
	      Sami: Replaces n-form Eng with the preferred N-form version.
	      Romanian and Moldovan: Replaces ŞşŢţ with the preferred ȘșȚț.
	pnum  Replaces monospaced digits with proportional versions.
	sinf  Replaces digits with scientific inferiors below the baseline.
	subs  Replaces digits with subscript versions on the baseline.
	sups  Replaces digits with superscript versions.
	zero  Replaces zero with a slashed version.


Supported glyph sets

	Adobe Latin 3
	OpenType W1G
	ISO 8859-1   Western European
	ISO 8859-2   Central European
	ISO 8859-3   South European
	ISO 8859-4   North European
	ISO 8859-5   Cyrillic
	ISO 8859-7   Greek
	ISO 8859-9   Turkish
	ISO 8859-10  Nordic
	ISO 8859-13  Baltic Rim
	ISO 8859-14  Celtic
	ISO 8859-15  Western European
	ISO 8859-16  South-Eastern European


Available glyphs

	 !"#$%&'()*+,-./0123456789:;<=>?
	@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
	`abcdefghijklmnopqrstuvwxyz{|}~

	 ¡¢£¤¥¦§¨©ª«¬ ®¯°±²³´µ¶·¸¹º»¼½¾¿
	ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞß
	àáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ
	ĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğ
	ĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľ
	ĿŀŁłŃńŅņŇňŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞş
	ŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽž
	ƒǺǻǼǽǾǿȘșȚțȷ

	ˆˇˉ˘˙˚˛˜˝

	ͺ;΄΅Ά·ΈΉΊΌΎΏΐ
	ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩΪΫάέήίΰ
	αβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ

	ЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОП
	РСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп
	рстуфхцчшщъыьэюяѐёђѓєѕіїјљњћќѝўџ
	ѢѣѲѳѴѵҐґҒғҔҕҖҗҘҙҚқҜҝҞҟҠҡҢңҤҥҦҧҨҩ
	ҪҫҬҭҮүҰұҲҳҴҵҶҷҸҹҺһҼҽӀӁӂӇӈӋӌӏӐӑӒӓ
	ӔӕӖӗӘәӜӝӞӟӠӡӢӣӤӥӦӧӨөӮӯӰӱӲӳӴӵӶӷӸӹ
	Ԥԥ

	ḂḃḊḋḞḟṀṁṖṗṠṡṪṫẀẁẂẃẄẅẞỲỳ

	     ‒–—―‘’‚‛“”„‟†‡•…‰′″‹›‽‾⁄
	⁰⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ⁿ₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎
	₤₦₩₫€₯₱₹₺₽₿
	℅ℓ№℗™Ω℮
	⅛⅜⅝⅞
	←↑→↓
	∂∆∏∑−∕∙√∞∟∫≈≠≤≥
	⌖
	■▬▮▰▲▶▼◀◆◊●◢◣◤◥
	☄★☠☢☣⚙⚛⚠⚡⛔
	❇❈❌❤❰❱❲❳
	fffiflffiffl
	🌌🌍🌎🌏👽💣🔥🔫
	😁😃😄😆😇😈😉😊😎😐😒😕😘
	😛😝😞😟😠😣😭😮😲😴😵
	🚀


Debugging glyphs

	  U+EFFD  Font version
	  U+F000  Font hinting indicator


Changelog

	Xolonium 4.1  2016-11-22  Severin Meyer  <sev.ch@web.de>
		Reverted frac OpenType feature to a more stable implementation

	Xolonium 4.0  2016-10-08  Severin Meyer  <sev.ch@web.de>
		Decreased width of most glyphs
		Thinner vertical stems in Xolonium-Regular
		Thicker horizontal stems in Xolonium-Bold
		Revised diagonal stems
		Lowered middle bars
		Revised diacritical bars
		Added glyphs:
			ӏẞ₿
			U+2007 U+2008 U+2009 U+200A U+202F
			U+EFFD U+F000
		Revised glyphs:
			$&,JKQRXkwxy~¢¤ßǻ˜ζκλμξφЖУжћѴѵ∕₱₺₦₩€ℓ№≈ffffiffl
			❤🌍🌎🌏😁😄😇😈😉😊😘😭😮😴🚀
		Removed uncommon glyphs:
			ʼnſʼҌҍҎҏҾҿӃӄӇӈӚӛӪӫӬӭ
			U+0312 U+0313 U+0326
		Simplified OpenType features pnum, zero, and case
		Removed OpenType feature dlig
		Revised vertical metrics
		Merged outlines of composite glyphs in otf version
		Added ttf version with custom outlines and instructions
		Added woff and woff2 version

	Xolonium 3.1  2015-06-10  Severin Meyer  <sev.ch@web.de>
		Added currency glyphs:
			₦₩₫₱₹₺₽
		Revised glyph:
			₯
		Relicensed public release under the SIL Open Font License 1.1

	Xolonium 3.0  2015-05-04  Severin Meyer  <sev.ch@web.de>
		Decreased width of glyphs
		Decreased descender height
		Increased height of super/subscript glyphs
		Revised width of dashes, underscore, and overscore
		Sharper bends with more circular proportions
		Decreased stroke thickness of mathematical glyphs
		Revised diacritical marks
		Revised diacritical bars
		Revised Cyrillic hooks
		Revised glyphs:
			GQRYjmuwßŊŒſƒǻfffiffiffl
			ΞΨΩδζιξπςστυφω
			ЉЄДЛУЭЯбдлэяєљђєћѢѣҨҩҼҽӃӄӘә
			#$&'()*,/69?@[]{}~¡£¤¥§©®¿
			‹›₤€₯ℓ№℗℮←↑→↓∂∏∑∞≈▰☄❈❰❱❲❳😝
		Raised vertical position of mathematical glyphs
		Unified advance width of numeral and monetary glyphs
		Unified advance width of mathematical glyphs
		Revised bearings
		Rewrote kern feature
		Bolder Xolonium-Bold with improved proportions
		Updated glyph names to conform to the AGLFN 1.7
		Revised hints and PS Private Dictionary
		Added glyphs:
			ӶӷԤԥ
		Added OpenType features:
			case frac liga locl pnum sinf subs sups zero

	Xolonium 2.4  2014-12-23  Severin Meyer  <sev.ch@web.de>
		Added dingbats:
			⛔💣🔥
		Revised size and design of emoticons
		Revised dingbats:
			⌖☄☠☣⚙⚛⚠⚡❇❈🌌🌍🌎🌏🔫
		Removed dingbat:
			💥

	Xolonium 2.3  2014-08-14  Severin Meyer  <sev.ch@web.de>
		Bugfixed ε and έ, thanks to bowzee for the feedback

	Xolonium 2.2  2014-03-01  Severin Meyer  <sev.ch@web.de>
		Added dingbats:
			⌖◆●❌💥
		Revised dingbats:
			•←↑→↓◊☄★☠☣⚙⚛⚠⚡❇❈❤🌌🌍🌎🌏👽🔫🚀
		Removed dingbats:
			♻✪💡📡🔋🔧🔭

	Xolonium 2.1  2013-10-20  Severin Meyer  <sev.ch@web.de>
		Added dingbats:
			←↑→↓❰❱❲❳■▬▮▰▲▶▼◀◢◣◤◥
			☄★☠☢☣♻⚙⚛⚠⚡✪❇❈❤
			🌌🌍🌎🌏👽💡📡🔋🔧🔫🔭🚀
			😁😃😄😆😇😈😉😊😎😐😒😕
			😘😛😝😞😟😠😣😭😮😲😴😵

	Xolonium 2.0.1  2013-07-12  Severin Meyer  <sev.ch@web.de>
		Reorganised and simplified files

	Xolonium 2.0  2012-08-11  Severin Meyer  <sev.ch@web.de>
		Revised bends
		Revised thickness of uppercase diagonal stems
		Revised diacritical marks
		Revised hints and PS Private Dictionary
		Revised glyphs:
			*1469@DPRly{}§©®¶ÐÞƒΘΞαεζνξνυЄЉЊ
			ЏБЗЛУЧЪЫЬЭЯбзлчъыьэяєљњџ•€∂∙√∞∫≠
		Completed glyph sets:
			Adobe Latin 3
			OpenType World Glyph Set 1 (W1G)
			Ghostscript Standard (ghostscript-fonts-std-8.11)
		Added OpenType kern feature
		Added Xolonium-Bold

	Xolonium 1.2  2011-02-12  Severin Meyer  <sev.ch@web.de>
		Revised glyphs:
			D·Ðı
		Completed glyph sets:
			ISO 8859-7 (Greek)
			Unicode Latin Extended-A block
		Added glyphs:
			†‡•…‰⁄™∂∑−√∞≠≤≥

	Xolonium 1.1  2011-01-17  Severin Meyer  <sev.ch@web.de>
		Revised placement of cedilla and ogonek in accented glyphs
		Revised glyphs:
			,;DKTjkvwxy¥§Ð˛€
		Completed glyph sets:
			ISO 8859-2  (Central European)
			ISO 8859-3  (South European, Esperanto)
			ISO 8859-4  (North European)
			ISO 8859-5  (Cyrillic)
			ISO 8859-9  (Turkish)
			ISO 8859-10 (Nordic)
			ISO 8859-13 (Baltic Rim)
			ISO 8859-14 (Celtic)
			ISO 8859-16 (South-Eastern European)
		Added glyphs:
			ȷʼ̒ ЀЍѐѝ‒–—‘’‚‛“”„‟‹›

	Xolonium 1.0  2011-01-04  Severin Meyer  <sev.ch@web.de>
		Completed glyph sets:
			ISO 8859-1  (Western European)
			ISO 8859-15 (Western European)
		Added glyphs:
			ĄĆĘŁŃŚŹŻąćęłńśźżıˆˇ˙˚˛˜


================================================
FILE: examples/dodge-the-creeps/game/dodge_assets/fonts/LICENSE.txt
================================================
Copyright 2011-2016 Severin Meyer <sev.ch@web.de>,
with Reserved Font Name Xolonium.

This Font Software is licensed under the SIL Open Font License,
Version 1.1. This license is copied below, and is also available
with a FAQ at <http://scripts.sil.org/OFL>


-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.


================================================
FILE: examples/dodge-the-creeps/game/lib/libmyproject.gdnlib
================================================
[general]

singleton=false
load_once=true
symbol_prefix="godot_"
reloadable=false

[entry]

X11.64="res://lib/libmyproject.so"


================================================
FILE: examples/dodge-the-creeps/game/project.godot
================================================
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
;   [section] ; section goes between []
;   param=value ; assign values to parameters

config_version=4

_global_script_classes=[  ]
_global_script_class_icons={

}

[application]

config/name="myproject"
run/main_scene="res://Main.tscn"

[audio]

default_bus_layout=""

[display]

window/size/width=480
window/size/height=720

[gdnative]

singletons=[  ]


================================================
FILE: examples/dodge-the-creeps/godot-haskell.nix
================================================
{ fetchFromGitHub, mkDerivation, aeson, ansi-wl-pprint, base, bytestring, c2hs
, casing, colour, containers, hpack, lens, linear, mtl, parsec
, parsers, stdenv, stm, template-haskell, text
, unordered-containers, vector
}:
mkDerivation {
  pname = "godot-haskell";
  version = "3.1.0.0";
  src = fetchFromGitHub {
    owner = "SimulaVR";
    repo = "godot-haskell";
    rev = "b423d4f2fa5a6a3dcfffb82bb36be571adb29d34"; # godot-haskell rev
    # Use nix-prefetch-git to get the hash
    sha256 = "0jh2j5rr90dqdxvcipygwnhhj7j2dj4zvm6gbdpg106ll60pyqrp";
    fetchSubmodules = true;
  };
  libraryHaskellDepends = [
    aeson ansi-wl-pprint base bytestring casing colour containers lens
    linear mtl parsec parsers stm template-haskell text
    unordered-containers vector
  ];
  libraryToolDepends = [ c2hs hpack ];
  doHaddock = false;
  preConfigure = "hpack";
  homepage = "https://github.com/KaneTW/godot-haskell#readme";
  description = "Haskell bindings for the Godot game engine API";
  license = stdenv.lib.licenses.bsd3;
}




================================================
FILE: examples/dodge-the-creeps/hie.yaml
================================================
cradle:
  stack:
    - path: "./src"
      component: "myproject:lib"

    - path: "./game"
      component: "myproject:lib"


================================================
FILE: examples/dodge-the-creeps/myproject.cabal
================================================
cabal-version: 1.12

-- This file has been generated from package.yaml by hpack version 0.33.0.
--
-- see: https://github.com/sol/hpack
--
-- hash: 98269f1144e3857ceb0d2b7a1ec2c981a99768d91b04e6febe2406912eda49b8

name:           myproject
version:        0.0.0.0
description:    Please see the README on Github at <https://github.com/SimulaVR/godot-haskell/tree/master/demo#readme>
homepage:       https://github.com/SimulaVR/godot-haskell#readme
bug-reports:    https://github.com/SimulaVR/godot-haskell/issues
author:         Andrei Barbu
maintainer:     andrei@0xab.com
copyright:      Andrei Barbu 2019, 2021
license:        BSD3
license-file:   LICENSE
build-type:     Simple
extra-source-files:
    ChangeLog.md
    README.md
foreign-library myproject
  type: native-shared
  other-modules: FLib
  hs-source-dirs: ffi/flib
  c-sources: ffi/cbits/flib.c
  build-depends:
      base >= 4.12 && <5
    , godot-haskell
    , myproject
    , text
  default-language: Haskell2010

source-repository head
  type: git
  location: https://github.com/SimulaVR/godot-haskell

library
  exposed-modules:
      Lib
  other-modules:
      Game.HUD
      Game.Main
      Game.Mob
      Game.Player
      Project.Requirements
      Project.Scenes
      Project.Scenes.HUD
      Project.Scenes.Main
      Project.Scenes.Mob
      Project.Scenes.Player
      Project.Support
      Paths_myproject
  hs-source-dirs:
      src
      game
  default-extensions: FlexibleContexts MultiParamTypeClasses OverloadedStrings TemplateHaskell TypeApplications TypeFamilies DataKinds FlexibleInstances ScopedTypeVariables AllowAmbiguousTypes TupleSections FunctionalDependencies
  ghc-options: -Wall -Wno-orphans -O0
  build-depends:
      base >=4.12 && <5
    , containers
    , extra
    , godot-haskell
    , lens
    , linear
    , random
    , strict-concurrency
    , template-haskell
    , text
    , th-abstraction
    , vector
  default-language: Haskell2010


================================================
FILE: examples/dodge-the-creeps/package.yaml
================================================
name: myproject
version: '0.0.0.0'
description: Please see the README on Github at <https://github.com/SimulaVR/godot-haskell/tree/master/demo#readme>
author: Andrei Barbu
maintainer: andrei@0xab.com
copyright: Andrei Barbu 2019, 2021
license: BSD3
github: SimulaVR/godot-haskell
extra-source-files:
  - ChangeLog.md
  - README.md
dependencies:
  - base >=4.12 && <5
  - godot-haskell
  - linear
  - random
  - text
  - vector
  - strict-concurrency
  - lens
  - template-haskell
  - th-abstraction
  - containers
  - extra
library:
  source-dirs:
    - src
    - game
  default-extensions:
    - FlexibleContexts
    - MultiParamTypeClasses
    - OverloadedStrings
    - TemplateHaskell
    - TypeApplications
    - TypeFamilies
    - DataKinds
    - FlexibleInstances
    - ScopedTypeVariables
    - AllowAmbiguousTypes
    - TupleSections
    - FunctionalDependencies
  exposed-modules:
    - Lib
  ghc-options: -Wall -Wno-orphans -O0

verbatim: |
  foreign-library myproject
    type: native-shared
    other-modules: FLib
    hs-source-dirs: ffi/flib
    c-sources: ffi/cbits/flib.c
    build-depends:
        base >= 4.12 && <5
      , godot-haskell
      , myproject
      , text
    default-language: Haskell2010


================================================
FILE: examples/dodge-the-creeps/pinned-nixpkgs.nix
================================================
{}:

let
  # 19.03-beta (25 feb)
  rev = "0c0954781e257b8b0dc49341795a2fe7d96945a3"; # pinned-nixpkgs rev
  pkgs = import (builtins.fetchTarball {
      url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
    }) {};
in
  pkgs




================================================
FILE: examples/dodge-the-creeps/shell.nix
================================================
{ nixpkgs ? import ./pinned-nixpkgs.nix {}
, compiler ? "default"
, doBenchmark ? false }:


let

  inherit (nixpkgs) pkgs;

  haskellPackages = if compiler == "default"
                       then pkgs.haskellPackages
                       else pkgs.haskell.packages.${compiler};

  f = { mkDerivation, stdenv, base, godot-haskell, linear, text , vector, stm }:
    mkDerivation {
      pname = "myproject";
      version = "3.1.0.0";
      src = ./.;
      libraryHaskellDepends = [
        base godot-haskell linear text vector stm
      ];
      libraryToolDepends = [];
      homepage = "https://github.com/abarbu/myproject#readme";
      license = stdenv.lib.licenses.bsd3;
    };

  variant = if doBenchmark then pkgs.haskell.lib.doBenchmark else pkgs.lib.id;

  drv = variant (haskellPackages.callPackage f {
      godot-haskell = haskellPackages.callPackage ./godot-haskell.nix {fetchFromGitHub = pkgs.fetchFromGitHub;};
    });

in

  if pkgs.lib.inNixShell then drv.env else drv




================================================
FILE: examples/dodge-the-creeps/src/Game/HUD.hs
================================================
module Game.HUD where
import Control.Lens
import Control.Monad
import qualified Data.Text as T
import Godot
import Godot.Core.CanvasItem as CanvasItem
import Godot.Core.Label as Label
import Godot.Core.Timer as Timer
import Project.Support
import Project.Scenes.HUD()

data HUD = HUD { _hBase :: CanvasLayer }

instance NodeInit HUD where
  init = pure . HUD
instance NodeMethod HUD "_on_MessageTimer_timeout" '[] (IO ()) where
  nodeMethod self = getNode' @"MessageLabel" self >>= CanvasItem.hide
instance NodeMethod HUD "_on_StartButton_pressed" '[] (IO ()) where
  nodeMethod self = do
    getNode' @"StartButton" self >>= CanvasItem.hide
    emit_signal' @"start_game" self []
instance NodeMethod HUD "show_message" '[GodotString] (IO ()) where
  nodeMethod = show_message
instance NodeMethod HUD "show_game_over" '[] (IO ()) where
  nodeMethod = show_game_over
instance NodeMethod HUD "update_score" '[Int] (IO ()) where
  nodeMethod = update_score
instance NodeSignal HUD "start_game" '[]

show_message :: HUD -> GodotString -> IO ()
show_message self text = do
  messageLabel <- getNode' @"MessageLabel" self 
  set_text messageLabel text
  CanvasItem.show messageLabel
  getNode' @"MessageTimer" self >>= (`Timer.start` Nothing)

show_game_over :: HUD -> IO ()
show_game_over self = do
  show_message self =<< toLowLevel "Game Over"
  await' @"MessageTimer" @"timeout" self $ \self' -> do
    messageLabel <- getNode' @"MessageLabel" self'
    set_text messageLabel =<< toLowLevel "Dodge the\nCreeps!"
    CanvasItem.show messageLabel
    getNode' @"StartButton" self' >>= CanvasItem.show
  pure ()

update_score :: HUD -> Int -> IO ()
update_score self score = do
  set_text
    <$> getNode' @"ScoreLabel" self 
    <*> toLowLevel (T.pack $ Prelude.show score)
    &   join

setupNode ''HUD "HUD" "HUD"
deriveBase ''HUD


================================================
FILE: examples/dodge-the-creeps/src/Game/Main.hs
================================================
module Game.Main where
import Control.Lens
import Control.Monad
import Foreign.C.Types
import Godot
import Godot.Core.Node as Node
import Godot.Core.Node2D as Node2D
import Godot.Core.Object as Object
import Godot.Core.PackedScene as PackedScene
import Godot.Core.PathFollow2D as PathFollow2D
import Godot.Core.RigidBody2D as RigidBody2D
import Godot.Core.Timer as Timer
import Godot.Gdnative
import Linear.V2
import System.Random
import Project.Support
import Project.Scenes.Main()
import Game.HUD
import Game.Mob
import Game.Player()

data Main = Main
  { _base     :: Node
  , _score    :: MVar Int
  , _mobScene :: MVar PackedScene
  }
makeFieldsNoPrefix ''Main

instance NodeInit Main where
  init b = Main b <$> newMVar 0 <*> newEmptyMVar

instance NodeMethod Main "_on_MobTimer_timeout" '[] (IO ()) where
  nodeMethod = on_MobTimer_timeout
instance NodeMethod Main "_on_StartTimer_timeout" '[] (IO ()) where
  nodeMethod = on_StartTimer_timeout
instance NodeMethod Main "_on_ScoreTimer_timeout" '[] (IO ()) where
  nodeMethod = on_ScoreTimer_timeout
instance NodeMethod Main "game_over" '[] (IO ()) where
  nodeMethod = game_over
instance NodeMethod Main "new_game" '[] (IO ()) where
  nodeMethod = new_game

instance NodeProperty Main "PackedScene" PackedScene 'False where
  nodeProperty = createMVarProperty' "PackedScene" _mobScene (Left VariantTypeObject)

game_over :: Main -> IO ()
game_over self = do
  getNode' @"ScoreTimer"  self  >>= Timer.stop
  getNode' @"MobTimer"    self  >>= Timer.stop
  getNodeNativeScript' @"HUD" self >>= show_game_over & void

new_game :: Main -> IO ()
new_game self = do
  void $ swapMVar (self ^. score) 0
  position <- getNode' @"StartPosition" self >>= get_position
  void $ call
    <$> getNodeNativeScript' @"Player" self 
    <*> toLowLevel "_start"
    <*> pure [toVariant position]
    &   join
  getNode' @"StartTimer" self >>= start `flip` Nothing
  hud <- getNodeNativeScript' @"HUD" self
  update_score hud 0
  show_message hud =<< toLowLevel "Get Ready!"

on_StartTimer_timeout :: Main -> IO ()
on_StartTimer_timeout self = do
  getNode' @"MobTimer" self  >>= start `flip` Nothing
  getNode' @"ScoreTimer" self  >>= start `flip` Nothing

on_ScoreTimer_timeout :: Main -> IO ()
on_ScoreTimer_timeout self = do
  modifyMVar_ (self ^. score) (pure . (+) 1)
  update_score
    <$> getNodeNativeScript' @"HUD" self
    <*> readMVar (self ^. score)
    &   join

on_MobTimer_timeout :: Main -> IO ()
on_MobTimer_timeout self@(Main _ _ mobScene_) = do
  -- Choose a random location on Path2D.
  mobSpawnLoc <- getNode' @"MobPath/MobSpawnLocation" self 
  PathFollow2D.set_offset mobSpawnLoc . fromInteger =<< randomIO
  -- Create a Mob instance and add it to the scene.
  mob :: Mob <- readMVar mobScene_
            >>= (`PackedScene.instance'` Just 0)
            >>= (asNativeScript . upcast)
            >>= maybe (error "Couldn't cast mob to NativeScript") pure
  add_child self (upcast mob) (Just False)
  -- Set the mob's direction perpendicular to the path direction.
  direction <- get_rotation mobSpawnLoc <&> (+ pi / 2)
  -- Set the mob's position to a random location.
  Node2D.set_position mob =<< get_position mobSpawnLoc
  -- Add some randomness to the direction.
  direction' <- (direction +) <$> randomRIO ((-pi) / 4, pi / 4)
  set_rotation mob direction'
  -- Set the velocity' (speed & direction).
  liftM2 (,) (readMVar $ _mMinSpeed mob) (readMVar $ _mMaxSpeed mob)
    >>= randomRIO
    >>= (\x -> toLowLevel (V2 x 0))
    >>= (`godot_vector2_rotated` CFloat direction')
    >>= set_linear_velocity mob

setupNode ''Main "Main" "Main"
deriveBase ''Main


================================================
FILE: examples/dodge-the-creeps/src/Game/Mob.hs
================================================
module Game.Mob where
import Godot
import Godot.Core.AnimatedSprite as AnimatedSprite
import Godot.Core.Node as Node
import System.Random
import Project.Support
import Project.Scenes.Mob()

data Mob = Mob
  { _mBase :: RigidBody2D
  , _mMinSpeed :: MVar Float
  , _mMaxSpeed :: MVar Float
  , _mMobTypes :: MVar [Text]
  }

instance NodeInit Mob where
  init base = Mob base <$> newMVar 150 <*> newMVar 250 <*> newMVar ["walk", "swim", "fly"]
instance NodeMethod Mob "_ready" '[] (IO ()) where
  nodeMethod self = do
        let randElem xs = (xs !!) <$> randomRIO (0, length xs - 1)
        randAnim <- readMVar (_mMobTypes self) >>= randElem >>= toLowLevel
        getNode' @"AnimatedSprite" self >>= (`set_animation` randAnim)
instance NodeMethod Mob "_on_VisibilityNotifier2D_screen_exited" '[] (IO ()) where
  nodeMethod = queue_free

setupNode ''Mob "Mob" "Mob"
deriveBase ''Mob


================================================
FILE: examples/dodge-the-creeps/src/Game/Player.hs
================================================
module Game.Player where
import Control.Lens
import Control.Monad
import Godot
import Godot.Core.AnimatedSprite as AnimatedSprite
import Godot.Core.CanvasItem as CanvasItem
import Godot.Core.CollisionShape2D as CollisionShape2D
import Godot.Core.Input as Input
import Godot.Core.Node2D as Node2D
import Godot.Core.Object as Object
import Godot.Gdnative
import Linear.Metric (normalize)
import Linear.V2
import Linear.Vector
import Project.Support
import Project.Scenes.Player()

data Player = Player
  { _pBase :: Area2D
  , _pSpeed :: MVar Float
  , _pScreenSize :: MVar (V2 Float)
  }

instance NodeInit Player where
  init base = Player base <$> newMVar 400 <*> newMVar zero

instance NodeMethod Player "_ready" '[] (IO ()) where
  nodeMethod = player_ready
instance NodeMethod Player "_process" '[Float] (IO ()) where
  nodeMethod = player_process
instance NodeMethod Player "_start" '[Vector2] (IO ()) where
  nodeMethod = player_start
instance NodeMethod Player "_on_Player_body_entered" '[Node] (IO ()) where
  nodeMethod self _body = do
    hide self -- Player disappears after being hit.
    emit_signal' @"hit" self []
    getNode' @"CollisionShape2D" self  >>= \cSh -> do
      disable <- toLowLevel "set_disabled"
      call_deferred cSh disable [VariantBool True]

instance NodeProperty Player "Player" Float 'False where
  nodeProperty = createMVarProperty' "Player" _pSpeed (Right 400)

instance NodeSignal Player "hit" '[]

player_ready :: Player -> IO ()
player_ready self = do
  screenRect <- get_viewport_rect self >>= fromLowLevel
  void $ swapMVar (_pScreenSize self) (screenRect ^. _y)
  hide self

player_start :: Player -> Vector2 -> IO ()
player_start self pos = do
  set_position self pos
  CanvasItem.show self
  getNode' @"CollisionShape2D" self >>= (`set_disabled` False)

player_process :: Player -> Float -> IO ()
player_process self delta = do
  animSprite              <- getNode' @"AnimatedSprite" self 
  screenSize              <- get_viewport_rect self >>= fromLowLevel <&> (^. _y)
  [left, right, up, down] <- do
    Just inp <- getSingleton @Input
    let isActionPressed = is_action_pressed inp <=< toLowLevel
    mapM isActionPressed ["ui_left", "ui_right", "ui_up", "ui_down"]
  let velocity =
        let bVal b v = if b then v else 0
        in  V2 (bVal left (-1) + bVal right 1) (bVal up (-1) + bVal down 1)
  if velocity /= zero
    then do
      speed <- readMVar (_pSpeed self)
      pos   <- get_position self >>= fromLowLevel
      let velocity' = normalize velocity ^* speed
          pos'      = pos + velocity' ^* delta
          clamp v a b = max a (min b v)
          newPos =
            let posX = clamp (pos' ^. _x) 0 (screenSize ^. _x)
                posY = clamp (pos' ^. _y) 0 (screenSize ^. _y)
            in  V2 posX posY
      set_position self =<< toLowLevel newPos
      animationName <- toLowLevel ""
      play animSprite (Just animationName) Nothing
      if velocity' ^. _x /= 0
        then do
          set_animation animSprite =<< toLowLevel "right"
          -- official demo sets flip_v to false but this is better
          set_flip_v animSprite (velocity' ^. _y > 0)
          set_flip_h animSprite (velocity' ^. _x < 0)
        else when (velocity' ^. _y /= 0) $ do
          set_animation animSprite =<< toLowLevel "up"
          set_flip_v animSprite (velocity' ^. _y > 0)
    else stop animSprite

setupNode ''Player "Player" "Player"
deriveBase ''Player


================================================
FILE: examples/dodge-the-creeps/src/Lib.hs
================================================
module Lib (exports) where
import Godot
import Game.Mob
import Game.Main
import Game.Player
import Game.HUD
import Project.Support
import Project.Requirements

exports :: GdnativeHandle -> IO ()
exports = registerAll' @Nodes @'[HUD, Main, Mob, Player]


================================================
FILE: examples/dodge-the-creeps/src/Project/Requirements.hs
================================================
-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT

module Project.Requirements where
import Project.Support

type Nodes = '[OneResourceNode "HUD" "HUD", OneResourceNode "Main" "Main", OneResourceNode "Mob" "Mob", OneResourceNode "Player" "Player"]


================================================
FILE: examples/dodge-the-creeps/src/Project/Scenes/HUD.hs
================================================
-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT

{-# LANGUAGE FlexibleContexts, FunctionalDependencies, MultiParamTypeClasses,
  UndecidableInstances, OverloadedStrings, TemplateHaskell, TypeApplications,
  TypeFamilies, DataKinds, TypeOperators, FlexibleInstances, RankNTypes,
  AllowAmbiguousTypes, ScopedTypeVariables, DerivingStrategies,
  GeneralizedNewtypeDeriving, LambdaCase #-}

module Project.Scenes.HUD where
import Project.Support
import Godot
import GHC.TypeLits

import Godot.Core.CanvasLayer()
import Godot.Core.Label()
import Godot.Core.Timer()
import Godot.Core.Button()

instance SceneResourcePath "HUD" where
  sceneResourcePath = "res://HUD.tscn"


instance SceneRoot "HUD" where
  type SceneRootNode "HUD" = "HUD"


instance SceneNode        "HUD" "HUD" where
  type SceneNodeType      "HUD" "HUD" = CanvasLayer
  type SceneNodeName      "HUD" "HUD" = "HUD"
  type SceneNodeIsHaskell "HUD" "HUD" = 'Just '("HUD", "HUD")


instance SceneNode        "HUD" "MessageLabel" where
  type SceneNodeType      "HUD" "MessageLabel" = Label
  type SceneNodeName      "HUD" "MessageLabel" = "MessageLabel"
  type SceneNodeIsHaskell "HUD" "MessageLabel" = 'Nothing


instance SceneNode        "HUD" "MessageTimer" where
  type SceneNodeType      "HUD" "MessageTimer" = Timer
  type SceneNodeName      "HUD" "MessageTimer" = "MessageTimer"
  type SceneNodeIsHaskell "HUD" "MessageTimer" = 'Nothing


instance SceneNode        "HUD" "ScoreLabel" where
  type SceneNodeType      "HUD" "ScoreLabel" = Label
  type SceneNodeName      "HUD" "ScoreLabel" = "ScoreLabel"
  type SceneNodeIsHaskell "HUD" "ScoreLabel" = 'Nothing


instance SceneNode        "HUD" "StartButton" where
  type SceneNodeType      "HUD" "StartButton" = Button
  type SceneNodeName      "HUD" "StartButton" = "StartButton"
  type SceneNodeIsHaskell "HUD" "StartButton" = 'Nothing


instance SceneConnection "HUD" "MessageTimer" "timeout" "HUD" "_on_MessageTimer_timeout"


instance SceneConnection "HUD" "StartButton" "pressed" "HUD" "_on_StartButton_pressed"



================================================
FILE: examples/dodge-the-creeps/src/Project/Scenes/Main.hs
================================================
-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT

{-# LANGUAGE FlexibleContexts, FunctionalDependencies, MultiParamTypeClasses,
  UndecidableInstances, OverloadedStrings, TemplateHaskell, TypeApplications,
  TypeFamilies, DataKinds, TypeOperators, FlexibleInstances, RankNTypes,
  AllowAmbiguousTypes, ScopedTypeVariables, DerivingStrategies,
  GeneralizedNewtypeDeriving, LambdaCase #-}

module Project.Scenes.Main where
import Project.Support
import Godot
import GHC.TypeLits

import Godot.Core.ColorRect()
import Godot.Core.PackedScene()
import Godot.Core.Node()
import Godot.Core.Path2D()
import Godot.Core.PathFollow2D()
import Godot.Core.Timer()
import Godot.Core.Position2D()

instance SceneResourcePath "Main" where
  sceneResourcePath = "res://Main.tscn"


instance SceneRoot "Main" where
  type SceneRootNode "Main" = "Main"


instance SceneNode        "Main" "ColorRect" where
  type SceneNodeType      "Main" "ColorRect" = ColorRect
  type SceneNodeName      "Main" "ColorRect" = "ColorRect"
  type SceneNodeIsHaskell "Main" "ColorRect" = 'Nothing


instance SceneNode        "Main" "HUD" where
  type SceneNodeType      "Main" "HUD" = PackedScene' "HUD"
  type SceneNodeName      "Main" "HUD" = "HUD"
  type SceneNodeIsHaskell "Main" "HUD" = 'Just '("HUD", "HUD")


instance SceneNode        "Main" "Main" where
  type SceneNodeType      "Main" "Main" = Node
  type SceneNodeName      "Main" "Main" = "Main"
  type SceneNodeIsHaskell "Main" "Main" = 'Just '("Main", "Main")


instance SceneNode        "Main" "MobPath" where
  type SceneNodeType      "Main" "MobPath" = Path2D
  type SceneNodeName      "Main" "MobPath" = "MobPath"
  type SceneNodeIsHaskell "Main" "MobPath" = 'Nothing


instance SceneNode        "Main" "MobPath/MobSpawnLocation" where
  type SceneNodeType      "Main" "MobPath/MobSpawnLocation" = PathFollow2D
  type SceneNodeName      "Main" "MobPath/MobSpawnLocation" = "MobSpawnLocation"
  type SceneNodeIsHaskell "Main" "MobPath/MobSpawnLocation" = 'Nothing


instance SceneNode        "Main" "MobTimer" where
  type SceneNodeType      "Main" "MobTimer" = Timer
  type SceneNodeName      "Main" "MobTimer" = "MobTimer"
  type SceneNodeIsHaskell "Main" "MobTimer" = 'Nothing


instance SceneNode        "Main" "Player" where
  type SceneNodeType      "Main" "Player" = PackedScene' "Player"
  type SceneNodeName      "Main" "Player" = "Player"
  type SceneNodeIsHaskell "Main" "Player" = 'Just '("Player", "Player")


instance SceneNode        "Main" "ScoreTimer" where
  type SceneNodeType      "Main" "ScoreTimer" = Timer
  type SceneNodeName      "Main" "ScoreTimer" = "ScoreTimer"
  type SceneNodeIsHaskell "Main" "ScoreTimer" = 'Nothing


instance SceneNode        "Main" "StartPosition" where
  type SceneNodeType      "Main" "StartPosition" = Position2D
  type SceneNodeName      "Main" "StartPosition" = "StartPosition"
  type SceneNodeIsHaskell "Main" "StartPosition" = 'Nothing


instance SceneNode        "Main" "StartTimer" where
  type SceneNodeType      "Main" "StartTimer" = Timer
  type SceneNodeName      "Main" "StartTimer" = "StartTimer"
  type SceneNodeIsHaskell "Main" "StartTimer" = 'Nothing


instance SceneConnection "Main" "HUD" "start_game" "Main" "new_game"


instance SceneConnection "Main" "StartTimer" "timeout" "Main" "_on_StartTimer_timeout"


instance SceneConnection "Main" "ScoreTimer" "timeout" "Main" "_on_ScoreTimer_timeout"


instance SceneConnection "Main" "MobTimer" "timeout" "Main" "_on_MobTimer_timeout"


instance SceneConnection "Main" "Player" "hit" "Main" "game_over"



================================================
FILE: examples/dodge-the-creeps/src/Project/Scenes/Mob.hs
================================================
-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT

{-# LANGUAGE FlexibleContexts, FunctionalDependencies, MultiParamTypeClasses,
  UndecidableInstances, OverloadedStrings, TemplateHaskell, TypeApplications,
  TypeFamilies, DataKinds, TypeOperators, FlexibleInstances, RankNTypes,
  AllowAmbiguousTypes, ScopedTypeVariables, DerivingStrategies,
  GeneralizedNewtypeDeriving, LambdaCase #-}

module Project.Scenes.Mob where
import Project.Support
import Godot
import GHC.TypeLits

import Godot.Core.AnimatedSprite()
import Godot.Core.CollisionShape2D()
import Godot.Core.RigidBody2D()
import Godot.Core.VisibilityNotifier2D()

instance SceneResourcePath "Mob" where
  sceneResourcePath = "res://Mob.tscn"


instance SceneRoot "Mob" where
  type SceneRootNode "Mob" = "Mob"


instance SceneNode        "Mob" "AnimatedSprite" where
  type SceneNodeType      "Mob" "AnimatedSprite" = AnimatedSprite
  type SceneNodeName      "Mob" "AnimatedSprite" = "AnimatedSprite"
  type SceneNodeIsHaskell "Mob" "AnimatedSprite" = 'Nothing


instance SceneNode        "Mob" "CollisionShape2D" where
  type SceneNodeType      "Mob" "CollisionShape2D" = CollisionShape2D
  type SceneNodeName      "Mob" "CollisionShape2D" = "CollisionShape2D"
  type SceneNodeIsHaskell "Mob" "CollisionShape2D" = 'Nothing


instance SceneNode        "Mob" "Mob" where
  type SceneNodeType      "Mob" "Mob" = RigidBody2D
  type SceneNodeName      "Mob" "Mob" = "Mob"
  type SceneNodeIsHaskell "Mob" "Mob" = 'Just '("Mob", "Mob")


instance SceneNode        "Mob" "VisibilityNotifier2D" where
  type SceneNodeType      "Mob" "VisibilityNotifier2D" = VisibilityNotifier2D
  type SceneNodeName      "Mob" "VisibilityNotifier2D" = "VisibilityNotifier2D"
  type SceneNodeIsHaskell "Mob" "VisibilityNotifier2D" = 'Nothing


instance SceneConnection "Mob" "VisibilityNotifier2D" "screen_exited" "Mob" "_on_VisibilityNotifier2D_screen_exited"



================================================
FILE: examples/dodge-the-creeps/src/Project/Scenes/Player.hs
================================================
-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT

{-# LANGUAGE FlexibleContexts, FunctionalDependencies, MultiParamTypeClasses,
  UndecidableInstances, OverloadedStrings, TemplateHaskell, TypeApplications,
  TypeFamilies, DataKinds, TypeOperators, FlexibleInstances, RankNTypes,
  AllowAmbiguousTypes, ScopedTypeVariables, DerivingStrategies,
  GeneralizedNewtypeDeriving, LambdaCase #-}

module Project.Scenes.Player where
import Project.Support
import Godot
import GHC.TypeLits

import Godot.Core.AnimatedSprite()
import Godot.Core.CollisionShape2D()
import Godot.Core.Area2D()

instance SceneResourcePath "Player" where
  sceneResourcePath = "res://Player.tscn"


instance SceneRoot "Player" where
  type SceneRootNode "Player" = "Player"


instance SceneNode        "Player" "AnimatedSprite" where
  type SceneNodeType      "Player" "AnimatedSprite" = AnimatedSprite
  type SceneNodeName      "Player" "AnimatedSprite" = "AnimatedSprite"
  type SceneNodeIsHaskell "Player" "AnimatedSprite" = 'Nothing


instance SceneNode        "Player" "CollisionShape2D" where
  type SceneNodeType      "Player" "CollisionShape2D" = CollisionShape2D
  type SceneNodeName      "Player" "CollisionShape2D" = "CollisionShape2D"
  type SceneNodeIsHaskell "Player" "CollisionShape2D" = 'Nothing


instance SceneNode        "Player" "Player" where
  type SceneNodeType      "Player" "Player" = Area2D
  type SceneNodeName      "Player" "Player" = "Player"
  type SceneNodeIsHaskell "Player" "Player" = 'Just '("Player", "Player")


instance SceneConnection "Player" "Player" "body_entered" "Player" "_on_Player_body_entered"



================================================
FILE: examples/dodge-the-creeps/src/Project/Scenes.hs
================================================
-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT

module Project.Scenes (module M) where
import qualified Project.Scenes.HUD as M
import qualified Project.Scenes.Main as M
import qualified Project.Scenes.Mob as M
import qualified Project.Scenes.Player as M



================================================
FILE: examples/dodge-the-creeps/src/Project/Support.hs
================================================
-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT

{-# LANGUAGE FlexibleContexts, FunctionalDependencies, MultiParamTypeClasses,
  UndecidableInstances, OverloadedStrings, TemplateHaskell, TypeApplications,
  TypeFamilies, DataKinds, TypeOperators, FlexibleInstances, RankNTypes,
  AllowAmbiguousTypes, ScopedTypeVariables, DerivingStrategies,
  GeneralizedNewtypeDeriving, LambdaCase #-}

{-# OPTIONS_GHC -Wno-name-shadowing #-}

module Project.Support where
import Godot.Core.Object
import Godot.Internal.Dispatch
import Godot.Gdnative.Internal.Types
import Data.Typeable
import qualified Data.Text as T
import qualified Data.Map as M
import Language.Haskell.TH
import Language.Haskell.TH.Datatype
import Control.Lens
import Control.Monad
import Godot
import Godot.Gdnative
import GHC.TypeLits
import Data.List
import Data.Maybe
import Data.Coerce
import Godot.Core.ResourceLoader
import Godot.Core.PackedScene

-- * Helper to keep Haskell types in sync with the Godot project.
newtype PackedScene' (scene :: Symbol) = PackedScene' PackedScene
                        deriving newtype AsVariant
instance HasBaseClass (PackedScene' scene) where
        type BaseClass (PackedScene' scene) = PackedScene
        super = coerce
deriveBase ''PackedScene'

-- | Use this to register all of your classes, it makes sure that you don't
-- forget a class that Godot needs.
-- 
-- exports :: GdnativeHandle -> IO ()
-- exports desc = registerAll' @Nodes @'[HUD, Main, Mob, Player] desc
registerAll' :: forall (res :: [*]) (ns :: [*]). ImplementedInHaskell res ns => GdnativeHandle -> IO ()
registerAll' = fill @res @ns

-- | A safe version of getNode; gives you back the Godot object
-- getNode' @"MobPath/MobSpawnLocation" self
getNode' :: forall label b cls scene name. (Object :< cls, Node :< cls,
                                      Node :< b,
                                      NodeInScene scene name cls,
                                      SceneNode scene label,
                                      SceneNodeType scene label ~ b,
                                      KnownSymbol label)
         => cls -> IO b
getNode' o = getNode @(SceneNodeType scene label) o (T.pack $ symbolVal (Proxy @label))

-- | A safe version of getNodeNativeScript; gives you back the Haskell object
-- getNodeNativeScript' @"HUD" self
getNodeNativeScript' :: forall label b cls scene name scene' label'.
                        (NativeScript b, Node :< cls, Object :< cls, NodeInScene scene name cls,
                         SceneNodeIsHaskell scene label ~ 'Just '(scene', label'),
                         NodeInScene scene' label' b,
                         KnownSymbol label)
                     => cls -> IO b
getNodeNativeScript' cls = getNodeNativeScript @b cls (T.pack $ symbolVal (Proxy @label))

-- | A safe version of emit_signal; will error at compile time if the signal doesn't exist
-- emit_signal' @"hit" self []
-- TODO We don't check arguments yet!
emit_signal' :: forall label args cls.
               (Object :< cls, Object :< cls, NodeSignal cls label args, KnownSymbol label)
             => cls -> [Variant 'GodotTy] -> IO ()
emit_signal' cls args = do
  name <- toLowLevel (T.pack $ symbolVal (Proxy @label))
  emit_signal cls name args

-- | A safe version of await; will error at compile time if the signal and nodes don't exist
-- await' @"MessageTimer" @"timeout" self $ \self' -> pure ()
await' :: forall (label :: Symbol) (signal :: Symbol) a b cls scene name.
         (NodeInScene scene name cls, NativeScript cls, KnownSymbol label, KnownSymbol signal,
          SceneNode scene label, Node :< cls, AsVariant a, Node :< SceneNodeType scene label,
          NodeSignal b signal '[], SceneNodeType scene label ~ b)
       => cls -> (cls -> IO a) -> IO ()
await' o f = do
  n <- getNode' @label o
  await o n (T.pack $ symbolVal (Proxy @signal)) f

-- | Preload a scene so you can instantiate it later.
-- Use this when the scene is known ahead of time. Store scenes in as @PackedScene' "SceneName"@
preloadScene :: forall scene. (KnownSymbol scene, SceneResourcePath scene) => IO (PackedScene' scene)
preloadScene = do
  Just r <- getSingleton @ResourceLoader
  path <- toLowLevel $ sceneResourcePath @scene
  PackedScene' <$> (tryCast' =<< load r path Nothing Nothing)

-- | Create an instance of a scene from a @PackedScene' "SceneName"@
-- Makes sure that you are getting the type of the scene root.
sceneInstance :: forall scene o. (Node :< o, Typeable o, AsVariant o, SceneNodeType scene (SceneRootNode scene) ~ o) => PackedScene' scene -> IO o
sceneInstance e = tryCast' =<< instance' e Nothing

-- | Combines nodeMethod with getNode' to call functions in a type-safe way
-- Provides no additional safety compared to using the two separately, but does clean up code a bit.
-- For example: fn @"MyNode" @"hide" self
fn :: forall (node :: Symbol) (func :: Symbol) scene name cls args ret b.
         (Object :< cls, Node :< cls,
           Node :< SceneNodeType scene node,
           NodeInScene scene name cls, SceneNode scene node,
           NodeMethodSuper (SceneNodeType scene node) func args ret,
           ListToFun args ret ~ IO b, KnownSymbol node) => cls -> IO b
fn self = nodeMethod' @_ @func =<< getNode' @node self

-- | Get the file path to the scene
class SceneResourcePath (scene :: Symbol) where
  sceneResourcePath :: forall scene. T.Text

-- * Internal helpers: You won't use these

-- | The root node of a scene
class SceneRoot (scene :: Symbol) where
  type SceneRootNode scene :: Symbol

-- | A node in the scene, we know its type and its name, @s@ is the path relate
-- to the scene
class (Typeable (SceneNodeType scene s),
       AsVariant (SceneNodeType scene s),
       Object :< SceneNodeType scene s) => SceneNode (scene :: Symbol) (s :: Symbol) where
  type SceneNodeType scene s :: *
  type SceneNodeName scene s :: Symbol
  type SceneNodeIsHaskell scene s :: Maybe (Symbol, Symbol)

-- | You declare this for your types. You offer up a haskell type, @n@, for the
-- node. This class verifies that your base class is correct.
class (HasBaseClass n, BaseClass n ~ SceneNodeType scene s) =>
      NodeInScene (scene :: Symbol) (s :: Symbol) n | scene s -> n, n -> scene s

-- | A connection between nodes in a scene. @from@ and @to@ are paths.
-- It connects @signal@ in @from@ to @method@ in @to@.
class SceneConnection (scene :: Symbol) (from :: Symbol) (signal :: Symbol) (to :: Symbol) (method :: Symbol)

-- | Internal, just for convenience
data OneResourceNode (resource :: Symbol) (name :: Symbol)

-- | Internal. Don't touch this and don't make instances of it. It's the
-- workhorse for making sure that you are implementing all of the classes that
-- Godot needs, nothing more and nothing less.
class ImplementedInHaskell (a :: [*]) (b :: [*]) where
  fill :: GdnativeHandle -> IO ()

instance ImplementedInHaskell '[] '[] where
  fill _ = pure ()

registerOne :: forall ty. (NativeScript ty, AsVariant (BaseClass ty)) => GdnativeHandle -> IO ()
registerOne desc = registerClass $ RegClass desc $ classInit @ty

instance (NodeInScene scene name n,
          NativeScript n, AsVariant (BaseClass n),
          ImplementedInHaskell t t',
          SceneNodeIsHaskell scene name ~ 'Just '(resource, name))
          => ImplementedInHaskell (OneResourceNode resource name ': t) (n ': t') where
  fill handle = do
    registerOne @n handle
    fill @t @t' handle

-- | Create a signal
-- TODO args ~ '[] is temproary, we need signeltons to reflect this into a runtime value
signal' :: forall cls label args.
          (NodeSignal cls label args, KnownSymbol label, args ~ '[])
        => (Text, [SignalArgument])
signal' = signal (T.pack $ symbolVal (Proxy @label)) []

createMVarProperty' :: (Typeable ty, AsVariant ty) => Text
                    -> (node -> MVar ty)
                    -- ^ We typically can't do IO (for initialisation) when calling this, in
                    -- which case we need to annotate the type without providing a value.
                    -> Either VariantType ty
                    -> (node -> IO ty
                      ,node -> ty -> IO ()
                      ,Maybe (Object -> node -> IO GodotVariant
                             ,Object -> node -> GodotVariant -> IO ()
                             ,PropertyAttributes))
createMVarProperty' name fieldName tyOrVal =
  (readMVar . fieldName,
   \c t -> propertySetter p undefined c =<< toGodotVariant t,
   Just (propertyGetter p, propertySetter p, propertyAttrs p))
  where p = createMVarProperty name fieldName tyOrVal

appsT :: Type -> [Type] -> Type
appsT t [] = t
appsT t (x:xs) = appsT (AppT t x) xs

-- | Verify that the signal connects to an endpoint that exists and has the right type.
witnessConnection :: forall (scene :: Symbol) (from :: Symbol) (signal :: Symbol) (to :: Symbol) (method :: Symbol) parent sigTy hTy.
                    (SceneNode scene to,
                      NodeSignal parent signal sigTy,
                      -- TODO This the check unsound, but SceneNodeType isn't right for this constraint. What is?
                      -- The warning produced because 'from' is not used is a reminder of this issue.
                      -- parent :< SceneNodeType scene from,
                      NodeMethod hTy method sigTy (IO ()),
                      NodeInScene scene to hTy) => ()
witnessConnection = ()

-- | Sets up a class
class NodeInit n where
  init :: BaseClass n -> IO n

-- | You never implement this. It's a helper so that we can have a more
-- polymorphic call to nodeMethod which will work when the method is implemneted
-- for any parent of the current node.
class NodeMethodSuper node (name :: Symbol) (args :: [*]) (ret :: *) | node name -> args, node name -> ret where
  nodeMethod' :: node -> ListToFun args ret

-- | An instance that supports calling nodeMethod' on your parents This can lead
-- to infinite loops in the type checker on error, so we isolate it in
-- NodeMethodSuper instead of NodeMethod.
instance {-# OVERLAPPABLE #-} (NodeMethod (BaseClass node) name arg ret, HasBaseClass node)
    => NodeMethodSuper node name arg ret where
  nodeMethod' = nodeMethod' @node @name @arg @ret

mkProperty' :: forall node (name :: Symbol) ty. (NodeProperty node name ty 'False, KnownSymbol name) => ClassProperty node
mkProperty' = ClassProperty (T.pack $ symbolVal (Proxy @name)) a s g
  where (_,_,Just (g,s,a)) = nodeProperty @node @name @ty @'False

-- | You should use this as:
--   setupNode ''Ty
--   deriveBase ''Ty
-- This will instantiate everything that your Object needs
setupNode :: Name -> String -> String -> Q [Dec]
setupNode ty scene sceneNode = do
  -- Collect information about all scenes
  tree         <- map unTree . classInstances <$> reify ''(:<)
  sceneRoots   <- M.fromList . map unSceneRootNode . familyInstances <$> reify ''SceneRootNode
  sceneNodes   <- map unSceneNodeType . familyInstances <$> reify ''SceneNodeType
  haskellNodes <- map unNodeInScene . classInstances <$> reify ''NodeInScene
  allSignals   <- map unNodeSignal . classInstances <$> reify ''NodeSignal
  -- Collect information about our node
  rdt <- reifyDatatype ty
  let base = case datatypeCons rdt of
                    (c:_) -> case (constructorFields c, constructorVariant c) of
                              (ConT baseTy:_, RecordConstructor (baseFn:_)) -> Just (baseTy, baseFn)
                              _ -> Nothing
                    _ -> Nothing
  --
  methods    <- filter (\i -> i^._1 == ty) . mapMaybe unNodeMethod . classInstances <$> reify ''NodeMethod
  properties <- filter (\i -> i^._1 == ty) . mapMaybe unNodeProperty . classInstances <$> reify ''NodeProperty
  let signals = filter (\i -> i^._1 == ty) allSignals
  connections <- filter (\i -> i^._1 == scene && i^._4 == sceneNode) . map unConnect . classInstances <$> reify ''SceneConnection
  -- Helpers
  let parentsOf cls = map snd $ filter (\(c,_) -> cls == c) tree
  let nodeToType :: String -> String -> Name
      nodeToType scene node = case (hty, ty ^. _4) of
                                (Just t, _) -> t
                                (_, Nothing) -> ty ^. _3
                                (_, Just scene') -> case M.lookup scene' sceneRoots of
                                                Nothing -> error $ "Looking up the root of a scene that is lacking one. This is a bug. " ++ show (scene', scene, node)
                                                Just node' -> nodeToType scene' node'
        where ty  = fromJust $ find (\n -> n^._1 == scene && n^._2 == node) sceneNodes
              hty = (^._3) <$> find (\n -> n^._1 == scene && n^._2 == node) haskellNodes
  let resolveSignalActualClass scene from signal =
        case mapMaybe (\p -> (p,) <$> find (\s -> s^._2 == signal && s^._1 == p) allSignals) $ parentsOf (nodeToType scene from) of
          -- The root issue is that the signal might not yet exist.
          -- If witnessConnection was not unsound, this would not be needed as the error would happen later.
           [] -> error $ "Class " ++ show from ++ " used in scene " ++ show scene ++ " is lacking a signal named " ++ show signal ++ "\n" ++ show (nodeToType scene from) ++ "\n" ++ show (parentsOf (nodeToType scene from))
           (h:_) -> h ^. _1

  -- Debug
  when False $ runIO $ do
    putStrLn "Regenerating .."
    print rdt
    putStrLn "\nScene roots:"
    print sceneRoots
    putStrLn "\nScene nodes types:"
    mapM_ print sceneNodes
    putStrLn "\nMethods:"
    mapM_ print methods
    putStrLn "\nProperties:"
    mapM_ print properties
    putStrLn "\nSignals:"
    mapM_ print allSignals
    mapM_ print signals
    putStrLn "\nConnections:"
    mapM_ print connections
    putStrLn "\nHaskell nodes:"
    mapM_ print haskellNodes

  -- Generate code
  bi <- case base of
    Just (baseTy, baseFn) ->
      [d|instance HasBaseClass $(pure $ PromotedT ty) where
          type BaseClass $(pure $ PromotedT ty) = $(pure $ PromotedT baseTy)
          super = $(pure $ VarE baseFn)|]
    _ -> error "setupNode can only handle records whose first field is the Godot base class. You can still interface with Godot, but you will need to set things up manually."
  nis <- [d|instance NodeInScene $(pure $ LitT $ StrTyLit scene) $(pure $ LitT $ StrTyLit sceneNode) $(pure $ PromotedT ty)|]
  ns <- [d|instance NativeScript $(pure $ PromotedT ty) where
            classInit = Project.Support.init
            classMethods = $(ListE <$> mapM (\(t,n,argTy,_) ->
                     let m = case nrArguments argTy of
                                  0 -> [e|method0|]
                                  1 -> [e|method1|]
                                  2 -> [e|method2|]
                                  3 -> [e|method3|]
                                  4 -> [e|method4|]
                                  5 -> [e|method5|]
                                  n -> error $ "More arguments than we currently impelement, look for 'method5' for more info " ++ show  n
                     in [e|$m $(pure $ LitE $ StringL n) (nodeMethod @ $(pure $ PromotedT t) @ $(pure $ LitT $ StrTyLit n))|]) methods)
            classProperties = $(ListE <$> mapM (\(name,prop,_,_) -> [e|mkProperty' @ $(pure $ PromotedT name) @ $(pure $ LitT $ StrTyLit prop) |]) properties)
            classSignals = $(ListE <$> mapM (\(ty,name,_) -> [e|signal' @ $(pure $ PromotedT ty) @ $(pure $ LitT $ StrTyLit name)|]) signals)|]
  let cn = mkName $ "witness_connections_" ++ nameBase ty
  ws <- (:) <$> (cn `sigD` [t| [()] |]) <*>
       [d|$(varP cn) =
             $(ListE <$> mapM (\(scene,from,signal,to,method) ->
                    [e|witnessConnection
                        @ $(pure $ LitT $ StrTyLit scene)  @ $(pure $ LitT $ StrTyLit from)
                        @ $(pure $ LitT $ StrTyLit signal) @ $(pure $ LitT $ StrTyLit to)
                        @ $(pure $ LitT $ StrTyLit method)
                        @ $(pure $ PromotedT $ resolveSignalActualClass scene from signal)
                    |]) connections)|]
  pure $ bi <> nis <> ns <> ws

  where
      unTree (InstanceD Nothing [] (AppT (AppT _ parent) child) []) = (unName child, unName parent)
      unTree p = error $ "I don't understand this parent " ++ show p
      unName (ConT x) = x
      unName (AppT (ConT x) _) = x
      unName x = error $ "I don't know how to extract the name of this type: " ++ show x
      unSceneRootNode (TySynInstD (TySynEqn Nothing (AppT _ (LitT (StrTyLit scene))) (LitT (StrTyLit node)))) = (scene,node)
      unSceneRootNode x = error $ "Don't know how unpack this SceneRootNode: " ++ show x
      unSceneNodeType (TySynInstD (TySynEqn Nothing (AppT (AppT _ (LitT (StrTyLit scene))) (LitT (StrTyLit node))) ty))
        = (scene,node,unName ty, unpackScene ty)
      unSceneNodeType x = error $ "Don't know how unpack this SceneNodeType: " ++ show x
      unpackScene (ConT _) = Nothing
      unpackScene (AppT (ConT _) (LitT (StrTyLit scene))) = Just scene
      unpackScene x = error $ "Don't know how unpack this Scene: " ++ show x
      unNodeMethod (InstanceD Nothing [] (AppT (AppT (AppT (AppT (ConT _) (ConT cls)) (LitT (StrTyLit name))) arg) ret) []) 
        = Just (cls, name, arg, ret)
      unNodeMethod _ = Nothing
      unNodeProperty (InstanceD Nothing [] (AppT (AppT (AppT (AppT (ConT _) (ConT cls)) (LitT (StrTyLit name))) arg) ret) []) 
        = Just (cls, name, arg, ret)
      unNodeProperty x = error $ show x
      unNodeInScene (InstanceD Nothing [] (AppT (AppT (AppT (ConT _) (LitT (StrTyLit scene))) (LitT (StrTyLit node))) (ConT hty)) [])
        = (scene, node, hty)
      unNodeInScene x = error $ show x
      unNodeSignal (InstanceD Nothing [] (AppT (AppT (AppT (ConT _) (ConT cls)) (LitT (StrTyLit name))) arg) []) = (cls, name, arg)
      unNodeSignal _ = error "Bad signal"
      unConnect (InstanceD Nothing [] (AppT (AppT (AppT (AppT (AppT _ (LitT (StrTyLit scene))) (LitT (StrTyLit from))) (LitT (StrTyLit signal))) (LitT (StrTyLit to))) (LitT (StrTyLit method))) []) = (scene, from, signal, to, method)
      unConnect x = error $ "Bad signal" ++ show x
      nrArguments :: Type -> Int
      nrArguments (AppT _ r) = 1 + nrArguments r
      nrArguments (SigT PromotedNilT (AppT ListT StarT)) = 0
      nrArguments _ = error "Can't compute # of arguments"
      classInstances :: Info -> [InstanceDec]
      classInstances (ClassI _ is) = is
      classInstances _ = error "Bad class"
      familyInstances :: Info -> [InstanceDec]
      familyInstances (FamilyI _ is) = is
      familyInstances _ = error "Bad class"


================================================
FILE: examples/dodge-the-creeps/stack-shell.nix
================================================
{ nixpkgs ? import ./pinned-nixpkgs.nix {}
, ghc
}:

with nixpkgs;

haskell.lib.buildStackProject {
  inherit ghc;
  name = "myproject";
  buildInputs = [];
}




================================================
FILE: examples/dodge-the-creeps/stack.yaml
================================================
resolver: nightly-2021-02-06

packages:
- .

extra-deps:
- ../../

require-stack-version: ">=1.8"

nix:
  enable: false
  pure: true
  packages: []
  shell-file: stack-shell.nix
  nix-shell-options: []
  path: []
  add-gc-roots: false




================================================
FILE: examples/rss-reader/.gitignore
================================================
dist*
*.hi
*.o
.stack-work/
.stack-work-devel/
*~
\#*
*.import
result




================================================
FILE: examples/rss-reader/ChangeLog.md
================================================
# Empty




================================================
FILE: examples/rss-reader/LICENSE
================================================
BSD 3-Clause License

Copyright (c) Andrei Barbu 2019
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



================================================
FILE: examples/rss-reader/Makefile
================================================
NAME = myproject
STACKLIBFILE = $(shell stack path --local-install-root)/lib/lib$(NAME).so
GODOTPROJECT = $(shell stack path --project-root)/game
all: stack
nix:
	nix-build shell.nix
	cp result/lib/ghc-*/lib$(NAME).so $(GODOTPROJECT)/lib
stack:
	stack build --fast --force-dirty
	cp $(STACKLIBFILE) $(GODOTPROJECT)/lib
stack-nix:
	stack --nix clean $(NAME)
	stack --nix build
	cp $(shell stack --nix path --local-install-root)/lib/lib$(NAME).so $(GODOTPROJECT)/lib
stack-run:
	stack build
	cp $(STACKLIBFILE) $(GODOTPROJECT)/lib
	godot -e --path ./game
stack-watch:
	stack build --file-watch --fast --exec "cp $(STACKLIBFILE) $(GODOTPROJECT)/lib"
project-watch:
	stack exec godot-haskell-project-generator game src
updatelib:
	cp $(STACKLIBFILE) $(GODOTPROJECT)/lib


================================================
FILE: examples/rss-reader/README.md
================================================
The official Godot demo from the manual: Dodge the Creeps.

Run with `make stack` then `godot game/project.godot` and press F5 to start, F8 to end.

Requires Godot 3.1


================================================
FILE: examples/rss-reader/Support.hs
================================================
{-# LANGUAGE FlexibleContexts, FunctionalDependencies, MultiParamTypeClasses, OverloadedLabels, UndecidableInstances,
  OverloadedStrings, TemplateHaskell, TypeApplications, TypeFamilies, DataKinds, TypeOperators, FlexibleInstances #-}

module Generated.Support where
import Godot
import GHC.TypeLits

class SceneNode (scene :: Symbol) (s :: Symbol) where
  type SceneNodeType scene s :: *
  type SceneNodeName scene s :: Symbol

class NodeInScheme (scene :: Symbol) (s :: Symbol) n | scene s -> n, n -> scene s


================================================
FILE: examples/rss-reader/ffi/cbits/flib.c
================================================
#include "HsFFI.h"

static void flib_init() __attribute__((constructor));
static void flib_init() {
  static char *argv[] = { "libGodotHaskellPlugin.so", 0 }, **argv_ = argv;
  static int argc = 1;
  hs_init(&argc, &argv_);
}

static void flib_fini() __attribute__((destructor));
static void flib_fini() {
  hs_exit();
}


================================================
FILE: examples/rss-reader/ffi/flib/FLib.hs
================================================
{-# LANGUAGE ForeignFunctionInterface #-}
module FLib where

import qualified Foreign
import           Foreign(nullPtr, Ptr,newForeignPtr_,castPtr)
import qualified Godot.Gdnative.Internal       as FFI
import           Godot.Gdnative
import           Godot.Nativescript
import           Lib
import qualified Data.Text as T
import qualified Data.Text.IO as T

godot_nativescript_init :: GdnativeHandle -> IO ()
godot_nativescript_init desc = do
  defaultExports desc
  exports desc
  putStrLn "Haskell NativeScript lib initialized"

foreign export ccall godot_nativescript_init :: GdnativeHandle -> IO ()


godot_gdnative_init :: FFI.GdnativeInitOptionsPtr -> IO ()
godot_gdnative_init opts = do
  Foreign.peek opts >>= FFI.initApiStructs

foreign export ccall godot_gdnative_init :: FFI.GdnativeInitOptionsPtr -> IO ()


godot_gdnative_terminate :: FFI.GdnativeTerminateOptionsPtr -> IO ()
godot_gdnative_terminate handle = pure ()

foreign export ccall godot_gdnative_terminate :: FFI.GdnativeTerminateOptionsPtr -> IO ()


================================================
FILE: examples/rss-reader/game/Rss_reader.gdns
================================================
[gd_resource type="NativeScript" load_steps=2 format=2]

[ext_resource path="res://lib/libmyproject.gdnlib" type="GDNativeLibrary" id=1]

[resource]
resource_name = "RSSReader"
class_name = "RSSReader"
library = ExtResource( 1 )


================================================
FILE: examples/rss-reader/game/Rss_reader.tscn
================================================
[gd_scene load_steps=2 format=2]

[ext_resource path="res://Rss_reader.gdns" type="Script" id=1]

[node name="RSSReader" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
margin_right = 1102.0
margin_bottom = 168.0
script = ExtResource( 1 )
__meta__ = {
"_edit_use_anchors_": false
}

[node name="OpenButton" type="Button" parent="."]
margin_left = 34.48
margin_top = 65.522
margin_right = 179.48
margin_bottom = 106.522
text = "Open"
__meta__ = {
"_edit_use_anchors_": false
}

[node name="TextEdit" type="TextEdit" parent="."]
visible = false
margin_left = 20.9119
margin_top = 575.146
margin_right = 585.912
margin_bottom = 868.146
__meta__ = {
"_edit_use_anchors_": false
}

[node name="HTTPRequest" type="HTTPRequest" parent="."]

[node name="ItemList" type="ItemList" parent="."]
margin_left = 25.0
margin_top = 137.0
margin_right = 850.0
margin_bottom = 490.0
__meta__ = {
"_edit_use_anchors_": false
}

[node name="DescriptionField" type="TextEdit" parent="."]
margin_left = 882.0
margin_top = 137.0
margin_right = 1555.0
margin_bottom = 489.0
readonly = true
wrap_enabled = true

[node name="LinkButton" type="LinkButton" parent="."]
margin_left = 29.8409
margin_top = 496.385
margin_right = 1289.84
margin_bottom = 554.385
__meta__ = {
"_edit_use_anchors_": false
}

[node name="SettingsButton" type="Button" parent="."]
margin_left = 1416.23
margin_top = 67.6134
margin_right = 1549.23
margin_bottom = 108.613
text = "Settings"
__meta__ = {
"_edit_use_anchors_": false
}

[node name="SettingsDialog" type="WindowDialog" parent="."]
margin_left = 352.0
margin_top = 256.0
margin_right = 1340.0
margin_bottom = 538.0
__meta__ = {
"_edit_use_anchors_": false
}

[node name="RSSURLText" type="LineEdit" parent="SettingsDialog"]
margin_left = 136.409
margin_top = 89.8409
margin_right = 847.409
margin_bottom = 131.841
__meta__ = {
"_edit_use_anchors_": false
}

[node name="Label" type="Label" parent="SettingsDialog"]
margin_left = 135.431
margin_top = 42.4543
margin_right = 436.431
margin_bottom = 80.4543
text = "The RSS feed URL "

[node name="Button" type="Button" parent="SettingsDialog"]
margin_left = 134.283
margin_top = 161.682
margin_right = 200.283
margin_bottom = 196.682
text = "Clear"

[node name="SaveButton" type="Button" parent="SettingsDialog"]
margin_left = 784.273
margin_top = 159.841
margin_right = 845.273
margin_bottom = 197.841
text = "Save"
__meta__ = {
"_edit_use_anchors_": false
}
[connection signal="ready" from="." to="." method="_on_RSSReader_ready"]
[connection signal="pressed" from="OpenButton" to="." method="_on_OpenButton_pressed"]
[connection signal="request_completed" from="HTTPRequest" to="." method="_on_HTTPRequest_request_completed"]
[connection signal="item_selected" from="ItemList" to="." method="_on_ItemList_item_selected"]
[connection signal="pressed" from="LinkButton" to="." method="_on_LinkButton_pressed"]
[connection signal="pressed" from="SettingsButton" to="." method="_on_SettingsButton_pressed"]
[connection signal="pressed" from="SettingsDialog/Button" to="." method="_on_Settings_Clear_Button_pressed"]
[connection signal="pressed" from="SettingsDialog/SaveButton" to="." method="_on_SaveButton_pressed"]


================================================
FILE: examples/rss-reader/game/export_presets.cfg
================================================
[preset.0]

name="Linux/X11"
platform="Linux/X11"
runnable=true
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../../../../../../../tmp/rssreader.x86_64"
patch_list=PoolStringArray(  )
script_export_mode=1
script_encryption_key=""

[preset.0.options]

texture_format/bptc=false
texture_format/s3tc=true
texture_format/etc=false
texture_format/etc2=false
texture_format/no_bptc_fallbacks=true
binary_format/64_bits=true
binary_format/embed_pck=false
custom_template/release=""
custom_template/debug=""


================================================
FILE: examples/rss-reader/game/lib/libmyproject.gdnlib
================================================
[general]

singleton=false
load_once=true
symbol_prefix="godot_"
reloadable=false

[entry]

X11.64="res://lib/libmyproject.so"


================================================
FILE: examples/rss-reader/game/project.godot
================================================
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
;   [section] ; section goes between []
;   param=value ; assign values to parameters

config_version=4

_global_script_classes=[  ]
_global_script_class_icons={

}

[application]

config/name="rss-reader"
run/main_scene="res://Rss_reader.tscn"

[audio]

default_bus_layout=""

[display]

window/size/width=480
window/size/height=720
window/dpi/allow_hidpi=true

[gdnative]

singletons=[  ]

[gui]

theme/use_hidpi=true


================================================
FILE: examples/rss-reader/godot-haskell.nix
================================================
{ fetchFromGitHub, mkDerivation, aeson, ansi-wl-pprint, base, bytestring, c2hs
, casing, colour, containers, hpack, lens, linear, mtl, parsec
, parsers, stdenv, stm, template-haskell, text
, unordered-containers, vector
}:
mkDerivation {
  pname = "godot-haskell";
  version = "3.1.0.0";
  src = fetchFromGitHub {
    owner = "SimulaVR";
    repo = "godot-haskell";
    rev = "b423d4f2fa5a6a3dcfffb82bb36be571adb29d34"; # godot-haskell rev
    # Use nix-prefetch-git to get the hash
    sha256 = "0jh2j5rr90dqdxvcipygwnhhj7j2dj4zvm6gbdpg106ll60pyqrp";
    fetchSubmodules = true;
  };
  libraryHaskellDepends = [
    aeson ansi-wl-pprint base bytestring casing colour containers lens
    linear mtl parsec parsers stm template-haskell text
    unordered-containers vector
  ];
  libraryToolDepends = [ c2hs hpack ];
  doHaddock = false;
  preConfigure = "hpack";
  homepage = "https://github.com/KaneTW/godot-haskell#readme";
  description = "Haskell bindings for the Godot game engine API";
  license = stdenv.lib.licenses.bsd3;
}




================================================
FILE: examples/rss-reader/hie.yaml
================================================
cradle:
  stack:
    - path: "./src"
      component: "myproject:lib"

    - path: "./game"
      component: "myproject:lib"


================================================
FILE: examples/rss-reader/myproject.cabal
================================================
cabal-version: 1.12

-- This file has been generated from package.yaml by hpack version 0.33.0.
--
-- see: https://github.com/sol/hpack
--
-- hash: b6a0d2a1fc09513a3765e90723389dc19ec4879f3963404979d2a68731de6d6e

name:           myproject
version:        0.0.0.0
description:    Please see the README on Github at <https://github.com/SimulaVR/godot-haskell/tree/master/demo#readme>
homepage:       https://github.com/SimulaVR/godot-haskell#readme
bug-reports:    https://github.com/SimulaVR/godot-haskell/issues
author:         Andrei Barbu
maintainer:     andrei@0xab.com
copyright:      Andrei Barbu 2019, 2021
license:        BSD3
license-file:   LICENSE
build-type:     Simple
extra-source-files:
    ChangeLog.md
    README.md
foreign-library myproject
  type: native-shared
  other-modules: FLib
  hs-source-dirs: ffi/flib
  c-sources: ffi/cbits/flib.c
  build-depends:
      base >= 4.12 && <5
    , godot-haskell
    , myproject
    , text
  default-language: Haskell2010

source-repository head
  type: git
  location: https://github.com/SimulaVR/godot-haskell

library
  exposed-modules:
      Lib
  other-modules:
      Game.RSSReader
      Project.Requirements
      Project.Scenes
      Project.Scenes.Rss_reader
      Project.Support
      Paths_myproject
  hs-source-dirs:
      src
      game
  default-extensions: FlexibleContexts MultiParamTypeClasses OverloadedStrings TemplateHaskell TypeApplications TypeFamilies DataKinds FlexibleInstances ScopedTypeVariables AllowAmbiguousTypes TypeOperators TupleSections
  ghc-options: -Wall -Wno-orphans -O0
  build-depends:
      aeson
    , base >=4.12 && <5
    , containers
    , directory
    , extra
    , godot-haskell
    , lens
    , linear
    , monad-loops
    , random
    , strict-concurrency
    , template-haskell
    , text
    , th-abstraction
    , vector
    , xeno
  default-language: Haskell2010


================================================
FILE: examples/rss-reader/package.yaml
================================================
name: myproject
version: '0.0.0.0'
description: Please see the README on Github at <https://github.com/SimulaVR/godot-haskell/tree/master/demo#readme>
author: Andrei Barbu
maintainer: andrei@0xab.com
copyright: Andrei Barbu 2019, 2021
license: BSD3
github: SimulaVR/godot-haskell
extra-source-files:
  - ChangeLog.md
  - README.md
dependencies:
  - base >=4.12 && <5
  - godot-haskell
  - linear
  - random
  - text
  - vector
  - strict-concurrency
  - lens
  - template-haskell
  - th-abstraction
  - containers
  - extra
  - monad-loops
  - xeno
  - aeson
  - directory
library:
  source-dirs:
    - src
    - game
  default-extensions:
    - FlexibleContexts
    - MultiParamTypeClasses
    - OverloadedStrings
    - TemplateHaskell
    - TypeApplications
    - TypeFamilies
    - DataKinds
    - FlexibleInstances
    - ScopedTypeVariables
    - AllowAmbiguousTypes
    - TypeOperators
    - TupleSections
  exposed-modules:
    - Lib
  ghc-options: -Wall -Wno-orphans -O0

verbatim: |
  foreign-library myproject
    type: native-shared
    other-modules: FLib
    hs-source-dirs: ffi/flib
    c-sources: ffi/cbits/flib.c
    build-depends:
        base >= 4.12 && <5
      , godot-haskell
      , myproject
      , text
    default-language: Haskell2010


================================================
FILE: examples/rss-reader/pinned-nixpkgs.nix
================================================
{}:

let
  # 19.03-beta (25 feb)
  rev = "0c0954781e257b8b0dc49341795a2fe7d96945a3"; # pinned-nixpkgs rev
  pkgs = import (builtins.fetchTarball {
      url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
    }) {};
in
  pkgs




================================================
FILE: examples/rss-reader/shell.nix
================================================
{ nixpkgs ? import ./pinned-nixpkgs.nix {}
, compiler ? "default"
, doBenchmark ? false }:


let

  inherit (nixpkgs) pkgs;

  haskellPackages = if compiler == "default"
                       then pkgs.haskellPackages
                       else pkgs.haskell.packages.${compiler};

  f = { mkDerivation, stdenv, base, godot-haskell, linear, text , vector, stm }:
    mkDerivation {
      pname = "myproject";
      version = "3.1.0.0";
      src = ./.;
      libraryHaskellDepends = [
        base godot-haskell linear text vector stm
      ];
      libraryToolDepends = [];
      homepage = "https://github.com/abarbu/myproject#readme";
      license = stdenv.lib.licenses.bsd3;
    };

  variant = if doBenchmark then pkgs.haskell.lib.doBenchmark else pkgs.lib.id;

  drv = variant (haskellPackages.callPackage f {
      godot-haskell = haskellPackages.callPackage ./godot-haskell.nix {fetchFromGitHub = pkgs.fetchFromGitHub;};
    });

in

  if pkgs.lib.inNixShell then drv.env else drv




================================================
FILE: examples/rss-reader/src/Game/RSSReader.hs
================================================
{-# LANGUAGE LambdaCase, FunctionalDependencies, DeriveGeneric, UndecidableInstances, ConstraintKinds #-}
module Game.RSSReader where
import Control.Lens
import Control.Monad
import Foreign.Ptr
import Godot
import Godot.Core.HTTPClient as HTTPClient
import Godot.Core.OS as OS
import Godot.Core.ItemList as ItemList
import Godot.Core.HTTPRequest as HTTPRequest
import Godot.Core.TextEdit as TextEdit
import Godot.Core.LineEdit as LineEdit
import Godot.Core.LinkButton as LinkButton
import Godot.Core.Popup as Popup
import Godot.Gdnative
import Project.Scenes.Rss_reader()
import Project.Support
import qualified Xeno.DOM.Robust as X
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import Data.List
import Data.Maybe
import Data.Typeable
import GHC.Generics
import qualified Data.Aeson as A
import System.Directory
import qualified Godot.Core.CanvasItem as CanvasItem

data Settings = Settings { _url :: Text }
   deriving (Generic, Show)
instance A.FromJSON Settings
instance A.ToJSON Settings
makeFieldsNoPrefix ''Settings

data Story = Story { _storyTitle :: T.Text
                   , _storyDescription :: Maybe T.Text
                   , _storyLink :: T.Text }
  deriving Show
makeFields ''Story

data RSSReader = RSSReader
  { _base :: Control
  , _feed :: MVar [Story]
  }
makeFieldsNoPrefix ''RSSReader

instance NodeInit RSSReader where
  init base = RSSReader base <$> newMVar []

instance NodeMethod RSSReader "_on_OpenButton_pressed" '[] (IO ()) where
  nodeMethod = populateEdit

instance NodeMethod RSSReader "populateEdit" '[] (IO ()) where
  nodeMethod = populateEdit

instance NodeMethod RSSReader "_on_HTTPRequest_request_completed" [Int, Int, PoolStringArray, PoolByteArray] (IO ()) where
  nodeMethod self _ _ _ body = do
    t <- getNode' @"TextEdit" self
    sz <- godot_pool_byte_array_size body
    s <- (\x -> godot_string_chars_to_utf8_with_len (castPtr x) sz) =<< godot_pool_byte_array_read_access_ptr =<< godot_pool_byte_array_read body
    TextEdit.set_text t s
    contents <- T.encodeUtf8 <$> fromLowLevel s
    let stories = parseXML contents
    lst <- getNode' @"ItemList" self
    void $ swapMVar (self ^. feed) stories
    mapM_ (\s -> ItemList.add_item lst <$> toLowLevel (s ^. title) <*> pure Nothing <*> pure (Just True) & join) stories

instance NodeMethod RSSReader "_on_ItemList_item_selected" '[Int] (IO ()) where
  nodeMethod self n = do
    f <- readMVar (self ^. feed)
    TextEdit.set_text <$> getNode' @"DescriptionField" self
                      <*> toLowLevel (fromMaybe "" $ (f !! n) ^. description)
                      & join
    LinkButton.set_text <$> getNode' @"LinkButton" self
                        <*> toLowLevel ((f !! n) ^. link)
                        & join
    pure ()

instance NodeMethod RSSReader "_on_LinkButton_pressed" '[] (IO ()) where
  nodeMethod self = do
    (Just os) <- getSingleton @OS
    void $ OS.shell_open os =<< LinkButton.get_text =<< getNode' @"LinkButton" self

instance NodeMethod RSSReader "_on_SettingsButton_pressed" '[] (IO ()) where
  nodeMethod self = do
    d <- getNode' @"SettingsDialog" self
    Popup.popup d Nothing

instance NodeMethod RSSReader "_on_Settings_Clear_Button_pressed" '[] (IO ()) where
  nodeMethod self = LineEdit.set_text <$> getNode' @"SettingsDialog/RSSURLText" self
                                      <*> toLowLevel ""
                                       & join

instance NodeMethod RSSReader "_on_RSSReader_ready" '[] (IO ()) where
  nodeMethod self = loadData self

instance NodeMethod RSSReader "_on_SaveButton_pressed" '[] (IO ()) where
  nodeMethod self = do
      saveData self
      CanvasItem.hide =<< getNode' @"SettingsDialog" self
      pure ()

clearFields (self :: RSSReader) = do
  void $ swapMVar (self ^. feed) []
  ItemList.clear =<< getNode' @"ItemList" self
  TextEdit.set_text <$> getNode' @"DescriptionField" self <*> toLowLevel "" & join
  LinkButton.set_text <$> getNode' @"LinkButton" self <*> toLowLevel "" & join
  pure ()

saveData self = do
  putStrLn "Saving data"
  (Just os) <- getSingleton @OS
  d <- fromLowLevel =<< OS.get_user_data_dir os
  t <- fromLowLevel =<< LineEdit.get_text =<< getNode' @"SettingsDialog/RSSURLText" self
  A.encodeFile (T.unpack d <> "/save_config.json") (Settings t)

loadData self = do
  putStrLn "Loading data"
  (Just os) <- getSingleton @OS
  d <- fromLowLevel =<< OS.get_user_data_dir os
  e <- doesFileExist (T.unpack d <> "/save_config.json")
  when e $ do
    r <- A.decodeFileStrict' (T.unpack d <> "/save_config.json")
    case r of
      Nothing -> pure ()
      Just (s :: Settings) -> do
        LineEdit.set_text <$> getNode' @"SettingsDialog/RSSURLText" self
          <*> toLowLevel (s ^. url)
          & join

parseXML x = case X.parse x of
            Right xml -> do
              case X.children xml of
                [chan] -> do
                  mapMaybe unItem $ X.children chan
                _ -> error "Unknown RSS"
            Left a -> []
  where head' (h:_) = Just h
        head' _ = Nothing
        byName name nodes = head' . nodeData =<< find (\e -> X.name e == name) nodes
        nodeData = mapMaybe (\case
                                X.Text t -> Just t
                                X.CData t -> Just t
                                _ -> Nothing) . X.contents
        unItem item = let nodes = X.children item
                      in do
                         t <- byName "title" nodes
                         l <- byName "link" nodes
                         pure $ Story (T.decodeUtf8 t) (T.decodeUtf8 <$> byName "description" nodes) (T.decodeUtf8 l)

nothing :: (Object :< a, Typeable a, AsVariant a) => IO a
nothing = fromJust <$> tryCast (Object nullPtr)

populateEdit :: RSSReader -> IO ()
populateEdit self = do
  url <- LineEdit.get_text =<< getNode' @"SettingsDialog/RSSURLText" self
  void $ HTTPRequest.request <$> getNode' @"HTTPRequest" self
                             <*> pure url
                             <*> (Just <$> godot_pool_string_array_new)
                             <*> pure (Just True)
                             <*> pure (Just HTTPClient._METHOD_GET)
                             <*> pure Nothing
                             & join

setupNode ''RSSReader "Rss_reader" "RSSReader"
deriveBase ''RSSReader


================================================
FILE: examples/rss-reader/src/Game/q
================================================
{-# LANGUAGE LambdaCase, FunctionalDependencies, DeriveGeneric, UndecidableInstances, ConstraintKinds #-}
module Game.RSSReader where
import Control.Lens
import Control.Monad
import Foreign.Ptr
import Godot
import Godot.Core.HTTPClient as HTTPClient
import Godot.Core.OS as OS
import Godot.Core.ItemList as ItemList
import Godot.Core.HTTPRequest as HTTPRequest
import Godot.Core.TextEdit as TextEdit
import Godot.Core.LineEdit as LineEdit
import Godot.Core.LinkButton as LinkButton
import Godot.Core.Popup as Popup
import Godot.Gdnative
import Project.Scenes.Rss_reader()
import Project.Support
import qualified Xeno.DOM.Robust as X
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import Data.List
import Data.Maybe
import Data.Typeable
import GHC.Generics
import qualified Data.Aeson as A
import System.Directory
import qualified Godot.Core.CanvasItem as CanvasItem

data Settings = Settings { _url :: Text }
   deriving (Generic, Show)
instance A.FromJSON Settings
instance A.ToJSON Settings
makeFieldsNoPrefix ''Settings

data Story = Story { _storyTitle :: T.Text
                   , _storyDescription :: Maybe T.Text
                   , _storyLink :: T.Text }
  deriving Show
makeFields ''Story

data RSSReader = RSSReader
  { _base :: Control
  , _feed :: MVar [Story]
  }
makeFieldsNoPrefix ''RSSReader

instance NodeInit RSSReader where
  init base = RSSReader base <$> newMVar []

instance NodeMethod RSSReader "_on_OpenButton_pressed" '[] (IO ()) where
  nodeMethod = populateEdit

instance NodeMethod RSSReader "populateEdit" '[] (IO ()) where
  nodeMethod = populateEdit

instance NodeMethod RSSReader "_on_HTTPRequest_request_completed" [Int, Int, PoolStringArray, PoolByteArray] (IO ()) where
  nodeMethod self _ _ _ body = do
    t <- getNode' @"TextEdit" self
    sz <- godot_pool_byte_array_size body
    s <- (\x -> godot_string_chars_to_utf8_with_len (castPtr x) sz) =<< godot_pool_byte_array_read_access_ptr =<< godot_pool_byte_array_read body
    TextEdit.set_text t s
    contents <- T.encodeUtf8 <$> fromLowLevel s
    let stories = parseXML contents
    lst <- getNode' @"ItemList" self
    void $ swapMVar (self ^. feed) stories
    mapM_ (\s -> ItemList.add_item lst <$> toLowLevel (s ^. title) <*> pure Nothing <*> pure (Just True) & join) stories

instance NodeMethod RSSReader "_on_ItemList_item_selected" '[Int] (IO ()) where
  nodeMethod = on_ItemList_item_selected

instance NodeMethod RSSReader "_on_LinkButton_pressed" '[] (IO ()) where
  nodeMethod = on_LinkButton_pressed

instance NodeMethod RSSReader "_on_SettingsButton_pressed" '[] (IO ()) where
  nodeMethod = on_SettingsButton_pressed

instance NodeMethod RSSReader "_on_Settings_Clear_Button_pressed" '[] (IO ()) where
  nodeMethod = on_Settings_Clear_Button_pressed

instance NodeMethod RSSReader "_on_RSSReader_ready" '[] (IO ()) where
  nodeMethod = on_RSSReader_ready

instance NodeMethod RSSReader "_on_SaveButton_pressed" '[] (IO ()) where
  nodeMethod = on_SaveButton_pressed

on_RSSReader_ready self = do
  loadData self

on_SaveButton_pressed (self :: RSSReader) = do
  saveData self
  CanvasItem.hide =<< getNode' @"SettingsDialog" self
  pure ()

clearFields (self :: RSSReader) = do
  void $ swapMVar (self ^. feed) []
  ItemList.clear =<< getNode' @"ItemList" self
  TextEdit.set_text <$> getNode' @"DescriptionField" self <*> toLowLevel "" & join
  LinkButton.set_text <$> getNode' @"LinkButton" self <*> toLowLevel "" & join
  pure ()

saveData self = do
  putStrLn "Saving data"
  (Just os) <- getSingleton @OS
  d <- fromLowLevel =<< OS.get_user_data_dir os
  t <- fromLowLevel =<< LineEdit.get_text =<< getNode' @"SettingsDialog/RSSURLText" self
  A.encodeFile (T.unpack d <> "/save_config.json") (Settings t)

loadData self = do
  putStrLn "Loading data"
  (Just os) <- getSingleton @OS
  d <- fromLowLevel =<< OS.get_user_data_dir os
  e <- doesFileExist (T.unpack d <> "/save_config.json")
  when e $ do
    r <- A.decodeFileStrict' (T.unpack d <> "/save_config.json")
    case r of
      Nothing -> pure ()
      Just (s :: Settings) -> do
        LineEdit.set_text <$> getNode' @"SettingsDialog/RSSURLText" self
          <*> toLowLevel (s ^. url)
          & join

on_Settings_Clear_Button_pressed :: RSSReader -> IO ()
on_Settings_Clear_Button_pressed self = do
  LineEdit.set_text <$> getNode' @"SettingsDialog/RSSURLText" self
                    <*> toLowLevel ""
                    & join

on_SettingsButton_pressed :: RSSReader -> IO ()
on_SettingsButton_pressed self = do
  d <- getNode' @"SettingsDialog" self
  Popup.popup d Nothing

on_LinkButton_pressed :: RSSReader -> IO ()
on_LinkButton_pressed self = do
  (Just os) <- getSingleton @OS
  void $ OS.shell_open os =<< LinkButton.get_text =<< getNode' @"LinkButton" self

on_ItemList_item_selected :: RSSReader -> Int -> IO ()
on_ItemList_item_selected self n = do
  f <- readMVar (self ^. feed)
  TextEdit.set_text <$> getNode' @"DescriptionField" self
                    <*> toLowLevel (fromMaybe "" $ (f !! n) ^. description)
                    & join
  LinkButton.set_text <$> getNode' @"LinkButton" self
                      <*> toLowLevel ((f !! n) ^. link)
                      & join
  pure ()

parseXML x = case X.parse x of
            Right xml -> do
              case X.children xml of
                [chan] -> do
                  mapMaybe unItem $ X.children chan
                _ -> error "Unknown RSS"
            Left a -> []
  where head' (h:_) = Just h
        head' _ = Nothing
        byName name nodes = head' . nodeData =<< find (\e -> X.name e == name) nodes
        nodeData = mapMaybe (\case
                                X.Text t -> Just t
                                X.CData t -> Just t
                                _ -> Nothing) . X.contents
        unItem item = let nodes = X.children item
                      in do
                         t <- byName "title" nodes
                         l <- byName "link" nodes
                         pure $ Story (T.decodeUtf8 t) (T.decodeUtf8 <$> byName "description" nodes) (T.decodeUtf8 l)

nothing :: (Object :< a, Typeable a, AsVariant a) => IO a
nothing = fromJust <$> tryCast (Object nullPtr)

on_HTTPRequest_request_completed :: RSSReader -> Int -> Int -> PoolStringArray -> PoolByteArray -> IO ()
on_HTTPRequest_request_completed self _ _ _ body = do
  t <- getNode' @"TextEdit" self
  sz <- godot_pool_byte_array_size body
  s <- (\x -> godot_string_chars_to_utf8_with_len (castPtr x) sz) =<< godot_pool_byte_array_read_access_ptr =<< godot_pool_byte_array_read body
  TextEdit.set_text t s
  contents <- T.encodeUtf8 <$> fromLowLevel s
  let stories = parseXML contents
  lst <- getNode' @"ItemList" self
  void $ swapMVar (self ^. feed) stories
  mapM_ (\s -> ItemList.add_item lst <$> toLowLevel (s ^. title) <*> pure Nothing <*> pure (Just True) & join) stories

populateEdit :: RSSReader -> IO ()
populateEdit self = do
  url <- LineEdit.get_text =<< getNode' @"SettingsDialog/RSSURLText" self
  void $ HTTPRequest.request <$> getNode' @"HTTPRequest" self
                             <*> pure url
                             <*> (Just <$> godot_pool_string_array_new)
                             <*> pure (Just True)
                             <*> pure (Just HTTPClient._METHOD_GET)
                             <*> pure Nothing
                             & join

setupNode ''RSSReader "Rss_reader" "RSSReader"
deriveBase ''RSSReader


================================================
FILE: examples/rss-reader/src/Lib.hs
================================================
module Lib (exports) where
import Godot
import Project.Support
import Project.Requirements
import Game.RSSReader

exports :: GdnativeHandle -> IO ()
exports = registerAll' @Nodes @'[RSSReader]


================================================
FILE: examples/rss-reader/src/Project/Requirements.hs
================================================
-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT

module Project.Requirements where
import Project.Support

type Nodes = '[OneResourceNode "Rss_reader" "RSSReader"]


================================================
FILE: examples/rss-reader/src/Project/Scenes/Rss_reader.hs
================================================
-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT

{-# LANGUAGE FlexibleContexts, FunctionalDependencies, MultiParamTypeClasses,
  UndecidableInstances, OverloadedStrings, TemplateHaskell, TypeApplications,
  TypeFamilies, DataKinds, TypeOperators, FlexibleInstances, RankNTypes,
  AllowAmbiguousTypes, ScopedTypeVariables, DerivingStrategies,
  GeneralizedNewtypeDeriving, LambdaCase #-}

module Project.Scenes.Rss_reader where
import Project.Support
import Godot
import GHC.TypeLits

import Godot.Core.Button()
import Godot.Core.TextEdit()
import Godot.Core.HTTPRequest()
import Godot.Core.ItemList()
import Godot.Core.Label()
import Godot.Core.LinkButton()
import Godot.Core.Control()
import Godot.Core.LineEdit()
import Godot.Core.WindowDialog()

instance SceneResourcePath "Rss_reader" where
  sceneResourcePath = "res://Rss_reader.tscn"


instance SceneRoot "Rss_reader" where
  type SceneRootNode "Rss_reader" = "RSSReader"


instance SceneNode        "Rss_reader" "SettingsDialog/Button" where
  type SceneNodeType      "Rss_reader" "SettingsDialog/Button" = Button
  type SceneNodeName      "Rss_reader" "SettingsDialog/Button" = "Button"
  type SceneNodeIsHaskell "Rss_reader" "SettingsDialog/Button" = 'Nothing


instance SceneNode        "Rss_reader" "DescriptionField" where
  type SceneNodeType      "Rss_reader" "DescriptionField" = TextEdit
  type SceneNodeName      "Rss_reader" "DescriptionField" = "DescriptionField"
  type SceneNodeIsHaskell "Rss_reader" "DescriptionField" = 'Nothing


instance SceneNode        "Rss_reader" "HTTPRequest" where
  type SceneNodeType      "Rss_reader" "HTTPRequest" = HTTPRequest
  type SceneNodeName      "Rss_reader" "HTTPRequest" = "HTTPRequest"
  type SceneNodeIsHaskell "Rss_reader" "HTTPRequest" = 'Nothing


instance SceneNode        "Rss_reader" "ItemList" where
  type SceneNodeType      "Rss_reader" "ItemList" = ItemList
  type SceneNodeName      "Rss_reader" "ItemList" = "ItemList"
  type SceneNodeIsHaskell "Rss_reader" "ItemList" = 'Nothing


instance SceneNode        "Rss_reader" "SettingsDialog/Label" where
  type SceneNodeType      "Rss_reader" "SettingsDialog/Label" = Label
  type SceneNodeName      "Rss_reader" "SettingsDialog/Label" = "Label"
  type SceneNodeIsHaskell "Rss_reader" "SettingsDialog/Label" = 'Nothing


instance SceneNode        "Rss_reader" "LinkButton" where
  type SceneNodeType      "Rss_reader" "LinkButton" = LinkButton
  type SceneNodeName      "Rss_reader" "LinkButton" = "LinkButton"
  type SceneNodeIsHaskell "Rss_reader" "LinkButton" = 'Nothing


instance SceneNode        "Rss_reader" "OpenButton" where
  type SceneNodeType      "Rss_reader" "OpenButton" = Button
  type SceneNodeName      "Rss_reader" "OpenButton" = "OpenButton"
  type SceneNodeIsHaskell "Rss_reader" "OpenButton" = 'Nothing


instance SceneNode        "Rss_reader" "RSSReader" where
  type SceneNodeType      "Rss_reader" "RSSReader" = Control
  type SceneNodeName      "Rss_reader" "RSSReader" = "RSSReader"
  type SceneNodeIsHaskell "Rss_reader" "RSSReader" = 'Just '("Rss_reader", "RSSReader")


instance SceneNode        "Rss_reader" "SettingsDialog/RSSURLText" where
  type SceneNodeType      "Rss_reader" "SettingsDialog/RSSURLText" = LineEdit
  type SceneNodeName      "Rss_reader" "SettingsDialog/RSSURLText" = "RSSURLText"
  type SceneNodeIsHaskell "Rss_reader" "SettingsDialog/RSSURLText" = 'Nothing


instance SceneNode        "Rss_reader" "SettingsDialog/SaveButton" where
  type SceneNodeType      "Rss_reader" "SettingsDialog/SaveButton" = Button
  type SceneNodeName      "Rss_reader" "SettingsDialog/SaveButton" = "SaveButton"
  type SceneNodeIsHaskell "Rss_reader" "SettingsDialog/SaveButton" = 'Nothing


instance SceneNode        "Rss_reader" "SettingsButton" where
  type SceneNodeType      "Rss_reader" "SettingsButton" = Button
  type SceneNodeName      "Rss_reader" "SettingsButton" = "SettingsButton"
  type SceneNodeIsHaskell "Rss_reader" "SettingsButton" = 'Nothing


instance SceneNode        "Rss_reader" "SettingsDialog" where
  type SceneNodeType      "Rss_reader" "SettingsDialog" = WindowDialog
  type SceneNodeName      "Rss_reader" "SettingsDialog" = "SettingsDialog"
  type SceneNodeIsHaskell "Rss_reader" "SettingsDialog" = 'Nothing


instance SceneNode        "Rss_reader" "TextEdit" where
  type SceneNodeType      "Rss_reader" "TextEdit" = TextEdit
  type SceneNodeName      "Rss_reader" "TextEdit" = "TextEdit"
  type SceneNodeIsHaskell "Rss_reader" "TextEdit" = 'Nothing


instance SceneConnection "Rss_reader" "SettingsDialog/SaveButton" "pressed" "RSSReader" "_on_SaveButton_pressed"


instance SceneConnection "Rss_reader" "SettingsDialog/Button" "pressed" "RSSReader" "_on_Settings_Clear_Button_pressed"


instance SceneConnection "Rss_reader" "SettingsButton" "pressed" "RSSReader" "_on_SettingsButton_pressed"


instance SceneConnection "Rss_reader" "LinkButton" "pressed" "RSSReader" "_on_LinkButton_pressed"


instance SceneConnection "Rss_reader" "ItemList" "item_selected" "RSSReader" "_on_ItemList_item_selected"


instance SceneConnection "Rss_reader" "HTTPRequest" "request_completed" "RSSReader" "_on_HTTPRequest_request_completed"


instance SceneConnection "Rss_reader" "OpenButton" "pressed" "RSSReader" "_on_OpenButton_pressed"


instance SceneConnection "Rss_reader" "RSSReader" "ready" "RSSReader" "_on_RSSReader_ready"



================================================
FILE: examples/rss-reader/src/Project/Scenes.hs
================================================
-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT

module Project.Scenes (module M) where
import qualified Project.Scenes.Rss_reader as M



================================================
FILE: examples/rss-reader/src/Project/Support.hs
================================================
-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT

{-# LANGUAGE FlexibleContexts, FunctionalDependencies, MultiParamTypeClasses,
  UndecidableInstances, OverloadedStrings, TemplateHaskell, TypeApplications,
  TypeFamilies, DataKinds, TypeOperators, FlexibleInstances, RankNTypes,
  AllowAmbiguousTypes, ScopedTypeVariables, DerivingStrategies,
  GeneralizedNewtypeDeriving, LambdaCase #-}

{-# OPTIONS_GHC -Wno-name-shadowing #-}

module Project.Support where
import Godot.Core.Object
import Godot.Internal.Dispatch
import Godot.Gdnative.Internal.Types
import Data.Typeable
import qualified Data.Text as T
import qualified Data.Map as M
import Language.Haskell.TH
import Language.Haskell.TH.Datatype
import Control.Lens
import Control.Monad
import Godot
import Godot.Gdnative
import GHC.TypeLits
import Data.List
import Data.Maybe
import Data.Coerce
import Godot.Core.ResourceLoader
import Godot.Core.PackedScene

-- * Helper to keep Haskell types in sync with the Godot project.
newtype PackedScene' (scene :: Symbol) = PackedScene' PackedScene
                        deriving newtype AsVariant
instance HasBaseClass (PackedScene' scene) where
        type BaseClass (PackedScene' scene) = PackedScene
        super = coerce
deriveBase ''PackedScene'

-- | Use this to register all of your classes, it makes sure that you don't
-- forget a class that Godot needs.
-- 
-- exports :: GdnativeHandle -> IO ()
-- exports desc = registerAll' @Nodes @'[HUD, Main, Mob, Player] desc
registerAll' :: forall (res :: [*]) (ns :: [*]). ImplementedInHaskell res ns => GdnativeHandle -> IO ()
registerAll' = fill @res @ns

-- | A safe version of getNode; gives you back the Godot object
-- getNode' @"MobPath/MobSpawnLocation" self
getNode' :: forall label b cls scene name. (Object :< cls, Node :< cls,
                                      Node :< b,
                                      NodeInScene scene name cls,
                                      SceneNode scene label,
                                      SceneNodeType scene label ~ b,
                                      KnownSymbol label)
         => cls -> IO b
getNode' o = getNode @(SceneNodeType scene label) o (T.pack $ symbolVal (Proxy @label))

-- | A safe version of getNodeNativeScript; gives you back the Haskell object
-- getNodeNativeScript' @"HUD" self
getNodeNativeScript' :: forall label b cls scene name scene' label'.
                        (NativeScript b, Node :< cls, Object :< cls, NodeInScene scene name cls,
                         SceneNodeIsHaskell scene label ~ 'Just '(scene', label'),
                         NodeInScene scene' label' b,
                         KnownSymbol label)
                     => cls -> IO b
getNodeNativeScript' cls = getNodeNativeScript @b cls (T.pack $ symbolVal (Proxy @label))

-- | A safe version of emit_signal; will error at compile time if the signal doesn't exist
-- emit_signal' @"hit" self []
-- TODO We don't check arguments yet!
emit_signal' :: forall label args cls.
               (Object :< cls, Object :< cls, NodeSignal cls label args, KnownSymbol label)
             => cls -> [Variant 'GodotTy] -> IO ()
emit_signal' cls args = do
  name <- toLowLevel (T.pack $ symbolVal (Proxy @label))
  emit_signal cls name args

-- | A safe version of await; will error at compile time if the signal and nodes don't exist
-- await' @"MessageTimer" @"timeout" self $ \self' -> pure ()
await' :: forall (label :: Symbol) (signal :: Symbol) a b cls scene name.
         (NodeInScene scene name cls, NativeScript cls, KnownSymbol label, KnownSymbol signal,
          SceneNode scene label, Node :< cls, AsVariant a, Node :< SceneNodeType scene label,
          NodeSignal b signal '[], SceneNodeType scene label ~ b)
       => cls -> (cls -> IO a) -> IO ()
await' o f = do
  n <- getNode' @label o
  await o n (T.pack $ symbolVal (Proxy @signal)) f

-- | Preload a scene so you can instantiate it later.
-- Use this when the scene is known ahead of time. Store scenes in as @PackedScene' "SceneName"@
preloadScene :: forall scene. (KnownSymbol scene, SceneResourcePath scene) => IO (PackedScene' scene)
preloadScene = do
  Just r <- getSingleton @ResourceLoader
  path <- toLowLevel $ sceneResourcePath @scene
  PackedScene' <$> (tryCast' =<< load r path Nothing Nothing)

-- | Create an instance of a scene from a @PackedScene' "SceneName"@
-- Makes sure that you are getting the type of the scene root.
sceneInstance :: forall scene o. (Node :< o, Typeable o, AsVariant o, SceneNodeType scene (SceneRootNode scene) ~ o) => PackedScene' scene -> IO o
sceneInstance e = tryCast' =<< instance' e Nothing

-- | Combines nodeMethod with getNode' to call functions in a type-safe way
-- Provides no additional safety compared to using the two separately, but does clean up code a bit.
-- For example: fn @"MyNode" @"hide" self
fn :: forall (node :: Symbol) (func :: Symbol) scene name cls args ret b.
         (Object :< cls, Node :< cls,
           Node :< SceneNodeType scene node,
           NodeInScene scene name cls, SceneNode scene node,
           NodeMethodSuper (SceneNodeType scene node) func args ret,
           ListToFun args ret ~ IO b, KnownSymbol node) => cls -> IO b
fn self = nodeMethod' @_ @func =<< getNode' @node self

-- | Get the file path to the scene
class SceneResourcePath (scene :: Symbol) where
  sceneResourcePath :: forall scene. T.Text

-- * Internal helpers: You won't use these

-- | The root node of a scene
class SceneRoot (scene :: Symbol) where
  type SceneRootNode scene :: Symbol

-- | A node in the scene, we know its type and its name, @s@ is the path relate
-- to the scene
class (Typeable (SceneNodeType scene s),
       AsVariant (SceneNodeType scene s),
       Object :< SceneNodeType scene s) => SceneNode (scene :: Symbol) (s :: Symbol) where
  type SceneNodeType scene s :: *
  type SceneNodeName scene s :: Symbol
  type SceneNodeIsHaskell scene s :: Maybe (Symbol, Symbol)

-- | You declare this for your types. You offer up a haskell type, @n@, for the
-- node. This class verifies that your base class is correct.
class (HasBaseClass n, BaseClass n ~ SceneNodeType scene s) =>
      NodeInScene (scene :: Symbol) (s :: Symbol) n | scene s -> n, n -> scene s

-- | A connection between nodes in a scene. @from@ and @to@ are paths.
-- It connects @signal@ in @from@ to @method@ in @to@.
class SceneConnection (scene :: Symbol) (from :: Symbol) (signal :: Symbol) (to :: Symbol) (method :: Symbol)

-- | Internal, just for convenience
data OneResourceNode (resource :: Symbol) (name :: Symbol)

-- | Internal. Don't touch this and don't make instances of it. It's the
-- workhorse for making sure that you are implementing all of the classes that
-- Godot needs, nothing more and nothing less.
class ImplementedInHaskell (a :: [*]) (b :: [*]) where
  fill :: GdnativeHandle -> IO ()

instance ImplementedInHaskell '[] '[] where
  fill _ = pure ()

registerOne :: forall ty. (NativeScript ty, AsVariant (BaseClass ty)) => GdnativeHandle -> IO ()
registerOne desc = registerClass $ RegClass desc $ classInit @ty

instance (NodeInScene scene name n,
          NativeScript n, AsVariant (BaseClass n),
          ImplementedInHaskell t t',
          SceneNodeIsHaskell scene name ~ 'Just '(resource, name))
          => ImplementedInHaskell (OneResourceNode resource name ': t) (n ': t') where
  fill handle = do
    registerOne @n handle
    fill @t @t' handle

-- | Create a signal
-- TODO args ~ '[] is temproary, we need signeltons to reflect this into a runtime value
signal' :: forall cls label args.
          (NodeSignal cls label args, KnownSymbol label, args ~ '[])
        => (Text, [SignalArgument])
signal' = signal (T.pack $ symbolVal (Proxy @label)) []

createMVarProperty' :: (Typeable ty, AsVariant ty) => Text
                    -> (node -> MVar ty)
                    -- ^ We typically can't do IO (for initialisation) when calling this, in
                    -- which case we need to annotate the type without providing a value.
                    -> Either VariantType ty
                    -> (node -> IO ty
                      ,node -> ty -> IO ()
                      ,Maybe (Object -> node -> IO GodotVariant
                             ,Object -> node -> GodotVariant -> IO ()
                             ,PropertyAttributes))
createMVarProperty' name fieldName tyOrVal =
  (readMVar . fieldName,
   \c t -> propertySetter p undefined c =<< toGodotVariant t,
   Just (propertyGetter p, propertySetter p, propertyAttrs p))
  where p = createMVarProperty name fieldName tyOrVal

appsT :: Type -> [Type] -> Type
appsT t [] = t
appsT t (x:xs) = appsT (AppT t x) xs

-- | Verify that the signal connects to an endpoint that exists and has the right type.
witnessConnection :: forall (scene :: Symbol) (from :: Symbol) (signal :: Symbol) (to :: Symbol) (method :: Symbol) parent sigTy hTy.
                    (SceneNode scene to,
                      NodeSignal parent signal sigTy,
                      -- TODO This the check unsound, but SceneNodeType isn't right for this constraint. What is?
                      -- The warning produced because 'from' is not used is a reminder of this issue.
                      -- parent :< SceneNodeType scene from,
                      NodeMethod hTy method sigTy (IO ()),
                      NodeInScene scene to hTy) => ()
witnessConnection = ()

-- | Sets up a class
class NodeInit n where
  init :: BaseClass n -> IO n

-- | You never implement this. It's a helper so that we can have a more
-- polymorphic call to nodeMethod which will work when the method is implemneted
-- for any parent of the current node.
class NodeMethodSuper node (name :: Symbol) (args :: [*]) (ret :: *) | node name -> args, node name -> ret where
  nodeMethod' :: node -> ListToFun args ret

-- | An instance that supports calling nodeMethod' on your parents This can lead
-- to infinite loops in the type checker on error, so we isolate it in
-- NodeMethodSuper instead of NodeMethod.
instance {-# OVERLAPPABLE #-} (NodeMethod (BaseClass node) name arg ret, HasBaseClass node)
    => NodeMethodSuper node name arg ret where
  nodeMethod' = nodeMethod' @node @name @arg @ret

mkProperty' :: forall node (name :: Symbol) ty. (NodeProperty node name ty 'False, KnownSymbol name) => ClassProperty node
mkProperty' = ClassProperty (T.pack $ symbolVal (Proxy @name)) a s g
  where (_,_,Just (g,s,a)) = nodeProperty @node @name @ty @'False

-- | You should use this as:
--   setupNode ''Ty
--   deriveBase ''Ty
-- This will instantiate everything that your Object needs
setupNode :: Name -> String -> String -> Q [Dec]
setupNode ty scene sceneNode = do
  -- Collect information about all scenes
  tree         <- map unTree . classInstances <$> reify ''(:<)
  sceneRoots   <- M.fromList . map unSceneRootNode . familyInstances <$> reify ''SceneRootNode
  sceneNodes   <- map unSceneNodeType . familyInstances <$> reify ''SceneNodeType
  haskellNodes <- map unNodeInScene . classInstances <$> reify ''NodeInScene
  allSignals   <- map unNodeSignal . classInstances <$> reify ''NodeSignal
  -- Collect information about our node
  rdt <- reifyDatatype ty
  let base = case datatypeCons rdt of
                    (c:_) -> case (constructorFields c, constructorVariant c) of
                              (ConT baseTy:_, RecordConstructor (baseFn:_)) -> Just (baseTy, baseFn)
                              _ -> Nothing
                    _ -> Nothing
  --
  methods    <- filter (\i -> i^._1 == ty) . mapMaybe unNodeMethod . classInstances <$> reify ''NodeMethod
  properties <- filter (\i -> i^._1 == ty) . mapMaybe unNodeProperty . classInstances <$> reify ''NodeProperty
  let signals = filter (\i -> i^._1 == ty) allSignals
  connections <- filter (\i -> i^._1 == scene && i^._4 == sceneNode) . map unConnect . classInstances <$> reify ''SceneConnection
  -- Helpers
  let parentsOf cls = map snd $ filter (\(c,_) -> cls == c) tree
  let nodeToType :: String -> String -> Name
      nodeToType scene node = case (hty, ty ^. _4) of
                                (Just t, _) -> t
                                (_, Nothing) -> ty ^. _3
                                (_, Just scene') -> case M.lookup scene' sceneRoots of
                                                Nothing -> error $ "Looking up the root of a scene that is lacking one. This is a bug. " ++ show (scene', scene, node)
                                                Just node' -> nodeToType scene' node'
        where ty  = fromJust $ find (\n -> n^._1 == scene && n^._2 == node) sceneNodes
              hty = (^._3) <$> find (\n -> n^._1 == scene && n^._2 == node) haskellNodes
  let resolveSignalActualClass scene from signal =
        case mapMaybe (\p -> (p,) <$> find (\s -> s^._2 == signal && s^._1 == p) allSignals) $ parentsOf (nodeToType scene from) of
          -- The root issue is that the signal might not yet exist.
          -- If witnessConnection was not unsound, this would not be needed as the error would happen later.
           [] -> error $ "Class " ++ show from ++ " used in scene " ++ show scene ++ " is lacking a signal named " ++ show signal ++ "\n" ++ show (nodeToType scene from) ++ "\n" ++ show (parentsOf (nodeToType scene from))
           (h:_) -> h ^. _1

  -- Debug
  when False $ runIO $ do
    putStrLn "Regenerating .."
    print rdt
    putStrLn "\nScene roots:"
    print sceneRoots
    putStrLn "\nScene nodes types:"
    mapM_ print sceneNodes
    putStrLn "\nMethods:"
    mapM_ print methods
    putStrLn "\nProperties:"
    mapM_ print properties
    putStrLn "\nSignals:"
    mapM_ print allSignals
    mapM_ print signals
    putStrLn "\nConnections:"
    mapM_ print connections
    putStrLn "\nHaskell nodes:"
    mapM_ print haskellNodes

  -- Generate code
  bi <- case base of
    Just (baseTy, baseFn) ->
      [d|instance HasBaseClass $(pure $ PromotedT ty) where
          type BaseClass $(pure $ PromotedT ty) = $(pure $ PromotedT baseTy)
          super = $(pure $ VarE baseFn)|]
    _ -> error "setupNode can only handle records whose first field is the Godot base class. You can still interface with Godot, but you will need to set things up manually."
  nis <- [d|instance NodeInScene $(pure $ LitT $ StrTyLit scene) $(pure $ LitT $ StrTyLit sceneNode) $(pure $ PromotedT ty)|]
  ns <- [d|instance NativeScript $(pure $ PromotedT ty) where
            classInit = Project.Support.init
            classMethods = $(ListE <$> mapM (\(t,n,argTy,_) ->
                     let m = case nrArguments argTy of
                                  0 -> [e|method0|]
                                  1 -> [e|method1|]
                                  2 -> [e|method2|]
                                  3 -> [e|method3|]
                                  4 -> [e|method4|]
                                  5 -> [e|method5|]
                                  n -> error $ "More arguments than we currently impelement, look for 'method5' for more info " ++ show  n
                     in [e|$m $(pure $ LitE $ StringL n) (nodeMethod @ $(pure $ PromotedT t) @ $(pure $ LitT $ StrTyLit n))|]) methods)
            classProperties = $(ListE <$> mapM (\(name,prop,_,_) -> [e|mkProperty' @ $(pure $ PromotedT name) @ $(pure $ LitT $ StrTyLit prop) |]) properties)
            classSignals = $(ListE <$> mapM (\(ty,name,_) -> [e|signal' @ $(pure $ PromotedT ty) @ $(pure $ LitT $ StrTyLit name)|]) signals)|]
  let cn = mkName $ "witness_connections_" ++ nameBase ty
  ws <- (:) <$> (cn `sigD` [t| [()] |]) <*>
       [d|$(varP cn) =
             $(ListE <$> mapM (\(scene,from,signal,to,method) ->
                    [e|witnessConnection
                        @ $(pure $ LitT $ StrTyLit scene)  @ $(pure $ LitT $ StrTyLit from)
                        @ $(pure $ LitT $ StrTyLit signal) @ $(pure $ LitT $ StrTyLit to)
                        @ $(pure $ LitT $ StrTyLit method)
                        @ $(pure $ PromotedT $ resolveSignalActualClass scene from signal)
                    |]) connections)|]
  pure $ bi <> nis <> ns <> ws

  where
      unTree (InstanceD Nothing [] (AppT (AppT _ parent) child) []) = (unName child, unName parent)
      unTree p = error $ "I don't understand this parent " ++ show p
      unName (ConT x) = x
      unName (AppT (ConT x) _) = x
      unName x = error $ "I don't know how to extract the name of this type: " ++ show x
      unSceneRootNode (TySynInstD (TySynEqn Nothing (AppT _ (LitT (StrTyLit scene))) (LitT (StrTyLit node)))) = (scene,node)
      unSceneRootNode x = error $ "Don't know how unpack this SceneRootNode: " ++ show x
      unSceneNodeType (TySynInstD (TySynEqn Nothing (AppT (AppT _ (LitT (StrTyLit scene))) (LitT (StrTyLit node))) ty))
        = (scene,node,unName ty, unpackScene ty)
      unSceneNodeType x = error $ "Don't know how unpack this SceneNodeType: " ++ show x
      unpackScene (ConT _) = Nothing
      unpackScene (AppT (ConT _) (LitT (StrTyLit scene))) = Just scene
      unpackScene x = error $ "Don't know how unpack this Scene: " ++ show x
      unNodeMethod (InstanceD Nothing [] (AppT (AppT (AppT (AppT (ConT _) (ConT cls)) (LitT (StrTyLit name))) arg) ret) []) 
        = Just (cls, name, arg, ret)
      unNodeMethod _ = Nothing
      unNodeProperty (InstanceD Nothing [] (AppT (AppT (AppT (AppT (ConT _) (ConT cls)) (LitT (StrTyLit name))) arg) ret) []) 
        = Just (cls, name, arg, ret)
      unNodeProperty x = error $ show x
      unNodeInScene (InstanceD Nothing [] (AppT (AppT (AppT (ConT _) (LitT (StrTyLit scene))) (LitT (StrTyLit node))) (ConT hty)) [])
        = (scene, node, hty)
      unNodeInScene x = error $ show x
      unNodeSignal (InstanceD Nothing [] (AppT (AppT (AppT (ConT _) (ConT cls)) (LitT (StrTyLit name))) arg) []) = (cls, name, arg)
      unNodeSignal _ = error "Bad signal"
      unConnect (InstanceD Nothing [] (AppT (AppT (AppT (AppT (AppT _ (LitT (StrTyLit scene))) (LitT (StrTyLit from))) (LitT (StrTyLit signal))) (LitT (StrTyLit to))) (LitT (StrTyLit method))) []) = (scene, from, signal, to, method)
      unConnect x = error $ "Bad signal" ++ show x
      nrArguments :: Type -> Int
      nrArguments (AppT _ r) = 1 + nrArguments r
      nrArguments (SigT PromotedNilT (AppT ListT StarT)) = 0
      nrArguments _ = error "Can't compute # of arguments"
      classInstances :: Info -> [InstanceDec]
      classInstances (ClassI _ is) = is
      classInstances _ = error "Bad class"
      familyInstances :: Info -> [InstanceDec]
      familyInstances (FamilyI _ is) = is
      familyInstances _ = error "Bad class"


================================================
FILE: examples/rss-reader/stack-shell.nix
================================================
{ nixpkgs ? import ./pinned-nixpkgs.nix {}
, ghc
}:

with nixpkgs;

haskell.lib.buildStackProject {
  inherit ghc;
  name = "myproject";
  buildInputs = [];
}




================================================
FILE: examples/rss-reader/stack.yaml
================================================
resolver: nightly-2021-02-06

packages:
- .

extra-deps:
- ../../

require-stack-version: ">=1.8"

nix:
  enable: false
  pure: true
  packages: []
  shell-file: stack-shell.nix
  nix-shell-options: []
  path: []
  add-gc-roots: false




================================================
FILE: examples/top-down-ten-minutes/.gitignore
================================================
dist*
*.hi
*.o
.stack-work/
.stack-work-devel/
*~
\#*
*.import
result




================================================
FILE: examples/top-down-ten-minutes/ChangeLog.md
================================================
# Empty




================================================
FILE: examples/top-down-ten-minutes/LICENSE
================================================
BSD 3-Clause License

Copyright (c) Andrei Barbu 2019
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



================================================
FILE: examples/top-down-ten-minutes/Makefile
================================================
NAME = top-down-ten-minutes
STACKLIBFILE = $(shell stack path --local-install-root)/lib/lib$(NAME).so
GODOTPROJECT = $(shell stack path --project-root)/game
all: stack
nix:
	nix-build shell.nix
	cp result/lib/ghc-*/lib$(NAME).so $(GODOTPROJECT)/lib
stack:
	stack build --fast --force-dirty
	cp $(STACKLIBFILE) $(GODOTPROJECT)/lib
stack-nix:
	stack --nix clean $(NAME)
	stack --nix build
	cp $(shell stack --nix path --local-install-root)/lib/lib$(NAME).so $(GODOTPROJECT)/lib
stack-run:
	stack build
	cp $(STACKLIBFILE) $(GODOTPROJECT)/lib
	godot -e --path ./game
stack-watch:
	stack build --file-watch --fast --exec "cp $(STACKLIBFILE) $(GODOTPROJECT)/lib"
project-watch:
	stack exec godot-haskell-project-generator game src
updatelib:
	cp $(STACKLIBFILE) $(GODOTPROJECT)/lib


================================================
FILE: examples/top-down-ten-minutes/README.md
================================================
The official Godot demo from the manual: Dodge the Creeps.

Run with `make stack` then `godot game/project.godot` and press F5 to start, F8 to end.

Requires Godot 3.1


================================================
FILE: examples/top-down-ten-minutes/ffi/cbits/flib.c
================================================
#include "HsFFI.h"

static void flib_init() __attribute__((constructor));
static void flib_init() {
  static char *argv[] = { "libGodotHaskellPlugin.so", 0 }, **argv_ = argv;
  static int argc = 1;
  hs_init(&argc, &argv_);
}

static void flib_fini() __attribute__((destructor));
static void flib_fini() {
  hs_exit();
}


================================================
FILE: examples/top-down-ten-minutes/ffi/flib/FLib.hs
================================================
{-# LANGUAGE ForeignFunctionInterface #-}
module FLib where

import qualified Foreign
import           Foreign(nullPtr, Ptr,newForeignPtr_,castPtr)
import qualified Godot.Gdnative.Internal       as FFI
import           Godot.Gdnative
import           Godot.Nativescript
import           Lib
import qualified Data.Text as T
import qualified Data.Text.IO as T

godot_nativescript_init :: GdnativeHandle -> IO ()
godot_nativescript_init desc = do
  defaultExports desc
  exports desc
  putStrLn "Haskell NativeScript lib initialized"

foreign export ccall godot_nativescript_init :: GdnativeHandle -> IO ()


godot_gdnative_init :: FFI.GdnativeInitOptionsPtr -> IO ()
godot_gdnative_init opts = do
  Foreign.peek opts >>= FFI.initApiStructs

foreign export ccall godot_gdnative_init :: FFI.GdnativeInitOptionsPtr -> IO ()


godot_gdnative_terminate :: FFI.GdnativeTerminateOptionsPtr -> IO ()
godot_gdnative_terminate handle = pure ()

foreign export ccall godot_gdnative_terminate :: FFI.GdnativeTerminateOptionsPtr -> IO ()


================================================
FILE: examples/top-down-ten-minutes/game/Bullet.gdns
================================================
[gd_resource type="NativeScript" load_steps=2 format=2]

[ext_resource path="res://lib/libtop-down-ten-minutes.gdnlib" type="GDNativeLibrary" id=1]

[resource]
resource_name = "Bullet"
class_name = "Bullet"
library = ExtResource( 1 )


================================================
FILE: examples/top-down-ten-minutes/game/Bullet.tscn
================================================
[gd_scene load_steps=5 format=2]

[ext_resource path="res://Player.png" type="Texture" id=1]
[ext_resource path="res://Bullet.gdns" type="Script" id=2]

[sub_resource type="RectangleShape2D" id=1]
extents = Vector2( 4, 1.6 )

[sub_resource type="Animation" id=2]
resource_name = "fadeout"
length = 0.4
tracks/0/type = "value"
tracks/0/path = NodePath("Sprite:modulate")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.3 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 0,
"values": [ Color( 1, 1, 1, 1 ), Color( 0.45098, 0.447059, 0.447059, 0 ) ]
}

[node name="Bullet" type="RigidBody2D"]
collision_layer = 8
continuous_cd = 1
contacts_reported = 1
contact_monitor = true
script = ExtResource( 2 )

[
Download .txt
gitextract_kt3cl1ny/

├── .gitignore
├── .gitmodules
├── .hlint.yaml
├── .travis.yml
├── .vscode/
│   └── tasks.json
├── LICENSE
├── README.md
├── Setup.hs
├── cbits/
│   └── util.h
├── classgen/
│   ├── README.md
│   ├── app-classgen/
│   │   └── Main.hs
│   ├── default.nix
│   ├── godot-haskell-classgen.cabal
│   ├── package.yaml
│   ├── release.nix
│   ├── src-classgen/
│   │   └── Classgen/
│   │       ├── Docs.hs
│   │       ├── Module.hs
│   │       ├── Spec.hs
│   │       └── Utils.hs
│   └── stack.yaml
├── default.nix
├── examples/
│   ├── dodge-the-creeps/
│   │   ├── .gitignore
│   │   ├── ChangeLog.md
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── Support.hs
│   │   ├── ffi/
│   │   │   ├── cbits/
│   │   │   │   └── flib.c
│   │   │   └── flib/
│   │   │       └── FLib.hs
│   │   ├── game/
│   │   │   ├── HUD.gdns
│   │   │   ├── HUD.tres
│   │   │   ├── HUD.tscn
│   │   │   ├── Main.gdns
│   │   │   ├── Main.tscn
│   │   │   ├── Mob.gdns
│   │   │   ├── Mob.tscn
│   │   │   ├── Player.gdns
│   │   │   ├── Player.tscn
│   │   │   ├── dodge_assets/
│   │   │   │   ├── art/
│   │   │   │   │   └── House In a Forest Loop.ogg
│   │   │   │   └── fonts/
│   │   │   │       ├── FONTLOG.txt
│   │   │   │       └── LICENSE.txt
│   │   │   ├── lib/
│   │   │   │   └── libmyproject.gdnlib
│   │   │   └── project.godot
│   │   ├── godot-haskell.nix
│   │   ├── hie.yaml
│   │   ├── myproject.cabal
│   │   ├── package.yaml
│   │   ├── pinned-nixpkgs.nix
│   │   ├── shell.nix
│   │   ├── src/
│   │   │   ├── Game/
│   │   │   │   ├── HUD.hs
│   │   │   │   ├── Main.hs
│   │   │   │   ├── Mob.hs
│   │   │   │   └── Player.hs
│   │   │   ├── Lib.hs
│   │   │   └── Project/
│   │   │       ├── Requirements.hs
│   │   │       ├── Scenes/
│   │   │       │   ├── HUD.hs
│   │   │       │   ├── Main.hs
│   │   │       │   ├── Mob.hs
│   │   │       │   └── Player.hs
│   │   │       ├── Scenes.hs
│   │   │       └── Support.hs
│   │   ├── stack-shell.nix
│   │   └── stack.yaml
│   ├── rss-reader/
│   │   ├── .gitignore
│   │   ├── ChangeLog.md
│   │   ├── LICENSE
│   │   ├── Makefile
│   │   ├── README.md
│   │   ├── Support.hs
│   │   ├── ffi/
│   │   │   ├── cbits/
│   │   │   │   └── flib.c
│   │   │   └── flib/
│   │   │       └── FLib.hs
│   │   ├── game/
│   │   │   ├── Rss_reader.gdns
│   │   │   ├── Rss_reader.tscn
│   │   │   ├── export_presets.cfg
│   │   │   ├── lib/
│   │   │   │   └── libmyproject.gdnlib
│   │   │   └── project.godot
│   │   ├── godot-haskell.nix
│   │   ├── hie.yaml
│   │   ├── myproject.cabal
│   │   ├── package.yaml
│   │   ├── pinned-nixpkgs.nix
│   │   ├── shell.nix
│   │   ├── src/
│   │   │   ├── Game/
│   │   │   │   ├── RSSReader.hs
│   │   │   │   └── q
│   │   │   ├── Lib.hs
│   │   │   └── Project/
│   │   │       ├── Requirements.hs
│   │   │       ├── Scenes/
│   │   │       │   └── Rss_reader.hs
│   │   │       ├── Scenes.hs
│   │   │       └── Support.hs
│   │   ├── stack-shell.nix
│   │   └── stack.yaml
│   └── top-down-ten-minutes/
│       ├── .gitignore
│       ├── ChangeLog.md
│       ├── LICENSE
│       ├── Makefile
│       ├── README.md
│       ├── ffi/
│       │   ├── cbits/
│       │   │   └── flib.c
│       │   └── flib/
│       │       └── FLib.hs
│       ├── game/
│       │   ├── Bullet.gdns
│       │   ├── Bullet.tscn
│       │   ├── Enemy.gdns
│       │   ├── Enemy.tscn
│       │   ├── Explosion.tscn
│       │   ├── Player.gdns
│       │   ├── lib/
│       │   │   └── libtop-down-ten-minutes.gdnlib
│       │   ├── project.godot
│       │   ├── wall.tres
│       │   └── world.tscn
│       ├── godot-haskell.nix
│       ├── hie.yaml
│       ├── package.yaml
│       ├── pinned-nixpkgs.nix
│       ├── shell.nix
│       ├── src/
│       │   ├── Game/
│       │   │   └── World.hs
│       │   ├── Lib.hs
│       │   └── Project/
│       │       ├── Requirements.hs
│       │       ├── Scenes/
│       │       │   ├── Bullet.hs
│       │       │   ├── Enemy.hs
│       │       │   ├── Explosion.hs
│       │       │   └── World.hs
│       │       ├── Scenes.hs
│       │       └── Support.hs
│       ├── stack-shell.nix
│       ├── stack.yaml
│       └── top-down-ten-minutes.cabal
├── godot-haskell.cabal
├── hie.yaml
├── nix/
│   ├── pinned/
│   │   ├── all-hies.json
│   │   ├── default.nix
│   │   ├── hie.nix
│   │   └── nixpkgs.json
│   └── spacemacs-hie.nix
├── nixpkgs-version.json
├── package.yaml
├── pinned-nixpkgs.nix
├── project-generator/
│   └── Main.hs
├── release.nix
├── shell-spacemacs-hie.nix
├── shell.nix
├── src/
│   ├── Godot/
│   │   ├── Api/
│   │   │   └── Types.hs
│   │   ├── Api.hs
│   │   ├── Core/
│   │   │   ├── ARVRAnchor.hs
│   │   │   ├── ARVRCamera.hs
│   │   │   ├── ARVRController.hs
│   │   │   ├── ARVRInterface.hs
│   │   │   ├── ARVRInterfaceGDNative.hs
│   │   │   ├── ARVROrigin.hs
│   │   │   ├── ARVRPositionalTracker.hs
│   │   │   ├── ARVRServer.hs
│   │   │   ├── AStar.hs
│   │   │   ├── AStar2D.hs
│   │   │   ├── AcceptDialog.hs
│   │   │   ├── AnimatedSprite.hs
│   │   │   ├── AnimatedSprite3D.hs
│   │   │   ├── AnimatedTexture.hs
│   │   │   ├── Animation.hs
│   │   │   ├── AnimationNode.hs
│   │   │   ├── AnimationNodeAdd2.hs
│   │   │   ├── AnimationNodeAdd3.hs
│   │   │   ├── AnimationNodeAnimation.hs
│   │   │   ├── AnimationNodeBlend2.hs
│   │   │   ├── AnimationNodeBlend3.hs
│   │   │   ├── AnimationNodeBlendSpace1D.hs
│   │   │   ├── AnimationNodeBlendSpace2D.hs
│   │   │   ├── AnimationNodeBlendTree.hs
│   │   │   ├── AnimationNodeOneShot.hs
│   │   │   ├── AnimationNodeOutput.hs
│   │   │   ├── AnimationNodeStateMachine.hs
│   │   │   ├── AnimationNodeStateMachinePlayback.hs
│   │   │   ├── AnimationNodeStateMachineTransition.hs
│   │   │   ├── AnimationNodeTimeScale.hs
│   │   │   ├── AnimationNodeTimeSeek.hs
│   │   │   ├── AnimationNodeTransition.hs
│   │   │   ├── AnimationPlayer.hs
│   │   │   ├── AnimationRootNode.hs
│   │   │   ├── AnimationTree.hs
│   │   │   ├── AnimationTreePlayer.hs
│   │   │   ├── Area.hs
│   │   │   ├── Area2D.hs
│   │   │   ├── ArrayMesh.hs
│   │   │   ├── AtlasTexture.hs
│   │   │   ├── AudioBusLayout.hs
│   │   │   ├── AudioEffect.hs
│   │   │   ├── AudioEffectAmplify.hs
│   │   │   ├── AudioEffectBandLimitFilter.hs
│   │   │   ├── AudioEffectBandPassFilter.hs
│   │   │   ├── AudioEffectChorus.hs
│   │   │   ├── AudioEffectCompressor.hs
│   │   │   ├── AudioEffectDelay.hs
│   │   │   ├── AudioEffectDistortion.hs
│   │   │   ├── AudioEffectEQ.hs
│   │   │   ├── AudioEffectEQ10.hs
│   │   │   ├── AudioEffectEQ21.hs
│   │   │   ├── AudioEffectEQ6.hs
│   │   │   ├── AudioEffectFilter.hs
│   │   │   ├── AudioEffectHighPassFilter.hs
│   │   │   ├── AudioEffectHighShelfFilter.hs
│   │   │   ├── AudioEffectInstance.hs
│   │   │   ├── AudioEffectLimiter.hs
│   │   │   ├── AudioEffectLowPassFilter.hs
│   │   │   ├── AudioEffectLowShelfFilter.hs
│   │   │   ├── AudioEffectNotchFilter.hs
│   │   │   ├── AudioEffectPanner.hs
│   │   │   ├── AudioEffectPhaser.hs
│   │   │   ├── AudioEffectPitchShift.hs
│   │   │   ├── AudioEffectRecord.hs
│   │   │   ├── AudioEffectReverb.hs
│   │   │   ├── AudioEffectSpectrumAnalyzer.hs
│   │   │   ├── AudioEffectSpectrumAnalyzerInstance.hs
│   │   │   ├── AudioEffectStereoEnhance.hs
│   │   │   ├── AudioServer.hs
│   │   │   ├── AudioStream.hs
│   │   │   ├── AudioStreamGenerator.hs
│   │   │   ├── AudioStreamGeneratorPlayback.hs
│   │   │   ├── AudioStreamMicrophone.hs
│   │   │   ├── AudioStreamOGGVorbis.hs
│   │   │   ├── AudioStreamPlayback.hs
│   │   │   ├── AudioStreamPlaybackResampled.hs
│   │   │   ├── AudioStreamPlayer.hs
│   │   │   ├── AudioStreamPlayer2D.hs
│   │   │   ├── AudioStreamPlayer3D.hs
│   │   │   ├── AudioStreamRandomPitch.hs
│   │   │   ├── AudioStreamSample.hs
│   │   │   ├── BackBufferCopy.hs
│   │   │   ├── BakedLightmap.hs
│   │   │   ├── BakedLightmapData.hs
│   │   │   ├── BaseButton.hs
│   │   │   ├── BitMap.hs
│   │   │   ├── BitmapFont.hs
│   │   │   ├── Bone2D.hs
│   │   │   ├── BoneAttachment.hs
│   │   │   ├── BoxContainer.hs
│   │   │   ├── BoxShape.hs
│   │   │   ├── BulletPhysicsDirectBodyState.hs
│   │   │   ├── BulletPhysicsServer.hs
│   │   │   ├── Button.hs
│   │   │   ├── ButtonGroup.hs
│   │   │   ├── CPUParticles.hs
│   │   │   ├── CPUParticles2D.hs
│   │   │   ├── CSGBox.hs
│   │   │   ├── CSGCombiner.hs
│   │   │   ├── CSGCylinder.hs
│   │   │   ├── CSGMesh.hs
│   │   │   ├── CSGPolygon.hs
│   │   │   ├── CSGPrimitive.hs
│   │   │   ├── CSGShape.hs
│   │   │   ├── CSGSphere.hs
│   │   │   ├── CSGTorus.hs
│   │   │   ├── Camera.hs
│   │   │   ├── Camera2D.hs
│   │   │   ├── CameraFeed.hs
│   │   │   ├── CameraServer.hs
│   │   │   ├── CameraTexture.hs
│   │   │   ├── CanvasItem.hs
│   │   │   ├── CanvasItemMaterial.hs
│   │   │   ├── CanvasLayer.hs
│   │   │   ├── CanvasModulate.hs
│   │   │   ├── CapsuleMesh.hs
│   │   │   ├── CapsuleShape.hs
│   │   │   ├── CapsuleShape2D.hs
│   │   │   ├── CenterContainer.hs
│   │   │   ├── CharFXTransform.hs
│   │   │   ├── CheckBox.hs
│   │   │   ├── CheckButton.hs
│   │   │   ├── CircleShape2D.hs
│   │   │   ├── ClassDB.hs
│   │   │   ├── ClippedCamera.hs
│   │   │   ├── CollisionObject.hs
│   │   │   ├── CollisionObject2D.hs
│   │   │   ├── CollisionPolygon.hs
│   │   │   ├── CollisionPolygon2D.hs
│   │   │   ├── CollisionShape.hs
│   │   │   ├── CollisionShape2D.hs
│   │   │   ├── ColorPicker.hs
│   │   │   ├── ColorPickerButton.hs
│   │   │   ├── ColorRect.hs
│   │   │   ├── ConcavePolygonShape.hs
│   │   │   ├── ConcavePolygonShape2D.hs
│   │   │   ├── ConeTwistJoint.hs
│   │   │   ├── ConfigFile.hs
│   │   │   ├── ConfirmationDialog.hs
│   │   │   ├── Container.hs
│   │   │   ├── Control.hs
│   │   │   ├── ConvexPolygonShape.hs
│   │   │   ├── ConvexPolygonShape2D.hs
│   │   │   ├── Crypto.hs
│   │   │   ├── CryptoKey.hs
│   │   │   ├── CubeMap.hs
│   │   │   ├── CubeMesh.hs
│   │   │   ├── Curve.hs
│   │   │   ├── Curve2D.hs
│   │   │   ├── Curve3D.hs
│   │   │   ├── CurveTexture.hs
│   │   │   ├── CylinderMesh.hs
│   │   │   ├── CylinderShape.hs
│   │   │   ├── DampedSpringJoint2D.hs
│   │   │   ├── DirectionalLight.hs
│   │   │   ├── Directory.hs
│   │   │   ├── DynamicFont.hs
│   │   │   ├── DynamicFontData.hs
│   │   │   ├── EncodedObjectAsID.hs
│   │   │   ├── Engine.hs
│   │   │   ├── Environment.hs
│   │   │   ├── Expression.hs
│   │   │   ├── File.hs
│   │   │   ├── FileDialog.hs
│   │   │   ├── Font.hs
│   │   │   ├── FuncRef.hs
│   │   │   ├── GDNative.hs
│   │   │   ├── GDNativeLibrary.hs
│   │   │   ├── GDScript.hs
│   │   │   ├── GDScriptFunctionState.hs
│   │   │   ├── GIProbe.hs
│   │   │   ├── GIProbeData.hs
│   │   │   ├── Generic6DOFJoint.hs
│   │   │   ├── Geometry.hs
│   │   │   ├── GeometryInstance.hs
│   │   │   ├── GlobalConstants.hs
│   │   │   ├── Gradient.hs
│   │   │   ├── GradientTexture.hs
│   │   │   ├── GraphEdit.hs
│   │   │   ├── GraphNode.hs
│   │   │   ├── GridContainer.hs
│   │   │   ├── GridMap.hs
│   │   │   ├── GrooveJoint2D.hs
│   │   │   ├── HBoxContainer.hs
│   │   │   ├── HScrollBar.hs
│   │   │   ├── HSeparator.hs
│   │   │   ├── HSlider.hs
│   │   │   ├── HSplitContainer.hs
│   │   │   ├── HTTPClient.hs
│   │   │   ├── HTTPRequest.hs
│   │   │   ├── HashingContext.hs
│   │   │   ├── HeightMapShape.hs
│   │   │   ├── HingeJoint.hs
│   │   │   ├── IP.hs
│   │   │   ├── IP_Unix.hs
│   │   │   ├── Image.hs
│   │   │   ├── ImageTexture.hs
│   │   │   ├── ImmediateGeometry.hs
│   │   │   ├── Input.hs
│   │   │   ├── InputDefault.hs
│   │   │   ├── InputEvent.hs
│   │   │   ├── InputEventAction.hs
│   │   │   ├── InputEventGesture.hs
│   │   │   ├── InputEventJoypadButton.hs
│   │   │   ├── InputEventJoypadMotion.hs
│   │   │   ├── InputEventKey.hs
│   │   │   ├── InputEventMIDI.hs
│   │   │   ├── InputEventMagnifyGesture.hs
│   │   │   ├── InputEventMouse.hs
│   │   │   ├── InputEventMouseButton.hs
│   │   │   ├── InputEventMouseMotion.hs
│   │   │   ├── InputEventPanGesture.hs
│   │   │   ├── InputEventScreenDrag.hs
│   │   │   ├── InputEventScreenTouch.hs
│   │   │   ├── InputEventWithModifiers.hs
│   │   │   ├── InputMap.hs
│   │   │   ├── InstancePlaceholder.hs
│   │   │   ├── InterpolatedCamera.hs
│   │   │   ├── ItemList.hs
│   │   │   ├── JSON.hs
│   │   │   ├── JSONParseResult.hs
│   │   │   ├── JSONRPC.hs
│   │   │   ├── JavaClass.hs
│   │   │   ├── JavaClassWrapper.hs
│   │   │   ├── JavaScript.hs
│   │   │   ├── Joint.hs
│   │   │   ├── Joint2D.hs
│   │   │   ├── KinematicBody.hs
│   │   │   ├── KinematicBody2D.hs
│   │   │   ├── KinematicCollision.hs
│   │   │   ├── KinematicCollision2D.hs
│   │   │   ├── Label.hs
│   │   │   ├── LargeTexture.hs
│   │   │   ├── Light.hs
│   │   │   ├── Light2D.hs
│   │   │   ├── LightOccluder2D.hs
│   │   │   ├── Line2D.hs
│   │   │   ├── LineEdit.hs
│   │   │   ├── LineShape2D.hs
│   │   │   ├── LinkButton.hs
│   │   │   ├── Listener.hs
│   │   │   ├── MainLoop.hs
│   │   │   ├── MarginContainer.hs
│   │   │   ├── Marshalls.hs
│   │   │   ├── Material.hs
│   │   │   ├── MenuButton.hs
│   │   │   ├── Mesh.hs
│   │   │   ├── MeshDataTool.hs
│   │   │   ├── MeshInstance.hs
│   │   │   ├── MeshInstance2D.hs
│   │   │   ├── MeshLibrary.hs
│   │   │   ├── MeshTexture.hs
│   │   │   ├── MobileVRInterface.hs
│   │   │   ├── MultiMesh.hs
│   │   │   ├── MultiMeshInstance.hs
│   │   │   ├── MultiMeshInstance2D.hs
│   │   │   ├── MultiplayerAPI.hs
│   │   │   ├── MultiplayerPeerGDNative.hs
│   │   │   ├── Mutex.hs
│   │   │   ├── NativeScript.hs
│   │   │   ├── Navigation.hs
│   │   │   ├── Navigation2D.hs
│   │   │   ├── NavigationMesh.hs
│   │   │   ├── NavigationMeshInstance.hs
│   │   │   ├── NavigationPolygon.hs
│   │   │   ├── NavigationPolygonInstance.hs
│   │   │   ├── NetworkedMultiplayerENet.hs
│   │   │   ├── NetworkedMultiplayerPeer.hs
│   │   │   ├── NinePatchRect.hs
│   │   │   ├── Node.hs
│   │   │   ├── Node2D.hs
│   │   │   ├── NoiseTexture.hs
│   │   │   ├── OS.hs
│   │   │   ├── Object.hs
│   │   │   ├── OccluderPolygon2D.hs
│   │   │   ├── OmniLight.hs
│   │   │   ├── OpenSimplexNoise.hs
│   │   │   ├── OptionButton.hs
│   │   │   ├── PCKPacker.hs
│   │   │   ├── PHashTranslation.hs
│   │   │   ├── PackedDataContainer.hs
│   │   │   ├── PackedDataContainerRef.hs
│   │   │   ├── PackedScene.hs
│   │   │   ├── PacketPeer.hs
│   │   │   ├── PacketPeerGDNative.hs
│   │   │   ├── PacketPeerStream.hs
│   │   │   ├── PacketPeerUDP.hs
│   │   │   ├── Panel.hs
│   │   │   ├── PanelContainer.hs
│   │   │   ├── PanoramaSky.hs
│   │   │   ├── ParallaxBackground.hs
│   │   │   ├── ParallaxLayer.hs
│   │   │   ├── Particles.hs
│   │   │   ├── Particles2D.hs
│   │   │   ├── ParticlesMaterial.hs
│   │   │   ├── Path.hs
│   │   │   ├── Path2D.hs
│   │   │   ├── PathFollow.hs
│   │   │   ├── PathFollow2D.hs
│   │   │   ├── Performance.hs
│   │   │   ├── PhysicalBone.hs
│   │   │   ├── Physics2DDirectBodyState.hs
│   │   │   ├── Physics2DDirectBodyStateSW.hs
│   │   │   ├── Physics2DDirectSpaceState.hs
│   │   │   ├── Physics2DServer.hs
│   │   │   ├── Physics2DServerSW.hs
│   │   │   ├── Physics2DShapeQueryParameters.hs
│   │   │   ├── Physics2DShapeQueryResult.hs
│   │   │   ├── Physics2DTestMotionResult.hs
│   │   │   ├── PhysicsBody.hs
│   │   │   ├── PhysicsBody2D.hs
│   │   │   ├── PhysicsDirectBodyState.hs
│   │   │   ├── PhysicsDirectSpaceState.hs
│   │   │   ├── PhysicsMaterial.hs
│   │   │   ├── PhysicsServer.hs
│   │   │   ├── PhysicsShapeQueryParameters.hs
│   │   │   ├── PhysicsShapeQueryResult.hs
│   │   │   ├── PinJoint.hs
│   │   │   ├── PinJoint2D.hs
│   │   │   ├── PlaneMesh.hs
│   │   │   ├── PlaneShape.hs
│   │   │   ├── PluginScript.hs
│   │   │   ├── PointMesh.hs
│   │   │   ├── Polygon2D.hs
│   │   │   ├── PolygonPathFinder.hs
│   │   │   ├── Popup.hs
│   │   │   ├── PopupDialog.hs
│   │   │   ├── PopupMenu.hs
│   │   │   ├── PopupPanel.hs
│   │   │   ├── Position2D.hs
│   │   │   ├── Position3D.hs
│   │   │   ├── PrimitiveMesh.hs
│   │   │   ├── PrismMesh.hs
│   │   │   ├── ProceduralSky.hs
│   │   │   ├── ProgressBar.hs
│   │   │   ├── ProjectSettings.hs
│   │   │   ├── ProximityGroup.hs
│   │   │   ├── ProxyTexture.hs
│   │   │   ├── QuadMesh.hs
│   │   │   ├── RandomNumberGenerator.hs
│   │   │   ├── Range.hs
│   │   │   ├── RayCast.hs
│   │   │   ├── RayCast2D.hs
│   │   │   ├── RayShape.hs
│   │   │   ├── RayShape2D.hs
│   │   │   ├── RectangleShape2D.hs
│   │   │   ├── Reference.hs
│   │   │   ├── ReferenceRect.hs
│   │   │   ├── ReflectionProbe.hs
│   │   │   ├── RegEx.hs
│   │   │   ├── RegExMatch.hs
│   │   │   ├── RemoteTransform.hs
│   │   │   ├── RemoteTransform2D.hs
│   │   │   ├── Resource.hs
│   │   │   ├── ResourceFormatLoader.hs
│   │   │   ├── ResourceFormatLoaderCrypto.hs
│   │   │   ├── ResourceFormatSaver.hs
│   │   │   ├── ResourceFormatSaverCrypto.hs
│   │   │   ├── ResourceImporter.hs
│   │   │   ├── ResourceInteractiveLoader.hs
│   │   │   ├── ResourceLoader.hs
│   │   │   ├── ResourcePreloader.hs
│   │   │   ├── ResourceSaver.hs
│   │   │   ├── RichTextEffect.hs
│   │   │   ├── RichTextLabel.hs
│   │   │   ├── RigidBody.hs
│   │   │   ├── RigidBody2D.hs
│   │   │   ├── RootMotionView.hs
│   │   │   ├── SceneState.hs
│   │   │   ├── SceneTree.hs
│   │   │   ├── SceneTreeTimer.hs
│   │   │   ├── Script.hs
│   │   │   ├── ScrollBar.hs
│   │   │   ├── ScrollContainer.hs
│   │   │   ├── SegmentShape2D.hs
│   │   │   ├── Semaphore.hs
│   │   │   ├── Separator.hs
│   │   │   ├── Shader.hs
│   │   │   ├── ShaderMaterial.hs
│   │   │   ├── Shape.hs
│   │   │   ├── Shape2D.hs
│   │   │   ├── ShortCut.hs
│   │   │   ├── Skeleton.hs
│   │   │   ├── Skeleton2D.hs
│   │   │   ├── SkeletonIK.hs
│   │   │   ├── Skin.hs
│   │   │   ├── SkinReference.hs
│   │   │   ├── Sky.hs
│   │   │   ├── Slider.hs
│   │   │   ├── SliderJoint.hs
│   │   │   ├── SoftBody.hs
│   │   │   ├── Spatial.hs
│   │   │   ├── SpatialGizmo.hs
│   │   │   ├── SpatialMaterial.hs
│   │   │   ├── SpatialVelocityTracker.hs
│   │   │   ├── SphereMesh.hs
│   │   │   ├── SphereShape.hs
│   │   │   ├── SpinBox.hs
│   │   │   ├── SplitContainer.hs
│   │   │   ├── SpotLight.hs
│   │   │   ├── SpringArm.hs
│   │   │   ├── Sprite.hs
│   │   │   ├── Sprite3D.hs
│   │   │   ├── SpriteBase3D.hs
│   │   │   ├── SpriteFrames.hs
│   │   │   ├── StaticBody.hs
│   │   │   ├── StaticBody2D.hs
│   │   │   ├── StreamPeer.hs
│   │   │   ├── StreamPeerBuffer.hs
│   │   │   ├── StreamPeerGDNative.hs
│   │   │   ├── StreamPeerSSL.hs
│   │   │   ├── StreamPeerTCP.hs
│   │   │   ├── StreamTexture.hs
│   │   │   ├── StyleBox.hs
│   │   │   ├── StyleBoxEmpty.hs
│   │   │   ├── StyleBoxFlat.hs
│   │   │   ├── StyleBoxLine.hs
│   │   │   ├── StyleBoxTexture.hs
│   │   │   ├── SurfaceTool.hs
│   │   │   ├── TCP_Server.hs
│   │   │   ├── TabContainer.hs
│   │   │   ├── Tabs.hs
│   │   │   ├── TextEdit.hs
│   │   │   ├── TextFile.hs
│   │   │   ├── Texture.hs
│   │   │   ├── Texture3D.hs
│   │   │   ├── TextureArray.hs
│   │   │   ├── TextureButton.hs
│   │   │   ├── TextureLayered.hs
│   │   │   ├── TextureProgress.hs
│   │   │   ├── TextureRect.hs
│   │   │   ├── Theme.hs
│   │   │   ├── Thread.hs
│   │   │   ├── TileMap.hs
│   │   │   ├── TileSet.hs
│   │   │   ├── Timer.hs
│   │   │   ├── ToolButton.hs
│   │   │   ├── TouchScreenButton.hs
│   │   │   ├── Translation.hs
│   │   │   ├── TranslationServer.hs
│   │   │   ├── Tree.hs
│   │   │   ├── TreeItem.hs
│   │   │   ├── TriangleMesh.hs
│   │   │   ├── Tween.hs
│   │   │   ├── UPNP.hs
│   │   │   ├── UPNPDevice.hs
│   │   │   ├── UndoRedo.hs
│   │   │   ├── VBoxContainer.hs
│   │   │   ├── VScrollBar.hs
│   │   │   ├── VSeparator.hs
│   │   │   ├── VSlider.hs
│   │   │   ├── VSplitContainer.hs
│   │   │   ├── VehicleBody.hs
│   │   │   ├── VehicleWheel.hs
│   │   │   ├── VideoPlayer.hs
│   │   │   ├── VideoStream.hs
│   │   │   ├── VideoStreamGDNative.hs
│   │   │   ├── VideoStreamTheora.hs
│   │   │   ├── VideoStreamWebm.hs
│   │   │   ├── Viewport.hs
│   │   │   ├── ViewportContainer.hs
│   │   │   ├── ViewportTexture.hs
│   │   │   ├── VisibilityEnabler.hs
│   │   │   ├── VisibilityEnabler2D.hs
│   │   │   ├── VisibilityNotifier.hs
│   │   │   ├── VisibilityNotifier2D.hs
│   │   │   ├── VisualInstance.hs
│   │   │   ├── VisualScript.hs
│   │   │   ├── VisualScriptBasicTypeConstant.hs
│   │   │   ├── VisualScriptBuiltinFunc.hs
│   │   │   ├── VisualScriptClassConstant.hs
│   │   │   ├── VisualScriptComment.hs
│   │   │   ├── VisualScriptComposeArray.hs
│   │   │   ├── VisualScriptCondition.hs
│   │   │   ├── VisualScriptConstant.hs
│   │   │   ├── VisualScriptConstructor.hs
│   │   │   ├── VisualScriptCustomNode.hs
│   │   │   ├── VisualScriptDeconstruct.hs
│   │   │   ├── VisualScriptEmitSignal.hs
│   │   │   ├── VisualScriptEngineSingleton.hs
│   │   │   ├── VisualScriptExpression.hs
│   │   │   ├── VisualScriptFunction.hs
│   │   │   ├── VisualScriptFunctionCall.hs
│   │   │   ├── VisualScriptFunctionState.hs
│   │   │   ├── VisualScriptGlobalConstant.hs
│   │   │   ├── VisualScriptIndexGet.hs
│   │   │   ├── VisualScriptIndexSet.hs
│   │   │   ├── VisualScriptInputAction.hs
│   │   │   ├── VisualScriptIterator.hs
│   │   │   ├── VisualScriptLists.hs
│   │   │   ├── VisualScriptLocalVar.hs
│   │   │   ├── VisualScriptLocalVarSet.hs
│   │   │   ├── VisualScriptMathConstant.hs
│   │   │   ├── VisualScriptNode.hs
│   │   │   ├── VisualScriptOperator.hs
│   │   │   ├── VisualScriptPreload.hs
│   │   │   ├── VisualScriptPropertyGet.hs
│   │   │   ├── VisualScriptPropertySet.hs
│   │   │   ├── VisualScriptResourcePath.hs
│   │   │   ├── VisualScriptReturn.hs
│   │   │   ├── VisualScriptSceneNode.hs
│   │   │   ├── VisualScriptSceneTree.hs
│   │   │   ├── VisualScriptSelect.hs
│   │   │   ├── VisualScriptSelf.hs
│   │   │   ├── VisualScriptSequence.hs
│   │   │   ├── VisualScriptSubCall.hs
│   │   │   ├── VisualScriptSwitch.hs
│   │   │   ├── VisualScriptTypeCast.hs
│   │   │   ├── VisualScriptVariableGet.hs
│   │   │   ├── VisualScriptVariableSet.hs
│   │   │   ├── VisualScriptWhile.hs
│   │   │   ├── VisualScriptYield.hs
│   │   │   ├── VisualScriptYieldSignal.hs
│   │   │   ├── VisualServer.hs
│   │   │   ├── VisualShader.hs
│   │   │   ├── VisualShaderNode.hs
│   │   │   ├── VisualShaderNodeBooleanConstant.hs
│   │   │   ├── VisualShaderNodeBooleanUniform.hs
│   │   │   ├── VisualShaderNodeColorConstant.hs
│   │   │   ├── VisualShaderNodeColorFunc.hs
│   │   │   ├── VisualShaderNodeColorOp.hs
│   │   │   ├── VisualShaderNodeColorUniform.hs
│   │   │   ├── VisualShaderNodeCompare.hs
│   │   │   ├── VisualShaderNodeCubeMap.hs
│   │   │   ├── VisualShaderNodeCubeMapUniform.hs
│   │   │   ├── VisualShaderNodeCustom.hs
│   │   │   ├── VisualShaderNodeDeterminant.hs
│   │   │   ├── VisualShaderNodeDotProduct.hs
│   │   │   ├── VisualShaderNodeExpression.hs
│   │   │   ├── VisualShaderNodeFaceForward.hs
│   │   │   ├── VisualShaderNodeFresnel.hs
│   │   │   ├── VisualShaderNodeGlobalExpression.hs
│   │   │   ├── VisualShaderNodeGroupBase.hs
│   │   │   ├── VisualShaderNodeIf.hs
│   │   │   ├── VisualShaderNodeInput.hs
│   │   │   ├── VisualShaderNodeIs.hs
│   │   │   ├── VisualShaderNodeOuterProduct.hs
│   │   │   ├── VisualShaderNodeOutput.hs
│   │   │   ├── VisualShaderNodeScalarClamp.hs
│   │   │   ├── VisualShaderNodeScalarConstant.hs
│   │   │   ├── VisualShaderNodeScalarDerivativeFunc.hs
│   │   │   ├── VisualShaderNodeScalarFunc.hs
│   │   │   ├── VisualShaderNodeScalarInterp.hs
│   │   │   ├── VisualShaderNodeScalarOp.hs
│   │   │   ├── VisualShaderNodeScalarSmoothStep.hs
│   │   │   ├── VisualShaderNodeScalarSwitch.hs
│   │   │   ├── VisualShaderNodeScalarUniform.hs
│   │   │   ├── VisualShaderNodeSwitch.hs
│   │   │   ├── VisualShaderNodeTexture.hs
│   │   │   ├── VisualShaderNodeTextureUniform.hs
│   │   │   ├── VisualShaderNodeTextureUniformTriplanar.hs
│   │   │   ├── VisualShaderNodeTransformCompose.hs
│   │   │   ├── VisualShaderNodeTransformConstant.hs
│   │   │   ├── VisualShaderNodeTransformDecompose.hs
│   │   │   ├── VisualShaderNodeTransformFunc.hs
│   │   │   ├── VisualShaderNodeTransformMult.hs
│   │   │   ├── VisualShaderNodeTransformUniform.hs
│   │   │   ├── VisualShaderNodeTransformVecMult.hs
│   │   │   ├── VisualShaderNodeUniform.hs
│   │   │   ├── VisualShaderNodeVec3Constant.hs
│   │   │   ├── VisualShaderNodeVec3Uniform.hs
│   │   │   ├── VisualShaderNodeVectorClamp.hs
│   │   │   ├── VisualShaderNodeVectorCompose.hs
│   │   │   ├── VisualShaderNodeVectorDecompose.hs
│   │   │   ├── VisualShaderNodeVectorDerivativeFunc.hs
│   │   │   ├── VisualShaderNodeVectorDistance.hs
│   │   │   ├── VisualShaderNodeVectorFunc.hs
│   │   │   ├── VisualShaderNodeVectorInterp.hs
│   │   │   ├── VisualShaderNodeVectorLen.hs
│   │   │   ├── VisualShaderNodeVectorOp.hs
│   │   │   ├── VisualShaderNodeVectorRefract.hs
│   │   │   ├── VisualShaderNodeVectorScalarMix.hs
│   │   │   ├── VisualShaderNodeVectorScalarSmoothStep.hs
│   │   │   ├── VisualShaderNodeVectorScalarStep.hs
│   │   │   ├── VisualShaderNodeVectorSmoothStep.hs
│   │   │   ├── WeakRef.hs
│   │   │   ├── WebRTCDataChannel.hs
│   │   │   ├── WebRTCDataChannelGDNative.hs
│   │   │   ├── WebRTCMultiplayer.hs
│   │   │   ├── WebRTCPeerConnection.hs
│   │   │   ├── WebRTCPeerConnectionGDNative.hs
│   │   │   ├── WebSocketClient.hs
│   │   │   ├── WebSocketMultiplayerPeer.hs
│   │   │   ├── WebSocketPeer.hs
│   │   │   ├── WebSocketServer.hs
│   │   │   ├── WindowDialog.hs
│   │   │   ├── World.hs
│   │   │   ├── World2D.hs
│   │   │   ├── WorldEnvironment.hs
│   │   │   ├── X509Certificate.hs
│   │   │   ├── XMLParser.hs
│   │   │   └── YSort.hs
│   │   ├── Gdnative/
│   │   │   ├── Internal/
│   │   │   │   ├── Api.hs
│   │   │   │   ├── Gdnative.chs
│   │   │   │   ├── TH.hs
│   │   │   │   └── Types.hs
│   │   │   └── Internal.hs
│   │   ├── Gdnative.hs
│   │   ├── Internal/
│   │   │   └── Dispatch.hs
│   │   ├── Nativescript.hs
│   │   └── Tools/
│   │       ├── AnimationTrackEditPlugin.hs
│   │       ├── EditorExportPlugin.hs
│   │       ├── EditorFeatureProfile.hs
│   │       ├── EditorFileDialog.hs
│   │       ├── EditorFileSystem.hs
│   │       ├── EditorFileSystemDirectory.hs
│   │       ├── EditorImportPlugin.hs
│   │       ├── EditorInspector.hs
│   │       ├── EditorInspectorPlugin.hs
│   │       ├── EditorInterface.hs
│   │       ├── EditorNavigationMeshGenerator.hs
│   │       ├── EditorPlugin.hs
│   │       ├── EditorProperty.hs
│   │       ├── EditorResourceConversionPlugin.hs
│   │       ├── EditorResourcePreview.hs
│   │       ├── EditorResourcePreviewGenerator.hs
│   │       ├── EditorSceneImporter.hs
│   │       ├── EditorSceneImporterAssimp.hs
│   │       ├── EditorScenePostImport.hs
│   │       ├── EditorScript.hs
│   │       ├── EditorSelection.hs
│   │       ├── EditorSettings.hs
│   │       ├── EditorSpatialGizmo.hs
│   │       ├── EditorSpatialGizmoPlugin.hs
│   │       ├── EditorSpinSlider.hs
│   │       ├── EditorVCSInterface.hs
│   │       ├── ScriptCreateDialog.hs
│   │       ├── ScriptEditor.hs
│   │       └── VisualScriptEditor.hs
│   └── Godot.hs
├── src-generate/
│   ├── Generate.hs
│   ├── Spec.hs
│   ├── Types/
│   │   └── Internal.hs
│   └── Types.hs
├── stack-shell.nix
├── stack.yaml
├── template/
│   ├── README.md
│   ├── demo/
│   │   ├── Makefile
│   │   ├── ffi/
│   │   │   └── cbits/
│   │   │       └── flib.c
│   │   └── game/
│   │       ├── Main.gdns
│   │       ├── lib/
│   │       │   └── libdemo.gdnlib
│   │       └── project.godot
│   ├── godot-haskell.hsfiles
│   ├── mkdemo.sh
│   └── update-template.sh
└── update-nixpkgs.sh
Download .txt
SYMBOL INDEX (8 symbols across 4 files)

FILE: examples/dodge-the-creeps/ffi/cbits/flib.c
  function flib_init (line 4) | static void flib_init() {
  function flib_fini (line 11) | static void flib_fini() {

FILE: examples/rss-reader/ffi/cbits/flib.c
  function flib_init (line 4) | static void flib_init() {
  function flib_fini (line 11) | static void flib_fini() {

FILE: examples/top-down-ten-minutes/ffi/cbits/flib.c
  function flib_init (line 4) | static void flib_init() {
  function flib_fini (line 11) | static void flib_fini() {

FILE: template/demo/ffi/cbits/flib.c
  function flib_init (line 4) | static void flib_init() {
  function flib_fini (line 11) | static void flib_fini() {
Copy disabled (too large) Download .json
Condensed preview — 788 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (12,040K chars).
[
  {
    "path": ".gitignore",
    "chars": 237,
    "preview": "dist*\n*.hi\n*.o\n.hsenv*\ncabal-dev/\n.stack-work/\n.cabal-sandbox\ncabal.sandbox.config\n.DS_Store\n*.dyn_o\n*.dyn_hi\napp/*.cpp\n"
  },
  {
    "path": ".gitmodules",
    "chars": 340,
    "preview": "[submodule \"godot_headers\"]\n\tpath = godot_headers\n\turl = https://github.com/GodotNativeTools/godot_headers/\n[submodule \""
  },
  {
    "path": ".hlint.yaml",
    "chars": 86,
    "preview": "- ignore: { name: \"Use camelCase\" }\n- ignore: { name: \"Use newtype instead of data\" }\n"
  },
  {
    "path": ".travis.yml",
    "chars": 519,
    "preview": "# https://docs.haskellstack.org/en/stable/travis_ci/\n\nsudo: false\ndist: bionic\nlanguage: generic\naddons:\n  apt:\n    upda"
  },
  {
    "path": ".vscode/tasks.json",
    "chars": 1091,
    "preview": "\n{\n  // Automatically created by phoityne-vscode extension.\n\n  \"version\": \"2.0.0\",\n  \"presentation\": {\n    \"reveal\": \"al"
  },
  {
    "path": "LICENSE",
    "chars": 1528,
    "preview": "Copyright David Kraeutmann (c) 2018\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or wi"
  },
  {
    "path": "README.md",
    "chars": 6038,
    "preview": "# godot-haskell\n\n[![Build Status](https://travis-ci.org/SimulaVR/godot-haskell.svg?branch=master)](https://travis-ci.org"
  },
  {
    "path": "Setup.hs",
    "chars": 46,
    "preview": "import Distribution.Simple\nmain = defaultMain\n"
  },
  {
    "path": "cbits/util.h",
    "chars": 131,
    "preview": "#ifndef GODOT_HASKELL_UTIL_H__\n#define GODOT_HASKELL_UTIL_H__\n\n#include <gdnative/gdnative.h>\n\n#endif /* GODOT_HASKELL_U"
  },
  {
    "path": "classgen/README.md",
    "chars": 93,
    "preview": "Generate bindings to the Godot API.\n\nSee the godot-haskell README.md for instructions on use\n"
  },
  {
    "path": "classgen/app-classgen/Main.hs",
    "chars": 4378,
    "preview": "import Classgen.Module\nimport Classgen.Spec\nimport Control.Lens\nimport Control.Monad.State\nimport Data.Maybe (mapMaybe)\n"
  },
  {
    "path": "classgen/default.nix",
    "chars": 3469,
    "preview": "{ mkDerivation, aeson, base, bytestring, c2hs, casing, containers\n, directory, filepath, hpack\n, lens, mtl, template-has"
  },
  {
    "path": "classgen/godot-haskell-classgen.cabal",
    "chars": 2436,
    "preview": "cabal-version: 1.12\n\n-- This file has been generated from package.yaml by hpack version 0.31.1.\n--\n-- see: https://githu"
  },
  {
    "path": "classgen/package.yaml",
    "chars": 1120,
    "preview": "name: godot-haskell-classgen\nversion: '0.1.0.0'\ncategory: Web\nauthor: David Kraeutmann\nmaintainer: kane@kane.cx\ncopyrigh"
  },
  {
    "path": "classgen/release.nix",
    "chars": 91,
    "preview": "let\n  pkgs = import <nixpkgs> { };\nin\n  pkgs.haskellPackages.callPackage ./default.nix { }\n"
  },
  {
    "path": "classgen/src-classgen/Classgen/Docs.hs",
    "chars": 5668,
    "preview": "{-# LANGUAGE TemplateHaskell, GeneralizedNewtypeDeriving, OverloadedStrings #-}\n{-# OPTIONS_GHC -Wno-orphans #-}\nmodule "
  },
  {
    "path": "classgen/src-classgen/Classgen/Module.hs",
    "chars": 24891,
    "preview": "{-# LANGUAGE NoMonoLocalBinds, NoMonomorphismRestriction #-}\nmodule Classgen.Module where\n\nimport Control.Lens hiding (i"
  },
  {
    "path": "classgen/src-classgen/Classgen/Spec.hs",
    "chars": 4061,
    "preview": "{-# LANGUAGE TemplateHaskell, GeneralizedNewtypeDeriving, OverloadedStrings #-}\n{-# OPTIONS_GHC -Wno-orphans #-}\nmodule "
  },
  {
    "path": "classgen/src-classgen/Classgen/Utils.hs",
    "chars": 477,
    "preview": "module Classgen.Utils where\n\nimport Control.Lens\nimport Language.Haskell.TH\n\nfixedTypeFields :: LensRules\nfixedTypeField"
  },
  {
    "path": "classgen/stack.yaml",
    "chars": 2247,
    "preview": "# This file was automatically generated by 'stack init'\n#\n# Some commonly used options have been documented as comments "
  },
  {
    "path": "default.nix",
    "chars": 1146,
    "preview": "{ mkDerivation, aeson, ansi-wl-pprint, base, bytestring, c2hs\n, casing, colour, containers, hpack, lens, linear, mtl, pa"
  },
  {
    "path": "examples/dodge-the-creeps/.gitignore",
    "chars": 72,
    "preview": "dist*\n*.hi\n*.o\n.stack-work/\n.stack-work-devel/\n*~\n\\#*\n*.import\nresult\n\n\n"
  },
  {
    "path": "examples/dodge-the-creeps/ChangeLog.md",
    "chars": 10,
    "preview": "# Empty\n\n\n"
  },
  {
    "path": "examples/dodge-the-creeps/LICENSE",
    "chars": 1512,
    "preview": "BSD 3-Clause License\n\nCopyright (c) Andrei Barbu 2019\nAll rights reserved.\n\nRedistribution and use in source and binary "
  },
  {
    "path": "examples/dodge-the-creeps/Makefile",
    "chars": 767,
    "preview": "NAME = myproject\nSTACKLIBFILE = $(shell stack path --local-install-root)/lib/lib$(NAME).so\nGODOTPROJECT = $(shell stack "
  },
  {
    "path": "examples/dodge-the-creeps/README.md",
    "chars": 168,
    "preview": "The official Godot demo from the manual: Dodge the Creeps.\n\nRun with `make stack` then `godot game/project.godot` and pr"
  },
  {
    "path": "examples/dodge-the-creeps/Support.hs",
    "chars": 512,
    "preview": "{-# LANGUAGE FlexibleContexts, FunctionalDependencies, MultiParamTypeClasses, OverloadedLabels, UndecidableInstances,\n  "
  },
  {
    "path": "examples/dodge-the-creeps/ffi/cbits/flib.c",
    "chars": 321,
    "preview": "#include \"HsFFI.h\"\n\nstatic void flib_init() __attribute__((constructor));\nstatic void flib_init() {\n  static char *argv["
  },
  {
    "path": "examples/dodge-the-creeps/ffi/flib/FLib.hs",
    "chars": 1023,
    "preview": "{-# LANGUAGE ForeignFunctionInterface #-}\nmodule FLib where\n\nimport qualified Foreign\nimport           Foreign(nullPtr, "
  },
  {
    "path": "examples/dodge-the-creeps/game/HUD.gdns",
    "chars": 217,
    "preview": "[gd_resource type=\"NativeScript\" load_steps=2 format=2]\n\n[ext_resource path=\"res://lib/libmyproject.gdnlib\" type=\"GDNati"
  },
  {
    "path": "examples/dodge-the-creeps/game/HUD.tres",
    "chars": 203,
    "preview": "[gd_resource type=\"DynamicFont\" load_steps=2 format=2]\n\n[ext_resource path=\"res://dodge_assets/fonts/Xolonium-Regular.tt"
  },
  {
    "path": "examples/dodge-the-creeps/game/HUD.tscn",
    "chars": 1355,
    "preview": "[gd_scene load_steps=5 format=2]\n\n[ext_resource path=\"res://HUD.gdns\" type=\"Script\" id=1]\n[ext_resource path=\"res://HUD."
  },
  {
    "path": "examples/dodge-the-creeps/game/Main.gdns",
    "chars": 196,
    "preview": "[gd_resource type=\"NativeScript\" load_steps=2 format=2]\n\n[ext_resource path=\"res://lib/libmyproject.gdnlib\" type=\"GDNati"
  },
  {
    "path": "examples/dodge-the-creeps/game/Main.tscn",
    "chars": 1663,
    "preview": "[gd_scene load_steps=6 format=2]\n\n[ext_resource path=\"res://Main.gdns\" type=\"Script\" id=1]\n[ext_resource path=\"res://Mob"
  },
  {
    "path": "examples/dodge-the-creeps/game/Mob.gdns",
    "chars": 217,
    "preview": "[gd_resource type=\"NativeScript\" load_steps=2 format=2]\n\n[ext_resource path=\"res://lib/libmyproject.gdnlib\" type=\"GDNati"
  },
  {
    "path": "examples/dodge-the-creeps/game/Mob.tscn",
    "chars": 1634,
    "preview": "[gd_scene load_steps=10 format=2]\n\n[ext_resource path=\"res://Mob.gdns\" type=\"Script\" id=1]\n[ext_resource path=\"res://dod"
  },
  {
    "path": "examples/dodge-the-creeps/game/Player.gdns",
    "chars": 223,
    "preview": "[gd_resource type=\"NativeScript\" load_steps=2 format=2]\n\n[ext_resource path=\"res://lib/libmyproject.gdnlib\" type=\"GDNati"
  },
  {
    "path": "examples/dodge-the-creeps/game/Player.tscn",
    "chars": 1197,
    "preview": "[gd_scene load_steps=8 format=2]\n\n[ext_resource path=\"res://Player.gdns\" type=\"Script\" id=1]\n[ext_resource path=\"res://d"
  },
  {
    "path": "examples/dodge-the-creeps/game/dodge_assets/fonts/FONTLOG.txt",
    "chars": 6744,
    "preview": "Please distribute this file along with the Xolonium fonts when possible.\n\n\nSource\n\n\tFind the sourcefiles of Xolonium at\n"
  },
  {
    "path": "examples/dodge-the-creeps/game/dodge_assets/fonts/LICENSE.txt",
    "chars": 4482,
    "preview": "Copyright 2011-2016 Severin Meyer <sev.ch@web.de>,\r\nwith Reserved Font Name Xolonium.\r\n\r\nThis Font Software is licensed "
  },
  {
    "path": "examples/dodge-the-creeps/game/lib/libmyproject.gdnlib",
    "chars": 127,
    "preview": "[general]\n\nsingleton=false\nload_once=true\nsymbol_prefix=\"godot_\"\nreloadable=false\n\n[entry]\n\nX11.64=\"res://lib/libmyproje"
  },
  {
    "path": "examples/dodge-the-creeps/game/project.godot",
    "chars": 511,
    "preview": "; Engine configuration file.\n; It's best edited using the editor UI and not directly,\n; since the parameters that go her"
  },
  {
    "path": "examples/dodge-the-creeps/godot-haskell.nix",
    "chars": 1034,
    "preview": "{ fetchFromGitHub, mkDerivation, aeson, ansi-wl-pprint, base, bytestring, c2hs\n, casing, colour, containers, hpack, lens"
  },
  {
    "path": "examples/dodge-the-creeps/hie.yaml",
    "chars": 125,
    "preview": "cradle:\n  stack:\n    - path: \"./src\"\n      component: \"myproject:lib\"\n\n    - path: \"./game\"\n      component: \"myproject:"
  },
  {
    "path": "examples/dodge-the-creeps/myproject.cabal",
    "chars": 1945,
    "preview": "cabal-version: 1.12\n\n-- This file has been generated from package.yaml by hpack version 0.33.0.\n--\n-- see: https://githu"
  },
  {
    "path": "examples/dodge-the-creeps/package.yaml",
    "chars": 1221,
    "preview": "name: myproject\nversion: '0.0.0.0'\ndescription: Please see the README on Github at <https://github.com/SimulaVR/godot-ha"
  },
  {
    "path": "examples/dodge-the-creeps/pinned-nixpkgs.nix",
    "chars": 240,
    "preview": "{}:\n\nlet\n  # 19.03-beta (25 feb)\n  rev = \"0c0954781e257b8b0dc49341795a2fe7d96945a3\"; # pinned-nixpkgs rev\n  pkgs = impor"
  },
  {
    "path": "examples/dodge-the-creeps/shell.nix",
    "chars": 993,
    "preview": "{ nixpkgs ? import ./pinned-nixpkgs.nix {}\n, compiler ? \"default\"\n, doBenchmark ? false }:\n\n\nlet\n\n  inherit (nixpkgs) pk"
  },
  {
    "path": "examples/dodge-the-creeps/src/Game/HUD.hs",
    "chars": 1829,
    "preview": "module Game.HUD where\nimport Control.Lens\nimport Control.Monad\nimport qualified Data.Text as T\nimport Godot\nimport Godot"
  },
  {
    "path": "examples/dodge-the-creeps/src/Game/Main.hs",
    "chars": 3626,
    "preview": "module Game.Main where\nimport Control.Lens\nimport Control.Monad\nimport Foreign.C.Types\nimport Godot\nimport Godot.Core.No"
  },
  {
    "path": "examples/dodge-the-creeps/src/Game/Mob.hs",
    "chars": 885,
    "preview": "module Game.Mob where\nimport Godot\nimport Godot.Core.AnimatedSprite as AnimatedSprite\nimport Godot.Core.Node as Node\nimp"
  },
  {
    "path": "examples/dodge-the-creeps/src/Game/Player.hs",
    "chars": 3439,
    "preview": "module Game.Player where\nimport Control.Lens\nimport Control.Monad\nimport Godot\nimport Godot.Core.AnimatedSprite as Anima"
  },
  {
    "path": "examples/dodge-the-creeps/src/Lib.hs",
    "chars": 252,
    "preview": "module Lib (exports) where\nimport Godot\nimport Game.Mob\nimport Game.Main\nimport Game.Player\nimport Game.HUD\nimport Proje"
  },
  {
    "path": "examples/dodge-the-creeps/src/Project/Requirements.hs",
    "chars": 278,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\nmodule Project.Requirements where\nimpor"
  },
  {
    "path": "examples/dodge-the-creeps/src/Project/Scenes/HUD.hs",
    "chars": 2068,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/dodge-the-creeps/src/Project/Scenes/Main.hs",
    "chars": 3583,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/dodge-the-creeps/src/Project/Scenes/Mob.hs",
    "chars": 1928,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/dodge-the-creeps/src/Project/Scenes/Player.hs",
    "chars": 1641,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/dodge-the-creeps/src/Project/Scenes.hs",
    "chars": 289,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\nmodule Project.Scenes (module M) where\n"
  },
  {
    "path": "examples/dodge-the-creeps/src/Project/Support.hs",
    "chars": 18614,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/dodge-the-creeps/stack-shell.nix",
    "chars": 161,
    "preview": "{ nixpkgs ? import ./pinned-nixpkgs.nix {}\n, ghc\n}:\n\nwith nixpkgs;\n\nhaskell.lib.buildStackProject {\n  inherit ghc;\n  nam"
  },
  {
    "path": "examples/dodge-the-creeps/stack.yaml",
    "chars": 237,
    "preview": "resolver: nightly-2021-02-06\n\npackages:\n- .\n\nextra-deps:\n- ../../\n\nrequire-stack-version: \">=1.8\"\n\nnix:\n  enable: false\n"
  },
  {
    "path": "examples/rss-reader/.gitignore",
    "chars": 72,
    "preview": "dist*\n*.hi\n*.o\n.stack-work/\n.stack-work-devel/\n*~\n\\#*\n*.import\nresult\n\n\n"
  },
  {
    "path": "examples/rss-reader/ChangeLog.md",
    "chars": 10,
    "preview": "# Empty\n\n\n"
  },
  {
    "path": "examples/rss-reader/LICENSE",
    "chars": 1512,
    "preview": "BSD 3-Clause License\n\nCopyright (c) Andrei Barbu 2019\nAll rights reserved.\n\nRedistribution and use in source and binary "
  },
  {
    "path": "examples/rss-reader/Makefile",
    "chars": 766,
    "preview": "NAME = myproject\nSTACKLIBFILE = $(shell stack path --local-install-root)/lib/lib$(NAME).so\nGODOTPROJECT = $(shell stack "
  },
  {
    "path": "examples/rss-reader/README.md",
    "chars": 168,
    "preview": "The official Godot demo from the manual: Dodge the Creeps.\n\nRun with `make stack` then `godot game/project.godot` and pr"
  },
  {
    "path": "examples/rss-reader/Support.hs",
    "chars": 512,
    "preview": "{-# LANGUAGE FlexibleContexts, FunctionalDependencies, MultiParamTypeClasses, OverloadedLabels, UndecidableInstances,\n  "
  },
  {
    "path": "examples/rss-reader/ffi/cbits/flib.c",
    "chars": 321,
    "preview": "#include \"HsFFI.h\"\n\nstatic void flib_init() __attribute__((constructor));\nstatic void flib_init() {\n  static char *argv["
  },
  {
    "path": "examples/rss-reader/ffi/flib/FLib.hs",
    "chars": 1023,
    "preview": "{-# LANGUAGE ForeignFunctionInterface #-}\nmodule FLib where\n\nimport qualified Foreign\nimport           Foreign(nullPtr, "
  },
  {
    "path": "examples/rss-reader/game/Rss_reader.gdns",
    "chars": 229,
    "preview": "[gd_resource type=\"NativeScript\" load_steps=2 format=2]\n\n[ext_resource path=\"res://lib/libmyproject.gdnlib\" type=\"GDNati"
  },
  {
    "path": "examples/rss-reader/game/Rss_reader.tscn",
    "chars": 3181,
    "preview": "[gd_scene load_steps=2 format=2]\n\n[ext_resource path=\"res://Rss_reader.gdns\" type=\"Script\" id=1]\n\n[node name=\"RSSReader\""
  },
  {
    "path": "examples/rss-reader/game/export_presets.cfg",
    "chars": 552,
    "preview": "[preset.0]\n\nname=\"Linux/X11\"\nplatform=\"Linux/X11\"\nrunnable=true\ncustom_features=\"\"\nexport_filter=\"all_resources\"\ninclude"
  },
  {
    "path": "examples/rss-reader/game/lib/libmyproject.gdnlib",
    "chars": 127,
    "preview": "[general]\n\nsingleton=false\nload_once=true\nsymbol_prefix=\"godot_\"\nreloadable=false\n\n[entry]\n\nX11.64=\"res://lib/libmyproje"
  },
  {
    "path": "examples/rss-reader/game/project.godot",
    "chars": 575,
    "preview": "; Engine configuration file.\n; It's best edited using the editor UI and not directly,\n; since the parameters that go her"
  },
  {
    "path": "examples/rss-reader/godot-haskell.nix",
    "chars": 1034,
    "preview": "{ fetchFromGitHub, mkDerivation, aeson, ansi-wl-pprint, base, bytestring, c2hs\n, casing, colour, containers, hpack, lens"
  },
  {
    "path": "examples/rss-reader/hie.yaml",
    "chars": 125,
    "preview": "cradle:\n  stack:\n    - path: \"./src\"\n      component: \"myproject:lib\"\n\n    - path: \"./game\"\n      component: \"myproject:"
  },
  {
    "path": "examples/rss-reader/myproject.cabal",
    "chars": 1878,
    "preview": "cabal-version: 1.12\n\n-- This file has been generated from package.yaml by hpack version 0.33.0.\n--\n-- see: https://githu"
  },
  {
    "path": "examples/rss-reader/package.yaml",
    "chars": 1261,
    "preview": "name: myproject\nversion: '0.0.0.0'\ndescription: Please see the README on Github at <https://github.com/SimulaVR/godot-ha"
  },
  {
    "path": "examples/rss-reader/pinned-nixpkgs.nix",
    "chars": 240,
    "preview": "{}:\n\nlet\n  # 19.03-beta (25 feb)\n  rev = \"0c0954781e257b8b0dc49341795a2fe7d96945a3\"; # pinned-nixpkgs rev\n  pkgs = impor"
  },
  {
    "path": "examples/rss-reader/shell.nix",
    "chars": 993,
    "preview": "{ nixpkgs ? import ./pinned-nixpkgs.nix {}\n, compiler ? \"default\"\n, doBenchmark ? false }:\n\n\nlet\n\n  inherit (nixpkgs) pk"
  },
  {
    "path": "examples/rss-reader/src/Game/RSSReader.hs",
    "chars": 6310,
    "preview": "{-# LANGUAGE LambdaCase, FunctionalDependencies, DeriveGeneric, UndecidableInstances, ConstraintKinds #-}\nmodule Game.RS"
  },
  {
    "path": "examples/rss-reader/src/Game/q",
    "chars": 7454,
    "preview": "{-# LANGUAGE LambdaCase, FunctionalDependencies, DeriveGeneric, UndecidableInstances, ConstraintKinds #-}\nmodule Game.RS"
  },
  {
    "path": "examples/rss-reader/src/Lib.hs",
    "chars": 193,
    "preview": "module Lib (exports) where\nimport Godot\nimport Project.Support\nimport Project.Requirements\nimport Game.RSSReader\n\nexport"
  },
  {
    "path": "examples/rss-reader/src/Project/Requirements.hs",
    "chars": 196,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\nmodule Project.Requirements where\nimpor"
  },
  {
    "path": "examples/rss-reader/src/Project/Scenes/Rss_reader.hs",
    "chars": 5388,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/rss-reader/src/Project/Scenes.hs",
    "chars": 169,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\nmodule Project.Scenes (module M) where\n"
  },
  {
    "path": "examples/rss-reader/src/Project/Support.hs",
    "chars": 18614,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/rss-reader/stack-shell.nix",
    "chars": 161,
    "preview": "{ nixpkgs ? import ./pinned-nixpkgs.nix {}\n, ghc\n}:\n\nwith nixpkgs;\n\nhaskell.lib.buildStackProject {\n  inherit ghc;\n  nam"
  },
  {
    "path": "examples/rss-reader/stack.yaml",
    "chars": 237,
    "preview": "resolver: nightly-2021-02-06\n\npackages:\n- .\n\nextra-deps:\n- ../../\n\nrequire-stack-version: \">=1.8\"\n\nnix:\n  enable: false\n"
  },
  {
    "path": "examples/top-down-ten-minutes/.gitignore",
    "chars": 72,
    "preview": "dist*\n*.hi\n*.o\n.stack-work/\n.stack-work-devel/\n*~\n\\#*\n*.import\nresult\n\n\n"
  },
  {
    "path": "examples/top-down-ten-minutes/ChangeLog.md",
    "chars": 10,
    "preview": "# Empty\n\n\n"
  },
  {
    "path": "examples/top-down-ten-minutes/LICENSE",
    "chars": 1512,
    "preview": "BSD 3-Clause License\n\nCopyright (c) Andrei Barbu 2019\nAll rights reserved.\n\nRedistribution and use in source and binary "
  },
  {
    "path": "examples/top-down-ten-minutes/Makefile",
    "chars": 777,
    "preview": "NAME = top-down-ten-minutes\nSTACKLIBFILE = $(shell stack path --local-install-root)/lib/lib$(NAME).so\nGODOTPROJECT = $(s"
  },
  {
    "path": "examples/top-down-ten-minutes/README.md",
    "chars": 168,
    "preview": "The official Godot demo from the manual: Dodge the Creeps.\n\nRun with `make stack` then `godot game/project.godot` and pr"
  },
  {
    "path": "examples/top-down-ten-minutes/ffi/cbits/flib.c",
    "chars": 321,
    "preview": "#include \"HsFFI.h\"\n\nstatic void flib_init() __attribute__((constructor));\nstatic void flib_init() {\n  static char *argv["
  },
  {
    "path": "examples/top-down-ten-minutes/ffi/flib/FLib.hs",
    "chars": 1023,
    "preview": "{-# LANGUAGE ForeignFunctionInterface #-}\nmodule FLib where\n\nimport qualified Foreign\nimport           Foreign(nullPtr, "
  },
  {
    "path": "examples/top-down-ten-minutes/game/Bullet.gdns",
    "chars": 234,
    "preview": "[gd_resource type=\"NativeScript\" load_steps=2 format=2]\n\n[ext_resource path=\"res://lib/libtop-down-ten-minutes.gdnlib\" t"
  },
  {
    "path": "examples/top-down-ten-minutes/game/Bullet.tscn",
    "chars": 1291,
    "preview": "[gd_scene load_steps=5 format=2]\n\n[ext_resource path=\"res://Player.png\" type=\"Texture\" id=1]\n[ext_resource path=\"res://B"
  },
  {
    "path": "examples/top-down-ten-minutes/game/Enemy.gdns",
    "chars": 232,
    "preview": "[gd_resource type=\"NativeScript\" load_steps=2 format=2]\n\n[ext_resource path=\"res://lib/libtop-down-ten-minutes.gdnlib\" t"
  },
  {
    "path": "examples/top-down-ten-minutes/game/Enemy.tscn",
    "chars": 944,
    "preview": "[gd_scene load_steps=5 format=2]\n\n[ext_resource path=\"res://Player.png\" type=\"Texture\" id=1]\n[ext_resource path=\"res://E"
  },
  {
    "path": "examples/top-down-ten-minutes/game/Explosion.tscn",
    "chars": 842,
    "preview": "[gd_scene load_steps=4 format=2]\n\n[sub_resource type=\"Curve\" id=1]\n_data = [ Vector2( 0, 1 ), 0.0, 0.0, 0, 0, Vector2( 1"
  },
  {
    "path": "examples/top-down-ten-minutes/game/Player.gdns",
    "chars": 234,
    "preview": "[gd_resource type=\"NativeScript\" load_steps=2 format=2]\n\n[ext_resource path=\"res://lib/libtop-down-ten-minutes.gdnlib\" t"
  },
  {
    "path": "examples/top-down-ten-minutes/game/lib/libtop-down-ten-minutes.gdnlib",
    "chars": 167,
    "preview": "[general]\n\nsingleton=false\nload_once=false\nsymbol_prefix=\"godot_\"\nreloadable=true\n\n[entry]\n\nX11.64=\"res://lib/libtop-dow"
  },
  {
    "path": "examples/top-down-ten-minutes/game/project.godot",
    "chars": 2064,
    "preview": "; Engine configuration file.\n; It's best edited using the editor UI and not directly,\n; since the parameters that go her"
  },
  {
    "path": "examples/top-down-ten-minutes/game/wall.tres",
    "chars": 979,
    "preview": "[gd_resource type=\"TileSet\" load_steps=4 format=2]\n\n[ext_resource path=\"res://Player.png\" type=\"Texture\" id=1]\n\n[sub_res"
  },
  {
    "path": "examples/top-down-ten-minutes/game/world.tscn",
    "chars": 17219,
    "preview": "[gd_scene load_steps=8 format=2]\n\n[ext_resource path=\"res://Player.png\" type=\"Texture\" id=1]\n[ext_resource path=\"res://P"
  },
  {
    "path": "examples/top-down-ten-minutes/godot-haskell.nix",
    "chars": 1034,
    "preview": "{ fetchFromGitHub, mkDerivation, aeson, ansi-wl-pprint, base, bytestring, c2hs\n, casing, colour, containers, hpack, lens"
  },
  {
    "path": "examples/top-down-ten-minutes/hie.yaml",
    "chars": 147,
    "preview": "cradle:\n  stack:\n    - path: \"./src\"\n      component: \"top-down-ten-minutes:lib\"\n\n    - path: \"./game\"\n      component: "
  },
  {
    "path": "examples/top-down-ten-minutes/package.yaml",
    "chars": 1332,
    "preview": "name: top-down-ten-minutes\nversion: '0.0.0.0'\ndescription: Please see the README on Github at <https://github.com/Simula"
  },
  {
    "path": "examples/top-down-ten-minutes/pinned-nixpkgs.nix",
    "chars": 240,
    "preview": "{}:\n\nlet\n  # 19.03-beta (25 feb)\n  rev = \"0c0954781e257b8b0dc49341795a2fe7d96945a3\"; # pinned-nixpkgs rev\n  pkgs = impor"
  },
  {
    "path": "examples/top-down-ten-minutes/shell.nix",
    "chars": 1015,
    "preview": "{ nixpkgs ? import ./pinned-nixpkgs.nix {}\n, compiler ? \"default\"\n, doBenchmark ? false }:\n\n\nlet\n\n  inherit (nixpkgs) pk"
  },
  {
    "path": "examples/top-down-ten-minutes/src/Game/World.hs",
    "chars": 5176,
    "preview": "{-# LANGUAGE LambdaCase, TypeOperators #-}\n{-# OPTIONS_GHC -Wno-name-shadowing #-}\nmodule Game.World where\nimport Contro"
  },
  {
    "path": "examples/top-down-ten-minutes/src/Lib.hs",
    "chars": 199,
    "preview": "module Lib (exports) where\nimport Godot\nimport Project.Support\nimport Project.Requirements\nimport Game.World\n\nexports ::"
  },
  {
    "path": "examples/top-down-ten-minutes/src/Project/Requirements.hs",
    "chars": 257,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\nmodule Project.Requirements where\nimpor"
  },
  {
    "path": "examples/top-down-ten-minutes/src/Project/Scenes/Bullet.hs",
    "chars": 2025,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/top-down-ten-minutes/src/Project/Scenes/Enemy.hs",
    "chars": 1842,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/top-down-ten-minutes/src/Project/Scenes/Explosion.hs",
    "chars": 984,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/top-down-ten-minutes/src/Project/Scenes/World.hs",
    "chars": 5401,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/top-down-ten-minutes/src/Project/Scenes.hs",
    "chars": 298,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\nmodule Project.Scenes (module M) where\n"
  },
  {
    "path": "examples/top-down-ten-minutes/src/Project/Support.hs",
    "chars": 18614,
    "preview": "-- | This file is AUTOGENERATED by godot-haskell-project-generator. DO NOT EDIT\n\n{-# LANGUAGE FlexibleContexts, Function"
  },
  {
    "path": "examples/top-down-ten-minutes/stack-shell.nix",
    "chars": 172,
    "preview": "{ nixpkgs ? import ./pinned-nixpkgs.nix {}\n, ghc\n}:\n\nwith nixpkgs;\n\nhaskell.lib.buildStackProject {\n  inherit ghc;\n  nam"
  },
  {
    "path": "examples/top-down-ten-minutes/stack.yaml",
    "chars": 237,
    "preview": "resolver: nightly-2021-02-06\n\npackages:\n- .\n\nextra-deps:\n- ../../\n\nrequire-stack-version: \">=1.8\"\n\nnix:\n  enable: false\n"
  },
  {
    "path": "examples/top-down-ten-minutes/top-down-ten-minutes.cabal",
    "chars": 2019,
    "preview": "cabal-version: 1.12\n\n-- This file has been generated from package.yaml by hpack version 0.33.0.\n--\n-- see: https://githu"
  },
  {
    "path": "godot-haskell.cabal",
    "chars": 25681,
    "preview": "cabal-version: 2.0\n\n-- This file has been generated from package.yaml by hpack version 0.33.0.\n--\n-- see: https://github"
  },
  {
    "path": "hie.yaml",
    "chars": 262,
    "preview": "cradle:\n  stack:\n    - path: \"./src\"\n      component: \"godot-haskell:lib\"\n\n    - path: \"./src-generate\"\n      component:"
  },
  {
    "path": "nix/pinned/all-hies.json",
    "chars": 290,
    "preview": "{\n  \"url\": \"https://github.com/Infinisil/all-hies.git\",\n  \"rev\": \"d98bdbff3ebdab408a12a9b7890d4cf400180839\",\n  \"date\": \""
  },
  {
    "path": "nix/pinned/default.nix",
    "chars": 405,
    "preview": "{ fetchFromGitHub, lib }:\n\nlet\n  fetch = owner: repo: jsonFile: fetchFromGitHub {\n    inherit owner repo;\n    inherit (l"
  },
  {
    "path": "nix/pinned/hie.nix",
    "chars": 776,
    "preview": "{ fetchFromGitHub, lib, ghc, useSystem ? true, useLatest ? false, versions ? [] }:\n\nlet\n  fetch = owner: repo: jsonFile:"
  },
  {
    "path": "nix/pinned/nixpkgs.json",
    "chars": 295,
    "preview": "{\n  \"url\": \"https://github.com/nixos/nixpkgs-channels.git\",\n  \"rev\": \"ce9f1aaa39ee2a5b76a9c9580c859a74de65ead5\",\n  \"date"
  },
  {
    "path": "nix/spacemacs-hie.nix",
    "chars": 461,
    "preview": "{ pkgs, hsPkgs }:\nlet\n  pinned = import ./pinned { inherit (pkgs) fetchFromGitHub lib; };\n  hie = pinned.hie { inherit ("
  },
  {
    "path": "nixpkgs-version.json",
    "chars": 249,
    "preview": "{\n  \"url\": \"https://github.com/nixos/nixpkgs-channels.git\",\n  \"rev\": \"c8db7a8a16ee9d54103cade6e766509e1d1c8d7b\",\n  \"date"
  },
  {
    "path": "package.yaml",
    "chars": 1487,
    "preview": "name: godot-haskell\nsynopsis: Haskell bindings for the Godot game engine API\ndescription: This package contains Haskell "
  },
  {
    "path": "pinned-nixpkgs.nix",
    "chars": 288,
    "preview": "{}:\nlet hostPkgs = import <nixpkgs> {};\n    pinnedVersion = hostPkgs.lib.importJSON ./nixpkgs-version.json;\n    pinnedPk"
  },
  {
    "path": "project-generator/Main.hs",
    "chars": 35012,
    "preview": "{-# LANGUAGE DerivingStrategies #-}\n{-# LANGUAGE FlexibleContexts #-}\n{-# LANGUAGE FlexibleInstances #-}\n{-# LANGUAGE Fu"
  },
  {
    "path": "release.nix",
    "chars": 108,
    "preview": "let\n  pkgs = import <nixpkgs> { };\nin\n  pkgs.haskellPackages.callPackage ./default.nix { api-json = null; }\n"
  },
  {
    "path": "shell-spacemacs-hie.nix",
    "chars": 385,
    "preview": "let\n  pinned = import ./nix/pinned {\n    inherit (import <nixpkgs> {})\n      fetchFromGitHub\n      lib;\n };\n\n  hsPkgs = "
  },
  {
    "path": "shell.nix",
    "chars": 467,
    "preview": "{ nixpkgs ? import ./pinned-nixpkgs.nix {}\n, compiler ? \"default\"\n, doBenchmark ? false }:\n\nlet\n  inherit (nixpkgs) pkgs"
  },
  {
    "path": "src/Godot/Api/Types.hs",
    "chars": 368538,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TemplateHaskell #-}\nmodule Godot.Api.Types\n"
  },
  {
    "path": "src/Godot/Api.hs",
    "chars": 64,
    "preview": "module Godot.Api (module M) where\n\nimport Godot.Api.Types as M\n\n"
  },
  {
    "path": "src/Godot/Core/ARVRAnchor.hs",
    "chars": 9811,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/ARVRCamera.hs",
    "chars": 487,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/ARVRController.hs",
    "chars": 17492,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/ARVRInterface.hs",
    "chars": 19859,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/ARVRInterfaceGDNative.hs",
    "chars": 505,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/ARVROrigin.hs",
    "chars": 3278,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/ARVRPositionalTracker.hs",
    "chars": 20418,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/ARVRServer.hs",
    "chars": 24585,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AStar.hs",
    "chars": 33282,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AStar2D.hs",
    "chars": 30775,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AcceptDialog.hs",
    "chars": 18148,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimatedSprite.hs",
    "chars": 24918,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimatedSprite3D.hs",
    "chars": 13987,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimatedTexture.hs",
    "chars": 134455,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/Animation.hs",
    "chars": 81381,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNode.hs",
    "chars": 29006,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeAdd2.hs",
    "chars": 3153,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeAdd3.hs",
    "chars": 3153,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeAnimation.hs",
    "chars": 3198,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeBlend2.hs",
    "chars": 3204,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeBlend3.hs",
    "chars": 3204,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeBlendSpace1D.hs",
    "chars": 58817,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeBlendSpace2D.hs",
    "chars": 76819,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeBlendTree.hs",
    "chars": 16719,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeOneShot.hs",
    "chars": 17687,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeOutput.hs",
    "chars": 503,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeStateMachine.hs",
    "chars": 28570,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeStateMachinePlayback.hs",
    "chars": 7859,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeStateMachineTransition.hs",
    "chars": 21694,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeTimeScale.hs",
    "chars": 506,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeTimeSeek.hs",
    "chars": 505,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationNodeTransition.hs",
    "chars": 27994,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationPlayer.hs",
    "chars": 60638,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationRootNode.hs",
    "chars": 501,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationTree.hs",
    "chars": 21644,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AnimationTreePlayer.hs",
    "chars": 93214,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/Area.hs",
    "chars": 62881,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/Area2D.hs",
    "chars": 55574,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/ArrayMesh.hs",
    "chars": 27885,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AtlasTexture.hs",
    "chars": 9428,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioBusLayout.hs",
    "chars": 493,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffect.hs",
    "chars": 490,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectAmplify.hs",
    "chars": 3181,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectBandLimitFilter.hs",
    "chars": 514,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectBandPassFilter.hs",
    "chars": 513,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectChorus.hs",
    "chars": 25527,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectCompressor.hs",
    "chars": 18538,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectDelay.hs",
    "chars": 31128,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectDistortion.hs",
    "chars": 13093,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectEQ.hs",
    "chars": 3700,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectEQ10.hs",
    "chars": 499,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectEQ21.hs",
    "chars": 499,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectEQ6.hs",
    "chars": 498,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectFilter.hs",
    "chars": 9286,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectHighPassFilter.hs",
    "chars": 513,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectHighShelfFilter.hs",
    "chars": 514,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectInstance.hs",
    "chars": 499,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectLimiter.hs",
    "chars": 10366,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectLowPassFilter.hs",
    "chars": 512,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  },
  {
    "path": "src/Godot/Core/AudioEffectLowShelfFilter.hs",
    "chars": 513,
    "preview": "{-# LANGUAGE DerivingStrategies, GeneralizedNewtypeDeriving,\n  TypeFamilies, TypeOperators, FlexibleContexts, DataKinds,"
  }
]

// ... and 588 more files (download for full content)

About this extraction

This page contains the full source code of the SimulaVR/godot-haskell GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 788 files (11.0 MB), approximately 2.9M tokens, and a symbol index with 8 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!