Skip to content

Commit

Permalink
Spike hack debugging the URL vs. thread bug.
Browse files Browse the repository at this point in the history
  • Loading branch information
niemeyer committed Sep 13, 2013
1 parent e66796b commit d0a17b7
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 13 deletions.
8 changes: 8 additions & 0 deletions bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,18 @@ var hookWaiting C.int
func guiLoop() {
runtime.LockOSThread()
C.newGuiApplication()
guiLock++
hookIdleTimer()
println("Should not run for now:")
C.startIdleTimer(&hookWaiting)
C.applicationExec()
}

func Run() {
println("Unlocking")
Unlock()
}

var guiFunc = make(chan func())
var guiDone = make(chan struct{})
var guiLock = 0
Expand Down
150 changes: 149 additions & 1 deletion cpp/capi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ QObject_ *componentCreate(QQmlComponent_ *component, QQmlContext_ *context)
QQmlComponent *qcomponent = reinterpret_cast<QQmlComponent *>(component);
QQmlContext *qcontext = reinterpret_cast<QQmlContext *>(context);

QObject *instance = qcomponent->create(qcontext);
QObject *instance = qcomponent->create(qcontext);
return instance;
}

Expand Down Expand Up @@ -443,4 +443,152 @@ void installLogHandler()
qInstallMessageHandler(internalLogHandler);
}


#include <QGuiApplication>
#include <QtQuick/QQuickView>
#include <QtQml/QtQml>

#include <unistd.h>

extern "C" {

const char *particleQml =
"import QtQuick 2.0\n"
"import QtQuick.Particles 2.0\n"
"import QtGraphicalEffects 1.0;\n"
"\n"
"Rectangle {\n"
" id: root\n"
" color: \"black\"\n"
"\n"
" width: 640\n"
" height: 480\n"
"\n"
" gradient: Gradient {\n"
" GradientStop { position: 0.0; color: \"#3a2c32\"; }\n"
" GradientStop { position: 0.8; color: \"#875864\"; }\n"
" GradientStop { position: 1.0; color: \"#9b616c\"; }\n"
" }\n"
"\n"
" Text {\n"
" //text: message.text\n"
" text: \"Hello from Go!\"\n"
"\n"
" x: parent.width/2 - width/2\n"
" y: parent.height/2 - height/2\n"
"\n"
" color: \"white\"\n"
" font.bold: true\n"
" font.pointSize: 20\n"
"\n"
" MouseArea {\n"
" id: mouseArea\n"
" anchors.fill: parent\n"
" drag.target: parent\n"
" onReleased: {\n"
" root.customEmit(parent.x + 15, parent.y + parent.height/2);\n"
" root.customEmit(parent.x + parent.width / 2, parent.y + parent.height/2);\n"
" root.customEmit(parent.x + parent.width - 15, parent.y + parent.height/2);\n"
" }\n"
" }\n"
" }\n"
"\n"
" ParticleSystem {\n"
" id: sys\n"
" }\n"
"\n"
" ImageParticle {\n"
" system: sys\n"
" source: \"particle.png\"\n"
" color: \"white\"\n"
" colorVariation: 1.0\n"
" alpha: 0.1\n"
" }\n"
"\n"
" Component {\n"
" id: emitterComp\n"
" Emitter {\n"
" id: container\n"
" Emitter {\n"
" id: emitMore\n"
" system: sys\n"
" emitRate: 128\n"
" lifeSpan: 600\n"
" size: 16\n"
" endSize: 8\n"
" velocity: AngleDirection {angleVariation:360; magnitude: 60}\n"
" }\n"
"\n"
" property int life: 2600\n"
" property real targetX: 0\n"
" property real targetY: 0\n"
" function go() {\n"
" xAnim.start();\n"
" yAnim.start();\n"
" container.enabled = true\n"
" }\n"
" system: sys\n"
" emitRate: 32\n"
" lifeSpan: 600\n"
" size: 24\n"
" endSize: 8\n"
" NumberAnimation on x {\n"
" id: xAnim;\n"
" to: targetX\n"
" duration: life\n"
" running: false\n"
" }\n"
" NumberAnimation on y {\n"
" id: yAnim;\n"
" to: targetY\n"
" duration: life\n"
" running: false\n"
" }\n"
" Timer {\n"
" interval: life\n"
" running: true\n"
" onTriggered: container.destroy();\n"
" }\n"
" }\n"
" }\n"
"\n"
" function customEmit(x,y) {\n"
" for (var i=0; i<8; i++) {\n"
" var obj = emitterComp.createObject(root);\n"
" obj.x = x\n"
" obj.y = y\n"
" obj.targetX = Math.random() * 240 - 120 + obj.x\n"
" obj.targetY = Math.random() * 240 - 120 + obj.y\n"
" obj.life = Math.round(Math.random() * 2400) + 200\n"
" obj.emitRate = Math.round(Math.random() * 32) + 32\n"
" obj.go();\n"
" }\n"
" }\n"
"}\n";

void hack(void *engine_, void *component_)
{
//static char empty[1] = {0};
//static char *fakeargv[] = {empty};
//static int fakeargc = 1;
//QGuiApplication *app = new QGuiApplication(fakeargc, fakeargv);
//qApp->setQuitOnLastWindowClosed(false);

//QQmlEngine *engine = new QQmlEngine(0);
QQmlEngine *engine = reinterpret_cast<QQmlEngine *>(engine_);
//QQmlComponent *component = new QQmlComponent(engine);
QQmlComponent *component = reinterpret_cast<QQmlComponent *>(component_);
QByteArray ba(particleQml);
//component->setData(ba, QUrl::fromLocalFile("particle.qml"));
component->setData(ba, QString("file://./particle.qml"));
QObject *instance = component->create();
QQuickView *view = new QQuickView(engine, 0);
view->setContent(component->url(), component, instance);
view->setResizeMode(QQuickView::SizeRootObjectToView);
view->show();
qApp->exec();
}
}


