void ConsumerStateTable::pops(std::deque<KeyOpFieldsValuesTuple> &vkco, std::string /*prefix*/)
{
    static std::string luaScript =
        "local ret = {}\n"
        "local keys = redis.call('SPOP', KEYS[1], ARGV[1])\n"
        "local n = table.getn(keys)\n"
        "for i = 1, n do\n"
            "local key = keys[i]\n"
            "local values = redis.call('HGETALL', KEYS[2] .. key)\n"
            "table.insert(ret, {key, values})\n"
        "end\n"
        "return ret\n";

    static std::string sha = loadRedisScript(m_db, luaScript);

    RedisCommand command;
    command.format(
        "EVALSHA %s 2 %s %s: %d ''",
        sha.c_str(),
        getKeySetName().c_str(),
        getTableName().c_str(),
        POP_BATCH_SIZE);

    RedisReply r(m_db, command);
    auto ctx0 = r.getContext();
    vkco.clear();

    // if the set is empty, return an empty kco object
    if (ctx0->type == REDIS_REPLY_NIL)
    {
        return;
    }

    assert(ctx0->type == REDIS_REPLY_ARRAY);
    size_t n = ctx0->elements;
    vkco.resize(n);
    for (size_t ie = 0; ie < n; ie++)
    {
        auto& kco = vkco[ie];
        auto& values = kfvFieldsValues(kco);
        assert(values.empty());

        auto& ctx = ctx0->element[ie];
        assert(ctx->elements == 2);
        assert(ctx->element[0]->type == REDIS_REPLY_STRING);
        std::string key = ctx->element[0]->str;
        kfvKey(kco) = key;

        assert(ctx->element[1]->type == REDIS_REPLY_ARRAY);
        auto ctx1 = ctx->element[1];
        for (size_t i = 0; i < ctx1->elements / 2; i++)
        {
            FieldValueTuple e;
            fvField(e) = ctx1->element[i * 2]->str;
            fvValue(e) = ctx1->element[i * 2 + 1]->str;
            values.push_back(e);
        }

        // if there is no field-value pair, the key is already deleted
        if (values.empty())
        {
            kfvOp(kco) = DEL_COMMAND;
        }
        else
        {
            kfvOp(kco) = SET_COMMAND;
        }
    }
}
Beispiel #2
0
namespace events
{

void context::add_handler(sdl_handler* ptr)
{
	/* Add new handlers to the staging list initially.
	This ensures that if an event handler adds more handlers, the new handlers
	won't be called for the event that caused them to be added. */
	staging_handlers.push_back(ptr);
}

bool context::remove_handler(sdl_handler* ptr)
{
	static int depth = 0;
	++depth;

	// The handler is most likely on the back of the events list,
	// so look there first, otherwise do a complete search.
	if(!handlers.empty() && handlers.back() == ptr) {
		if(focused_handler != handlers.end() && *focused_handler == ptr) {
			focused_handler = handlers.end();
		}

		handlers.pop_back();
	} else {
		const handler_list::iterator i = std::find(handlers.begin(), handlers.end(), ptr);

		if(i == handlers.end()) {
			--depth;

			// The handler may be in the staging area. Search it from there.
			auto j = std::find(staging_handlers.begin(), staging_handlers.end(), ptr);
			if (j != staging_handlers.end())
			{
				staging_handlers.erase(j);
				return true;
			}
			else
			{
				return false;
			}
		}

		if(i == focused_handler) {
			focused_handler != handlers.begin() ? --focused_handler : ++focused_handler;
		}

		handlers.erase(i);
	}

	--depth;

	if(depth == 0) {
		cycle_focus();
	} else {
		focused_handler = handlers.end();
	}

	return true;
}

void context::cycle_focus()
{
	if (handlers.begin() == handlers.end()) {
		return;
	}

	handler_list::iterator current = focused_handler;
	handler_list::iterator last = focused_handler;

	if (last != handlers.begin()) {
		--last;
	}

	if (current == handlers.end()) {
		current = handlers.begin();
	} else {
		++current;
	}

	while (current != last) {

		if(current != handlers.end() && (*current)->requires_event_focus()) {
			focused_handler = current;
			break;
		}

		if (current == handlers.end()) {
			current = handlers.begin();
		} else {
			++current;
		}
	}
}

void context::set_focus(const sdl_handler* ptr)
{
	const handler_list::iterator i = std::find(handlers.begin(),handlers.end(),ptr);
	if(i != handlers.end() && (*i)->requires_event_focus()) {
		focused_handler = i;
	}
}

void context::add_staging_handlers()
{
	std::copy(staging_handlers.begin(), staging_handlers.end(), std::back_inserter(handlers));
	staging_handlers.clear();
}

context::~context()
{
	for (sdl_handler* h : handlers)
	{
		if (h->has_joined())
		{
			h->has_joined_ = false;
		}
		if (h->has_joined_global())
		{
			h->has_joined_global_ = false;
		}
	}
}

// This object stores all the event handlers. It is a stack of event 'contexts'.
// a new event context is created when e.g. a modal dialog is opened, and then
// closed when that dialog is closed. Each context contains a list of the handlers
// in that context. The current context is the one on the top of the stack.
// The global context must always be in the first position.
std::deque<context> event_contexts;



std::vector<pump_monitor*> pump_monitors;

pump_monitor::pump_monitor() {
	pump_monitors.push_back(this);
}

pump_monitor::~pump_monitor() {
	pump_monitors.erase(
		std::remove(pump_monitors.begin(), pump_monitors.end(), this),
		pump_monitors.end());
}

event_context::event_context()
{
	event_contexts.emplace_back();
}

event_context::~event_context()
{
	assert(event_contexts.empty() == false);
	event_contexts.pop_back();
}

sdl_handler::sdl_handler(const bool auto_join) :
	has_joined_(false),
	has_joined_global_(false)
{

	if(auto_join) {
		assert(!event_contexts.empty());
		event_contexts.back().add_handler(this);
		has_joined_ = true;
	}
}

sdl_handler::~sdl_handler()
{
	if (has_joined_)
		leave();

	if (has_joined_global_)
		leave_global();

}

void sdl_handler::join() {

	// this assert will fire if someone will inadvertedly try to join
	// an event context but might end up in the global context instead.
	assert(&event_contexts.back() != &event_contexts.front());

	join(event_contexts.back());
}

void sdl_handler::join(context &c)
{
	if (has_joined_global_) {
		leave_global();
	}

	if(has_joined_) {
		leave(); // should not be in multiple event contexts
	}

	//join self
	c.add_handler(this);
	has_joined_ = true;

	//instruct members to join
	sdl_handler_vector members = handler_members();
	if(!members.empty()) {
		for(sdl_handler_vector::iterator i = members.begin(); i != members.end(); ++i) {
			(*i)->join(c);
		}
	}
}

void sdl_handler::join_same(sdl_handler* parent)
{
	if(has_joined_) {
		leave(); // should not be in multiple event contexts
	}

	for(std::deque<context>::reverse_iterator i = event_contexts.rbegin(); i != event_contexts.rend(); ++i) {
		handler_list& handlers = (*i).handlers;
		if (std::find(handlers.begin(), handlers.end(), parent) != handlers.end()) {
			join(*i);
			return;
		}
	}

	join(event_contexts.back());
}

void sdl_handler::leave()
{
	sdl_handler_vector members = handler_members();
	if(!members.empty()) {
		for(sdl_handler_vector::iterator i = members.begin(); i != members.end(); ++i) {
			(*i)->leave();
		}
	} else {
		assert(event_contexts.empty() == false);
	}
	for(std::deque<context>::reverse_iterator i = event_contexts.rbegin(); i != event_contexts.rend(); ++i) {
		if(i->remove_handler(this)) {
			break;
		}
	}
	has_joined_ = false;
}

void sdl_handler::join_global()
{
	if(has_joined_) {
		leave();
	}

	if(has_joined_global_) {
		leave_global(); // should not be in multiple event contexts
	}
	//join self
	event_contexts.front().add_handler(this);
	has_joined_global_ = true;

	//instruct members to join
	sdl_handler_vector members = handler_members();
	if(!members.empty()) {
		for(sdl_handler_vector::iterator i = members.begin(); i != members.end(); ++i) {
			(*i)->join_global();
		}
	}
}

void sdl_handler::leave_global()
{
	sdl_handler_vector members = handler_members();
	if(!members.empty()) {
		for(sdl_handler_vector::iterator i = members.begin(); i != members.end(); ++i) {
			(*i)->leave_global();
		}
	}

	event_contexts.front().remove_handler(this);

	has_joined_global_ = false;
}

void focus_handler(const sdl_handler* ptr)
{
	if(event_contexts.empty() == false) {
		event_contexts.back().set_focus(ptr);
	}
}

bool has_focus(const sdl_handler* hand, const SDL_Event* event)
{
	if(event_contexts.empty()) {
		return true;
	}

	if(hand->requires_event_focus(event) == false) {
		return true;
	}

	const handler_list::iterator foc = event_contexts.back().focused_handler;
	auto& handlers = event_contexts.back().handlers;

	// If no-one has focus at the moment, this handler obviously wants
	// focus, so give it to it.
	if(foc == handlers.end()) {
		focus_handler(hand);
		return true;
	}

	sdl_handler* const foc_hand = *foc;
	if(foc_hand == hand){
		return true;
	} else if(!foc_hand->requires_event_focus(event)) {
		// If the currently focused handler doesn't need focus for this event
		// allow the most recent interested handler to take care of it
		for(auto i = handlers.rbegin(); i != handlers.rend(); ++i) {
			sdl_handler* const thief_hand = *i;

			if(thief_hand != foc_hand && thief_hand->requires_event_focus(event)) {
				// Steal focus
				focus_handler(thief_hand);

				// Position the previously focused handler to allow stealing back
				handlers.splice(handlers.end(), handlers, foc);

				return thief_hand == hand;
			}
		}
	}
	return false;
}


const Uint32 resize_timeout = 100;
SDL_Event last_resize_event;
bool last_resize_event_used = true;

static bool remove_on_resize(const SDL_Event &a) {
	if (a.type == DRAW_EVENT || a.type == DRAW_ALL_EVENT) {
		return true;
	}
	if (a.type == SHOW_HELPTIP_EVENT) {
		return true;
	}
	if ((a.type == SDL_WINDOWEVENT) &&
			(a.window.event == SDL_WINDOWEVENT_RESIZED ||
					a.window.event == SDL_WINDOWEVENT_SIZE_CHANGED ||
					a.window.event == SDL_WINDOWEVENT_EXPOSED)) {
		return true;
	}

	return false;
}

// TODO: I'm uncertain if this is always safe to call at static init; maybe set in main() instead?
static const boost::thread::id main_thread = boost::this_thread::get_id();
void pump()
{
	if(boost::this_thread::get_id() != main_thread) {
		// Can only call this on the main thread!
		return;
	}
	SDL_PumpEvents();
	peek_for_resize();
	pump_info info;

	//used to keep track of double click events
	static int last_mouse_down = -1;
	static int last_click_x = -1, last_click_y = -1;

	SDL_Event temp_event;
	int poll_count = 0;
	int begin_ignoring = 0;
	std::vector< SDL_Event > events;
	while(SDL_PollEvent(&temp_event)) {
		++poll_count;
		peek_for_resize();

		if(!begin_ignoring && temp_event.type == SDL_WINDOWEVENT
				&& (temp_event.window.event == SDL_WINDOWEVENT_ENTER
						|| temp_event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED))
		{
			begin_ignoring = poll_count;
		} else if(begin_ignoring > 0 && is_input(temp_event)) {
			//ignore user input events that occurred after the window was activated
			continue;
		}
		events.push_back(temp_event);
	}

	std::vector<SDL_Event>::iterator ev_it = events.begin();
	for(int i=1; i < begin_ignoring; ++i){
		if(is_input(*ev_it)) {
			//ignore user input events that occurred before the window was activated
			ev_it = events.erase(ev_it);
		} else {
			++ev_it;
		}
	}

	std::vector<SDL_Event>::iterator ev_end = events.end();
	bool resize_found = false;
	for(ev_it = events.begin(); ev_it != ev_end; ++ev_it){
		SDL_Event &event = *ev_it;
		if (event.type == SDL_WINDOWEVENT &&
				event.window.event == SDL_WINDOWEVENT_RESIZED) {
			resize_found = true;
			last_resize_event = event;
			last_resize_event_used = false;

		}
	}
	// remove all inputs, draw events and only keep the last of the resize events
	// This will turn horrible after ~38 days when the Uint32 wraps.
	if (resize_found || SDL_GetTicks() <= last_resize_event.window.timestamp + resize_timeout) {
		events.erase(std::remove_if(events.begin(), events.end(), remove_on_resize), events.end());
	} else if(SDL_GetTicks() > last_resize_event.window.timestamp + resize_timeout && !last_resize_event_used) {
		events.insert(events.begin(), last_resize_event);
		last_resize_event_used = true;
	}

	ev_end = events.end();

	for(ev_it = events.begin(); ev_it != ev_end; ++ev_it){
		for (context& c : event_contexts)
		{
			c.add_staging_handlers();
		}

		SDL_Event &event = *ev_it;
		switch(event.type) {

			case SDL_WINDOWEVENT:
				switch(event.window.event) {
					case SDL_WINDOWEVENT_ENTER:
					case SDL_WINDOWEVENT_FOCUS_GAINED:
						cursor::set_focus(1);
						break;

					case SDL_WINDOWEVENT_LEAVE:
					case SDL_WINDOWEVENT_FOCUS_LOST:
						cursor::set_focus(1);
						break;

					case SDL_WINDOWEVENT_RESIZED:
						info.resize_dimensions.first = event.window.data1;
						info.resize_dimensions.second = event.window.data2;
						break;
				}
				//make sure this runs in it's own scope.
				{
					flip_locker flip_lock(CVideo::get_singleton());
					for( std::deque<context>::iterator i = event_contexts.begin() ; i != event_contexts.end(); ++i) {
						const handler_list& event_handlers = (*i).handlers;
						for(auto handler : event_handlers) {
							handler->handle_window_event(event);
						}
					}
					const handler_list& event_handlers = event_contexts.front().handlers;
					for(auto handler : event_handlers) {
						handler->handle_window_event(event);
					}
				}

				//This event was just distributed, don't re-distribute.
				continue;

			case SDL_MOUSEMOTION: {
				//always make sure a cursor is displayed if the
				//mouse moves or if the user clicks
				cursor::set_focus(true);
				raise_help_string_event(event.motion.x,event.motion.y);
				break;
			}

			case SDL_MOUSEBUTTONDOWN: {
				//always make sure a cursor is displayed if the
				//mouse moves or if the user clicks
				cursor::set_focus(true);
				if(event.button.button == SDL_BUTTON_LEFT) {
					static const int DoubleClickTime = 500;
					static const int DoubleClickMaxMove = 3;
					if(last_mouse_down >= 0 && info.ticks() - last_mouse_down < DoubleClickTime &&
					   abs(event.button.x - last_click_x) < DoubleClickMaxMove &&
					   abs(event.button.y - last_click_y) < DoubleClickMaxMove) {
						SDL_UserEvent user_event;
						user_event.type = DOUBLE_CLICK_EVENT;
						user_event.code = 0;
						user_event.data1 = reinterpret_cast<void*>(event.button.x);
						user_event.data2 = reinterpret_cast<void*>(event.button.y);
						::SDL_PushEvent(reinterpret_cast<SDL_Event*>(&user_event));
					}
					last_mouse_down = info.ticks();
					last_click_x = event.button.x;
					last_click_y = event.button.y;
				}
				break;
			}
			case DRAW_ALL_EVENT:
			{
				flip_locker flip_lock(CVideo::get_singleton());
				/* iterate backwards as the most recent things will be at the top */
				for( std::deque<context>::iterator i = event_contexts.begin() ; i != event_contexts.end(); ++i) {
					handler_list& event_handlers = (*i).handlers;
					for( handler_list::iterator i1 = event_handlers.begin(); i1 != event_handlers.end(); ++i1) {
						(*i1)->handle_event(event);
					}
				}
				continue; //do not do further handling here
			}

#ifndef __APPLE__
			case SDL_KEYDOWN: {
				if(event.key.keysym.sym == SDLK_F4 && (event.key.keysym.mod == KMOD_RALT || event.key.keysym.mod == KMOD_LALT)) {
					quit_confirmation::quit_to_desktop();
					continue; // this event is already handled
				}
				break;
			}
#endif

#if defined(_X11) && !defined(__APPLE__)
			case SDL_SYSWMEVENT: {
				//clipboard support for X11
				desktop::clipboard::handle_system_event(event);
				break;
			}
#endif

#if defined _WIN32
			case SDL_SYSWMEVENT: {
				windows_tray_notification::handle_system_event(event);
				break;
			}
#endif

			case SDL_QUIT: {
				quit_confirmation::quit_to_desktop();
				continue; //this event is already handled.
			}
		}

		const handler_list& event_handlers = event_contexts.front().handlers;
		for(auto handler : event_handlers) {
			handler->handle_event(event);
		}

		if(event_contexts.empty() == false) {

			const handler_list& event_handlers = event_contexts.back().handlers;

			//events may cause more event handlers to be added and/or removed,
			//so we must use indexes instead of iterators here.
			for(auto handler : event_handlers) {
				handler->handle_event(event);
			}
		}

	}

	//inform the pump monitors that an events::pump() has occurred
	for(size_t i1 = 0, i2 = pump_monitors.size(); i1 != i2 && i1 < pump_monitors.size(); ++i1) {
		pump_monitors[i1]->process(info);
	}
}

void raise_process_event()
{
	if(event_contexts.empty() == false) {

		const handler_list& event_handlers = event_contexts.back().handlers;

		//events may cause more event handlers to be added and/or removed,
		//so we must use indexes instead of iterators here.
		for(auto handler : event_handlers) {
			handler->process_event();
		}
	}
}

void raise_resize_event()
{
	SDL_Event event;
	event.window.type = SDL_WINDOWEVENT;
	event.window.event = SDL_WINDOWEVENT_RESIZED;
	event.window.windowID = 0; // We don't check this anyway... I think...
	event.window.data1 = CVideo::get_singleton().getx();
	event.window.data2 = CVideo::get_singleton().gety();

	SDL_PushEvent(&event);
}

void raise_draw_event()
{
	if(event_contexts.empty() == false) {
		event_contexts.back().add_staging_handlers();
		const handler_list& event_handlers = event_contexts.back().handlers;

		//events may cause more event handlers to be added and/or removed,
		//so we must use indexes instead of iterators here.
		for(auto handler : event_handlers) {
			handler->draw();
		}
	}
}

void raise_draw_all_event()
{
	for( std::deque<context>::iterator i = event_contexts.begin() ; i != event_contexts.end(); ++i) {
		const handler_list& event_handlers = (*i).handlers;
		for(auto handler : event_handlers) {
			handler->draw();
		}
	}
}

void raise_volatile_draw_event()
{
	if(event_contexts.empty() == false) {

		const handler_list& event_handlers = event_contexts.back().handlers;

		//events may cause more event handlers to be added and/or removed,
		//so we must use indexes instead of iterators here.
		for(auto handler : event_handlers) {
			handler->volatile_draw();
		}
	}
}

void raise_volatile_draw_all_event()
{
	for( std::deque<context>::iterator i = event_contexts.begin() ; i != event_contexts.end(); ++i) {
		const handler_list& event_handlers = (*i).handlers;
		for(auto handler : event_handlers) {
			handler->volatile_draw();
		}
	}
}

void raise_volatile_undraw_event()
{
	if(event_contexts.empty() == false) {

		const handler_list& event_handlers = event_contexts.back().handlers;

		//events may cause more event handlers to be added and/or removed,
		//so we must use indexes instead of iterators here.
		for(auto handler : event_handlers) {
			handler->volatile_undraw();
		}
	}
}

void raise_help_string_event(int mousex, int mousey)
{
	if(event_contexts.empty() == false) {

		const handler_list& event_handlers = event_contexts.back().handlers;

		for(auto handler : event_handlers) {
			handler->process_help_string(mousex,mousey);
			handler->process_tooltip_string(mousex,mousey);
		}
	}
}

int pump_info::ticks(unsigned *refresh_counter, unsigned refresh_rate) {
	if(!ticks_ && !(refresh_counter && ++*refresh_counter % refresh_rate)) {
		ticks_ = ::SDL_GetTicks();
	}
	return ticks_;
}


/* The constants for the minimum and maximum are picked from the headers. */
#define INPUT_MIN 0x300
#define INPUT_MAX 0x8FF

bool is_input(const SDL_Event& event)
{
	return event.type >= INPUT_MIN && event.type <= INPUT_MAX;
}

void discard_input()
{
	SDL_FlushEvents(INPUT_MIN, INPUT_MAX);
}

void peek_for_resize()
{
	SDL_Event events[100];
	int num = SDL_PeepEvents(events, 100, SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT);
	for (int i = 0; i < num; ++i) {
		if (events[i].type == SDL_WINDOWEVENT &&
				events[i].window.event == SDL_WINDOWEVENT_RESIZED) {
			CVideo::get_singleton().update_framebuffer();

		}
	}
}


} //end events namespace
void cHpiSubProviderReset::GetActions( std::deque<HpiAction>& actions ) const
{
    actions.clear();
    actions.push_back( HpiAction( 1, L"TODO" ) );
}
Beispiel #4
0
event_context::event_context()
{
	event_contexts.emplace_back();
}
Beispiel #5
0
void focus_handler(const sdl_handler* ptr)
{
	if(event_contexts.empty() == false) {
		event_contexts.back().set_focus(ptr);
	}
}
Beispiel #6
0
static wint_t lookahead_front(void) { return lookahead_list.front(); }
Beispiel #7
0
// Recurse through all subloops and all loops  into LQ.
static void addLoopIntoQueue(Loop *L, std::deque<Loop *> &LQ) {
  LQ.push_back(L);
  for (Loop::reverse_iterator I = L->rbegin(), E = L->rend(); I != E; ++I)
    addLoopIntoQueue(*I, LQ);
}
Beispiel #8
0
// Recurse through all subregions and all regions  into RQ.
static void addRegionIntoQueue(Region &R, std::deque<Region *> &RQ) {
  RQ.push_back(&R);
  for (const auto &E : R)
    addRegionIntoQueue(*E, RQ);
}
void backtrace_fake_clear_all() {
  g_fake_backtrace.clear();
}
    void GenerateFaceIndicators(const int &sampleIdx,
                                std::vector<double> &eyesHeightVec, 
                                FaceFeature &faceFeatures,
                                std::deque<InfoPERCLOS> &PERCLOSDeque, 
                                std::deque<InfoBLINK> &BLINKDeque, 
                                const double &intervalTime)
    {
        double eyesHeight = 0, lastEyesHeight = faceFeatures.lastHeight;
        double PERCLOS = 0, MICROSLEEP = 0, MICROSLEEPTime = faceFeatures.MICROSLEEPTime, BLINK = 0;
        
        double eyesHeight_b = faceFeatures.Height_Baseline;
        //Find the min size between two eyes.
        if (!eyesHeightVec.empty()) {
            sort(eyesHeightVec.begin(), eyesHeightVec.end(), SortBigger);
            eyesHeight = eyesHeightVec.front();
            if(eyesHeight > 2*eyesHeight_b )
                eyesHeight = 2*eyesHeight_b;
        }
        else {
            //Negative, if can NOT detect eyes correctly
            eyesHeight = lastEyesHeight;
        }

/*********************************************/
/*  PERCLOS: Percentage of eye closure       */
/*********************************************/   
        InfoPERCLOS perclosInfo;
        perclosInfo.time = intervalTime;
        if(!PERCLOSDeque.empty()){
            /// Calculate the number of frames in fixed time
            if (eyesHeight < faceFeatures.Height_Baseline * THRESHOLD_PERCLOS) {
                perclosInfo.eyePERCLOS = 1; // eye closed
                perclosInfo.timePERCLOS = PERCLOSDeque.back().timePERCLOS +intervalTime;
            }
            else {
                perclosInfo.eyePERCLOS = 0;
                perclosInfo.timePERCLOS = PERCLOSDeque.back().timePERCLOS;
                
            }
            perclosInfo.winTimePERCLOS = PERCLOSDeque.back().winTimePERCLOS + intervalTime;

            //! Only focus on the fixed time interval.
            while(perclosInfo.winTimePERCLOS > TIME_PERCLOS_WINDOW)
            {
                perclosInfo.winTimePERCLOS -= PERCLOSDeque.front().time;
                if(PERCLOSDeque.front().eyePERCLOS == 1)
                {
                    perclosInfo.timePERCLOS -= PERCLOSDeque.front().time;
                }
                PERCLOSDeque.pop_front();
            }
            
            //cout << "time PERCLOS: " << perclosInfo.timePERCLOS << endl;
        }
        else 
        {// The first frames without any PERCLOSInfo
            if (eyesHeight < faceFeatures.Height_Baseline * THRESHOLD_PERCLOS) {
                perclosInfo.eyePERCLOS = 1;
                perclosInfo.timePERCLOS = intervalTime;
            }
            else {
                perclosInfo.eyePERCLOS = 0;
                perclosInfo.timePERCLOS = 0;
            }
            perclosInfo.winTimePERCLOS = intervalTime;
        }
        PERCLOSDeque.push_back(perclosInfo);
        
        //! PERCLOS
        if(perclosInfo.winTimePERCLOS < TIME_PERCLOS_WINDOW / 2)
            PERCLOS = 0;//In first time interval too high value
        else 
            PERCLOS = perclosInfo.timePERCLOS / perclosInfo.winTimePERCLOS;
        
/************************************************/
/*  Statistics of Continuous Eye Closure        */
/*  MICROSLEEP: ND: 0~0.5                       */
/*              SD: 0.5~1                       */
/*              MD: 1~2                         */
/*              VD: 2~4                         */
/*              ED: 4~                          */
/************************************************/
        if (eyesHeight < faceFeatures.Height_Baseline * THRESHOLD_CLOSURE) {
            MICROSLEEPTime += intervalTime;
        } 
        else {
            MICROSLEEPTime -= intervalTime;
            MICROSLEEPTime = MICROSLEEPTime > 0 ? MICROSLEEPTime : 0;
        }
        
        //! When MICROSLEEPTime not equal to 0, Update the MICROSLEEP
        if (MICROSLEEPTime < 0.5)
            MICROSLEEP = 0.25 * MICROSLEEPTime;  //Alert
        else if (MICROSLEEPTime >= 0.5 && MICROSLEEPTime < 1)
            MICROSLEEP = 0.5 * MICROSLEEPTime - 0.125;  //Slightly Drowsy
        else if (MICROSLEEPTime >= 1 && MICROSLEEPTime < 2)
            MICROSLEEP = 0.25 * MICROSLEEPTime + 0.125;  //Moderately Drowsy
        else if(MICROSLEEPTime >= 2 && MICROSLEEPTime < 4)
            MICROSLEEP = 0.125 * MICROSLEEPTime + 0.375;  //Very Drowsy
        else if(MICROSLEEPTime >= 4 && MICROSLEEPTime < 5)
            MICROSLEEP = 0.125 * MICROSLEEPTime + 0.375;
        else
            MICROSLEEP = 1;    //Extremely Drowsy
        
/************************************************/
//! BLINK: Blink Frequency Statistics 
/************************************************/
        InfoBLINK blinkInfo;
        blinkInfo.time = intervalTime;
        if(!BLINKDeque.empty()) {
            /// Calculate the number of frames in fixed time
            if (eyesHeight < faceFeatures.Height_Baseline * THRESHOLD_CLOSURE) {
                blinkInfo.eyeBLINK = 1;
            }
            else {
                blinkInfo.eyeBLINK = 0;
            }
            blinkInfo.winTimeBLINK = BLINKDeque.back().winTimeBLINK + intervalTime;
            
            //! Only focus on the fixed time interval.
            while(blinkInfo.winTimeBLINK  > TIME_BLINK_WINDOW)
            {
                blinkInfo.winTimeBLINK  -= BLINKDeque.front().time;
                BLINKDeque.pop_front();
            }
        }
        else {
            if (eyesHeight < faceFeatures.Height_Baseline * THRESHOLD_CLOSURE) {
                blinkInfo.eyeBLINK = 1;
            }
            else {
                blinkInfo.eyeBLINK = 0;
            }
            blinkInfo.winTimeBLINK = intervalTime;
        }
        BLINKDeque.push_back(blinkInfo);

        //! Calculate the BLINK number 
        int flagBLINK = 0, numBLINK = 0;//start with open eyes
        for (std::deque<InfoBLINK>::const_iterator iter = BLINKDeque.begin(); iter != BLINKDeque.end(); ++iter)
        {
            if (iter->eyeBLINK == 1) {   
                //! closed eyes at first should change flag = 1.
                if (flagBLINK == 0) {
                    flagBLINK = 1;
                    numBLINK ++;
                }
            }
            else {  
                //! open eyes will change flag = 0.
                if (flagBLINK == 1) {
                    flagBLINK = 0;
                } 
            }// end if
        }// end for
        
        BLINK = numBLINK;
//        BLINK = (double)numBLINK / (double)BLINKDeque.size();
//        BLINK = (BLINK - faceFeatures.BLINK_Baseline) / faceFeatures.BLINK_Baseline;
//        BLINK = BLINK < 0 ? 0 : BLINK; 
//        BLINK = BLINK > 1 ? 1 : BLINK; 
        
        
        //! Update the faceFeatures
        faceFeatures.frame  = sampleIdx;
        faceFeatures.Height = eyesHeight;
        faceFeatures.lastHeight = eyesHeight;
        faceFeatures.PERCLOS = PERCLOS;
        faceFeatures.MICROSLEEPTime = MICROSLEEPTime;
        faceFeatures.MICROSLEEP = MICROSLEEP;
        faceFeatures.BLINK = BLINK;
        
    }///GenerateFaceIndicators
