Tech/LxEngine/FAQ

When should data be specified via an Element's value rather than an attribute?
This is a good and fairly fundamental question that relates to all uses of XML, but has some particular nuances as it relates to LxEngine. There's an obvious vagueness to this definition, but...

The value should be used for data that is "essential" to the definition of the object whereas attributes are for "optional, non-essential, or add-on" behavior.

For example, in defining a  element, the "center" and "radius" might be essential to the sphere being at all usable; however, the "material" might be best left as an attribute as the system likely could still render the sphere using a default or fallback material. Again, this is obviously a loose definition: the application could easily define a default "center" or "radius" as well.


 * An exception to this rule might be when there is an precedent in HTML: for example, the "src" attribute being used to reference an external file. This may be essential to the element definition, but by following the HTML convention is made an attribute, not part of the value. --Arthur 20:48, 15 July 2011 (CDT)

Why aren't Linux and gcc supported?
The short answer is time.

Support for is being added first, but it is the eventual goal for LxEngine to be fully cross-platform.

Any contributions in this area would be most appreciated.

Why can't you support Visual Studio 2008?
LxEngine makes extensive use of lambda functions, std::shared_ptr, and other C++11 features. Rewriting code using this functionality to be compatible with VS 2008 would be time-consuming and distract from the project objectives.

There are currently no plans to eventually make LxEngine compatible with older compilers as changes such as removal of lambda functions would have a drastic effect on the maintainability of the code base. (Sorry!)

Is clang or LLVM supported?
I'd love it to be the default compiler, but it just hasn't made the list of priorities quite yet!

Aren't std::shared_ptrs<> inefficient?
The short answer is yes, they are. They are larger and slower than a custom reference counting mechanism that embeds the ref-count in the object (i.e. Boost's intrusive pointer) and are certainly more overhead than raw pointers.

The justification for the use of std::shared_ptr<> through LxEngine is therefore:
 * 1) std::shared_ptr<> is a standard.  The design philosophy of LxEngine is to use standards whenever it does not prevent other goals from being reached.  This allows new developers to learn LxEngine more quickly and keeps the code reusable.
 * 2) std::shared_ptr<> is not used in bottleneck areas.  For example, the  is small enough and does have usage characteristics that std::shared_ptr<> was deemed to have an unexpectable amount of overhead - therefore, within it's implementation it is using an intrusive pointer scheme; however, as this is part of the implementation, not the interface, most developers will never have to worry about this.

I don't like exceptions. Why does LxEngine use them?
This was a design decision that was made after considerable deliberation. No exceptions would be simpler in some regards (which is good), but exceptions provide some benefits (which is also good).

In short, the major argument against using C++ exceptions seemed to be that many programmers misuse C++ exceptions. That is a valid reason to avoid them, as a design objective of LxEngine is to have it be extremely stable and ease to use, even for new programmers - i.e. easy to use correctly, difficult to use incorrectly.

However, exceptions do serve a purpose and are a useful language feature. For LxEngine, they solve the 'return value problem' of how to distinguish valid return values from error conditions. If error conditions are rare and unexpected, then use an exception to indicate the errors and thus reserve the return value to cover only valid conditions. Exceptions allows all more structured clean-up and detail gathering from an error as the error moves up the call stack.

Aren't string-based events inefficient and not type safe?
Yes...but everything is a trade-off.

There are consequent advantages to the inefficiency of using strings and to the lack of type safety. LxEngine strives to allow high degrees of reuse and loose coupling in its components. The lack of type safety and use of arbitrarily named string events allows this. The compiler doesn't need to know in advance about every possible enumeration of event.

Note: a future revision of LxEngine may use a global string to ID mapping if the efficiency of string look-ups turns out to be a real bottleneck.

Why does LxEngine use such deep nesting of namespaces but then include them all in the namespace lx0?

 * Ability to import only a portion of the LxEngine functionality (i.e. "using namespace lx0::subsystem::shaderbulder_ns"), yet still access everything via a concise namespace (i.e. "lx0")

Why is X so slow???
I'm really not sure.

Post about it on the forums and we'll see if we can get write up a benchmark and improve the performance for you.