All Projects → martinky → Qt Interactive Coding

martinky / Qt Interactive Coding

Licence: mit
C++ interactive / live coding with Qt

Programming Languages

cpp
1120 projects

Projects that are alternatives of or similar to Qt Interactive Coding

Progressbarcollection
I create this application to show up the demonstration for the collection of progress bars
Stars: ✭ 21 (-57.14%)
Mutual labels:  qt5
Schannel Qt5
A GUI client of schannel powered by therecipe/qt and golang
Stars: ✭ 36 (-26.53%)
Mutual labels:  qt5
Kdceditor
Kirby's Dream Course / Kirby Bowl level editor (C++ / Qt)
Stars: ✭ 43 (-12.24%)
Mutual labels:  qt5
Pyqt5
PyQt5 from riverbank
Stars: ✭ 949 (+1836.73%)
Mutual labels:  qt5
Pixelannotationtool
Annotate quickly images.
Stars: ✭ 962 (+1863.27%)
Mutual labels:  qt5
Qlogo
QLogo is a rewrite of the UCBLogo language and user interface with UCB compatibility. It is cross-platform and uses hardware-accelerated graphics.
Stars: ✭ 39 (-20.41%)
Mutual labels:  qt5
Revery Playground
Live, interactive playground for Revery examples
Stars: ✭ 14 (-71.43%)
Mutual labels:  live-coding
Spix
UI test automation library for QtQuick/QML Apps
Stars: ✭ 48 (-2.04%)
Mutual labels:  qt5
Pencil
Pencil2D is an easy, intuitive tool to make 2D hand-drawn animations. Pencil2D is open source and cross-platform.
Stars: ✭ 968 (+1875.51%)
Mutual labels:  qt5
Zeit
Qt frontend to at & crontab CLI utilities
Stars: ✭ 42 (-14.29%)
Mutual labels:  qt5
Lqt
Lua Binding for Qt5
Stars: ✭ 30 (-38.78%)
Mutual labels:  qt5
Kalendar
A calendar Qt application to manage your time in an efficient way
Stars: ✭ 31 (-36.73%)
Mutual labels:  qt5
Mlde.d.moonlightde
Modular and Qt5 light new behavior desktop environment
Stars: ✭ 40 (-18.37%)
Mutual labels:  qt5
Livecoder.net
A simple browser environment for coding live javascript.
Stars: ✭ 27 (-44.9%)
Mutual labels:  live-coding
Derpibooru Downloader
Downloads images from derpibooru.org using a variety of options
Stars: ✭ 45 (-8.16%)
Mutual labels:  qt5
Slacken
A lightweight Qt client for Slack
Stars: ✭ 20 (-59.18%)
Mutual labels:  qt5
Openconnect Gui
Mirror - Graphical OpenConnect client (beta phase)
Stars: ✭ 993 (+1926.53%)
Mutual labels:  qt5
Redasm
The OpenSource Disassembler
Stars: ✭ 1,042 (+2026.53%)
Mutual labels:  qt5
Mumumusic
基于Qt5的模仿网易云音乐的app
Stars: ✭ 46 (-6.12%)
Mutual labels:  qt5
Jarmlib
jarmlib is Jack Armitage's (mostly TidalCycles) live coding library
Stars: ✭ 42 (-14.29%)
Mutual labels:  live-coding

Qt Interactive Coding

Author: Martin Kutny
License: MIT

Summary

Simple, cross-platform library to automate the process of compilation and execution of C++ code from within a running application. Allows to use C++ as a scripting language. This library is implemented using Qt and therefore is suitable for integrating with Qt projects.

Possible uses:

  • interactive / creative / live coding
  • debugging, state inspection
  • application scripting

Dependencies: Qt 5 (libQtCore5, qmake), C++ compiler toolchain
Platforms: Windows, Linux, possibly other platforms supported by Qt

Demo

demo gif

Integration