Beispiel #11
0
void hier_push_mat()
{
    matrix_stack.push_back(current_mat);
}
namespace pyston {

static uint64_t next_stack_addr = 0x4270000000L;
static std::deque<uint64_t> available_addrs;

// There should be a better way of getting this:
#define PAGE_SIZE 4096

#define INITIAL_STACK_SIZE (8 * PAGE_SIZE)
#define STACK_REDZONE_SIZE PAGE_SIZE
#define MAX_STACK_SIZE (4 * 1024 * 1024)

static std::unordered_map<void*, BoxedGenerator*> s_generator_map;
static_assert(THREADING_USE_GIL, "have to make the generator map thread safe!");

class RegisterHelper {
private:
    void* frame_addr;

public:
    RegisterHelper(BoxedGenerator* generator, void* frame_addr) : frame_addr(frame_addr) {
        s_generator_map[frame_addr] = generator;
    }
    ~RegisterHelper() {
        assert(s_generator_map.count(frame_addr));
        s_generator_map.erase(frame_addr);
    }
};

static void freeGeneratorStack(BoxedGenerator* g) {
    if (g->stack_begin == NULL)
        return;

    available_addrs.push_back((uint64_t)g->stack_begin);
    // Limit the number of generator stacks we keep around:
    if (available_addrs.size() > 5) {
        uint64_t addr = available_addrs.front();
        available_addrs.pop_front();
        int r = munmap((void*)(addr - MAX_STACK_SIZE), MAX_STACK_SIZE);
        assert(r == 0);
    }

    g->stack_begin = NULL;
}

Context* getReturnContextForGeneratorFrame(void* frame_addr) {
    BoxedGenerator* generator = s_generator_map[frame_addr];
    assert(generator);
    return generator->returnContext;
}

void generatorEntry(BoxedGenerator* g) {
    {
        assert(g->cls == generator_cls);
        assert(g->function->cls == function_cls);

        threading::pushGenerator(g, g->stack_begin, g->returnContext);
        try {
            RegisterHelper context_registerer(g, __builtin_frame_address(0));

            // call body of the generator
            BoxedFunctionBase* func = g->function;

            Box** args = g->args ? &g->args->elts[0] : nullptr;
            callCLFunc<ExceptionStyle::CXX>(func->f, nullptr, func->f->numReceivedArgs(), func->closure, g,
                                            func->globals, g->arg1, g->arg2, g->arg3, args);
        } catch (ExcInfo e) {
            // unhandled exception: propagate the exception to the caller
            g->exception = e;
        }

        // we returned from the body of the generator. next/send/throw will notify the caller
        g->entryExited = true;
        threading::popGenerator();
    }
    swapContext(&g->context, g->returnContext, 0);
}

Box* generatorIter(Box* s) {
    return s;
}

// called from both generatorHasNext and generatorSend/generatorNext (but only if generatorHasNext hasn't been called)
template <ExceptionStyle S> static bool generatorSendInternal(BoxedGenerator* self, Box* v) noexcept(S == CAPI) {
    STAT_TIMER(t0, "us_timer_generator_switching", 0);

    if (!self->returnContext && v != None) {
        if (S == CAPI) {
            PyErr_SetString(TypeError, "can't send non-None value to a just-started generator");
            return true;
        } else
            raiseExcHelper(TypeError, "can't send non-None value to a just-started generator");
    }

    if (self->running) {
        if (S == CAPI) {
            PyErr_SetString(ValueError, "generator already executing");
            return true;
        } else
            raiseExcHelper(ValueError, "generator already executing");
    }

    // check if the generator already exited
    if (self->entryExited) {
        freeGeneratorStack(self);
        if (S == CAPI) {
            PyErr_SetObject(StopIteration, None);
            return true;
        } else
            raiseExcHelper(StopIteration, (const char*)nullptr);
    }

    self->returnValue = v;
    self->running = true;

#if STAT_TIMERS
    if (!self->prev_stack)
        self->prev_stack = StatTimer::createStack(self->my_timer);
    else
        self->prev_stack = StatTimer::swapStack(self->prev_stack);
#endif

    swapContext(&self->returnContext, self->context, (intptr_t)self);

#if STAT_TIMERS
    self->prev_stack = StatTimer::swapStack(self->prev_stack);
    if (self->entryExited) {
        assert(self->prev_stack == &self->my_timer);
        assert(self->my_timer.isPaused());
    }
#endif

    self->running = false;

    // propagate exception to the caller
    if (self->exception.type) {
        freeGeneratorStack(self);
        // don't raise StopIteration exceptions because those are handled specially.
        if (!self->exception.matches(StopIteration)) {
            if (S == CAPI) {
                setCAPIException(self->exception);
                return true;
            } else
                throw self->exception;
        }
        return false;
    }

    if (self->entryExited) {
        freeGeneratorStack(self);
        // Reset the current exception.
        // We could directly create the StopIteration exception but we delay creating it because often the caller is not
        // interested in the exception (=generatorHasnext). If we really need it we will create it inside generatorSend.
        self->exception = ExcInfo(NULL, NULL, NULL);
        return false;
    }
    return false;
}

template <ExceptionStyle S> static Box* generatorSend(Box* s, Box* v) noexcept(S == CAPI) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    if (self->iterated_from__hasnext__)
        Py_FatalError(".throw called on generator last advanced with __hasnext__");

