Skip to content

rework package to be importable (proof of concept) #4

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 13 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<img src="./assets/mascot.png" width="170" align="right">

# Go Flutter desktop embedder
# Go Flutter desktop embedder

A Go (golang) [Custom Flutter Engine
Embedder](https://github.com/flutter/engine/wiki/Custom-Flutter-Engine-Embedders)
for desktop

# Purpose
This project doesn't compete with
[this](https://github.com/google/flutter-desktop-embedding) awesome one.
The purpose of this project is to support the
[this](https://github.com/google/flutter-desktop-embedding) awesome one.
The purpose of this project is to support the
[Flutter](https://github.com/flutter/flutter) framework on Windows, macOS, and
Linux using a **SINGLE** code base.

Expand All @@ -19,11 +19,9 @@ provides the right abstractions over the OpenGL's Buffer/mouse/keyboard for each
The choice of [Golang](https://github.com/golang/go) comes from the fact that it
has the same tooling on every platform.
Plus golang is a great language because it keeps everything simple and readable,
which, I hope, will encourage people to contribute :grin:.
which, I hope, will encourage people to contribute :grin:.

## How to install


<details>
<summary> :package: :penguin: Linux</summary>
<h4>From binaries</h4>
Expand All @@ -33,32 +31,26 @@ Check out the <a href="https://github.com/Drakirus/go-flutter-desktop-embedder/r

Go read first: [go-gl/glfw](https://github.com/go-gl/glfw/)


```bash

# Clone
git clone https://github.com/Drakirus/Go-Flutter-desktop-embedder.git
cd Go-Flutter-desktop-embedder

# build the flutter project
cd example/stocks/

# Download the share library
wget https://storage.googleapis.com/flutter_infra/flutter/1ed25ca7b7e3e3e8047df050bba4174074c9b336/linux-x64/linux-x64-embedder \
-O temp.zip; unzip temp.zip;
wget https://storage.googleapis.com/flutter_infra/flutter/1ed25ca7b7e3e3e8047df050bba4174074c9b336/linux-x64/linux-x64-embedder \ -O .build/temp.zip

# Move the share library
mv libflutter_engine.so ./flutter/library/linux/

# Clean-up
rm flutter_embedder.h; rm temp.zip
unzip .build/temp.zip -x flutter_embedder.h && mv libflutter_engine.so flutter/library/linux/

# build the Embedder
go get -u github.com/go-gl/glfw/v3.2/glfw
go build

# build the flutter project
cd flutter_project/stocks/
flutter build bundle
cd ../..

# Play
./Go-Flutter-desktop-embedder
cd flutter_project/stocks; flutter build bundle; cd ../..
CGO_LDFLAGS="-L${PWD}/flutter/library/linux" go run main.go
```
</details>

Expand Down
1 change: 1 addition & 0 deletions example/stocks/.build/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
temp.zip
File renamed without changes
File renamed without changes
2 changes: 2 additions & 0 deletions example/stocks/flutter/library/linux/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
51 changes: 51 additions & 0 deletions example/stocks/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package main

import (
"image"
_ "image/png"
"log"
"os"
"os/signal"

gutter "github.com/Drakirus/go-flutter-desktop-embedder"

"github.com/go-gl/glfw/v3.2/glfw"
)

// #cgo linux LDFLAGS: -L${SRCDIR}/flutter/library/linux
import "C"

func main() {
var (
err error
)

options := []gutter.Option{
gutter.OptionAssetPath("flutter_project/stocks/build/flutter_assets"),
gutter.OptionICUDataPath("../../flutter/library/icudtl.dat"),
gutter.OptionWindowInitializer(setIcon),
}

if err = gutter.Run(options...); err != nil {
log.Fatalln(err)
}

signals := make(chan os.Signal, 1)
signal.Notify(signals, os.Kill, os.Interrupt)
select {
case <-signals:
}
}

func setIcon(window *glfw.Window) error {
imgFile, err := os.Open("assets/icon.png")
if err != nil {
return err
}
img, _, err := image.Decode(imgFile)
if err != nil {
return err
}
window.SetIcon([]image.Image{img})
return nil
}
7 changes: 6 additions & 1 deletion flutter/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ package flutter
// Linux Build Tags
// ----------------
#cgo linux CFLAGS: -I${SRCDIR}/library
#cgo linux LDFLAGS: -L${SRCDIR}/library/linux -lflutter_engine -Wl,-rpath,$ORIGIN/flutter/library/linux
#cgo linux LDFLAGS: -lflutter_engine -Wl,-rpath,flutter/library/linux

*/
import "C"

import (
// prevents dep from stripping out the c source files in flutter library.
_ "github.com/Drakirus/go-flutter-desktop-embedder/flutter/library"
Copy link
Member

Choose a reason for hiding this comment

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

i just learned something new.
Very useful!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

useful in this case being a nasty hack because dep does the wrong thing lol

)
4 changes: 4 additions & 0 deletions flutter/library/library.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package library

// this file along with its _ import in build.go prevent this package
// from being pruned by dep. see https://github.com/golang/dep/issues/1847
Empty file removed flutter/library/linux/.gitkeep
Empty file.
99 changes: 56 additions & 43 deletions main.go → gutter.go
Original file line number Diff line number Diff line change
@@ -1,49 +1,77 @@
package main
package gutter

import (
"encoding/json"
"flutter_desktop_go_embedding/flutter"
"image"
_ "image/png"
"log"
"os"
"runtime"
"time"
"unsafe"

"github.com/Drakirus/go-flutter-desktop-embedder/flutter"
"github.com/go-gl/glfw/v3.2/glfw"
)

// TextInput model
var state = textModel{}
// Option for gutter
type Option func(*config)

func init() {
runtime.LockOSThread()
// OptionAssetPath specify the flutter asset directory.
func OptionAssetPath(p string) Option {
return func(c *config) {
c.AssetPath = p
}
}

func main() {
err := glfw.Init()
if err != nil {
panic(err)
// OptionICUDataPath specify the path to the ICUData.
func OptionICUDataPath(p string) Option {
return func(c *config) {
c.ICUDataPath = p
}
defer glfw.Terminate()
}

window, err := glfw.CreateWindow(800, 600, "Loading..", nil, nil)
if err != nil {
panic(err)
// OptionWindowInitializer allow initializing the window.
func OptionWindowInitializer(ini func(*glfw.Window) error) Option {
return func(c *config) {
c.WindowInitializer = ini
}
}

defer window.Destroy()
type config struct {
AssetPath string
ICUDataPath string
WindowInitializer func(*glfw.Window) error
}

// set icon
if err := setIcon(window); err != nil {
log.Printf("unable to set window icon: %v\n", err)
func (t config) merge(options ...Option) config {
for _, opt := range options {
opt(&t)
}

assetsPath := "./flutter_project/stocks/build/flutter_assets"
icuDataPath := "./flutter/library/icudtl.dat"
return t
}

// Run executes a flutter application with the provided options.
// given limitations this method must be called by the main function directly.
func Run(options ...Option) (err error) {
var (
window *glfw.Window
c config
)
c = c.merge(options...)

engine := runFlutter(window, assetsPath, icuDataPath)
if err = glfw.Init(); err != nil {
return err
}
defer glfw.Terminate()

if window, err = glfw.CreateWindow(800, 600, "Loading..", nil, nil); err != nil {
return err
}
defer window.Destroy()

if err = c.WindowInitializer(window); err != nil {
return err
}

engine := runFlutter(window, c.AssetPath, c.ICUDataPath)

defer engine.Shutdown()

Expand All @@ -53,10 +81,10 @@ func main() {
flutter.EngineFlushPendingTasksNow()
}

return nil
}

// GLFW callbacks to the Flutter Engine

func glfwCursorPositionCallbackAtPhase(
window *glfw.Window, phase flutter.PointerPhase,
x float64, y float64,
Expand Down Expand Up @@ -91,6 +119,8 @@ func glfwMouseButtonCallback(window *glfw.Window, key glfw.MouseButton, action g

}

var state = textModel{}

func glfwKeyCallback(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) {

if key == glfw.KeyEscape && action == glfw.Press {
Expand Down Expand Up @@ -146,16 +176,13 @@ func glfwKeyCallback(w *glfw.Window, key glfw.Key, scancode int, action glfw.Act
state.addChar([]rune(clpString))
}
}

}

}
}

}

func glfwWindowSizeCallback(window *glfw.Window, width int, height int) {

event := flutter.WindowMetricsEvent{
Width: width,
Height: height,
Expand All @@ -173,7 +200,6 @@ func glfwCharCallback(w *glfw.Window, char rune) {
}

// Flutter Engine

func runFlutter(window *glfw.Window, assetsPath string, icuDataPath string) *flutter.EngineOpenGL {

flutterOGL := flutter.EngineOpenGL{
Expand Down Expand Up @@ -301,16 +327,3 @@ func updateEditingState(window *glfw.Window) {
flutterOGL := *(*flutter.EngineOpenGL)(window.GetUserPointer())
flutterOGL.EngineSendPlatformMessage(mess)
}

func setIcon(window *glfw.Window) error {
imgFile, err := os.Open("assets/icon.png")
if err != nil {
return err
}
img, _, err := image.Decode(imgFile)
if err != nil {
return err
}
window.SetIcon([]image.Image{img})
return nil
}
2 changes: 1 addition & 1 deletion textModel.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package gutter

import (
"sort"
Expand Down