In this article, we'll investigate the fundamentals of C++
programming for the BREW platform. This time out, you'll learn the fundamental
structure of a BREW C++ application and discover the subset of C++ features that
can be used while developing for BREW. We'll also design a basic C++ drawing
application and code its foundation. This foundation will serve as the basis for
exploring BREW user-interface design issues in future articles.
I assume you've read the Getting Started
articles. If not, they can be found here.
C++ Basics for BREW
Figure 1 - Click here for
larger image
Figure 1 shows the header file containing the skeletal definition
of the application class (ShapeApp
) for our drawing program. The
first thing you're likely to notice is that ShapeApp
is derived
from AEEApplet
. In aeeappgen.h
,
AEEApplet
is a typedef
for a struct
. Thus, via public inheritance and the default
visibility of struct
members in C++, all of AEEApplet's members can
be accessed directly from any ShapeApp member function.
Next, you can see that the ShapeApp
class definition
includes 2 versions for each of the event handling function, the data
initialization function, and the data freeing function. All of the public
versions are declared static
while the protected
versions are instance methods. The static versions provide
ShapeApp
's interface to the Application Execution Environment
(AEE). As shown in Figure 3, each of these static versions exist only to call
the corresponding instance method. In this way, the application class acquires a
this
pointer that can be used to implicitly access members of ShapeApp
, including the members of the inherited
AEEApplet struct
.
Figure 2 - Click here for larger
image
As shown in Figure 2, AEEClsCreateInstance()
must be
enclosed by an extern "C"
linkage block. Note that the static
versions of both the event handler and freeAppData()
are specified
in the call to AEEApplet_New()
. Subsequently, the static data
initializer is called. Apart from these minor differences,
AEEClsCreateInstance()
is identical to that specified for HelloBREW
in the previous article.
Figure 3 contains the remainder of the ShapeApp
implementation
file. As you can see, the file does nothing but set up the framework for our
drawing program. Later, we'll create event handling code and generally flesh out
this skeleton. Before we can do that, however, we need to understand the
limitations imposed on our use of standard C++ for coding BREW applications.
Figure 3 - Click here for larger image
You can use C++, BUT...
Understandably, the minimalists among you may have gasped at the sight of our
static event handler calling the member event handler. Clearly, the cost of the
extra function call is incurred every time the AEE dispatches an event to
ShapeApp
. At runtime then, this overhead might be incurred many
thousands of times before the application is terminated. If speed is of the
essence for your application, you might consider handling every event in the
static event handler. The efficiency gain might far outweigh the convenience of
having a this
pointer to work with, especially since only one
instance of the application can be running at any given time. If, for example,
you make ShapeApp
a struct
, a this
pointer becomes unnecessary since ShapeApp *pi
can be used to
access the members of the one and only application instance.
On the topic of efficiency, as defined in the standard, certain elements of
the C++ language contribute substantial amounts of overhead, even if they are
not used in a program (see this article). In an embedded environment where memory is scarce,
an application may not be able to afford these costs.
To address this issue, a Japanese consortium has hammered out the Embedded C++ (EC++)
specification. EC++ is a proper subset of standard C++ intended to meet the
needs of the embedded development community. Essentially, EC++ is standard C++
without multiple inheritance, virtual base classes, templates, exception
handling, run-time type identification, the mutable
specifier,
namespaces, and new-style casts. Modern ARM C++ compilers support the EC++
dialect. Thus, if you restrict yourself to EC++, you should have no trouble
compiling an application to run on a handset.
The Program Design
Figure
4
Figure 4 includes a simple UML (Unified Modeling Language) class diagram. For
the sake of anyone unfamiliar with the notation, the diagram shows that
ShapeApp
"is a" AEEApplet
that "has a"
List
as a data member. This List
is composed of a
number of Shape
s (pointers to Shape
s actually, since
Shape
is an abstract base class (ABC) that cannot have concrete
instances). Each Shape
"has a" Color
and every
concrete Shape
must implement the pure virtual draw()
function. Circle
s and Rectangle
s are possible concrete
Shape
s. Every Circle
has a Point
instance
for its center and each Rectangle
is specified by two
Point
instances: its upper left corner (ulc) and its lower right
corner (lrc). The intent of this example is to demonstrate that EC++ supports
polymorphism (I've verified this by building the source code with ARM Developer
Suite v1.2 and testing the executable on the Sharp Z800 handset). Admittedly,
this design won't be winning any awards for code reusability.
The complete source code for this example can be obtained via the link
included at the bottom of this article. The only part that I want to cover in
detail in the remainder of this article is the drawing code that renders shapes
on the device's display. This functionality resides in the List
and
concrete shape classes, namely Circle
and
Rectangle
.
Drawing Shapes
Figure 5 - Click here for larger image
In BREW, a color is stored in an RGBVAL
, which is a
typedef
name for a 32-bit unsigned integer. The Color
class has an RGBVAL
as its sole data member. The class also
provides public member functions for accessing the individual components of an
RGBVAL; namely uint8 getr()
, uint8 getg()
, and
uint8 getb()
. These functions merely slice off the requested value
by bit shifting the RGBVAL
according to the layout given by Figure
5. Note that the RGBVAL diagram shown on page 736 of the SDK 1.0 API Reference
is incorrect. The diagram has been corrected in the SDK 2.0 Reference though I
have not checked the SDK 1.1 API Reference.
Recall from the discussion of Figure 4 above that the application class,
ShapeApp
, maintains a List
instance that tracks
Shape
pointers. As shown in Figure 6 below, the list class includes
a public update()
instance method that is called from the
application's event handler whenever a drawing event occurs. This
update()
method receives the application's IShell *
so
that an instance of the IGraphics
interface can be created through
a call to ISHELL_CreateInstance()
. Please see the BREW API
Reference for a description of the various IGraphics
API functions
used throughout CList::Update()
.
Figure 6 - Click here for larger image
In Figure 6, within the body of the while()
, you need to know
that CNode
is a struct
nested within the
CList
class's private
visibility section. Further, the
data part of a node consists of a CShape *
named dat
.
Thus, the expression pn->dat->getClr()->getr()
returns the
red component of the current CShape
's CColor
instance.
Still within the body of the loop, the expression
pn->dat->draw(pg)
polymorphically calls the draw function
pertaining to the current, concrete shape instance. Thus, a rectangle draws
itself by using the passed in IGraphics *
to call
IGRAPHICS_DrawRect()
and a circle similarly draws itself by calling
IGRAPHICS_DrawCircle()
. Note that the calls to the
IGraphics
color setting functions are contained within the body of
the loop in order to capture the fact that each shape can have a different
color.
Running ShapeApp
Figure 7
So far, this applet does not require any
string or image resources, beyond the application icons included within the
.mif, so a BREW Applet Resource (.bar) file is unnecessary. If you've forgotten
the details about creating a module information file (.mif), which is required
for every applet, please review the Getting Started articles which can
be found here. Note
that I've included a .mif with the source code. Running the application on the
emulator should result in the display looking as shown in the rightmost portion
of Figure 7, above.
Next time, we'll begin enabling user-interaction with
ShapeApp by experimenting with various user interface designs.
Download source: Shapes.zip
(11KB)
Instructions: (Assumes you have read the Getting Started
articles.)
- Use the BREW Application Wizard to create a new project named 'shapeapp'
under your BREW directory's 'Examples' directory.
- Delete the shapeapp.c file the wizard created for you.
- Unzip the source files to the shapeapp directory (include the
.bid file).
- Use VC++'s file view to add the .h and .cpp files to the project.
- Copy the provided .mif file to your MIF directory.
- Build the application and run it using the emulator.
# # #
© Copyright 2002, Golden Creek Software Inc.
<!--content_stop-->
相关推荐
从头开始涵盖Java语言以及AWT,包括线程,布局管理器,异常,事件处理,数据结构,输入和输出等。
Whey as a Brewing Material. II. Influence of Galactose on Fermentation by Brewery Yeasts
tl; dr: 出 。背景在拥有酿的州(大约每70平方英里有1个啤酒厂), 生产的被认为是最好的啤酒。 根据Troon专门为他们酿造的协议,它们很可能是与共享的最小的财产之一,而BFT不购买的任何东西都可用于现场零售。...
四度_www Fourtitude Brewing Co. 网站
ftc_brewing []需要postgresql-postgres:// localhost / brew []需要.env / SECRET ='cookie的任何秘密'/ DATABASE_URL ='postgres:// localhost / brew' []需要将数据库设置为本地时间 部署 []需要将部署设置为...
挑战 我们需要创建6个区域,可以理解为配送中心(以可交付周的6天为基准),并确保我们在每个区域中行驶的距离最小,不超过均衡停站等配送日限制卷。 换句话说,这些区域应该在“卡车”中具有相同数量的商店和相同的...
BrewNIX 是多种 *nix 的酿造软件,但急需帮助。 与其为一些昂贵的 Windows 平台程序付费,不如加入这个开源替代方案的开发。
吉德蒙网 本自述文件概述了与此Ember应用程序进行协作的细节。 此应用程序的简短介绍可以轻松地转到此处。 先决条件 您需要在计算机上正确安装以下物品。 (带有NPM) 安装 安装Git 安装Node.js ...
Raspberry Pi支持的Brewing软件 该自述文件也提供 主要特征 在Raspberry Pi( )上运行 免费的,可付诸实施的开源许可证(MIT) 易于设置(一根衬管) 简单:一个传感器,一个继电器 PD控制器可与简单且便宜的非...
Docker setup out-of-the-box brewing Ubuntu installation the standard platform Debian installation install caffe with a single command OS X installation RHEL / CentOS / Fedora installation Windows...
欢迎来到更好的酿造 目的 更好的酿造是啤酒自制者通过帮助他们跟踪其食谱,酿造和品尝笔记来改善其Craft.io的地方。 用 ... 登录后,您可以从可以导出BeerXML的任何配方软件上载自己的配方(大多数配方软件),也可以...
酿造立场 用Elixir编写的Minecraft Classic服务器。 Minecraft Classic的玩具服务器,作为Elixir的学习体验。 不要对此抱有太大期望,尽管将来可能会包括插件的可扩展性。 去做 一切(稍后将填写)
酿造盐 自动确定酿造用水的盐添加量。 这是一个基于网络的工具,用于确定向酿造水中添加哪些矿物质以实现特定的目标水分布。 它目前正在进行中。 除了粗略的用户界面,它不会尝试模拟最大溶解度(尤其是与粉笔相关...
该软件包包含许多啤酒、葡萄酒等酿造商可能会发现有用的功能。 那些使用折光仪来估计比重、糖和酒精含量并创建许多可打印图表以帮助他们使用的人特别感兴趣。 这是基于 Beerlib.c,由 Domenick Venezia 编写。...
酿造盐计算器该工具用于计算酿造水的最佳矿物质添加量。 很难计算出盐的添加量,因为酿造水的轮廓需要平衡6种不同的离子(钙,镁,钠,硫酸根,氯离子和碳酸氢根)。 困难在于啤酒酿造者可能添加到水中的每种矿物质...
BILL(酿造在线分类帐) 注意:“内联”部分仅用于填写首字母缩略词。 欢迎提出改进建议(或可能的含义)。 BILL 是一种酿造分类账,可帮助您计算或跟踪酿造啤酒所需的价值。 它的灵感来自命令行财务账本程序,...
咖啡酿造伙伴 Web应用程序,用于跟踪咖啡冲泡 该项目是通过引导的。 可用脚本 在项目目录中,可以运行: yarn start 在开发模式下运行应用程序。 打开在浏览器中查看它。 如果您进行编辑,则页面将重新加载。...
OpenBrews:采用Ionic框架构建的一个brewing app支持iOS和Android
On the technology side, a volatile mix of acronyms like SOA Service Oriented Architecture, SaaS Software as a Service and Web2.0 is brewing that is drastically changing our view on the role and value...
In fact, this new world is awesome—the coffee’s brewing, and the aroma of fresh-baked danishes makes this new world a place you want to wake up to. JavaScript is better than ever—it’s time to ...