    bool exc = generatorSendInternal<S>(self, v);
    if (S == CAPI && exc)
        return NULL;

    // throw StopIteration if the generator exited
    if (self->entryExited) {
        // But we can't just create a new exc because the generator may have exited because of an explicit
        // 'raise StopIterationSubClass, "test"' statement and we can't replace it with the generic StopIteration
        // exception.
        // That's why we set inside 'generatorSendInternal()' 'self->exception' to the raised StopIteration exception or
        // create a new one if the generator exited implicit.
        // CPython raises the custom exception just once, on the next generator 'next' it will we a normal StopIteration
        // exc.
        assert(self->exception.type == NULL || self->exception.matches(StopIteration));
        ExcInfo old_exc = self->exception;
        // Clear the exception for GC purposes:
        self->exception = ExcInfo(nullptr, nullptr, nullptr);
        if (old_exc.type == NULL) {
            if (S == CAPI) {
                PyErr_SetObject(StopIteration, None);
                return NULL;
            } else
                raiseExcHelper(StopIteration, (const char*)nullptr);
        } else {
            if (S == CAPI) {
                setCAPIException(old_exc);
                return NULL;
            } else
                throw old_exc;
        }
    }

    return self->returnValue;
}

Box* generatorThrow(Box* s, BoxedClass* exc_cls, Box* exc_val = nullptr, Box** args = nullptr) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    if (self->iterated_from__hasnext__ && !self->entryExited)
        Py_FatalError(".throw called on generator last advanced with __hasnext__");

    Box* exc_tb = args ? args[0] : nullptr;
    if (exc_tb && exc_tb != None && !PyTraceBack_Check(exc_tb))
        raiseExcHelper(TypeError, "throw() third argument must be a traceback object");
    if (!exc_val)
        exc_val = None;
    if (!exc_tb)
        exc_tb = None;

    ExcInfo exc_info = excInfoForRaise(exc_cls, exc_val, exc_tb);
    if (self->entryExited)
        throw exc_info;

    self->exception = exc_info;
    return generatorSend<CXX>(self, None);
}