The library consists of one C++ source file and a couple of headers. You can either build it as a shared or static library using qicruntime.pro, or copy the code directly into your Qt project and include qicruntime.pri.

Usage

Basic example: Compiling and running C++ code at runtime.

#include <qicruntime.h>

int main()
{
    qicRuntime rt;
    // configure your runtime build environment
    rt.setIncludePath({ "/path/to/src/qicruntime" });
    rt.setQmake("/path/to/qt/version/platform/bin/qmake");

    const char src[] = "#include <qicentry.h>\n"
                       "#include <stdio.h>\n"
                       "extern \"C\" QIC_ENTRY_EXPORT void qic_entry(qicContext *ctx) {\n"
                       "    printf(\"hello runtime!\");\n"
                       "}\n";

    rt.exec(src);

    return 0;
}

For more examples, see the code in the examples directory.

Interop

To interact and exchange data with the runtime-compiled code, use context variables. An entire, complex application model can be shared with the runtime code this way.

class AppModel {
    // This class represents the data and functionality of our application that
    // we want to be able to make 'scriptable'. Actually defined somewhere
    // in a common header or shared library, so it can be included and linked
    // by both the host program and the runtime-compiled code.
};

int main()
{
    AppModel model;

    qicRuntime rt;
    rt.ctx()->set(&model, "model");

    rt.exec(...);
}

In the runtime code, access the context variable via the qicContext.

#include <AppModel.h> // possibly also link with AppModel.lib/.dll

extern "C" void qic_entry(qicContext *ctx)
{
    AppModel *const model = static_cast<AppModel*>(ctx->get("model"));
    model->... // access or modify data, call methods
}

Design

The principle behind this library is very simple, no magic, no special tricks. Conceptually, the process is similar to how plugin systems work and boils down to 4 simple steps.

  1. compile user code into a shared object (.dll)
  2. dlopen()
  3. entry_point = dlsym()
  4. call entry_point(app_context)

The purpose of this library is to automate this process in a simple and portable manner so that from the user's perspective this is a simple one-liner:

//qicRuntime rt;
rt.exec(source_code);

To compile the runtime code, we make use of Qt's own build system qmake and leverage its natural cross-platform capability.

There are no restrictions on what can or cannot go into the runtime-compiled source code. The only requirement is that the code exports one C-style function that serves as the main entry point:

extern "C" void qic_entry(qicContext *ctx);

The qicContext is a simple interface for exchange of void* pointers to arbitrary data between the host program and the runtime code. This is most flexible, as the user is free to use any techique for data exchange and interaction:

  • pointers to POD structures,
  • C function pointers, callbacks,
  • virtual base interfaces,
  • full C++ classes in common shared libraries,
  • or whatever data persistence mechanism the user comes up with.

Things to Keep in Mind

The mechanism of this library is similar to plugin systems and share the same set of behaviors the user should be aware of:

  1. We are loading and executing unsafe, untested, native code. There are a million ways how to shoot yourself in the foot with this. Let’s just accept that we can bring the host program down any time. This technique is intended for development only. It should not be used in production or situations where you can’t afford to lose data.
  2. Make sure that both the host program and the script code are compiled in a binary compatible manner: using the same toolchain, same build options, and if they share any libraries, be sure that both link the same version of those libraries. Failing to do so is an invitation to undefined behavior and crashes.
  3. You need to be aware of object lifetime and ownership when sharing data between the host program and a script. At some point, the library that contains script code will be unloaded – its code and data unmapped from the host process address space. If the host program accesses this data or code after it has been unloaded, it will result in a segfault. Typically, a strange crash just before the program exits is indicative of an object lifetime issue.

Resources

Blog:

Inspiration:

  1. Using runtime-compiled C++ code as a scripting language: under the hood
  2. Runtime Compiled C++
  3. DLL Hot Reloading in Theory and Practice
  4. Read-Compile-Run-Loop - a tiny REPL for C++
  5. A comprehensive list of projects and resources on runtime compiled C/C++ compiled by @dougbinks
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].