386 lines
8.1 KiB
Twig
386 lines
8.1 KiB
Twig
|
|
{% macro decl_units(meta) %}
|
|
|
|
{%- for u in meta.getunits ~%}
|
|
{%- if u.object is instanceof('\\mtgMetaStruct') -%}
|
|
{{ _self.decl_struct(u.object) }}
|
|
{%- elseif u.object is instanceof('\\mtgMetaEnum') -%}
|
|
{{ _self.decl_enum(u.object) }}
|
|
{%- endif ~%}
|
|
{%- endfor ~%}
|
|
|
|
{% endmacro %}
|
|
|
|
{% macro decl_struct(o) %}
|
|
|
|
class {{o.name}} {{o.parent ? 'extends ' ~ o.parent.name}}
|
|
{
|
|
const CLASS_ID = {{o.classid}};
|
|
{{ _self.struct_fields(o) }}
|
|
|
|
static function CLASS_PROPS()
|
|
{
|
|
static $props = {{o.tokens|var_export}};
|
|
return $props;
|
|
}
|
|
|
|
static function CLASS_FIELDS()
|
|
{
|
|
static $flds = null;
|
|
if($flds === null)
|
|
$flds = {{_self.fields_names(o)}};
|
|
return $flds;
|
|
}
|
|
|
|
static function CLASS_FIELDS_TYPES()
|
|
{
|
|
static $flds = null;
|
|
if($flds === null)
|
|
$flds = {{_self.fields_types(o)}};
|
|
return $flds;
|
|
}
|
|
|
|
static function CLASS_FIELDS_PROPS()
|
|
{
|
|
static $flds = null;
|
|
if($flds === null)
|
|
$flds = {{_self.fields_props(o)}};
|
|
return $flds;
|
|
}
|
|
|
|
function __construct(&$data = null, $assoc = false)
|
|
{
|
|
{{_self.fields_init(o)}}
|
|
|
|
if(!is_null($data))
|
|
$this->import($data, $assoc);
|
|
}
|
|
|
|
function getClassId()
|
|
{
|
|
return self::CLASS_ID;
|
|
}
|
|
|
|
function import(&$data, $assoc = false, $root = true)
|
|
{
|
|
$IDX = -1;
|
|
|
|
try
|
|
{
|
|
if(!is_array($data))
|
|
throw new Exception("Bad data: $data");
|
|
try
|
|
{
|
|
$IDX = 0;
|
|
{{_self.import_fields(o)}}
|
|
}
|
|
catch(Exception $e)
|
|
{
|
|
if($IDX > -1)
|
|
{
|
|
$FIELDS = self::CLASS_FIELDS();
|
|
throw new Exception($e->getMessage() . " < {$FIELDS[$IDX]}");
|
|
}
|
|
else
|
|
throw $e;
|
|
}
|
|
if($root && $assoc && sizeof($data) > 0)
|
|
throw new Exception("Junk fields: " . implode(',', array_keys($data)));
|
|
}
|
|
catch(Exception $e)
|
|
{
|
|
throw new Exception($e->getMessage() . " < ({{o.name}})");
|
|
}
|
|
return $IDX;
|
|
}
|
|
|
|
function export($assoc = false, $virtual = false)
|
|
{
|
|
$data = array();
|
|
$this->fill($data, $assoc, $virtual);
|
|
return $data;
|
|
}
|
|
|
|
function fill(&$data, $assoc = false, $virtual = false)
|
|
{
|
|
if($virtual)
|
|
\metagen_php\array_set_value($data, $assoc, 'vclass__', $this->getClassId());
|
|
try
|
|
{
|
|
$__last_var = null;
|
|
$__last_val = null;
|
|
|
|
{{_self.export_fields(o)}}
|
|
}
|
|
catch(Exception $e)
|
|
{
|
|
throw new Exception("[{{o.name}}]\n->$__last_var\n" . serialize($__last_val) . "\n\t" . $e->getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
{% endmacro %}
|
|
|
|
{% macro struct_fields(o) %}
|
|
{%- for f in o.fields ~%}
|
|
{{ _self.decl_struct_field(o, f) }}
|
|
{%- endfor -%}
|
|
{% endmacro %}
|
|
|
|
{% macro decl_struct_field(o, f) ~%}
|
|
/** @var {{f.type}}*/
|
|
{%- if f.type is instanceof('\\mtgBuiltinType') and f.type.isstring ~%}
|
|
public ${{f.name}} = '';
|
|
{%- elseif f.type is instanceof('\\mtgArrType') ~%}
|
|
public ${{f.name}} = [];
|
|
{%- else ~%}
|
|
public ${{f.name}};
|
|
{%- endif -%}
|
|
{% endmacro %}
|
|
|
|
{% macro fields_names(o) %}
|
|
{%- if o.parent -%}
|
|
array_merge(parent::CLASS_FIELDS(),
|
|
{%- endif -%}
|
|
|
|
[
|
|
{%- for f in o.fields -%}
|
|
'{{f.name}}' {{not loop.last ? ','}}
|
|
{%- endfor -%}
|
|
]
|
|
|
|
{%- if o.parent -%}
|
|
)
|
|
{%- endif -%}
|
|
|
|
{% endmacro %}
|
|
|
|
{% macro fields_types(o) %}
|
|
{%- if o.parent -%}
|
|
array_merge(parent::CLASS_FIELDS_TYPES(),
|
|
{%- endif -%}
|
|
|
|
[
|
|
{%- for f in o.fields -%}
|
|
'{{f.name}}' => '{{f.type}}' {{not loop.last ? ','}}
|
|
{%- endfor -%}
|
|
]
|
|
|
|
{%- if o.parent -%}
|
|
)
|
|
{%- endif -%}
|
|
|
|
{% endmacro %}
|
|
|
|
{% macro fields_props(o) %}
|
|
{%- if o.parent -%}
|
|
array_merge(parent::CLASS_FIELDS_PROPS(),
|
|
{%- endif -%}
|
|
|
|
[
|
|
{%- for f in o.fields -%}
|
|
'{{f.name}}' => {{f.tokens|var_export}} {{not loop.last ? ','}}
|
|
{%- endfor -%}
|
|
]
|
|
|
|
{%- if o.parent -%}
|
|
)
|
|
{%- endif -%}
|
|
|
|
{% endmacro %}
|
|
|
|
{% macro field_init_value(o, f) %}
|
|
{%- if f.type is instanceof('\\mtgMetaStruct') ~%}
|
|
|
|
{%- if has_token(f, 'default') and token(f, 'default') == 'null' -%}
|
|
null
|
|
{%- else -%}
|
|
new {{f.type}}()
|
|
{%- endif -%}
|
|
|
|
{%- elseif f.type is instanceof('\\mtgMetaEnum') ~%}
|
|
{%- if has_token(f, 'default') -%}
|
|
{{f.type}}::{{token(f, 'default')|replace({'"' : ''})|default_value}}
|
|
{%- else -%}
|
|
{{f.type}}::DEFAULT_VALUE
|
|
{%- endif -%}
|
|
{%- elseif f.type is instanceof('\\mtgArrType') ~%}
|
|
[]
|
|
{%- elseif f.type is instanceof('\\mtgBuiltinType') ~%}
|
|
{%- if has_token(f, 'default') -%}
|
|
\metagen_php\val_{{f.type}}({{apply_value_filters(f.name, f.tokens, token(f, 'default')|default_value, false)}})
|
|
{%- elseif f.type.isstring -%}
|
|
''
|
|
{%- else -%}
|
|
0
|
|
{%- endif -%}
|
|
{%- else -%}
|
|
{{Error("Uknown type: " ~ f.type)}}
|
|
{%- endif -%}
|
|
{% endmacro %}
|
|
|
|
{% macro field_init(o, f) %}
|
|
$this->{{f.name}} = {{_self.field_init_value(o, f)}};
|
|
{% endmacro %}
|
|
|
|
{% macro fields_init(o) %}
|
|
{%- if o.parent -%}
|
|
parent::__construct();
|
|
{%- endif -%}
|
|
{%- for f in o.fields ~%}
|
|
{{_self.field_init(o, f)}}
|
|
{%- endfor -%}
|
|
{% endmacro %}
|
|
|
|
{% macro import_fields(o) %}
|
|
{%- if o.parent -%}
|
|
$IDX = parent::import($data, $assoc, false);
|
|
{%- endif -%}
|
|
{%- for f in o.fields ~%}
|
|
{{data2value(f.name, f.type, '$data', '$this->', f.tokens)}}
|
|
++$IDX;
|
|
{%- endfor -%}
|
|
{% endmacro %}
|
|
|
|
{% macro export_fields(o) %}
|
|
{%- if o.parent -%}
|
|
$__last_var = 'parent';
|
|
$__last_val = '<<skipped>>';
|
|
parent::fill($data, $assoc, false);
|
|
{%- endif -%}
|
|
{%- for f in o.fields ~%}
|
|
{{value2data(f.name, f.type, '$data', '$this->', f.tokens)}}
|
|
{%- endfor -%}
|
|
{% endmacro %}
|
|
|
|
{% macro decl_enum(o) %}
|
|
|
|
class {{o.name}}
|
|
{
|
|
const CLASS_ID = {{o.classid}};
|
|
|
|
{{ _self.enum_values(o) }}
|
|
|
|
const DEFAULT_VALUE = {{o.values | first}};
|
|
|
|
function getClassId()
|
|
{
|
|
return self::CLASS_ID;
|
|
}
|
|
|
|
static function isValueValid($value)
|
|
{
|
|
$values_list = self::getValuesList();
|
|
return in_array($value, self::$values_list_);
|
|
}
|
|
|
|
static private $values_map_;
|
|
|
|
static function getValueByName($name)
|
|
{
|
|
if(!self::$values_map_)
|
|
{
|
|
self::$values_map_ = array(
|
|
{{ _self.enum_values_map(o) }}
|
|
);
|
|
}
|
|
|
|
if(!isset(self::$values_map_[$name]))
|
|
throw new Exception("Value with name '$name' isn't defined in enum {{o.name}}. Accepted: " . implode(',', self::getNamesList()));
|
|
|
|
return self::$values_map_[$name];
|
|
}
|
|
|
|
static private $names_map_;
|
|
|
|
static function getNameByValue($value)
|
|
{
|
|
if(!self::$names_map_)
|
|
{
|
|
self::$names_map_ = array(
|
|
{{ _self.enum_names_map(o) }}
|
|
);
|
|
}
|
|
|
|
if(!isset(self::$names_map_[$value]))
|
|
throw new Exception("Value $value isn't defined in enum {{o.name}}. Accepted: " . implode(',', self::getValuesList()));
|
|
|
|
return self::$names_map_[$value];
|
|
}
|
|
|
|
// throws exception if $value is not valid numeric enum value
|
|
static function checkValidity($value)
|
|
{
|
|
if(!is_numeric($value))
|
|
throw new Exception("Numeric expected but got $value");
|
|
|
|
if(!self::isValueValid($value))
|
|
throw new Exception("Numeric value '$value' isn't value from enum {{o.name}}. Accepted numerics are " . implode(',', self::getValuesList()) . " but better to use one of names instead: " . implode(',', self::getNamesList()));
|
|
}
|
|
|
|
static private $values_list_;
|
|
|
|
static function getValuesList()
|
|
{
|
|
if(!self::$values_list_)
|
|
{
|
|
self::$values_list_ = array(
|
|
{{ _self.enum_values_list(o) }}
|
|
);
|
|
}
|
|
return self::$values_list_;
|
|
}
|
|
|
|
static private $names_list_;
|
|
|
|
static function getNamesList()
|
|
{
|
|
if(!self::$names_list_)
|
|
{
|
|
self::$names_list_ = array(
|
|
{{ _self.enum_names_list(o) }}
|
|
);
|
|
}
|
|
return self::$names_list_;
|
|
}
|
|
}
|
|
{% endmacro %}
|
|
|
|
{% macro enum_values(o) %}
|
|
{%- for n,v in o.values ~%}
|
|
const {{n}} = {{v}};
|
|
{%- endfor ~%}
|
|
{% endmacro %}
|
|
|
|
{% macro enum_values_map(o) %}
|
|
{%- for n,v in o.values ~%}
|
|
'{{n}}' => {{v}},
|
|
{%- endfor ~%}
|
|
{% endmacro %}
|
|
|
|
{% macro enum_names_map(o) %}
|
|
{%- for n,v in o.values ~%}
|
|
{{v}} => '{{n}}',
|
|
{%- endfor ~%}
|
|
{% endmacro %}
|
|
|
|
{% macro enum_values_list(o) %}
|
|
{%- for v in o.values ~%}
|
|
{{v}},
|
|
{%- endfor ~%}
|
|
{% endmacro %}
|
|
|
|
{% macro enum_names_list(o) %}
|
|
{%- for n,v in o.values ~%}
|
|
'{{n}}',
|
|
{%- endfor ~%}
|
|
{% endmacro %}
|
|
|
|
{% macro class_map(meta) %}
|
|
|
|
{%- for u in meta.getunits ~%}
|
|
case {{u.object.classid}} : return "{{u.object.name}}";
|
|
{%- endfor ~%}
|
|
|
|
{% endmacro %}
|