Box* generatorClose(Box* s) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    // check if the generator already exited
    if (self->entryExited)
        return None;

    try {
        generatorThrow(self, GeneratorExit, nullptr, nullptr);
        raiseExcHelper(RuntimeError, "generator ignored GeneratorExit");
    } catch (ExcInfo e) {
        if (e.matches(StopIteration) || e.matches(GeneratorExit))
            return None;
        throw e;
    }
    assert(0); // unreachable
}

template <ExceptionStyle S> static Box* generatorNext(Box* s) noexcept(S == CAPI) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    if (self->iterated_from__hasnext__) {
        self->iterated_from__hasnext__ = false;
        return self->returnValue;
    }

    return generatorSend<S>(s, None);
}

i1 generatorHasnextUnboxed(Box* s) {
    assert(s->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(s);

    if (!self->iterated_from__hasnext__) {
        generatorSendInternal<CXX>(self, None);
        self->iterated_from__hasnext__ = true;
    }

    return !self->entryExited;
}

Box* generatorHasnext(Box* s) {
    return boxBool(generatorHasnextUnboxed(s));
}


extern "C" Box* yield(BoxedGenerator* obj, Box* value) {
    STAT_TIMER(t0, "us_timer_generator_switching", 0);

    assert(obj->cls == generator_cls);
    BoxedGenerator* self = static_cast<BoxedGenerator*>(obj);
    self->returnValue = value;

    threading::popGenerator();
    swapContext(&self->context, self->returnContext, 0);
    threading::pushGenerator(obj, obj->stack_begin, obj->returnContext);

    // if the generator receives a exception from the caller we have to throw it
    if (self->exception.type) {
        ExcInfo e = self->exception;
        self->exception = ExcInfo(NULL, NULL, NULL);
        throw e;
    }
    return self->returnValue;
}


extern "C" BoxedGenerator* createGenerator(BoxedFunctionBase* function, Box* arg1, Box* arg2, Box* arg3, Box** args) {
    assert(function);
    assert(function->cls == function_cls);
    return new BoxedGenerator(function, arg1, arg2, arg3, args);
}

#if STAT_TIMERS
static uint64_t* generator_timer_counter = Stats::getStatCounter("us_timer_generator_toplevel");
#endif
extern "C" BoxedGenerator::BoxedGenerator(BoxedFunctionBase* function, Box* arg1, Box* arg2, Box* arg3, Box** args)
    : function(function),
      arg1(arg1),
      arg2(arg2),
      arg3(arg3),
      args(nullptr),
      entryExited(false),
      running(false),
      returnValue(nullptr),
      exception(nullptr, nullptr, nullptr),
      context(nullptr),
      returnContext(nullptr)
#if STAT_TIMERS
      ,
      prev_stack(NULL),
      my_timer(generator_timer_counter, 0, true)
#endif
{

    int numArgs = function->f->numReceivedArgs();
    if (numArgs > 3) {
        numArgs -= 3;
        this->args = new (numArgs) GCdArray();
        memcpy(&this->args->elts[0], args, numArgs * sizeof(Box*));
    }

    static StatCounter generator_stack_reused("generator_stack_reused");
    static StatCounter generator_stack_created("generator_stack_created");

    void* initial_stack_limit;
    if (available_addrs.size() == 0) {
        generator_stack_created.log();

        uint64_t stack_low = next_stack_addr;
        uint64_t stack_high = stack_low + MAX_STACK_SIZE;
        next_stack_addr = stack_high;

#if STACK_GROWS_DOWN
        this->stack_begin = (void*)stack_high;

        initial_stack_limit = (void*)(stack_high - INITIAL_STACK_SIZE);
        void* p = mmap(initial_stack_limit, INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE,
                       MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0);
        ASSERT(p == initial_stack_limit, "%p %s", p, strerror(errno));

        // Create an inaccessible redzone so that the generator stack won't grow indefinitely.
        // Looks like it throws a SIGBUS if we reach the redzone; it's unclear if that's better
        // or worse than being able to consume all available memory.
        void* p2
            = mmap((void*)stack_low, STACK_REDZONE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
        assert(p2 == (void*)stack_low);
        // Interestingly, it seems like MAP_GROWSDOWN will leave a page-size gap between the redzone and the growable
        // region.

        if (VERBOSITY() >= 1) {
            printf("Created new generator stack, starts at %p, currently extends to %p\n", (void*)stack_high,
                   initial_stack_limit);
            printf("Created a redzone from %p-%p\n", (void*)stack_low, (void*)(stack_low + STACK_REDZONE_SIZE));
        }
#else
#error "implement me"
#endif

        // we're registering memory that isn't in the gc heap here,
        // which may sound wrong.  Generators, however, can represent
        // a larger tax on system resources than just their GC
        // allocation, so we try to encode that here as additional gc
        // heap pressure.
        gc::registerGCManagedBytes(INITIAL_STACK_SIZE);
    } else {
        generator_stack_reused.log();

#if STACK_GROWS_DOWN
        uint64_t stack_high = available_addrs.back();
        this->stack_begin = (void*)stack_high;
        initial_stack_limit = (void*)(stack_high - INITIAL_STACK_SIZE);
        available_addrs.pop_back();
#else
#error "implement me"
#endif
    }

    assert(((intptr_t)stack_begin & (~(intptr_t)(0xF))) == (intptr_t)stack_begin && "stack must be aligned");

    context = makeContext(stack_begin, (void (*)(intptr_t))generatorEntry);
}

void BoxedGenerator::gcHandler(GCVisitor* v, Box* b) {
    Box::gcHandler(v, b);

    BoxedGenerator* g = (BoxedGenerator*)b;

    v->visit(g->function);
    int num_args = g->function->f->numReceivedArgs();
    if (num_args >= 1)
        v->visit(g->arg1);
    if (num_args >= 2)
        v->visit(g->arg2);
    if (num_args >= 3)
        v->visit(g->arg3);
    if (g->args)
        v->visit(g->args);
    if (num_args > 3)
        v->visitPotentialRange(reinterpret_cast<void* const*>(&g->args->elts[0]),
                               reinterpret_cast<void* const*>(&g->args->elts[num_args - 3]));
    if (g->returnValue)
        v->visit(g->returnValue);
    if (g->exception.type)
        v->visit(g->exception.type);
    if (g->exception.value)
        v->visit(g->exception.value);
    if (g->exception.traceback)
        v->visit(g->exception.traceback);

    if (g->running) {
        v->visitPotentialRange((void**)g->returnContext,
                               ((void**)g->returnContext) + sizeof(*g->returnContext) / sizeof(void*));
    } else {
        // g->context is always set for a running generator, but we can trigger a GC while constructing
        // a generator in which case we can see a NULL context
        if (g->context) {
#if STACK_GROWS_DOWN
            v->visitPotentialRange((void**)g->context, (void**)g->stack_begin);
#endif
        }
    }
}

Box* generatorName(Box* _self, void* context) {
    assert(isSubclass(_self->cls, generator_cls));
    BoxedGenerator* self = static_cast<BoxedGenerator*>(_self);

    return self->function->f->source->getName();
}

void generatorDestructor(Box* b) {
    assert(isSubclass(b->cls, generator_cls));
    BoxedGenerator* self = static_cast<BoxedGenerator*>(b);
    freeGeneratorStack(self);
}

void setupGenerator() {
    generator_cls
        = BoxedHeapClass::create(type_cls, object_cls, &BoxedGenerator::gcHandler, 0,
                                 offsetof(BoxedGenerator, weakreflist), sizeof(BoxedGenerator), false, "generator");
    generator_cls->tp_dealloc = generatorDestructor;
    generator_cls->has_safe_tp_dealloc = true;
    generator_cls->giveAttr("__iter__",
                            new BoxedFunction(boxRTFunction((void*)generatorIter, typeFromClass(generator_cls), 1)));

    generator_cls->giveAttr("close", new BoxedFunction(boxRTFunction((void*)generatorClose, UNKNOWN, 1)));

    auto generator_next = boxRTFunction((void*)generatorNext<CXX>, UNKNOWN, 1, ParamNames::empty(), CXX);
    addRTFunction(generator_next, (void*)generatorNext<CAPI>, UNKNOWN, CAPI);
    generator_cls->giveAttr("next", new BoxedFunction(generator_next));

    CLFunction* hasnext = boxRTFunction((void*)generatorHasnextUnboxed, BOOL, 1);
    addRTFunction(hasnext, (void*)generatorHasnext, BOXED_BOOL);
    generator_cls->giveAttr("__hasnext__", new BoxedFunction(hasnext));

    generator_cls->giveAttr("send", new BoxedFunction(boxRTFunction((void*)generatorSend<CXX>, UNKNOWN, 2)));
    auto gthrow = new BoxedFunction(boxRTFunction((void*)generatorThrow, UNKNOWN, 4, 2, false, false), { NULL, NULL });
    generator_cls->giveAttr("throw", gthrow);

    generator_cls->giveAttr("__name__", new (pyston_getset_cls) BoxedGetsetDescriptor(generatorName, NULL, NULL));

    generator_cls->freeze();
    generator_cls->tp_iter = PyObject_SelfIter;
}
}
extern "C" BoxedGenerator::BoxedGenerator(BoxedFunctionBase* function, Box* arg1, Box* arg2, Box* arg3, Box** args)
    : function(function),
      arg1(arg1),
      arg2(arg2),
      arg3(arg3),
      args(nullptr),
      entryExited(false),
      running(false),
      returnValue(nullptr),
      exception(nullptr, nullptr, nullptr),
      context(nullptr),
      returnContext(nullptr)
#if STAT_TIMERS
      ,
      prev_stack(NULL),
      my_timer(generator_timer_counter, 0, true)
#endif
{

    int numArgs = function->f->numReceivedArgs();
    if (numArgs > 3) {
        numArgs -= 3;
        this->args = new (numArgs) GCdArray();
        memcpy(&this->args->elts[0], args, numArgs * sizeof(Box*));
    }

    static StatCounter generator_stack_reused("generator_stack_reused");
    static StatCounter generator_stack_created("generator_stack_created");

    void* initial_stack_limit;
    if (available_addrs.size() == 0) {
        generator_stack_created.log();

        uint64_t stack_low = next_stack_addr;
        uint64_t stack_high = stack_low + MAX_STACK_SIZE;
        next_stack_addr = stack_high;

#if STACK_GROWS_DOWN
        this->stack_begin = (void*)stack_high;

        initial_stack_limit = (void*)(stack_high - INITIAL_STACK_SIZE);
        void* p = mmap(initial_stack_limit, INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE,
                       MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0);
        ASSERT(p == initial_stack_limit, "%p %s", p, strerror(errno));

        // Create an inaccessible redzone so that the generator stack won't grow indefinitely.
        // Looks like it throws a SIGBUS if we reach the redzone; it's unclear if that's better
        // or worse than being able to consume all available memory.
        void* p2
            = mmap((void*)stack_low, STACK_REDZONE_SIZE, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
        assert(p2 == (void*)stack_low);
        // Interestingly, it seems like MAP_GROWSDOWN will leave a page-size gap between the redzone and the growable
        // region.

        if (VERBOSITY() >= 1) {
            printf("Created new generator stack, starts at %p, currently extends to %p\n", (void*)stack_high,
                   initial_stack_limit);
            printf("Created a redzone from %p-%p\n", (void*)stack_low, (void*)(stack_low + STACK_REDZONE_SIZE));
        }
#else
#error "implement me"
#endif

        // we're registering memory that isn't in the gc heap here,
        // which may sound wrong.  Generators, however, can represent
        // a larger tax on system resources than just their GC
        // allocation, so we try to encode that here as additional gc
        // heap pressure.
        gc::registerGCManagedBytes(INITIAL_STACK_SIZE);
    } else {
        generator_stack_reused.log();

#if STACK_GROWS_DOWN
        uint64_t stack_high = available_addrs.back();
        this->stack_begin = (void*)stack_high;
        initial_stack_limit = (void*)(stack_high - INITIAL_STACK_SIZE);
        available_addrs.pop_back();
#else
#error "implement me"
#endif
    }

    assert(((intptr_t)stack_begin & (~(intptr_t)(0xF))) == (intptr_t)stack_begin && "stack must be aligned");

    context = makeContext(stack_begin, (void (*)(intptr_t))generatorEntry);
}
Beispiel #14
0
/** Dynamic word wrap algorithm
 * (Knuth's word wrapping algorithm that minimizes raggedness of formatted text)
 *
 * @param wrap_after [out]
 * @param nwords number of "words"
 * @param width_val maximal desired out line width
 * @param exponent_val cost function exponent
 * @param widths_orig ith word width original
 * @param widths_trim ith word width trimmed
 * @param add_para_1
 * @param add_para_a
 *
 * @version 0.1-?? (Bartek Tartanus)
 *          original implementation
 *
 * @version 0.2-2 (Marek Gagolewski, 2014-04-30)
 *          BreakIterator usage mods
 *
 * @version 0.4-1 (Marek Gagolewski, 2014-12-06)
 *    new args: add_para_1, add_para_n,
 *    cost of the last line is zero
 */
void stri__wrap_dynamic(std::deque<R_len_t>& wrap_after,
   R_len_t nwords, int width_val, double exponent_val,
   const std::vector<R_len_t>& widths_orig,
   const std::vector<R_len_t>& widths_trim,
   int add_para_1, int add_para_n)
{
#define IDX(i,j) (i)*nwords+(j)
   vector<double> cost(nwords*nwords);
   // where cost[IDX(i,j)] == cost of printing words i..j in a single line, i<=j

   // calculate costs:
   // there is some "punishment" for leaving blanks at the end of each line
   // (number of "blank" codepoints ^ exponent_val)
   for (int i=0; i<nwords; i++) {
      int sum = 0;
      for (int j=i; j<nwords; j++) {
         if (j > i) {
            if (cost[IDX(i,j-1)] < 0.0) { // already Inf
               cost[IDX(i,j)] = -1.0; // Inf
               continue;
            }
            else {
               sum -= widths_trim[j-1];
               sum += widths_orig[j-1];
            }
         }
         sum += widths_trim[j];
         int ct = width_val - sum;
         if (i == 0) ct -= add_para_1;
         else        ct -= add_para_n;

         if (j == nwords-1) { // last line == cost 0
            if (j == i || ct >= 0)
               cost[IDX(i,j)] = 0.0;
            else
               cost[IDX(i,j)] = -1.0/*Inf*/;
         }
         else if (j == i)
            // some words don't fit in a line at all -> cost 0.0
            cost[IDX(i,j)] = (ct < 0) ? 0.0 : pow((double)ct, exponent_val);
         else
            cost[IDX(i,j)] = (ct < 0) ? -1.0/*"Inf"*/ : pow((double)ct, exponent_val);
      }
   }

   vector<double> f(nwords); // f[j] == total cost of  (optimally) printing words 0..j
   vector<bool> where(nwords*nwords, false); // where[IDX(i,j)] == false iff
                                             // we don't wrap after i-th word, i<=j
                                             // when (optimally) printing words 0..j

   for (int j=0; j<nwords; ++j) {
      if (cost[IDX(0,j)] >= 0.0) {
         // no breaking needed: words 0..j fit in one line
         f[j] = cost[IDX(0,j)];
         continue;
      }

      // let i = optimal way of printing of words 0..i + printing i+1..j
      int i = 0;
      while (i <= j) {
         if (cost[IDX(i+1,j)] >= 0.0) break;
         ++i;
      }

      double best_i = f[i] + cost[IDX(i+1,j)];
      for (int k=i+1; k<j; ++k) {
         if (cost[IDX(k+1,j)] < 0.0) continue;
         double best_cur = f[k] + cost[IDX(k+1,j)];
         if (best_cur < best_i) {
            best_i = best_cur;
            i = k;
         }
      }
      for (int k=0; k<i; ++k)
         where[IDX(k,j)] = where[IDX(k,i)];
      where[IDX(i,j)] = true;
      f[j] = best_i;
   }

   //result is in the last row of where...
   for (int k=0; k<nwords; ++k)
      if (where[IDX(k, nwords-1)])
         wrap_after.push_back(k);
}
Beispiel #15
0
static void lookahead_push_back(wint_t c) { lookahead_list.push_back(c); }
void backtrace_fake_add(const std::vector<uintptr_t>& ips) {
  g_fake_backtrace.push_back(ips);
}
Beispiel #17
0
static void lookahead_push_front(wint_t c) { lookahead_list.push_front(c); }
Beispiel #18
0
	~CProfiler2GPU_EXT_timer_query()
	{
		// Pop frames to return queries to the free list
		while (!m_Frames.empty())
			PopFrontFrame();
	}
 *      OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *******************************************************************************/
#include <stdlib.h>
#include <AL/alut.h>
#include <stdio.h>
#include <deque>
#include <string>
#include <sstream>
#include <time.h>
#include <math.h>
#include <iostream>
#include <typeinfo>
#include <deque>

std::deque<int> state;
typename std::deque<int>::iterator it = state.begin();

#include "../include/genetic_process.h"
#include <time.h>

//up to 1/(2^4) second beat resolution
//so for each note, we can hold it 1, 1/2, 1/4, 1/8, or 1/16 beat
// (ie 5 combinations)
#define duration_resolution 5
// assume we're running 1 measure per second
// 4 beats per measure
// then we have 4*16 potential beat-start combinations
// #define num_beats 4 * 16

ALuint sound_source_;
Beispiel #20
0
	void ProcessFrames()
	{
		while (!m_Frames.empty())
		{
			SFrame& frame = m_Frames.front();

			// Queries don't become available in order, so check them all before
			// trying to read the results from any
			for (size_t j = 0; j < m_QueryTypes.size(); ++j)
			{
				size_t size = m_QueryTypes[j].counterBufferSize;
				shared_ptr<char> buf(new char[size], ArrayDeleter());

				for (size_t i = 0; i < frame.events.size(); ++i)
				{
					if (!frame.events[i].isEnter)
						continue;

					GLuint length = 0;
					pglGetPerfQueryDataINTEL(frame.events[i].queries[j], INTEL_PERFQUERIES_NONBLOCK, size, buf.get(), &length);
					ogl_WarnIfError();
					if (length == 0)
						return;
				}
			}

			double lastTime = frame.timeStart;
			std::stack<double> endTimes;

			m_Storage.RecordFrameStart(frame.timeStart);

			for (size_t i = 0; i < frame.events.size(); ++i)
			{
				if (frame.events[i].isEnter)
				{
					m_Storage.Record(CProfiler2::ITEM_ENTER, lastTime, frame.events[i].id);

					if (i == 0)
						m_Storage.RecordAttributePrintf("%u", frame.num);

					double elapsed = 0.0;

					for (size_t j = 0; j < m_QueryTypes.size(); ++j)
					{
						GLuint length;
						char* buf = new char[m_QueryTypes[j].counterBufferSize];
						pglGetPerfQueryDataINTEL(frame.events[i].queries[j], INTEL_PERFQUERIES_BLOCK, m_QueryTypes[j].counterBufferSize, buf, &length);
						ogl_WarnIfError();
						ENSURE(length == m_QueryTypes[j].counterBufferSize);

						m_Storage.RecordAttributePrintf("-- %s --", m_QueryTypes[j].name.c_str());

						for (size_t k = 0; k < m_QueryTypes[j].counters.size(); ++k)
						{
							SPerfCounter& counter = m_QueryTypes[j].counters[k];

							if (counter.type == INTEL_PERFQUERIES_TYPE_UNSIGNED_INT)
							{
								ENSURE(counter.size == 4);
								GLuint value;
								memcpy(&value, buf + counter.offset, counter.size);
								m_Storage.RecordAttributePrintf("%s: %u", counter.name.c_str(), value);
							}
							else if (counter.type == INTEL_PERFQUERIES_TYPE_UNSIGNED_INT64)
							{
								ENSURE(counter.size == 8);
								GLuint64 value;
								memcpy(&value, buf + counter.offset, counter.size);
								m_Storage.RecordAttributePrintf("%s: %.0f", counter.name.c_str(), (double)value);

								if (counter.name == "TotalTime")
									elapsed = (double)value / 1e6;
							}
							else if (counter.type == INTEL_PERFQUERIES_TYPE_FLOAT)
							{
								ENSURE(counter.size == 4);
								GLfloat value;
								memcpy(&value, buf + counter.offset, counter.size);
								m_Storage.RecordAttributePrintf("%s: %f", counter.name.c_str(), value);
							}
							else if (counter.type == INTEL_PERFQUERIES_TYPE_BOOL)
							{
								ENSURE(counter.size == 4);
								GLuint value;
								memcpy(&value, buf + counter.offset, counter.size);
								ENSURE(value == 0 || value == 1);
								m_Storage.RecordAttributePrintf("%s: %u", counter.name.c_str(), value);
							}
							else
							{
								debug_warn(L"unrecognised Intel performance counter type");
							}
						}

						delete[] buf;
					}

					endTimes.push(lastTime + elapsed);
				}
				else
				{
					lastTime = endTimes.top();
					endTimes.pop();
					m_Storage.Record(CProfiler2::ITEM_LEAVE, lastTime, frame.events[i].id);
				}
			}

			PopFrontFrame();
		}
	}
Beispiel #21
0
void Mips16TargetLowering::
getOpndList(SmallVectorImpl<SDValue> &Ops,
            std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
            bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
            CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
  SelectionDAG &DAG = CLI.DAG;
  MachineFunction &MF = DAG.getMachineFunction();
  MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();
  const char* Mips16HelperFunction = 0;
  bool NeedMips16Helper = false;

  if (getTargetMachine().Options.UseSoftFloat &&
      Subtarget->inMips16HardFloat()) {
    //
    // currently we don't have symbols tagged with the mips16 or mips32
    // qualifier so we will assume that we don't know what kind it is.
    // and generate the helper
    //
    bool LookupHelper = true;
    if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(CLI.Callee)) {
      Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL, S->getSymbol() };

      if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls),
                             Find))
        LookupHelper = false;
      else {
        Mips16IntrinsicHelperType IntrinsicFind = {S->getSymbol(), ""};
        // one more look at list of intrinsics
        if (std::binary_search(Mips16IntrinsicHelper,
            array_endof(Mips16IntrinsicHelper),
                                     IntrinsicFind)) {
          const Mips16IntrinsicHelperType *h =(std::find(Mips16IntrinsicHelper,
              array_endof(Mips16IntrinsicHelper),
                                       IntrinsicFind));
          Mips16HelperFunction = h->Helper;
          NeedMips16Helper = true;
          LookupHelper = false;
        }

      }
    } else if (GlobalAddressSDNode *G =
                   dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
      Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL,
                             G->getGlobal()->getName().data() };

      if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls),
                             Find))
        LookupHelper = false;
    }
    if (LookupHelper) Mips16HelperFunction =
      getMips16HelperFunction(CLI.RetTy, CLI.Args, NeedMips16Helper);

  }

  SDValue JumpTarget = Callee;

  // T9 should contain the address of the callee function if
  // -reloction-model=pic or it is an indirect call.
  if (IsPICCall || !GlobalOrExternal) {
    unsigned V0Reg = Mips::V0;
    if (NeedMips16Helper) {
      RegsToPass.push_front(std::make_pair(V0Reg, Callee));
      JumpTarget = DAG.getExternalSymbol(Mips16HelperFunction, getPointerTy());
      ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(JumpTarget);
      JumpTarget = getAddrGlobal(S, JumpTarget.getValueType(), DAG,
                                 MipsII::MO_GOT, Chain,
                                 FuncInfo->callPtrInfo(S->getSymbol()));
    } else
      RegsToPass.push_front(std::make_pair((unsigned)Mips::T9, Callee));
  }

  Ops.push_back(JumpTarget);

  MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
                                  InternalLinkage, CLI, Callee, Chain);
}
Beispiel #22
0
namespace UI {

static View *focusedView;
static bool focusMovementEnabled;

static recursive_mutex mutex_;

const float ITEM_HEIGHT = 64.f;


struct DispatchQueueItem {
	Event *e;
	EventParams params;
};

std::deque<DispatchQueueItem> g_dispatchQueue;


void EventTriggered(Event *e, EventParams params) {
	lock_guard guard(mutex_);

	DispatchQueueItem item;
	item.e = e;
	item.params = params;
	g_dispatchQueue.push_front(item);
}

void DispatchEvents() {
	lock_guard guard(mutex_);

	while (!g_dispatchQueue.empty()) {
		DispatchQueueItem item = g_dispatchQueue.back();
		g_dispatchQueue.pop_back();
		if (item.e) {
			item.e->Dispatch(item.params);
		}
	}
}

void RemoveQueuedEvents(View *v) {
	for (size_t i = 0; i < g_dispatchQueue.size(); i++) {
		if (g_dispatchQueue[i].params.v == v)
			g_dispatchQueue.erase(g_dispatchQueue.begin() + i);
	}
}

View *GetFocusedView() {
	return focusedView;
}

void SetFocusedView(View *view) {
	if (focusedView) {
		focusedView->FocusChanged(FF_LOSTFOCUS);
	}
	focusedView = view;
	if (focusedView) {
		focusedView->FocusChanged(FF_GOTFOCUS);
	}
}

void EnableFocusMovement(bool enable) {
	focusMovementEnabled = enable;
	if (!enable)
		focusedView = 0;
}

bool IsFocusMovementEnabled() {
	return focusMovementEnabled;
}

void MeasureBySpec(Size sz, float contentWidth, MeasureSpec spec, float *measured) {
	*measured = sz;
	if (sz == WRAP_CONTENT) {
		if (spec.type == UNSPECIFIED || spec.type == AT_MOST)
			*measured = contentWidth;
		else if (spec.type == EXACTLY)
			*measured = spec.size;
	} else if (sz == FILL_PARENT)	{
		if (spec.type == UNSPECIFIED)
			*measured = contentWidth;  // We have no value to set
		else
			*measured = spec.size;
	} else if (spec.type == EXACTLY || (spec.type == AT_MOST && *measured > spec.size)) {
		*measured = spec.size;
	}
}

void Event::Add(std::function<EventReturn(EventParams&)> func) {
	HandlerRegistration reg;
	reg.func = func;
	handlers_.push_back(reg);
}

// Call this from input thread or whatever, it doesn't matter
void Event::Trigger(EventParams &e) {
	EventTriggered(this, e);	
}

// Call this from UI thread
EventReturn Event::Dispatch(EventParams &e) {
	bool eventHandled = false;
	for (auto iter = handlers_.begin(); iter != handlers_.end(); ++iter) {
		if ((iter->func)(e) == UI::EVENT_DONE) {
			// Event is handled, stop looping immediately. This event might even have gotten deleted.
			return UI::EVENT_DONE;
		}
	}
	return UI::EVENT_SKIPPED;
}

View::~View() {
	if (HasFocus())
		SetFocusedView(0);
	RemoveQueuedEvents(this);
}

void View::Measure(const UIContext &dc, MeasureSpec horiz, MeasureSpec vert) {
	float contentW = 0.0f, contentH = 0.0f;
	GetContentDimensions(dc, contentW, contentH);
	MeasureBySpec(layoutParams_->width, contentW, horiz, &measuredWidth_);
	MeasureBySpec(layoutParams_->height, contentH, vert, &measuredHeight_);
}

// Default values

void View::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	w = 10.0f;
	h = 10.0f;
}

