/**
 * \brief Initialize the item.
 */
void ptb::bonus_all_dead_by_category::build()
{
  super::build();

  set_condition
    ( bear::expr::boolean_function_maker
      ( this,
        std::mem_fun_ref( &ptb::bonus_all_dead_by_category::check_all_dead )));
} // bonus_all_dead_by_category::build()
Ejemplo n.º 2
0
/**
 * \brief Set the expression used for the condition.
 * \param e The expression.
 */
void bear::engine::with_trigger::do_set_expression
( const expr::boolean_expression& e )
{
  set_condition(e);
} // with_trigger::do_set_expression()
Ejemplo n.º 3
0
StateMachineState *
StateMachineBifurcate::optimise(SMScopes *scopes, const AllowableOptimisations &opt, bool *done_something)
{
	if (current_optimisation_gen == last_optimisation_gen)
		return this;
	last_optimisation_gen = current_optimisation_gen;

	if (trueTarget == falseTarget) {
		*done_something = true;
		return trueTarget;
	}

	*done_something |= set_condition(simplifyBDD(&scopes->bools, condition, opt));
	if (condition->isLeaf()) {
		*done_something = true;
		if (condition->leaf())
			return trueTarget->optimise(scopes, opt, done_something);
		else
			return falseTarget->optimise(scopes, opt, done_something);
	}
	trueTarget = trueTarget->optimise(scopes, opt, done_something);
	falseTarget = falseTarget->optimise(scopes, opt, done_something);

	if (trueTarget->type == StateMachineState::Terminal &&
	    falseTarget->type == StateMachineState::Terminal) {
		*done_something = true;
		smrbdd *n = 
			smrbdd::ifelse(
				&scopes->smrs,
				condition,
				((StateMachineTerminal *)trueTarget)->res,
				((StateMachineTerminal *)falseTarget)->res);
		return new StateMachineTerminal(dbg_origin, n);
	}

	if (opt.ignoreUnreached()) {
		if (trueTarget->type == StateMachineState::Terminal &&
		    ((StateMachineTerminal *)trueTarget)->res->isLeaf() &&
		    ((StateMachineTerminal *)trueTarget)->res->leaf() == smr_unreached) {
			*done_something = true;
			return falseTarget;
		}
		if (falseTarget->type == StateMachineState::Terminal &&
		    ((StateMachineTerminal *)falseTarget)->res->isLeaf() &&
		    ((StateMachineTerminal *)falseTarget)->res->leaf() == smr_unreached) {
			*done_something = true;
			return trueTarget;
		}
	}

#if TRACK_FRAMES
	if (trueTarget->type == StateMachineState::SideEffecting &&
	    falseTarget->type == StateMachineState::SideEffecting &&
	    ((StateMachineSideEffecting *)trueTarget)->sideEffect ==
		((StateMachineSideEffecting *)falseTarget)->sideEffect &&
	    ((StateMachineSideEffecting *)trueTarget)->sideEffect &&
	    ((StateMachineSideEffecting *)trueTarget)->sideEffect->type == StateMachineSideEffect::StackLayout) {
		*done_something = true;
		return new StateMachineSideEffecting(
			trueTarget->dbg_origin,
			((StateMachineSideEffecting *)trueTarget)->sideEffect,
			new StateMachineBifurcate(
				dbg_origin,
				condition,
				((StateMachineSideEffecting *)trueTarget)->target,
				((StateMachineSideEffecting *)falseTarget)->target));
	}
#endif

	if (falseTarget->type == StateMachineState::Bifurcate) {
		StateMachineBifurcate *falseBifur = (StateMachineBifurcate *)falseTarget;
		if (falseTarget != falseBifur->falseTarget &&
		    trueTarget == falseBifur->trueTarget) {
			falseTarget = falseBifur->falseTarget;
			set_condition(bbdd::Or(&scopes->bools, condition, falseBifur->condition));
			*done_something = true;
			return this;
		}
		if (falseTarget != falseBifur->trueTarget &&
		    trueTarget == falseBifur->falseTarget) {
			falseTarget = falseBifur->trueTarget;
			set_condition(
				bbdd::Or(&scopes->bools,
					 condition,
					 bbdd::invert(&scopes->bools,
						      falseBifur->condition)));
			*done_something = true;
			return this;
		}
	}
	if (trueTarget->type == StateMachineState::Bifurcate) {
		StateMachineBifurcate *trueBifur = (StateMachineBifurcate *)trueTarget;
		if (trueTarget != trueBifur->trueTarget &&
		    falseTarget == trueBifur->falseTarget) {
			trueTarget = trueBifur->trueTarget;
			set_condition(
				bbdd::And(
					&scopes->bools,
					condition,
					trueBifur->condition));
			*done_something = true;
			return this;
		}
		if (trueTarget != trueBifur->falseTarget &&
		    falseTarget == trueBifur->trueTarget) {
			trueTarget = trueBifur->falseTarget;
			set_condition(
				bbdd::And(
					&scopes->bools,
					condition,
					bbdd::invert(
						&scopes->bools,
						trueBifur->condition)));
			*done_something = true;
			return this;
		}
	}

	return this;
}