Ignore:
Timestamp:
02/08/13 18:41:26 (12 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
Phase:
public
Message:

Implemented the basics of the multi-buffer support for C

Location:
src/client/c/hu/varadiistvan/xplra
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/client/c/hu/varadiistvan/xplra/xplra.cc

    r27 r28  
    3232
    3333#include "XPlane.h"
     34#include "MultiGetter.h"
     35#include "MultiSetter.h"
    3436#include "Exception.h"
    3537
     
    4345
    4446using hu::varadiistvan::xplra::XPlane;
     47using hu::varadiistvan::xplra::MultiBuffer;
     48using hu::varadiistvan::xplra::MultiGetter;
     49using hu::varadiistvan::xplra::MultiSetter;
    4550using hu::varadiistvan::xplra::Exception;
    4651using hu::varadiistvan::xplra::IOException;
     
    5358using std::string;
    5459using std::vector;
     60using std::set;
    5561using std::auto_ptr;
    5662
     
    5965namespace {
    6066
     67//------------------------------------------------------------------------------
     68
     69/**
     70 * Template for handling slots.
     71 */
     72template <class Value>
     73struct Slot
     74{
     75private:
     76    /**
     77     * The slots.
     78     */
     79    static std::vector< Slot<Value> > slots;
     80
     81    /**
     82     * The index of the first free slot.
     83     */
     84    static int firstFree;
     85
     86public:
     87    /**
     88     * Add a new value.
     89     *
     90     * @return the ID of the new value
     91     */
     92    static int addValue(Value value) throw();
     93
     94    /**
     95     * Get the value with the given ID.
     96     */
     97    static Value getValue(int valueID) throw();
     98
     99    /**
     100     * Clear the value with the given ID.
     101     */
     102    static void clearValue(int valueID) throw();
     103
     104private:
     105    /**
     106     * Indicate if the slot contains a valid value or not.
     107     */
     108    bool valid;
     109
     110    union {
     111        // The value, if the slot contains a value
     112        Value value;
     113
     114        // The index of the next free slot
     115        int nextFreeIndex;
     116    };
     117
     118    /**
     119     * Construct a slot with the given value
     120     */
     121    Slot(Value value) throw();
     122
     123    /**
     124     * Set the value and return the former next free index. It
     125     * should be called for a slot with no value.
     126     */
     127    int setValue(Value value) throw();
     128
     129    /**
     130     * Get the value if this slot contains a value. Otherwise 0 is
     131     * returned (converted to value).
     132     */
     133    Value getValue() const throw();
     134
     135    /**
     136     * Clear the value and set the given next free index.
     137     */
     138    void clear(int nextFreeIndex) throw();
     139};
     140
     141//------------------------------------------------------------------------------
     142
     143template <class Value> vector< Slot<Value> > Slot<Value>::slots;
     144
     145//------------------------------------------------------------------------------
     146
     147template <class Value> int Slot<Value>::firstFree = -1;
     148
     149//------------------------------------------------------------------------------
     150
     151template <class Value>
     152inline Slot<Value>::Slot(Value value) throw() :
     153    valid(true)
     154{
     155    this->value = value;
     156}
     157
     158//------------------------------------------------------------------------------
     159
     160template <class Value>
     161inline int Slot<Value>::setValue(Value value) throw()
     162{
     163    assert(!valid);
     164    int nextFreeIndex = this->nextFreeIndex;
     165    this->value = value;
     166    valid = true;
     167    return nextFreeIndex;
     168}
     169
     170//------------------------------------------------------------------------------
     171
     172template <class Value>
     173inline Value Slot<Value>::getValue() const throw()
     174{
     175    return valid ? value : static_cast<Value>(0);
     176}
     177
     178//------------------------------------------------------------------------------
     179
     180template <class Value>
     181inline void Slot<Value>::clear(int nextFreeIndex) throw()
     182{
     183    assert(valid);
     184    valid = false;
     185    this->nextFreeIndex = nextFreeIndex;
     186}
     187
     188//------------------------------------------------------------------------------
     189
     190template <class Value>
     191int Slot<Value>::addValue(Value value) throw()
     192{
     193    int id = firstFree;
     194    if (id<0) {
     195        id = slots.size();
     196        slots.push_back(Slot<Value>(value));
     197    } else {
     198        Slot& slot = slots[id];
     199        firstFree = slot.setValue(value);
     200    }
     201
     202    return id;
     203}
     204
     205//------------------------------------------------------------------------------
     206
     207template <class Value>
     208Value Slot<Value>::getValue(int valueID) throw()
     209{
     210    size_t index = static_cast<size_t>(valueID);
     211    return (index<slots.size()) ?
     212        slots[index].getValue() : static_cast<Value>(0);
     213}
     214
     215//------------------------------------------------------------------------------
     216
     217template <class Value>
     218void Slot<Value>::clearValue(int valueID) throw()
     219{
     220    size_t index = static_cast<size_t>(valueID);
     221    if (index<slots.size()) {
     222        slots[index].clear(firstFree);
     223        firstFree = index;
     224    }
     225}
     226
     227//------------------------------------------------------------------------------
     228//------------------------------------------------------------------------------
     229
     230typedef Slot<MultiBuffer*> MultiBufferSlot;
     231
     232//------------------------------------------------------------------------------
    61233//------------------------------------------------------------------------------
    62234
     
    68240private:
    69241    /**
     242     * Type for the set of multi-dataref buffers belonging to this connection.
     243     */
     244    typedef std::set<int> multiBufferIDs_t;
     245
     246    /**
    70247     * The last error code.
    71248     */
     
    82259    std::string lastErrorString;
    83260
     261    /**
     262     * The set of multi-dataref buffers belonging to this connection.
     263     */
     264    multiBufferIDs_t multiBufferIDs;
     265
    84266public:
    85267    /**
     
    89271
    90272    /**
     273     * Destroy the connection.
     274     */
     275    ~Connection() throw();
     276
     277    /**
    91278     * Handle the currently pending exception.
    92279     */
     
    107294     */
    108295    void clearLastError() throw();
     296
     297    /**
     298     * Create a multi-dataref getter object and register it in a slot.
     299     *
     300     * @return the ID of the new getter.
     301     */
     302    int createMultiGetter() throw();
     303
     304    /**
     305     * Create a multi-dataref setter object and register it in a slot.
     306     *
     307     * @return the ID of the new setter.
     308     */
     309    int createMultiSetter() throw();
     310
     311    /**
     312     * Destroy the multi-dataref buffer with the given ID.
     313     *
     314     * @param bufferID the ID of the buffer. It should be a valid ID,
     315     * that belongs to this connection.
     316     *
     317     * @return whether the buffer was found and could be destroyed.
     318     */
     319    bool destroyMultiBuffer(int bufferID) throw(Exception);
    109320};
    110321
     
    115326    lastErrorSubCode(0)
    116327{
     328}
     329
     330//------------------------------------------------------------------------------
     331
     332Connection::~Connection() throw()
     333{
     334    for(multiBufferIDs_t::iterator i = multiBufferIDs.begin();
     335        i!=multiBufferIDs.end(); ++i)
     336    {
     337        MultiBufferSlot::clearValue(*i);
     338    }
    117339}
    118340
     
    180402
    181403//------------------------------------------------------------------------------
    182 //------------------------------------------------------------------------------
    183 
    184 /**
    185  * Template for handling slots.
    186  */
    187 template <class Value>
    188 struct Slot
    189 {
    190 private:
    191     /**
    192      * The slots.
    193      */
    194     static std::vector< Slot<Value> > slots;
    195 
    196     /**
    197      * The index of the first free slot.
    198      */
    199     static int firstFree;
    200 
    201 public:
    202     /**
    203      * Add a new value.
    204      *
    205      * @return the ID of the new value
    206      */
    207     static int addValue(Value value) throw();
    208 
    209     /**
    210      * Get the value with the given ID.
    211      */
    212     static Value getValue(int valueID) throw();
    213 
    214     /**
    215      * Clear the value with the given ID.
    216      */
    217     static void clearValue(int valueID) throw();
    218 
    219 private:
    220     /**
    221      * Indicate if the slot contains a valid value or not.
    222      */
    223     bool valid;
    224 
    225     union {
    226         // The value, if the slot contains a value
    227         Value value;
    228 
    229         // The index of the next free slot
    230         int nextFreeIndex;
    231     };
    232 
    233     /**
    234      * Construct a slot with the given value
    235      */
    236     Slot(Value value) throw();
    237 
    238     /**
    239      * Set the value and return the former next free index. It
    240      * should be called for a slot with no value.
    241      */
    242     int setValue(Value value) throw();
    243 
    244     /**
    245      * Get the value if this slot contains a value. Otherwise 0 is
    246      * returned (converted to value).
    247      */
    248     Value getValue() const throw();
    249 
    250     /**
    251      * Clear the value and set the given next free index.
    252      */
    253     void clear(int nextFreeIndex) throw();
    254 };
    255 
    256 //------------------------------------------------------------------------------
    257 
    258 template <class Value> vector< Slot<Value> > Slot<Value>::slots;
    259 
    260 //------------------------------------------------------------------------------
    261 
    262 template <class Value> int Slot<Value>::firstFree = -1;
    263 
    264 //------------------------------------------------------------------------------
    265 
    266 template <class Value>
    267 inline Slot<Value>::Slot(Value value) throw() :
    268     valid(true)
    269 {
    270     this->value = value;
    271 }
    272 
    273 //------------------------------------------------------------------------------
    274 
    275 template <class Value>
    276 inline int Slot<Value>::setValue(Value value) throw()
    277 {
    278     assert(!valid);
    279     int nextFreeIndex = this->nextFreeIndex;
    280     this->value = value;
    281     valid = true;
    282     return nextFreeIndex;
    283 }
    284 
    285 //------------------------------------------------------------------------------
    286 
    287 template <class Value>
    288 inline Value Slot<Value>::getValue() const throw()
    289 {
    290     return valid ? value : static_cast<Value>(0);
    291 }
    292 
    293 //------------------------------------------------------------------------------
    294 
    295 template <class Value>
    296 inline void Slot<Value>::clear(int nextFreeIndex) throw()
    297 {
    298     assert(valid);
    299     valid = false;
    300     this->nextFreeIndex = nextFreeIndex;
    301 }
    302 
    303 //------------------------------------------------------------------------------
    304 
    305 template <class Value>
    306 int Slot<Value>::addValue(Value value) throw()
    307 {
    308     int id = firstFree;
    309     if (id<0) {
    310         id = slots.size();
    311         slots.push_back(Slot<Value>(value));
     404
     405inline int Connection::createMultiGetter() throw()
     406{
     407    MultiGetter& getter = XPlane::createMultiGetter();
     408    return MultiBufferSlot::addValue(&getter);
     409}
     410
     411//------------------------------------------------------------------------------
     412
     413inline int Connection::createMultiSetter() throw()
     414{
     415    MultiSetter& setter = XPlane::createMultiSetter();
     416    return MultiBufferSlot::addValue(&setter);
     417}
     418
     419//------------------------------------------------------------------------------
     420
     421bool Connection::destroyMultiBuffer(int bufferID) throw(Exception)
     422{
     423    MultiBuffer* buffer = MultiBufferSlot::getValue(bufferID);
     424    if (buffer==0) return false;
     425
     426    if (XPlane::destroyMultiBuffer(*buffer)) {
     427        multiBufferIDs.erase(bufferID);
     428        MultiBufferSlot::clearValue(bufferID);
     429        return true;
    312430    } else {
    313         Slot& slot = slots[id];
    314         firstFree = slot.setValue(value);
    315     }
    316 
    317     return id;
    318 }
    319 
    320 //------------------------------------------------------------------------------
    321 
    322 template <class Value>
    323 Value Slot<Value>::getValue(int valueID) throw()
    324 {
    325     size_t index = static_cast<size_t>(valueID);
    326     return (index<slots.size()) ?
    327         slots[index].getValue() : static_cast<Value>(0);
    328 }
    329 
    330 //------------------------------------------------------------------------------
    331 
    332 template <class Value>
    333 void Slot<Value>::clearValue(int valueID) throw()
    334 {
    335     size_t index = static_cast<size_t>(valueID);
    336     if (index<slots.size()) {
    337         slots[index].clear(firstFree);
    338         firstFree = index;
     431        return false;
    339432    }
    340433}
     
    641734}
    642735
     736//------------------------------------------------------------------------------
     737//------------------------------------------------------------------------------
     738
     739extern "C" int xplra_create_multi_getter(int connectionID)
     740{
     741    Connection* connection = ConnectionSlot::getValue(connectionID);
     742    return (connection==0) ? -1 : connection->createMultiGetter();
     743}
     744
     745//------------------------------------------------------------------------------
     746
     747extern "C" int xplra_create_multi_setter(int connectionID)
     748{
     749    Connection* connection = ConnectionSlot::getValue(connectionID);
     750    return (connection==0) ? -1 : connection->createMultiSetter();
     751}
     752
     753//------------------------------------------------------------------------------
     754
     755extern "C" int xplra_destroy_multi_buffer(int connectionID, int bufferID)
     756{
     757    Connection* connection = ConnectionSlot::getValue(connectionID);
     758    if (connection==0) return -1;
     759
     760    try {
     761        return connection->destroyMultiBuffer(bufferID) ? 0 : -1;
     762    } catch(...) {
     763        connection->handleException();
     764        return -1;
     765    }
     766}
     767
     768//------------------------------------------------------------------------------
    643769//------------------------------------------------------------------------------
    644770
  • src/client/c/hu/varadiistvan/xplra/xplra.h

    r27 r28  
    320320/*----------------------------------------------------------------------------*/
    321321
    322 
     322/**
     323 * Create a multi-dataref getter for the given connection.
     324 *
     325 * @return the ID of the new getter, or -1 on error
     326 */
     327int xplra_create_multi_getter(int connectionID);
     328
     329/*----------------------------------------------------------------------------*/
     330
     331/**
     332 * Create a multi-dataref setter for the given connection.
     333 *
     334 * @return the ID of the new setter, or -1 on error
     335 */
     336int xplra_create_multi_setter(int connectionID);
     337
     338/*----------------------------------------------------------------------------*/
     339
     340/**
     341 * Destruy a multi-dataref buffer for the given connection.
     342 *
     343 * @param connectionID the ID of the connection for which the buffer
     344 * has been created.
     345 *
     346 * @return 0 on success, -1 on error.
     347 */
     348int xplra_destroy_multi_buffer(int connectionID, int bufferID);
    323349
    324350/*----------------------------------------------------------------------------*/
Note: See TracChangeset for help on using the changeset viewer.