Point View::GetFocusPosition(FocusDirection dir) {
	// The +2/-2 is some extra fudge factor to cover for views sitting right next to each other.
	// Distance zero yields strange results otherwise.
	switch (dir) {
	case FOCUS_LEFT: return Point(bounds_.x + 2, bounds_.centerY());
	case FOCUS_RIGHT: return Point(bounds_.x2() - 2, bounds_.centerY());
	case FOCUS_UP: return Point(bounds_.centerX(), bounds_.y + 2);
	case FOCUS_DOWN: return Point(bounds_.centerX(), bounds_.y2() - 2);

	default:
		return bounds_.Center();
	}
}


void Clickable::Click() {
	UI::EventParams e;
	e.v = this;
	OnClick.Trigger(e);
};

void Clickable::FocusChanged(int focusFlags) {
	if (focusFlags & FF_LOSTFOCUS) {
		down_ = false;
		dragging_ = false;
	}
}

void Clickable::Touch(const TouchInput &input) {
	if (!enabled_) {
		dragging_ = false;
		down_ = false;
		return;
	}

	if (input.flags & TOUCH_DOWN) {
		if (bounds_.Contains(input.x, input.y)) {
			if (IsFocusMovementEnabled())
				SetFocusedView(this);
			dragging_ = true;
			down_ = true;
		} else {
			down_ = false;
			dragging_ = false;
		}
	} else if (input.flags & TOUCH_MOVE) {
		if (dragging_)
			down_ = bounds_.Contains(input.x, input.y);
	}
	if (input.flags & TOUCH_UP) {
		if ((input.flags & TOUCH_CANCEL) == 0 && dragging_ && bounds_.Contains(input.x, input.y)) {
			Click();
		}
		down_ = false;
		downCountDown_ = 0;
		dragging_ = false;
	}
}

