/*                                              -*- mode:C++; fill-column:100 -*-
  SFBMemory.h Support for 'Working Memory' - redispatching packets
  Copyright (C) 2009 The Regents of the University of New Mexico.  All rights reserved.

  This library 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 2.1 of the License, or (at your option) any later version.

  This library 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 General Public License
  along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
  USA

  $Id$
*/

/**
  \file SFBMemory.h Support for 'Working Memory' - redispatching packets
  \author David H. Ackley.  
  \date (C) 2009 All rights reserved.
  \lgpl
 */
#ifndef SFBMEMORY_H
#define SFBMEMORY_H

#include "SFBFrame.h"
#include "SFBHeap.h"
#include "SFBReactor.h"  /* For PacketHandler, ::reflex */

#define MAX_PACKETS_IN_MEMORY 20

/**
 * A class for temporarily storing packets, and then retriggering on them at a later time.
 */
class SFBMemory {

public:

  SFBMemory() ;

  void reflex(const char type, PacketHandler ph) {
    ::reflex(type, ph, SFBReactor::TRIGGER_MEMORY);
  }

  bool dispatch(int maxPackets, u32 deadline) ;

  int remember(const u8 * packet) ;

  int rememberUnread(const u8 * packet,u8 sourceOverride = MAX_FACE_INDEX) ; 

  u8 * makeNewMemory(u32 packetLength) ;

  void forget() {
    if (inTrigger)
      killIt = true;
  }

  void remember() {
    if (inTrigger)
      killIt = false;
  }

  bool forget(u32 index) ;

  u8 * get(const u32 index) {
    API_ASSERT_MAX(index,MAX_PACKETS_IN_MEMORY);
    return packets[index];
  }
  bool fire(const u32 index) ;
  int find(const u8 type) {
    return find((const char *) &type, 1);
  }
  int find(const char * prefix, const int len = -1) ;

private:
  SFBHeap heap;
  u8 * packets[MAX_PACKETS_IN_MEMORY];
  u8 spinner;
  u8 inUse;
  bool inTrigger;
  bool killIt;
};

extern SFBMemory Memory;

#endif  /* SFBMEMORY_H */

