int MultiReader::add(int fd) {
  int nPos;
  nPos=getEmptySlot();
  
  if (nPos == -1) {
    return -1;
  }
  lineInputArray[nPos]->fd=fd;
  lineInputArray[nPos]->empty=false;
  return nPos;
}
/*---------------------------------------------------------------------*//**
	意識深度変化通知
**//*---------------------------------------------------------------------*/
void StatGauge::onConcentrateChange(s32 cur, s32 prev)
{
	GaugeAnim* ga = getEmptySlot();
	if(ga == 0L) { return; }
	bool damage = cur < prev;

	f32 rateMax = _rect->w() / (f32)CharStat::CONCD_HENL_MIN;
	f32 w = (damage ? prev - cur : cur - prev) * rateMax;
	f32 x = cur * rateMax;
	if(w < 0.1f) { return; }
	if(w > _rect->w()) { w = _rect->w(); }
	if(x > _rect->w()) { x = _rect->w(); }

	ga->_kind = damage ? GAK_CNS_DMG : GAK_CNS_RCV;
	ga->_rect->set(
		damage ? _rect->x() + x : _rect->x() + x - w,
		_rect->y() + StatusDrawer::H_NAME_DEFAULT + StatusDrawer::H_LFGAUGE_DEFAULT + 1.0f,
		w,
		StatusDrawer::H_CONSGAUGE_DEFAULT);
	ga->_fcntAnim = 0.0f;
}
/*---------------------------------------------------------------------*//**
	生命エネルギー変化通知
**//*---------------------------------------------------------------------*/
void StatGauge::onLifeChange(s32 cur, s32 prev)
{
	GaugeAnim* ga = getEmptySlot();
	if(ga == 0L) { return; }
	bool damage = cur < prev;

	f32 rateMax = _rect->w() / _cstatRef->getMaxEnergy();
	f32 w = (damage ? prev - cur : cur - prev) * rateMax;
	f32 x = cur * rateMax;
	if(w < 0.1f) { return; }
	if(w > _rect->w()) { w = _rect->w(); }
	if(x > _rect->w()) { x = _rect->w(); }

	ga->_kind = damage ? GAK_LFE_DMG : GAK_LFE_RCV;
	ga->_rect->set(
		damage ? _rect->x() + x : _rect->x() + x - w,
		_rect->y() + StatusDrawer::H_NAME_DEFAULT,
		w,
		StatusDrawer::H_LFGAUGE_DEFAULT);
	ga->_fcntAnim = 0.0f;
}
// . returns false and sets g_errno on error
bool Loop::addSlot ( bool forReading , int fd, void *state, void (* callback)(int fd, void *state),
                     int32_t niceness , int32_t tick, bool immediate ) {
	// ensure fd is >= 0
	if ( fd < 0 ) {
		g_errno = EBADENGINEER;
		log(LOG_LOGIC,"loop: fd to register is negative.");
		return false;
	}
	// sanity
	if ( fd > MAX_NUM_FDS ) {
		log(LOG_ERROR, "loop: bad fd of %" PRId32,(int32_t)fd);
		g_process.shutdownAbort(true);
	}

	if ( g_conf.m_logDebugLoop || g_conf.m_logDebugTcp ) {
		log( LOG_DEBUG, "loop: registering %s callback sd=%i", forReading ? "read" : "write", fd);
	}

	ScopedLock sl(m_slotMutex);
	// . ensure fd not already registered with this callback/state
	// . prevent dups so you can keep calling register w/o fear
	Slot *s;
	if ( forReading ) {
		s = m_readSlots  [ fd ];
	} else {
		s = m_writeSlots [ fd ];
	}

	while ( s ) {
		if ( s->m_callback == callback &&
		     s->m_state    == state      ) {
			// don't set g_errno for this anymore, just bitch
			//g_errno = EBADENGINEER;
			log(LOG_LOGIC,"loop: fd=%i is already registered.",fd);
			return true;
		}
		s = s->m_next;
	}
	// . make a new slot
	// . TODO: implement mprimealloc() to pre-alloc slots for us for speed
	//s = (Slot *) mmalloc ( sizeof(Slot ) ,"Loop");
	s = getEmptySlot ( );
	if ( ! s ) return false;
	// for pointing to slot already in position for fd
	Slot *next ;
	// store ourselves in the slot for this fd
	if ( forReading ) {
		next = m_readSlots [ fd ];
		m_readSlots  [ fd ] = s;
		// if not already registered, add to list
		if ( fd < MAX_NUM_FDS && ! FD_ISSET( fd,&s_selectMaskRead ) ) {
			// sanity
			if ( s_numReadFds >= MAX_NUM_FDS){
				g_process.shutdownAbort(true);
			}
			
			s_readFds[s_numReadFds++] = fd;
			FD_SET ( fd,&s_selectMaskRead  );
		}
		// fd == MAX_NUM_FDS if it's a sleep callback
		//if ( fd < MAX_NUM_FDS ) {
		//FD_SET ( fd , &m_readfds   );
		//FD_SET ( fd , &m_exceptfds );
		//}
	}
	else {
	 	next = m_writeSlots [ fd ];
	 	m_writeSlots [ fd ] = s;
	 	//FD_SET ( fd , &m_writefds );
	 	// if not already registered, add to list
	 	if ( fd<MAX_NUM_FDS && ! FD_ISSET ( fd,&s_selectMaskWrite ) ) {
	 		// sanity
	 		if ( s_numWriteFds>=MAX_NUM_FDS){
			    g_process.shutdownAbort(true);
		    }

	 		s_writeFds[s_numWriteFds++] = fd;
	 		FD_SET ( fd,&s_selectMaskWrite  );
	 	}
	}
	// set our callback and state
	s->m_callback  = callback;
	s->m_state     = state;

	// point to the guy that was registered for fd before us
	s->m_next      = next;

	// save our niceness for doPoll()
	s->m_niceness  = niceness;

	// store the tick for sleep wrappers (should be max for others)
	s->m_tick      = tick;

	// the last called time
	s->m_lastCall = immediate ? 0 : gettimeofdayInMilliseconds();

	// debug msg
	//log("Loop::registered fd=%i state=%" PRIu32,fd,state);

	// if fd == MAX_NUM_FDS if it's a sleep callback
	if ( fd == MAX_NUM_FDS ) {
		return true;
	}

	// watch out for big bogus fds used for thread exit callbacks
	if ( fd >  MAX_NUM_FDS ) {
		return true;
	}

	// set fd non-blocking
	return setNonBlocking ( fd , niceness ) ;
}