void arrow_primitive::set_value(const std::string& key, const variant& value) { if(key == "points") { set_points(value); } else if(key == "color") { color_ = graphics::color(value); } else if(key == "granularity") { granularity_ = value.as_decimal().as_float(); } else if(key == "arrow_head_length") { arrow_head_length_ = value.as_int(); } else if(key == "arrow_head_width") { arrow_head_width_ = value.as_decimal().as_float(); } else if(key == "fade_in_length") { fade_in_length_ = value.as_int(); } else if(key == "width_base") { width_base_ = value.as_decimal().as_float(); } else if(key == "width_head") { width_head_ = value.as_decimal().as_float(); } else { ASSERT_LOG(false, "ILLEGAL KEY IN ARROW: " << key); } varray_.clear(); carray_.clear(); }
void slider::set_value(const std::string& key, const variant& v) { if(key == "position") { position_ = v.as_decimal().as_float(); } widget::set_value(key, v); }
variant variant::operator/(const variant& v) const { if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) { int denominator = v.as_decimal(); if(denominator == 0) { throw type_error((formatter() << "divide by zero error").str()); } long long long_int = as_decimal(); long_int *= 10000; long_int /= denominator; if( long_int%10 >= 5) { long_int /= 10; ++long_int; } else long_int/=10; return variant( static_cast<int>(long_int) , variant::DECIMAL_VARIANT); } const int numerator = as_int(); const int denominator = v.as_int(); if(denominator == 0) { throw type_error((formatter() << "divide by zero error").str());; } return variant(numerator/denominator); }
bool variant::operator==(const variant& v) const { if(type_ != v.type_) { if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) { return as_decimal() == v.as_decimal(); } return false; } switch(type_) { case TYPE_NULL: { return v.is_null(); } case TYPE_STRING: { return string_->str == v.string_->str; } case TYPE_INT: { return int_value_ == v.int_value_; } case TYPE_DECIMAL: { return decimal_value_ == v.decimal_value_; } case TYPE_LIST: { if(num_elements() != v.num_elements()) { return false; } for(size_t n = 0; n != num_elements(); ++n) { if((*this)[n] != v[n]) { return false; } } return true; } case TYPE_MAP: { return map_->elements == v.map_->elements; } case TYPE_CALLABLE_LOADING: { return false; } case TYPE_CALLABLE: { return callable_->equals(v.callable_); } case TYPE_FUNCTION: { return fn_ == v.fn_; } } assert(false); return false; }
variant variant::operator*(const variant& v) const { if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) { return variant(as_decimal() * v.as_decimal()); } if(type_ == TYPE_LIST) { int ncopies = v.as_int(); if(ncopies < 0) { ncopies *= -1; } const std::vector<variant>& items = list_->elements; std::vector<variant> res; res.reserve(items.size()*ncopies); for(int n = 0; n != ncopies; ++n) { for(int m = 0; m != items.size(); ++m) { res.push_back(items[m]); } } return variant(&res); } return variant(as_int() * v.as_int()); }
void bar_widget::set_value(const std::string& key, const variant& value) { if(key == "segments") { segments_ = value.as_int(); ASSERT_GE(segments_, 0); init(); } else if(key == "segment_length") { segment_length_ = value.as_int(); ASSERT_GT(segment_length_, 0); init(); } else if(key == "tick_width") { tick_width_ = value.as_int(); ASSERT_GT(tick_width_, 0); init(); } else if(key == "scale") { scale_ = value.as_decimal().as_float(); ASSERT_GT(scale_, 0.0f); init(); } else if(key == "drain_rate") { drain_rate_ = value.as_decimal().as_float(); ASSERT_GE(drain_rate_, 0.0); } else if(key == "drained") { int drain = value.as_int(); if(drain == drained_segments_) { return; } int animation_start_position = segments_-drained_segments_; animation_current_position_ = 0; drained_segments_after_anim_ = drain; if(drained_segments_after_anim_ < 0) { drained_segments_after_anim_ = 0; } if(drained_segments_after_anim_ > segments_) { drained_segments_after_anim_ = segments_; } int animation_end_position = segments_-drained_segments_after_anim_; animation_end_point_unscaled_ = animation_end_position - animation_start_position; animating_ = true; init(); } else if(key == "max_width") { bar_max_width_ = value.as_int(); init(); } else if(key == "animation_position") { animation_current_position_ = value.as_decimal().as_float(); } widget::set_value(key, value); }
variant variant::operator-(const variant& v) const { if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) { return variant( as_decimal() - v.as_decimal() , DECIMAL_VARIANT); } return variant(as_int() - v.as_int()); }
variant variant::operator/(const variant& v) const { if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) { if(v.as_decimal().value() == 0) { throw type_error((formatter() << "divide by zero error").str()); } return variant(as_decimal() / v.as_decimal()); } const int numerator = as_int(); const int denominator = v.as_int(); if(denominator == 0) { throw type_error(formatter() << "divide by zero error"); } return variant(numerator/denominator); }
bool variant::operator<=(const variant& v) const { if(type_ != v.type_) { if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) { return as_decimal() <= v.as_decimal(); } return type_ < v.type_; } switch(type_) { case TYPE_NULL: { return true; } case TYPE_STRING: { return string_->str <= v.string_->str; } case TYPE_INT: { return int_value_ <= v.int_value_; } case TYPE_DECIMAL: { return decimal_value_ <= v.decimal_value_; } case TYPE_LIST: { for(size_t n = 0; n != num_elements() && n != v.num_elements(); ++n) { if((*this)[n] < v[n]) { return true; } else if((*this)[n] > v[n]) { return false; } } return num_elements() <= v.num_elements(); } case TYPE_MAP: { return map_->elements <= v.map_->elements; } case TYPE_CALLABLE_LOADING: { return false; } case TYPE_CALLABLE: { return !v.callable_->less(callable_); } } assert(false); return false; }
void luaW_pushfaivariant(lua_State* L, variant val) { if(val.is_int()) { lua_pushinteger(L, val.as_int()); } else if(val.is_decimal()) { lua_pushnumber(L, val.as_decimal() / 1000.0); } else if(val.is_string()) { const std::string result_string = val.as_string(); lua_pushlstring(L, result_string.c_str(), result_string.size()); } else if(val.is_list()) { lua_newtable(L); for(const variant& v : val.as_list()) { lua_pushinteger(L, lua_rawlen(L, -1) + 1); luaW_pushfaivariant(L, v); lua_settable(L, -3); } } else if(val.is_map()) { typedef std::map<variant,variant>::value_type kv_type; lua_newtable(L); for(const kv_type& v : val.as_map()) { luaW_pushfaivariant(L, v.first); luaW_pushfaivariant(L, v.second); lua_settable(L, -3); } } else if(val.is_callable()) { // First try a few special cases if(unit_callable* u_ref = val.try_convert<unit_callable>()) { const unit& u = u_ref->get_unit(); unit_map::iterator un_it = resources::gameboard->units().find(u.get_location()); if(&*un_it == &u) { luaW_pushunit(L, u.underlying_id()); } else { luaW_pushunit(L, u.side(), u.underlying_id()); } } else if(location_callable* loc_ref = val.try_convert<location_callable>()) { luaW_pushlocation(L, loc_ref->loc()); } else { // If those fail, convert generically to a map const formula_callable* obj = val.as_callable(); std::vector<formula_input> inputs; obj->get_inputs(&inputs); lua_newtable(L); for(const formula_input& attr : inputs) { if(attr.access == FORMULA_WRITE_ONLY) { continue; } lua_pushstring(L, attr.name.c_str()); luaW_pushfaivariant(L, obj->query_value(attr.name)); lua_settable(L, -3); } } } else if(val.is_null()) { lua_pushnil(L); } }
variant variant::operator^(const variant& v) const { if( type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL ) { double res = pow( as_decimal().value()/double(VARIANT_DECIMAL_PRECISION), v.as_decimal().value()/double(VARIANT_DECIMAL_PRECISION)); res *= DECIMAL_PRECISION; #if defined(TARGET_BLACKBERRY) return variant(static_cast<int64_t>(llround(res)), DECIMAL_VARIANT); #else return variant(static_cast<int64_t>(res), DECIMAL_VARIANT); #endif } return variant(static_cast<int>(pow(static_cast<double>(as_int()), v.as_int()))); }
variant variant::operator^(const variant& v) const { if( type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL ) { double res = pow( as_decimal()/1000.0 , v.as_decimal()/1000.0 ); res *= 1000; int i = static_cast<int>( res ); res -= i; if( res > 0.5 ) i++; return variant( i , variant::DECIMAL_VARIANT); } return variant(static_cast<int>( round_portable(pow(static_cast<double>(as_int()), v.as_int())))); }
variant variant::operator*(const variant& v) const { if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) { long long long_int = as_decimal(); long_int *= v.as_decimal(); long_int /= 100; if( long_int%10 >= 5) { long_int /= 10; ++long_int; } else long_int/=10; return variant( static_cast<int>(long_int) , variant::DECIMAL_VARIANT ); } return variant(as_int() * v.as_int()); }
variant variant::operator+(const variant& v) const { if(type_ == TYPE_LIST) { if(v.type_ == TYPE_LIST) { std::vector<variant> res; res.reserve(list_->elements.size() + v.list_->elements.size()); for(size_t i = 0; i<list_->elements.size(); ++i) { const variant& var = list_->elements[i]; res.push_back(var); } for(size_t j = 0; j<v.list_->elements.size(); ++j) { const variant& var = v.list_->elements[j]; res.push_back(var); } return variant(&res); } } if(type_ == TYPE_MAP) { if(v.type_ == TYPE_MAP) { std::map<variant,variant> res(map_->elements); for(std::map<variant,variant>::const_iterator i = v.map_->elements.begin(); i != v.map_->elements.end(); ++i) { res[i->first] = i->second; } return variant(&res); } } if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) { return variant( as_decimal() + v.as_decimal() , DECIMAL_VARIANT); } return variant(as_int() + v.as_int()); }
variant variant::operator+(const variant& v) const { if(type_ == TYPE_INT && v.type_ == TYPE_INT) { //strictly an optimization -- this is handled below, but the case //of adding two integers is the most common so we want it to be fast. return variant(int_value_ + v.int_value_); } if(type_ == TYPE_STRING) { if(v.type_ == TYPE_MAP) { return variant(as_string() + v.as_string()); } else if(v.type_ == TYPE_STRING) { return variant(as_string() + v.as_string()); } std::string s; v.serialize_to_string(s); return variant(as_string() + s); } if(v.type_ == TYPE_STRING) { std::string s; serialize_to_string(s); return variant(s + v.as_string()); } if(type_ == TYPE_DECIMAL || v.type_ == TYPE_DECIMAL) { return variant(as_decimal() + v.as_decimal()); } if(type_ == TYPE_INT) { return variant(int_value_ + v.as_int()); } if(type_ == TYPE_NULL) { return v; } else if(v.type_ == TYPE_NULL) { return *this; } if(type_ == TYPE_LIST) { if(v.type_ == TYPE_LIST) { std::vector<variant> res; res.reserve(list_->elements.size() + v.list_->elements.size()); for(size_t i = 0; i<list_->elements.size(); ++i) { const variant& var = list_->elements[i]; res.push_back(var); } for(size_t j = 0; j<v.list_->elements.size(); ++j) { const variant& var = v.list_->elements[j]; res.push_back(var); } return variant(&res); } } if(type_ == TYPE_MAP) { if(v.type_ == TYPE_MAP) { std::map<variant,variant> res(map_->elements); for(std::map<variant,variant>::const_iterator i = v.map_->elements.begin(); i != v.map_->elements.end(); ++i) { res[i->first] = i->second; } return variant(&res); } } return variant(as_int() + v.as_int()); }