#pragma once #ifdef OSC_ENABLE #define OSCBUFFER_SIZE (256) #define SERVERUP_POS (0) // (Int32) : indica se il server e' up o down #define START_OF_BUFFER (SERVERUP_POS + sizeof(uint32_t)) // prima locazione di memoria utile per il buffer circolare class oscCircBuffer { private: uint8_t * mapAccess; int rdPtr; int WR_PTR_POS; int P0; int PN; public: static int bufferOverhead() { return sizeof(uint32_t); } // n. di bytes EXTRA richiesti per la gestione del buffer circolare void Clear() { rdPtr = wrPtr_get(); } oscCircBuffer(int bufferSize, void *acc, int offset) { WR_PTR_POS = offset; P0 = WR_PTR_POS + bufferOverhead(); // posizione 0 memoria effettiva (dove salvare e leggere i dati, dopo i primi 8 bytes riservati ai puntatori rd/wr) PN = P0 + bufferSize - bufferOverhead(); mapAccess = (uint8_t *)acc; Clear(); } ~oscCircBuffer() { mapAccess = NULL; } void WriteChunk(OSCMsg *msg) { uint8_t *ptr = (uint8_t *)msg; int cur_wrPtr = wrPtr_get(); for(int k = 0; k < (int)sizeof(OSCMsg); k++) cur_wrPtr = Put(*ptr++, cur_wrPtr); wrPtr_set(cur_wrPtr); // finalizza IN SOLIDO il chunk appena letto } bool ReadChunk(OSCMsg *msg) { if(data_available()) { uint8_t *p = (uint8_t *)msg; for(int k = 0; k < (int)sizeof(OSCMsg); k++) *p++ = Get(); return true; } return false; } private: int wrPtr_get() { return *((uint32_t *)(mapAccess + WR_PTR_POS)); } void wrPtr_set(uint32_t v) { uint32_t *ptr = (uint32_t *)(mapAccess + WR_PTR_POS); *ptr = v; } bool data_available() { return rdPtr != wrPtr_get(); } int incPtr(int ptr) { if(++ptr >= PN) ptr = P0; return ptr; } int Put(uint8_t b, int ptr) { mapAccess[ptr] = b; return incPtr(ptr); } uint8_t Get() { int trdPtr = rdPtr; uint8_t rv = mapAccess[trdPtr]; rdPtr = incPtr(trdPtr); return rv; } }; #endif