// TODO: O/X confirm preference for xperia play?

bool IsAcceptKeyCode(int keyCode) {
	return std::find(confirmKeys.begin(), confirmKeys.end(), (keycode_t)keyCode) != confirmKeys.end();
}

bool IsEscapeKeyCode(int keyCode) {
	return std::find(cancelKeys.begin(), cancelKeys.end(), (keycode_t)keyCode) != cancelKeys.end();
}

void Clickable::Key(const KeyInput &key) {
	if (!HasFocus() && key.deviceId != DEVICE_ID_MOUSE) {
		down_ = false;
		return;
	}
	// TODO: Replace most of Update with this.
	if (key.flags & KEY_DOWN) {
		if (IsAcceptKeyCode(key.keyCode)) {
			down_ = true;
		}
	}
	if (key.flags & KEY_UP) {
		if (IsAcceptKeyCode(key.keyCode)) {
			if (down_) {
				Click();
				down_ = false;
			}
		} else if (IsEscapeKeyCode(key.keyCode)) {
			down_ = false;
		}
	}
}

void StickyChoice::Touch(const TouchInput &input) {
	dragging_ = false;
	if (!enabled_) {
		down_ = false;
		return;
	}

	if (input.flags & TOUCH_DOWN) {
		if (bounds_.Contains(input.x, input.y)) {
			if (IsFocusMovementEnabled())
				SetFocusedView(this);
			down_ = true;
			Click();
		}
	}
}

void StickyChoice::Key(const KeyInput &key) {
	if (!HasFocus()) {
		return;
	}

	// TODO: Replace most of Update with this.
	if (key.flags & KEY_DOWN) {
		if (IsAcceptKeyCode(key.keyCode)) {
			down_ = true;
			Click();
		}
	}
}

void StickyChoice::FocusChanged(int focusFlags) {
	// Override Clickable's FocusChanged to do nothing.
}

Item::Item(LayoutParams *layoutParams) : InertView(layoutParams) {
	layoutParams_->width = FILL_PARENT;
	layoutParams_->height = ITEM_HEIGHT;
}

void Item::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	w = 0.0f;
	h = 0.0f;
}

void ClickableItem::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	w = 0.0f;
	h = 0.0f;
}

ClickableItem::ClickableItem(LayoutParams *layoutParams) : Clickable(layoutParams) {
	if (layoutParams_->width == WRAP_CONTENT)
		layoutParams_->width = FILL_PARENT;
	layoutParams_->height = ITEM_HEIGHT;
}

void ClickableItem::Draw(UIContext &dc) {
	Style style =	dc.theme->itemStyle;

	if (HasFocus()) {
		style = dc.theme->itemFocusedStyle;
	}
	if (down_) {
		style = dc.theme->itemDownStyle;
	}

	dc.FillRect(style.background, bounds_);
}

void Choice::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	if (atlasImage_ != -1) {
		const AtlasImage &img = dc.Draw()->GetAtlas()->images[atlasImage_];
		w = img.w;
		h = img.h;
	} else {
		dc.MeasureText(dc.theme->uiFont, text_.c_str(), &w, &h);
	}
	w += 24;
	h += 16;
}

void Choice::HighlightChanged(bool highlighted){
	highlighted_ = highlighted;
}

void Choice::Draw(UIContext &dc) {
	if (!IsSticky()) {
		ClickableItem::Draw(dc);
	} else {
		Style style =	dc.theme->itemStyle;
		if (highlighted_) {
			style = dc.theme->itemHighlightedStyle;
		}
		if (down_) {
			style = dc.theme->itemDownStyle;
		}
		if (HasFocus()) {
			style = dc.theme->itemFocusedStyle;
		}
		dc.FillRect(style.background, bounds_);
	}

	Style style = dc.theme->itemStyle;
	if (!IsEnabled())
		style = dc.theme->itemDisabledStyle;

	if (atlasImage_ != -1) {
		dc.Draw()->DrawImage(atlasImage_, bounds_.centerX(), bounds_.centerY(), 1.0f, style.fgColor, ALIGN_CENTER);
	} else {
		int paddingX = 12;
		dc.SetFontStyle(dc.theme->uiFont);
		if (centered_) {
			dc.DrawText(text_.c_str(), bounds_.centerX(), bounds_.centerY(), style.fgColor, ALIGN_CENTER);
		} else {
			dc.DrawText(text_.c_str(), bounds_.x + paddingX, bounds_.centerY(), style.fgColor, ALIGN_VCENTER);
		}
	}

	if (selected_) {
		dc.Draw()->DrawImage(dc.theme->checkOn, bounds_.x2() - 40, bounds_.centerY(), 1.0f, style.fgColor, ALIGN_CENTER);
	}
}

