;; This file is part of ola-egg. ;; Copyright (C) 2014-2015 John J. Foerch ;; ;; ola-egg is free software: you can redistribute it and/or modify it ;; under the terms of the GNU Lesser General Public License as published ;; by the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; ;; ola-egg is distributed in the hope that it will be useful, but WITHOUT ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public ;; License for more details. ;; ;; You should have received a copy of the GNU Lesser General Public ;; License along with ola-egg. If not, see ;; . (foreign-declare "#include ") (foreign-declare "#include ") (foreign-declare "#include ") ;; ;; Foreign Instance Interface ;; ;; The 'instance' foreign type requires an object that can be passed to ;; (make t 'this pointer) and (slot-ref obj 'this). We will be using ;; srfi-99 record-types for the scheme types, so we need to define these ;; two procedures. ;; (define (make recordtype thisfield thisarg) ((rtd-constructor recordtype) thisarg)) (define slot-ref (getter-with-setter (lambda (instance field) ((rtd-accessor (record-rtd instance) field) instance)) (lambda (instance field value) ((rtd-mutator (record-rtd instance) field) instance value)))) ;; ;; Logging ;; (define-foreign-enum-type (log-level (enum ola::log_level)) (log-level->int int->log-level) (log-level/none ola::OLA_LOG_NONE) (log-level/fatal ola::OLA_LOG_FATAL) (log-level/warn ola::OLA_LOG_WARN) (log-level/info ola::OLA_LOG_INFO) (log-level/debug ola::OLA_LOG_DEBUG) (log-level/max ola::OLA_LOG_MAX)) (define-foreign-enum-type (log-output int) (log-output->int int->log-output) (log-output/stderr ola::OLA_LOG_STDERR) (log-output/syslog ola::OLA_LOG_SYSLOG) (log-output/null ola::OLA_LOG_NULL)) (foreign-declare "bool InitLoggingWrapper1 (ola::log_level level, int output) {" " return(ola::InitLogging(level, static_cast(output)));" "}") (define init-logging (case-lambda ((level output) ((foreign-lambda bool "InitLoggingWrapper1" log-level log-output) level output)) ((level) (init-logging level 'log-output/stderr)) (() (init-logging 'log-level/warn 'log-output/stderr)))) ;; ;; DmxBuffer ;; (define-record-type :dmxbuffer (%dmxbuffer this) dmxbuffer? (this dmxbuffer-this dmxbuffer-this-set!)) (define-foreign-type dmxbuffer (instance ola::DmxBuffer :dmxbuffer)) (define (dmxbuffer . args) (let ((buffer (match args (() ((foreign-lambda dmxbuffer "new ola::DmxBuffer"))) (((? dmxbuffer? buffer)) ((foreign-lambda* dmxbuffer ((dmxbuffer buffer)) "C_return(new ola::DmxBuffer(*buffer));") buffer)) (((? blob? blob)) ((foreign-lambda* dmxbuffer ((nonnull-blob data) (unsigned-int length)) "C_return(new ola::DmxBuffer(data, length));") blob (blob-size blob)))))) (set-finalizer! buffer (foreign-lambda* void ((dmxbuffer buffer)) "delete buffer;")) buffer)) (define dmxbuffer=? (foreign-lambda* bool ((dmxbuffer a) (dmxbuffer b)) "C_return(*a == *b);")) (define dmxbuffer-size (foreign-lambda* unsigned-int ((dmxbuffer buffer)) "C_return(buffer->Size());")) (define (dmxbuffer-get buffer) (let* ((size (dmxbuffer-size buffer)) (blob (make-blob size))) ((foreign-lambda* void ((dmxbuffer buffer) (nonnull-blob data) (unsigned-int length)) "buffer->Get(data, &length);") buffer blob size) blob)) (define dmxbuffer-get-channel (foreign-lambda* unsigned-byte ((dmxbuffer buffer) (unsigned-int channel)) "C_return(buffer->Get(channel));")) (define (dmxbuffer-get-range buffer offset length) (let ((blob (make-blob length))) ((foreign-lambda* void ((dmxbuffer buffer) (nonnull-blob data) (unsigned-int offset) (unsigned-int length)) "buffer->GetRange(offset, data, &length);") buffer blob offset length) blob)) (define dmxbuffer-set! (match-lambda* ((buffer (? blob? data) offset size) ((foreign-lambda* bool ((dmxbuffer buffer) (nonnull-blob data) (unsigned-int offset) (unsigned-int size)) "C_return(buffer->Set(&data[offset], size));") buffer data offset size)) ((buffer (? blob? data)) (dmxbuffer-set! buffer data 0 (blob-size data))) ((buffer (? dmxbuffer? other)) ((foreign-lambda* bool ((dmxbuffer buffer) (dmxbuffer other)) "C_return(buffer->Set(*other));") buffer other)))) (define dmxbuffer-set-channel! (foreign-lambda* void ((dmxbuffer buffer) (unsigned-int channel) (unsigned-byte data)) "buffer->SetChannel(channel, data);")) (define dmxbuffer-set-from-string! (foreign-lambda* bool ((dmxbuffer buffer) (nonnull-c-string s)) "std::string ss = s;" "C_return(buffer->SetFromString(ss));")) (define dmxbuffer-set-range! (case-lambda ((dmxbuffer i data offset length) ((foreign-lambda* bool ((dmxbuffer buffer) (unsigned-int i) (nonnull-blob data) (unsigned-int offset) (unsigned-int length)) "C_return(buffer->SetRange(i, &data[offset], length));") dmxbuffer i data offset length)) ((dmxbuffer i data) (dmxbuffer-set-range! dmxbuffer i data 0 (blob-size data))))) (define dmxbuffer-set-range-to-value! (foreign-lambda* bool ((dmxbuffer buffer) (unsigned-int offset) (unsigned-byte data) (unsigned-int length)) "C_return(buffer->SetRangeToValue(offset, data, length));")) (define dmxbuffer-htp-merge! (foreign-lambda* bool ((dmxbuffer buffer) (dmxbuffer other)) "C_return(buffer->HTPMerge(*other));")) (define dmxbuffer-blackout! (foreign-lambda* bool ((dmxbuffer buffer)) "C_return(buffer->Blackout());")) (define dmxbuffer-reset! (foreign-lambda* void ((dmxbuffer buffer)) "buffer->Reset();")) (define dmxbuffer->string (foreign-lambda* c-string* ((dmxbuffer buffer)) "std::string s = buffer->ToString();" "char* c = new char[s.size() + 1];" "std::copy(s.begin(), s.end(), c);" "c[s.size()] = 0;" "C_return(c);")) ;; ;; StreamingClient ;; (define-record-type :streamingclient-options (%streamingclient-options this) streamingclient-options? (this streamingclient-options-this streamingclient-options-this-set!)) (define-foreign-type streamingclient-options (instance ola::client::StreamingClient::Options :streamingclient-options)) (define (streamingclient-options . keys) (let* ((constructor (foreign-lambda streamingclient-options "new ola::client::StreamingClient::Options")) (options (constructor)) (keys (plist->alist keys))) (set-finalizer! options (foreign-lambda* void ((streamingclient-options options)) "delete options;")) (and-let* ((auto-start (assq auto-start: keys))) ((foreign-lambda* void ((streamingclient-options options) (bool auto_start)) "options->auto_start = auto_start;") options (cdr auto-start))) (and-let* ((server-port (assq server-port: keys))) ((foreign-lambda* void ((streamingclient-options options) (unsigned-short server_port)) "options->server_port = (uint16_t)server_port;") options (cdr server-port))) options)) (define-record-type :streamingclient (%streamingclient this) streamingclient? (this streamingclient-this streamingclient-this-set!)) (define-foreign-type streamingclient (instance ola::client::StreamingClient :streamingclient)) (define (streamingclient . options) (let ((client ((foreign-lambda* streamingclient ((streamingclient-options options)) "C_return(new ola::client::StreamingClient(*options));") (apply streamingclient-options options)))) (set-finalizer! client (foreign-lambda* void ((streamingclient client)) "delete client;")) client)) (define streamingclient-setup (foreign-lambda* bool ((streamingclient client)) "C_return(client->Setup());")) (define streamingclient-stop (foreign-lambda* void ((streamingclient client)) "client->Stop();")) (define streamingclient-send-dmx (foreign-lambda* bool ((streamingclient client) (unsigned-int universe) (dmxbuffer data)) "C_return(client->SendDmx(universe, *data));"))