// vim:ts=4:sw=4:et:ft=cpp
5 changes: 5 additions & 0 deletions datatype.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ var (
typeFloat64 = reflect.TypeOf(float64(0))
typeFloat32 = reflect.TypeOf(float32(0))
typeIface = reflect.TypeOf(new(interface{})).Elem()
typeValue = reflect.TypeOf(Value{})
)

func init() {
Expand Down Expand Up @@ -144,6 +145,10 @@ func dataTypeOf(typ reflect.Type) C.DataType {
return C.DTFloat64
case typeIface:
return C.DTAny
// TODO Test this and understand how to handle pointers properly
// (the above should work with pointers too):
case typeValue, reflect.TypeOf(&Value{}):
return C.DTObject
}
panic("Go type not supported yet: " + typ.Name())
}
Expand Down
32 changes: 20 additions & 12 deletions qml.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package qml
//
// #include "capi.h"
//
// void hack(void *engine, void *component);
import "C"

import (
Expand All @@ -23,6 +24,12 @@ type InitOptions struct {

var initialized int32

func Hack(engine *Engine, component *Component) {
gui(func() {
C.hack(engine.addr, component.addr)
})
}

// Init initializes the qml package with the provided parameters.
// If the options parameter is nil, default options suitable for a
// normal graphic application will be used.
Expand All @@ -34,6 +41,7 @@ func Init(options *InitOptions) {
panic("qml.Init called more than once")
}

fmt.Println("main() thread:", C.currentThread())
go guiLoop()

// Wait for app to be created and event loop to be running.
Expand All @@ -56,10 +64,12 @@ var engines = make(map[unsafe.Pointer]*Engine)
func NewEngine() *Engine {
engine := &Engine{values: make(map[interface{}]*valueFold)}
gui(func() {
fmt.Println("NewEngine thread:", C.currentThread())
engine.addr = C.newEngine(nil)
engines[engine.addr] = engine
stats.enginesAlive(+1)
})
fmt.Println("main() thread:", C.currentThread())
return engine
}

Expand Down Expand Up @@ -132,12 +142,7 @@ func (e *Engine) Load(c Content) (*Component, error) {
if err != nil {
return nil, err
}
component, err := e.newComponent(c.Location(), data)
if err != nil {
// TODO: component.Delete()
return nil, err
}
return component, nil
return e.newComponent(c.Location(), data)
}

// Context returns the engine's root context.
Expand Down Expand Up @@ -224,12 +229,15 @@ func (e *Engine) newComponent(location string, data []byte) (*Component, error)
var err error
gui(func() {
component.addr = C.newComponent(e.addr, nilPtr)
C.componentSetData(component.addr, cdata, cdatalen, cloc, cloclen)
message := C.componentErrorString(component.addr)
if message != nilCharPtr {
err = errors.New(strings.TrimRight(C.GoString(message), "\n"))
C.free(unsafe.Pointer(message))
}
_, _, _, _ = cdata, cdatalen, cloc, cloclen
_ = errors.New
_ = strings.Split
//C.componentSetData(component.addr, cdata, cdatalen, cloc, cloclen)
//message := C.componentErrorString(component.addr)
//if message != nilCharPtr {
// err = errors.New(strings.TrimRight(C.GoString(message), "\n"))
// C.free(unsafe.Pointer(message))
//}
})
if err != nil {
return nil, err
Expand Down

0 comments on commit d0a17b7

Please sign in to comment.