clispinner

A simple cli spinner.
git clone https://noulin.net/git/clispinner.git
Log | Files | Refs | LICENSE

commit 7e599a16abfc8e5e3cd9438fe047beea7b3986f9
parent 7220628689e620bc37407d2f294014c2cb378c56
Author: Remy Noulin <loader2x@gmail.com>
Date:   Sat, 19 May 2018 23:40:24 +0200

clispinner sheepy package

clispinner.c         | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++
clispinner.h         | 106 ++++++++++++++++++++++++++
clispinnerInternal.h |   3 +
package.yml          |  18 +++++
test.c               |  55 ++++++++++++++
5 files changed, 390 insertions(+)

Diffstat:
Aclispinner.c | 208+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aclispinner.h | 106+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
AclispinnerInternal.h | 3+++
Apackage.yml | 18++++++++++++++++++
Atest.c | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 390 insertions(+), 0 deletions(-)

diff --git a/clispinner.c b/clispinner.c @@ -0,0 +1,208 @@ + +#include "libsheepyObject.h" +#include "clispinner.h" +#include "clispinnerInternal.h" + + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +void initiateClispinner(clispinnert *self); +void registerMethodsClispinner(clispinnerFunctionst *f); +void initiateAllocateClispinner(clispinnert **self); +void finalizeClispinner(void); +clispinnert* allocClispinner(u64 interval, const char *title); +internal void freeClispinner(clispinnert *self); +internal void terminateClispinner(clispinnert **self); +internal char* toStringClispinner(clispinnert *self); +internal clispinnert* duplicateClispinner(clispinnert *self); +internal void smashClispinner(clispinnert **self); +internal void finishClispinner(clispinnert **self); +internal void startClispinner(clispinnert *self); +internal void stopClispinner(clispinnert *self); +internal void createTheSignalTimerClispinner(clispinnert *self); +internal void setSignalTimerClispinner(clispinnert *self, signalTimert * signalTimer); +internal signalTimert* getSignalTimerClispinner(clispinnert *self); +internal void pauseProcessClispinner(clispinnert *self); +internal void setSpinStringClispinner(clispinnert *self, const char *spinString); +internal void setIntervalClispinner(clispinnert *self, u64 interval); +internal bool isSpinningClispinner(clispinnert *self); + +static signalTimert *theSignalTimerAddr = NULL; +static bool cliSpinnerAllocatedTheSignalTimer = false; + +internal void doSpin(void *arg); + +void initiateClispinner(clispinnert *self) { + + self->type = "clispinner"; + if (!clispinnerF) { + clispinnerF = malloc(sizeof(clispinnerFunctionst)); + registerMethodsClispinner(clispinnerF); + pErrorNot0(atexit(finalizeClispinner)); + } + self->f = clispinnerF; + self->isSpinning = false; + self->interval = 100; + self->title[0] = 0; + strcpy(self->spinString, "|/-\\"); +} + +void registerMethodsClispinner(clispinnerFunctionst *f) { + + f->free = freeClispinner; + f->terminate = terminateClispinner; + f->toString = toStringClispinner; + f->duplicate = duplicateClispinner; + f->smash = smashClispinner; + f->finish = finishClispinner; + f->start = startClispinner; + f->stop = stopClispinner; + f->createTheSignalTimer = createTheSignalTimerClispinner; + f->setSignalTimer = setSignalTimerClispinner; + f->getSignalTimer = getSignalTimerClispinner; + f->pauseProcess = pauseProcessClispinner; + f->setSpinString = setSpinStringClispinner; + f->setInterval = setIntervalClispinner; + f->isSpinning = isSpinningClispinner; +} + +void initiateAllocateClispinner(clispinnert **self) { + + if (self) { + (*self) = malloc(sizeof(clispinnert)); + if (*self) { + initiateClispinner(*self); + } + } +} + +void finalizeClispinner(void) { + + if (clispinnerF) { + free(clispinnerF); + clispinnerF = NULL; + } +} + +clispinnert* allocClispinner(u64 interval, const char *title) { + clispinnert *r = NULL; + + initiateAllocateClispinner(&r); + createTheSignalTimerClispinner(r); + r->interval = interval; + + if (title) { + strLCpy(r->title, CLISPINNERTITLESIZE, title); + } + else r->title[0] = 0; + return(r); +} + + +internal void freeClispinner(clispinnert *self) { + + /* no internal data to free */ + return; +} + +internal void terminateClispinner(clispinnert **self) { + + // stop and terminate theSignalTimerAddr if clispinner allocated it + if (theSignalTimerAddr and cliSpinnerAllocatedTheSignalTimer) { + terminateG(theSignalTimerAddr); + cliSpinnerAllocatedTheSignalTimer = false; + } + + freeClispinner(*self); + free(*self); + *self = NULL; +} + + +internal char* toStringClispinner(clispinnert *self) { + + return(strdup("TODO - class template")); +} + +internal clispinnert* duplicateClispinner(clispinnert *self) { + + createAllocateClispinner(dup); + /* TODO COPY data */ + return(dup); +} + +internal void smashClispinner(clispinnert **self) { + + finishClispinner(self); +} + +internal void finishClispinner(clispinnert **self) { + + free(*self); + *self = NULL; +} + + +internal void startClispinner(clispinnert *self) { + + if (!theSignalTimerAddr) return; + + indexerInit(self->ix, strlen(self->spinString)); + startTimerG(theSignalTimerAddr, self->interval, doSpin, self); + + printf(self->title); + self->isSpinning = true; + // set unbuffered stdout, to show the characters directly + //setbuf(stdout, NULL); +} + +internal void stopClispinner(clispinnert *self) { + if (!theSignalTimerAddr) return; + stopG(theSignalTimerAddr); + self->isSpinning = false; +} + +internal void createTheSignalTimerClispinner(clispinnert *self) { + initiateAllocateSignalTimer(&theSignalTimerAddr); + cliSpinnerAllocatedTheSignalTimer = true; +} + +internal void setSignalTimerClispinner(clispinnert *self, signalTimert * signalTimer) { + theSignalTimerAddr = signalTimer; +} + +internal signalTimert* getSignalTimerClispinner(clispinnert *self) { + return theSignalTimerAddr; +} + +internal void pauseProcessClispinner(clispinnert *self) { + if (!theSignalTimerAddr) return; + pauseProcessG(theSignalTimerAddr); +} + +internal void setSpinStringClispinner(clispinnert *self, const char *spinString) { + if (spinString) { + strLCpy(self->spinString, 32, spinString); + } +} + +internal void setIntervalClispinner(clispinnert *self, u64 interval) { + self->interval = interval; + if (!theSignalTimerAddr) return; + setIntervalG(theSignalTimerAddr, interval); +} + +internal bool isSpinningClispinner(clispinnert *self) { + return self->isSpinning; +} + +internal void doSpin(void *arg) { + cast(clispinnert *, this, arg); + + indexerPush(this->ix); + putchar(this->spinString[this->ix.last]); + fflush(stdout); + putchar('\b'); +} diff --git a/clispinner.h b/clispinner.h @@ -0,0 +1,106 @@ +#pragma once + +#include "shpPackages/signalTimer/signalTimer.h" + +#define startG(obj) (obj)->f->start(obj) +#define createTheSignalTimerG(obj) (obj)->f->createTheSignalTimer(obj) +#define setSignalTimerG(obj, signalTimer) (obj)->f->setSignalTimer(obj, signalTimer) +//pauseProcessG +#define setSpinStringG(obj, spinString) (obj)->f->setSpinString(obj, spinString) +//setInterval +#define isSpinningG(obj) (obj)->f->isSpinning(obj) + +/* Class clispinner */ +typedef struct clispinner clispinnert; + +/* for object inheriting clispinner, cast to clispinner to be able to use this class functions and generics*/ +#define cClispinner(self) ( (clispinnert*) self ) + +typedef void (*freeClispinnerFt) (clispinnert *self); +typedef void (*terminateClispinnerFt) (clispinnert **self); +typedef char* (*toStringClispinnerFt) (clispinnert *self); +typedef clispinnert* (*duplicateClispinnerFt) (clispinnert *self); +typedef void (*smashClispinnerFt) (clispinnert **self); + +/** + * free clispinner + */ +typedef void (*finishClispinnerFt) (clispinnert **self); + +typedef void (*startClispinnerFt) (clispinnert *self); +typedef void (*stopClispinnerFt) (clispinnert *self); +typedef void (*createTheSignalTimerClispinnerFt)(clispinnert *self); +typedef void (*setSignalTimerClispinnerFt) (clispinnert *self, signalTimert * signalTimer); +typedef signalTimert* (*getSignalTimerClispinnerFt) (clispinnert *self); +typedef void (*pauseProcessClispinnerFt) (clispinnert *self); +typedef void (*setSpinStringClispinnerFt) (clispinnert *self, const char *spinString); +typedef void (*setIntervalClispinnerFt) (clispinnert *self, u64 interval); +typedef bool (*isSpinningClispinnerFt) (clispinnert *self); + +#define CLISPINNERTITLESIZE 1024 + +/** + * class functions + * allocated once for all objects + * + * freed with finalizeClispinner + */ + +/** + * use this define in child classes and add the new function after this class functions + * + * in this define, add the methods after <finishClispinnerFt finish;> + * + * Example: + * #define RINGFUNCTIONST \n * CLISPINNERFUNCTIONST; \n * setSizeRingFt setSize + */ +#define CLISPINNERFUNCTIONST \ + startClispinnerFt start;\ + stopClispinnerFt stop;\ + createTheSignalTimerClispinnerFt createTheSignalTimer;\ + setSignalTimerClispinnerFt setSignalTimer;\ + getSignalTimerClispinnerFt getSignalTimer;\ + pauseProcessClispinnerFt pauseProcess;\ + setSpinStringClispinnerFt setSpinString;\ + setIntervalClispinnerFt setInterval;\ + isSpinningClispinnerFt isSpinning; + + +typedef struct { + freeClispinnerFt free; + terminateClispinnerFt terminate; + toStringClispinnerFt toString; + duplicateClispinnerFt duplicate; + smashClispinnerFt smash; + finishClispinnerFt finish; + CLISPINNERFUNCTIONST; +} clispinnerFunctionst; + +/** + * class + */ +struct clispinner { + const char *type; + clispinnerFunctionst *f; + bool isSpinning; + indexer ix; + u64 interval; + char title[CLISPINNERTITLESIZE]; + char spinString[32]; +}; + +/* clispinner */ + +#define createClispinner(obj) clispinnert obj; initiateClispinner(&obj) +#define createAllocateClispinner(obj) clispinnert *obj; initiateAllocateClispinner(&obj) + +void initiateClispinner(clispinnert *self); +void initiateAllocateClispinner(clispinnert **self); +void finalizeClispinner(void); + +/* initialize class methods, call registerMethodsClispinner from classes inheriting this class */ +void registerMethodsClispinner(clispinnerFunctionst *f); + +clispinnert* allocClispinner(u64 interval, const char *title); + +/* end class clispinner*/ diff --git a/clispinnerInternal.h b/clispinnerInternal.h @@ -0,0 +1,3 @@ +#pragma once + +static clispinnerFunctionst *clispinnerF = NULL; diff --git a/package.yml b/package.yml @@ -0,0 +1,18 @@ +--- + name: clispinner + version: 0.0.2 + description: "A simple cli spinner." + bin: ./clispinner.c + repository: + type: git + url: git+https://github.com/RemyNoulin/clispinner.git + keywords: + - utility + - cli + author: Remy + license: MIT + bugs: + url: https://github.com/RemyNoulin/clispinner/issues + homepage: https://github.com/RemyNoulin/clispinner#readme + dependencies: + signalTimer: diff --git a/test.c b/test.c @@ -0,0 +1,55 @@ +#! /usr/bin/env sheepy +/* or direct path to sheepy: #! /usr/local/bin/sheepy */ + +#include "libsheepyObject.h" +#include "clispinner.h" + +/* signalTimert theSignalTimer; */ + +int argc; char **argv; + +int main(int ARGC, char** ARGV) { + + argc = ARGC; argv = ARGV; + + initLibsheepy(argv[0]); + + puts("C template"); + /* initiateSignalTimer(&theSignalTimer); */ + + clispinnert *sp = allocClispinner(50, "processing.. "); + //setSpinStringG(sp, ".oO'Oo."); + setSpinStringG(sp, ".oO@*"); + setIntervalG(sp, 150); + /* createAllocateClispinner(sp); */ + /* setSignalTimerG(sp, &theSignalTimer); */ + /* createTheSignalTimerG(sp); */ + + startG(sp); + + i16 c = 0; + while(1) { + /* theSignalTimer.f->pauseProcess(&theSignalTimer); */ + pauseProcessG(sp); + c++; + if (c == 60) break; + } + + stopG(sp); + logVarG(isSpinningG(sp)); + put; + + startG(sp); + + c = 0; + while(1) { + /* theSignalTimer.f->pauseProcess(&theSignalTimer); */ + pauseProcessG(sp); + c++; + if (c == 20) break; + } + + logVarG(isSpinningG(sp)); + terminateG(sp); + +}