void InfoItem::Draw(UIContext &dc) {
	Item::Draw(dc);
	int paddingX = 12;
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(text_.c_str(), bounds_.x + paddingX, bounds_.centerY(), 0xFFFFFFFF, ALIGN_VCENTER);
	dc.DrawText(rightText_.c_str(), bounds_.x2() - paddingX, bounds_.centerY(), 0xFFFFFFFF, ALIGN_VCENTER | ALIGN_RIGHT);
// 	dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y, bounds_.x2(), bounds_.y + 2, dc.theme->itemDownStyle.bgColor);
}

ItemHeader::ItemHeader(const std::string &text, LayoutParams *layoutParams)
	: Item(layoutParams), text_(text) {
		layoutParams_->width = FILL_PARENT;
		layoutParams_->height = 40;
}

void ItemHeader::Draw(UIContext &dc) {
	dc.SetFontStyle(dc.theme->uiFontSmall);
	dc.DrawText(text_.c_str(), bounds_.x + 4, bounds_.centerY(), 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER);
	dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), 0xFFFFFFFF);
}

void PopupHeader::Draw(UIContext &dc) {
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(text_.c_str(), bounds_.x + 12, bounds_.centerY(), dc.theme->popupTitle.fgColor, ALIGN_LEFT | ALIGN_VCENTER);
	dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y2()-2, bounds_.x2(), bounds_.y2(), dc.theme->popupTitle.fgColor);
}

EventReturn CheckBox::OnClicked(EventParams &e) {
	if (toggle_)
		*toggle_ = !(*toggle_);
	return EVENT_CONTINUE;  // It's safe to keep processing events.
}

void CheckBox::Draw(UIContext &dc) {
	ClickableItem::Draw(dc);
	int paddingX = 12;
	int paddingY = 8;

	int image = *toggle_ ? dc.theme->checkOn : dc.theme->checkOff;

	Style style = dc.theme->itemStyle;
	if (!IsEnabled())
		style = dc.theme->itemDisabledStyle;

	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(text_.c_str(), bounds_.x + paddingX, bounds_.centerY(), style.fgColor, ALIGN_VCENTER);
	dc.Draw()->DrawImage(image, bounds_.x2() - paddingX, bounds_.centerY(), 1.0f, style.fgColor, ALIGN_RIGHT | ALIGN_VCENTER);
}

void Button::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	dc.MeasureText(dc.theme->uiFont, text_.c_str(), &w, &h);
}

void Button::Draw(UIContext &dc) {
	Style style = dc.theme->buttonStyle;

	if (HasFocus()) style = dc.theme->buttonFocusedStyle;
	if (down_) style = dc.theme->buttonDownStyle;
	if (!enabled_) style = dc.theme->buttonDisabledStyle;
	
	// dc.Draw()->DrawImage4Grid(style.image, bounds_.x, bounds_.y, bounds_.x2(), bounds_.y2(), style.bgColor);
	dc.FillRect(style.background, bounds_);
	float tw, th;
	dc.MeasureText(dc.theme->uiFont, text_.c_str(), &tw, &th);
	if (tw > bounds_.w) {
		dc.PushScissor(bounds_);
	}
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(text_.c_str(), bounds_.centerX(), bounds_.centerY(), style.fgColor, ALIGN_CENTER);
	if (tw > bounds_.w) {
		dc.PopScissor();
	}
}

void ImageView::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	const AtlasImage &img = dc.Draw()->GetAtlas()->images[atlasImage_];
	// TODO: involve sizemode
	w = img.w;
	h = img.h;
}

void ImageView::Draw(UIContext &dc) {
	const AtlasImage &img = dc.Draw()->GetAtlas()->images[atlasImage_];
	// TODO: involve sizemode
	float scale = bounds_.w / img.w;
	dc.Draw()->DrawImage(atlasImage_, bounds_.x, bounds_.y, scale, 0xFFFFFFFF, ALIGN_TOPLEFT);
}

void TextureView::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	// TODO: involve sizemode
	if (texture_) {
		w = (float)texture_->Width();
		h = (float)texture_->Height();
	} else {
		w = 16;
		h = 16;
	}
}

void TextureView::Draw(UIContext &dc) {
	// TODO: involve sizemode
	if (texture_) {
		dc.Flush();
		texture_->Bind(0);
		dc.Draw()->Rect(bounds_.x, bounds_.y, bounds_.w, bounds_.h, color_);
		dc.Flush();
		dc.RebindTexture();
	}
}

void TextView::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	dc.MeasureText(small_ ? dc.theme->uiFontSmall : dc.theme->uiFont, text_.c_str(), &w, &h);
}

void TextView::Draw(UIContext &dc) {
	dc.SetFontStyle(small_ ? dc.theme->uiFontSmall : dc.theme->uiFont);
	dc.DrawTextRect(text_.c_str(), bounds_, 0xFFFFFFFF, textAlign_);
}

void ProgressBar::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	dc.MeasureText(dc.theme->uiFont, "  100%  ", &w, &h);
}

void ProgressBar::Draw(UIContext &dc) {
	char temp[32];
	sprintf(temp, "%i%%", (int)(progress_ * 100.0f));
	dc.Draw()->DrawImageStretch(dc.theme->whiteImage, bounds_.x, bounds_.y, bounds_.x + bounds_.w * progress_, bounds_.y2(), 0xc0c0c0c0);
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawTextRect(temp, bounds_, 0xFFFFFFFF, ALIGN_CENTER);
}

void TriggerButton::Touch(const TouchInput &input) {
	if (input.flags & TOUCH_DOWN) {
		if (bounds_.Contains(input.x, input.y)) {
			down_ |= 1 << input.id;
		}
	}
	if (input.flags & TOUCH_MOVE) {
		if (bounds_.Contains(input.x, input.y))
			down_ |= 1 << input.id;
		else
			down_ &= ~(1 << input.id);
	}

	if (input.flags & TOUCH_UP) {
		down_ &= ~(1 << input.id);
	}

	if (down_ != 0) {
		*bitField_ |= bit_;
	} else {
		*bitField_ &= ~bit_;
	}
}

void TriggerButton::Draw(UIContext &dc) {
	dc.Draw()->DrawImage(imageBackground_, bounds_.centerX(), bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER);
	dc.Draw()->DrawImage(imageForeground_, bounds_.centerX(), bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER);
}

void TriggerButton::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	const AtlasImage &image = dc.Draw()->GetAtlas()->images[imageBackground_];
	w = image.w;
	h = image.h;
}

void Slider::Key(const KeyInput &input) {
	if (HasFocus() && input.flags & KEY_DOWN) {
		switch (input.keyCode) {
		case NKCODE_DPAD_LEFT:
		case NKCODE_MINUS:
		case NKCODE_NUMPAD_SUBTRACT:
			*value_ -= 1;
			break;
		case NKCODE_DPAD_RIGHT:
		case NKCODE_PLUS:
		case NKCODE_NUMPAD_ADD:
			*value_ += 1;
			break;
		}
		Clamp();
	}
}

void Slider::Touch(const TouchInput &input) {
	if (dragging_ || bounds_.Contains(input.x, input.y)) {
		float relativeX = (input.x - (bounds_.x + paddingLeft_)) / (bounds_.w - paddingLeft_ - paddingRight_);
		*value_ = floorf(relativeX * (maxValue_ - minValue_) + minValue_ + 0.5f);
		Clamp();
	}
}

void Slider::Clamp() {
	if (*value_ < minValue_) *value_ = minValue_;
	else if (*value_ > maxValue_) *value_ = maxValue_;
}

void Slider::Draw(UIContext &dc) {
	bool focus = HasFocus();
	float knobX = ((float)(*value_) - minValue_) / (maxValue_ - minValue_) * (bounds_.w - paddingLeft_ - paddingRight_) + (bounds_.x + paddingLeft_);
	dc.FillRect(Drawable(focus ? dc.theme->popupTitle.fgColor : 0xFFFFFFFF), Bounds(bounds_.x + paddingLeft_, bounds_.centerY() - 2, knobX - (bounds_.x + paddingLeft_), 4));
	dc.FillRect(Drawable(0xFF808080), Bounds(knobX, bounds_.centerY() - 2, (bounds_.x + bounds_.w - paddingRight_ - knobX), 4));
	dc.Draw()->DrawImage(dc.theme->sliderKnob, knobX, bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER);
	char temp[64];
	if (showPercent_)
		sprintf(temp, "%i%%", *value_);
	else
		sprintf(temp, "%i", *value_);
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(temp, bounds_.x2() - 22, bounds_.centerY(), 0xFFFFFFFF, ALIGN_CENTER);
}

void Slider::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	// TODO
	w = 100;
	h = 50;
}

void SliderFloat::Key(const KeyInput &input) {
	if (HasFocus() && input.flags & KEY_DOWN) {
		switch (input.keyCode) {
		case NKCODE_DPAD_LEFT:
		case NKCODE_MINUS:
		case NKCODE_NUMPAD_SUBTRACT:
			*value_ -= (maxValue_ - minValue_) / 20.0f;
			break;
		case NKCODE_DPAD_RIGHT:
		case NKCODE_PLUS:
		case NKCODE_NUMPAD_ADD:
			*value_ += (maxValue_ - minValue_) / 20.0f;
			break;
		}
		Clamp();
	}
}

void SliderFloat::Touch(const TouchInput &input) {
	if (dragging_ || bounds_.Contains(input.x, input.y)) {
		float relativeX = (input.x - (bounds_.x + paddingLeft_)) / (bounds_.w - paddingLeft_ - paddingRight_);
		*value_ = (relativeX * (maxValue_ - minValue_) + minValue_);
		Clamp();
	}
}

void SliderFloat::Clamp() {
	if (*value_ < minValue_) *value_ = minValue_;
	else if (*value_ > maxValue_) *value_ = maxValue_;
}

void SliderFloat::Draw(UIContext &dc) {
	bool focus = HasFocus();
	float knobX = (*value_ - minValue_) / (maxValue_ - minValue_) * (bounds_.w - paddingLeft_ - paddingRight_) + (bounds_.x + paddingLeft_);
	dc.FillRect(Drawable(focus ? dc.theme->popupTitle.fgColor : 0xFFFFFFFF), Bounds(bounds_.x + paddingLeft_, bounds_.centerY() - 2, knobX - (bounds_.x + paddingLeft_), 4));
	dc.FillRect(Drawable(0xFF808080), Bounds(knobX, bounds_.centerY() - 2, (bounds_.x + bounds_.w - paddingRight_ - knobX), 4));
	dc.Draw()->DrawImage(dc.theme->sliderKnob, knobX, bounds_.centerY(), 1.0f, 0xFFFFFFFF, ALIGN_CENTER);
	char temp[64];
	sprintf(temp, "%0.2f", *value_);
	dc.SetFontStyle(dc.theme->uiFont);
	dc.DrawText(temp, bounds_.x2() - 22, bounds_.centerY(), 0xFFFFFFFF, ALIGN_CENTER);
}

void SliderFloat::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
	// TODO
	w = 100;
	h = 50;
}


/*
TabStrip::TabStrip()
	: selected_(0) {
}

void TabStrip::Touch(const TouchInput &touch) {
	int tabw = bounds_.w / tabs_.size();
	int h = 20;
	if (touch.flags & TOUCH_DOWN) {
		for (int i = 0; i < MAX_POINTERS; i++) {
			if (UIRegionHit(i, bounds_.x, bounds_.y, bounds_.w, h, 8)) {
				selected_ = (touch.x - bounds_.x) / tabw;
			}
		}
		if (selected_ < 0) selected_ = 0;
		if (selected_ >= (int)tabs_.size()) selected_ = (int)tabs_.size() - 1;
	}
}

void TabStrip::Draw(DrawContext &dc) {
	int tabw = bounds_.w / tabs_.size();
	int h = 20;
	for (int i = 0; i < numTabs; i++) {
		dc.draw->DrawImageStretch(WHITE, x + 1, y + 2, x + tabw - 1, y + h, 0xFF202020);
		dc.draw->DrawText(font, tabs_[i].title.c_str(), x + tabw/2, y + h/2, 0xFFFFFFFF, ALIGN_VCENTER | ALIGN_HCENTER);
		if (selected_ == i) {
			float tw, th;
			ui_draw2d.MeasureText(font, names[i], &tw, &th);
			// TODO: better image
			ui_draw2d.DrawImageStretch(WHITE, x + 1, y + h - 6, x + tabw - 1, y + h, tabColors ? tabColors[i] : 0xFFFFFFFF);
		} else {
			ui_draw2d.DrawImageStretch(WHITE, x + 1, y + h - 1, x + tabw - 1, y + h, tabColors ? tabColors[i] : 0xFFFFFFFF);
		}
		x += tabw;
	}
}*/

