mirror of
https://github.com/esphome/esphome.git
synced 2026-02-25 21:43:14 -07:00
dry
This commit is contained in:
@@ -16,7 +16,12 @@ from esphome.const import (
|
||||
CONF_UPDATE_INTERVAL,
|
||||
)
|
||||
from esphome.core import ID
|
||||
from esphome.cpp_generator import MockObj, MockObjClass, TemplateArgsType
|
||||
from esphome.cpp_generator import (
|
||||
LambdaExpression,
|
||||
MockObj,
|
||||
MockObjClass,
|
||||
TemplateArgsType,
|
||||
)
|
||||
from esphome.schema_extractors import SCHEMA_EXTRACT, schema_extractor
|
||||
from esphome.types import ConfigType
|
||||
from esphome.util import Registry
|
||||
@@ -102,25 +107,34 @@ StatelessLambdaCondition = cg.esphome_ns.class_("StatelessLambdaCondition", Cond
|
||||
ForCondition = cg.esphome_ns.class_("ForCondition", Condition, cg.Component)
|
||||
|
||||
|
||||
def use_stateless_lambda_if_applicable(id_obj, lambda_expr, stateless_class):
|
||||
"""Return appropriate ID for lambda based on whether it has capture.
|
||||
def new_lambda_pvariable(
|
||||
id_obj: ID,
|
||||
lambda_expr: LambdaExpression,
|
||||
stateless_class: MockObjClass,
|
||||
template_arg: cg.TemplateArguments | None = None,
|
||||
) -> MockObj:
|
||||
"""Create Pvariable for lambda, using stateless class if applicable.
|
||||
|
||||
For stateless lambdas (empty capture), returns a copy of id_obj with type
|
||||
set to stateless_class to use function pointer instead of std::function.
|
||||
Otherwise returns the original ID unchanged.
|
||||
Combines ID selection and Pvariable creation in one call. For stateless
|
||||
lambdas (empty capture), uses function pointer instead of std::function.
|
||||
|
||||
Args:
|
||||
id_obj: The ID object (action_id, condition_id, or filter_id)
|
||||
lambda_expr: The lambda expression object
|
||||
stateless_class: The stateless class to use (StatelessLambdaAction, StatelessLambdaCondition, or StatelessLambdaFilter)
|
||||
stateless_class: The stateless class to use for stateless lambdas
|
||||
template_arg: Optional template arguments (for actions/conditions)
|
||||
|
||||
Returns:
|
||||
ID to use with cg.new_Pvariable() - either original or modified copy
|
||||
The created Pvariable
|
||||
"""
|
||||
# For stateless lambdas, use function pointer instead of std::function
|
||||
if lambda_expr.capture == "":
|
||||
id_obj = id_obj.copy()
|
||||
id_obj.type = stateless_class
|
||||
return id_obj
|
||||
|
||||
if template_arg is not None:
|
||||
return cg.new_Pvariable(id_obj, template_arg, lambda_expr)
|
||||
return cg.new_Pvariable(id_obj, lambda_expr)
|
||||
|
||||
|
||||
def validate_automation(extra_schema=None, extra_validators=None, single=False):
|
||||
@@ -263,12 +277,8 @@ async def lambda_condition_to_code(
|
||||
args: TemplateArgsType,
|
||||
) -> MockObj:
|
||||
lambda_ = await cg.process_lambda(config, args, return_type=bool)
|
||||
return cg.new_Pvariable(
|
||||
use_stateless_lambda_if_applicable(
|
||||
condition_id, lambda_, StatelessLambdaCondition
|
||||
),
|
||||
template_arg,
|
||||
lambda_,
|
||||
return new_lambda_pvariable(
|
||||
condition_id, lambda_, StatelessLambdaCondition, template_arg
|
||||
)
|
||||
|
||||
|
||||
@@ -435,11 +445,7 @@ async def lambda_action_to_code(
|
||||
args: TemplateArgsType,
|
||||
) -> MockObj:
|
||||
lambda_ = await cg.process_lambda(config, args, return_type=cg.void)
|
||||
return cg.new_Pvariable(
|
||||
use_stateless_lambda_if_applicable(action_id, lambda_, StatelessLambdaAction),
|
||||
template_arg,
|
||||
lambda_,
|
||||
)
|
||||
return new_lambda_pvariable(action_id, lambda_, StatelessLambdaAction, template_arg)
|
||||
|
||||
|
||||
@register_action(
|
||||
|
||||
@@ -300,10 +300,7 @@ async def lambda_filter_to_code(config, filter_id):
|
||||
lambda_ = await cg.process_lambda(
|
||||
config, [(bool, "x")], return_type=cg.optional.template(bool)
|
||||
)
|
||||
filter_id = automation.use_stateless_lambda_if_applicable(
|
||||
filter_id, lambda_, StatelessLambdaFilter
|
||||
)
|
||||
return cg.new_Pvariable(filter_id, lambda_)
|
||||
return automation.new_lambda_pvariable(filter_id, lambda_, StatelessLambdaFilter)
|
||||
|
||||
|
||||
@register_filter(
|
||||
|
||||
@@ -430,12 +430,8 @@ async def logger_log_action_to_code(config, action_id, template_arg, args):
|
||||
text = str(cg.statement(esp_log(config[CONF_TAG], config[CONF_FORMAT], *args_)))
|
||||
|
||||
lambda_ = await cg.process_lambda(Lambda(text), args, return_type=cg.void)
|
||||
return cg.new_Pvariable(
|
||||
automation.use_stateless_lambda_if_applicable(
|
||||
action_id, lambda_, StatelessLambdaAction
|
||||
),
|
||||
template_arg,
|
||||
lambda_,
|
||||
return automation.new_lambda_pvariable(
|
||||
action_id, lambda_, StatelessLambdaAction, template_arg
|
||||
)
|
||||
|
||||
|
||||
@@ -461,12 +457,8 @@ async def logger_set_level_to_code(config, action_id, template_arg, args):
|
||||
text = str(cg.statement(logger.set_log_level(level)))
|
||||
|
||||
lambda_ = await cg.process_lambda(Lambda(text), args, return_type=cg.void)
|
||||
return cg.new_Pvariable(
|
||||
automation.use_stateless_lambda_if_applicable(
|
||||
action_id, lambda_, StatelessLambdaAction
|
||||
),
|
||||
template_arg,
|
||||
lambda_,
|
||||
return automation.new_lambda_pvariable(
|
||||
action_id, lambda_, StatelessLambdaAction, template_arg
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -574,10 +574,7 @@ async def lambda_filter_to_code(config, filter_id):
|
||||
lambda_ = await cg.process_lambda(
|
||||
config, [(float, "x")], return_type=cg.optional.template(float)
|
||||
)
|
||||
filter_id = automation.use_stateless_lambda_if_applicable(
|
||||
filter_id, lambda_, StatelessLambdaFilter
|
||||
)
|
||||
return cg.new_Pvariable(filter_id, lambda_)
|
||||
return automation.new_lambda_pvariable(filter_id, lambda_, StatelessLambdaFilter)
|
||||
|
||||
|
||||
DELTA_SCHEMA = cv.Schema(
|
||||
|
||||
@@ -71,10 +71,7 @@ async def lambda_filter_to_code(config, filter_id):
|
||||
lambda_ = await cg.process_lambda(
|
||||
config, [(cg.std_string, "x")], return_type=cg.optional.template(cg.std_string)
|
||||
)
|
||||
filter_id = automation.use_stateless_lambda_if_applicable(
|
||||
filter_id, lambda_, StatelessLambdaFilter
|
||||
)
|
||||
return cg.new_Pvariable(filter_id, lambda_)
|
||||
return automation.new_lambda_pvariable(filter_id, lambda_, StatelessLambdaFilter)
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register("to_upper", ToUpperFilter, {})
|
||||
|
||||
@@ -58,7 +58,7 @@ def test_text_config_value_mode_set(generate_main):
|
||||
|
||||
def test_text_config_lamda_is_set(generate_main):
|
||||
"""
|
||||
Test if lambda is set for lambda mode
|
||||
Test if lambda is set for lambda mode (optimized with stateless lambda)
|
||||
"""
|
||||
# Given
|
||||
|
||||
@@ -66,5 +66,5 @@ def test_text_config_lamda_is_set(generate_main):
|
||||
main_cpp = generate_main("tests/component_tests/text/test_text.yaml")
|
||||
|
||||
# Then
|
||||
assert "it_4->set_template([=]() -> esphome::optional<std::string> {" in main_cpp
|
||||
assert "it_4->set_template(+[]() -> esphome::optional<std::string> {" in main_cpp
|
||||
assert 'return std::string{"Hello"};' in main_cpp
|
||||
|
||||
Reference in New Issue
Block a user