void Fill(UIContext &dc, const Bounds &bounds, const Drawable &drawable) {
	if (drawable.type == DRAW_SOLID_COLOR) {
		
	}
}

}  // namespace
Beispiel #23
0
event_context::~event_context()
{
	assert(event_contexts.empty() == false);
	event_contexts.pop_back();
}
Beispiel #24
0
void RemoveQueuedEvents(View *v) {
	for (size_t i = 0; i < g_dispatchQueue.size(); i++) {
		if (g_dispatchQueue[i].params.v == v)
			g_dispatchQueue.erase(g_dispatchQueue.begin() + i);
	}
}
Beispiel #25
0
void pump()
{
	if(boost::this_thread::get_id() != main_thread) {
		// Can only call this on the main thread!
		return;
	}
	SDL_PumpEvents();
	peek_for_resize();
	pump_info info;

	//used to keep track of double click events
	static int last_mouse_down = -1;
	static int last_click_x = -1, last_click_y = -1;

	SDL_Event temp_event;
	int poll_count = 0;
	int begin_ignoring = 0;
	std::vector< SDL_Event > events;
	while(SDL_PollEvent(&temp_event)) {
		++poll_count;
		peek_for_resize();

		if(!begin_ignoring && temp_event.type == SDL_WINDOWEVENT
				&& (temp_event.window.event == SDL_WINDOWEVENT_ENTER
						|| temp_event.window.event == SDL_WINDOWEVENT_FOCUS_GAINED))
		{
			begin_ignoring = poll_count;
		} else if(begin_ignoring > 0 && is_input(temp_event)) {
			//ignore user input events that occurred after the window was activated
			continue;
		}
		events.push_back(temp_event);
	}

	std::vector<SDL_Event>::iterator ev_it = events.begin();
	for(int i=1; i < begin_ignoring; ++i){
		if(is_input(*ev_it)) {
			//ignore user input events that occurred before the window was activated
			ev_it = events.erase(ev_it);
		} else {
			++ev_it;
		}
	}

	std::vector<SDL_Event>::iterator ev_end = events.end();
	bool resize_found = false;
	for(ev_it = events.begin(); ev_it != ev_end; ++ev_it){
		SDL_Event &event = *ev_it;
		if (event.type == SDL_WINDOWEVENT &&
				event.window.event == SDL_WINDOWEVENT_RESIZED) {
			resize_found = true;
			last_resize_event = event;
			last_resize_event_used = false;

		}
	}
	// remove all inputs, draw events and only keep the last of the resize events
	// This will turn horrible after ~38 days when the Uint32 wraps.
	if (resize_found || SDL_GetTicks() <= last_resize_event.window.timestamp + resize_timeout) {
		events.erase(std::remove_if(events.begin(), events.end(), remove_on_resize), events.end());
	} else if(SDL_GetTicks() > last_resize_event.window.timestamp + resize_timeout && !last_resize_event_used) {
		events.insert(events.begin(), last_resize_event);
		last_resize_event_used = true;
	}

	ev_end = events.end();

	for(ev_it = events.begin(); ev_it != ev_end; ++ev_it){
		for (context& c : event_contexts)
		{
			c.add_staging_handlers();
		}

		SDL_Event &event = *ev_it;
		switch(event.type) {

			case SDL_WINDOWEVENT:
				switch(event.window.event) {
					case SDL_WINDOWEVENT_ENTER:
					case SDL_WINDOWEVENT_FOCUS_GAINED:
						cursor::set_focus(1);
						break;

					case SDL_WINDOWEVENT_LEAVE:
					case SDL_WINDOWEVENT_FOCUS_LOST:
						cursor::set_focus(1);
						break;

					case SDL_WINDOWEVENT_RESIZED:
						info.resize_dimensions.first = event.window.data1;
						info.resize_dimensions.second = event.window.data2;
						break;
				}
				//make sure this runs in it's own scope.
				{
					flip_locker flip_lock(CVideo::get_singleton());
					for( std::deque<context>::iterator i = event_contexts.begin() ; i != event_contexts.end(); ++i) {
						const handler_list& event_handlers = (*i).handlers;
						for(auto handler : event_handlers) {
							handler->handle_window_event(event);
						}
					}
					const handler_list& event_handlers = event_contexts.front().handlers;
					for(auto handler : event_handlers) {
						handler->handle_window_event(event);
					}
				}

				//This event was just distributed, don't re-distribute.
				continue;

			case SDL_MOUSEMOTION: {
				//always make sure a cursor is displayed if the
				//mouse moves or if the user clicks
				cursor::set_focus(true);
				raise_help_string_event(event.motion.x,event.motion.y);
				break;
			}

			case SDL_MOUSEBUTTONDOWN: {
				//always make sure a cursor is displayed if the
				//mouse moves or if the user clicks
				cursor::set_focus(true);
				if(event.button.button == SDL_BUTTON_LEFT) {
					static const int DoubleClickTime = 500;
					static const int DoubleClickMaxMove = 3;
					if(last_mouse_down >= 0 && info.ticks() - last_mouse_down < DoubleClickTime &&
					   abs(event.button.x - last_click_x) < DoubleClickMaxMove &&
					   abs(event.button.y - last_click_y) < DoubleClickMaxMove) {
						SDL_UserEvent user_event;
						user_event.type = DOUBLE_CLICK_EVENT;
						user_event.code = 0;
						user_event.data1 = reinterpret_cast<void*>(event.button.x);
						user_event.data2 = reinterpret_cast<void*>(event.button.y);
						::SDL_PushEvent(reinterpret_cast<SDL_Event*>(&user_event));
					}
					last_mouse_down = info.ticks();
					last_click_x = event.button.x;
					last_click_y = event.button.y;
				}
				break;
			}
			case DRAW_ALL_EVENT:
			{
				flip_locker flip_lock(CVideo::get_singleton());
				/* iterate backwards as the most recent things will be at the top */
				for( std::deque<context>::iterator i = event_contexts.begin() ; i != event_contexts.end(); ++i) {
					handler_list& event_handlers = (*i).handlers;
					for( handler_list::iterator i1 = event_handlers.begin(); i1 != event_handlers.end(); ++i1) {
						(*i1)->handle_event(event);
					}
				}
				continue; //do not do further handling here
			}

#ifndef __APPLE__
			case SDL_KEYDOWN: {
				if(event.key.keysym.sym == SDLK_F4 && (event.key.keysym.mod == KMOD_RALT || event.key.keysym.mod == KMOD_LALT)) {
					quit_confirmation::quit_to_desktop();
					continue; // this event is already handled
				}
				break;
			}
#endif

#if defined(_X11) && !defined(__APPLE__)
			case SDL_SYSWMEVENT: {
				//clipboard support for X11
				desktop::clipboard::handle_system_event(event);
				break;
			}
#endif

#if defined _WIN32
			case SDL_SYSWMEVENT: {
				windows_tray_notification::handle_system_event(event);
				break;
			}
#endif

			case SDL_QUIT: {
				quit_confirmation::quit_to_desktop();
				continue; //this event is already handled.
			}
		}

		const handler_list& event_handlers = event_contexts.front().handlers;
		for(auto handler : event_handlers) {
			handler->handle_event(event);
		}

		if(event_contexts.empty() == false) {

			const handler_list& event_handlers = event_contexts.back().handlers;

			//events may cause more event handlers to be added and/or removed,
			//so we must use indexes instead of iterators here.
			for(auto handler : event_handlers) {
				handler->handle_event(event);
			}
		}

	}

	//inform the pump monitors that an events::pump() has occurred
	for(size_t i1 = 0, i2 = pump_monitors.size(); i1 != i2 && i1 < pump_monitors.size(); ++i1) {
		pump_monitors[i1]->process(info);
	}
}
Beispiel #26
0
static bool has_lookahead(void) { return !lookahead_list.empty(); }
Beispiel #27
0
namespace libtorrent
{
	struct async_t
	{
		async_t() : refs(0) {}
		std::string stack;
		int refs;
	};

	// defined in session_impl.cpp
	extern std::map<std::string, async_t> _async_ops;
	extern int _async_ops_nthreads;
	extern mutex _async_ops_mutex;

	// timestamp -> operation
	struct wakeup_t
	{
		time_point timestamp;
		boost::uint64_t context_switches;
		char const* operation;
	};
	extern std::deque<wakeup_t> _wakeups;

	inline bool has_outstanding_async(char const* name)
	{
		mutex::scoped_lock l(_async_ops_mutex);
		std::map<std::string, async_t>::iterator i = _async_ops.find(name);
		return i != _async_ops.end();
	}

	inline void add_outstanding_async(char const* name)
	{
		mutex::scoped_lock l(_async_ops_mutex);
		async_t& a = _async_ops[name];
		if (a.stack.empty())
		{
			char stack_text[10000];
			print_backtrace(stack_text, sizeof(stack_text), 9);

			// skip the stack frame of 'add_outstanding_async'
			char* ptr = strchr(stack_text, '\n');
			if (ptr != NULL) ++ptr;
			else ptr = stack_text;
			a.stack = ptr;
		}
		++a.refs;
	}

	inline void complete_async(char const* name)
	{
		mutex::scoped_lock l(_async_ops_mutex);
		async_t& a = _async_ops[name];
		TORRENT_ASSERT(a.refs > 0);
		--a.refs;

		// don't let this grow indefinitely
		if (_wakeups.size() < 100000)
		{
			_wakeups.push_back(wakeup_t());
			wakeup_t& w = _wakeups.back();
			w.timestamp = clock_type::now();
#ifdef __MACH__
			task_events_info teinfo;
			mach_msg_type_number_t t_info_count = task_events_info_count;
			task_info(mach_task_self(), TASK_EVENTS_INFO,
				reinterpret_cast<task_info_t>(&teinfo), &t_info_count);
			w.context_switches = teinfo.csw;
#else
			w.context_switches = 0;
#endif
			w.operation = name;
		}
	}

	inline void async_inc_threads()
	{
		mutex::scoped_lock l(_async_ops_mutex);
		++_async_ops_nthreads;
	}

	inline void async_dec_threads()
	{
		mutex::scoped_lock l(_async_ops_mutex);
		--_async_ops_nthreads;
	}

	inline int log_async()
	{
		mutex::scoped_lock l(_async_ops_mutex);
		int ret = 0;
		for (std::map<std::string, async_t>::iterator i = _async_ops.begin()
			, end(_async_ops.end()); i != end; ++i)
		{
			if (i->second.refs <= _async_ops_nthreads - 1) continue;
			ret += i->second.refs;
			printf("%s: (%d)\n%s\n", i->first.c_str(), i->second.refs, i->second.stack.c_str());
		}
		return ret;
	}
}
Beispiel #28
0
static wint_t lookahead_pop(void) {
    wint_t result = lookahead_list.front();
    lookahead_list.pop_front();
    return result;
}
void cHpiSubProviderReset::GetEntries( std::deque<HpiEntry>& entries ) const
{
    entries.clear();
}
Beispiel #30
0
static void	load_bot(std::deque<AObject*> &map, std::vector<int> &m_vector)
{
   map.push_back(new Monster(m_vector[POSX], m_vector[POSY], (e_type)m_vector[TYPE]));
}