filestoraging commit
|
|
@ -0,0 +1,21 @@
|
|||
# minesweeping
|
||||
### 1、项目说明
|
||||
总体思路:扫雷程序项目开发的总体思路如图1.1示意,拟实现交互界面与交互控制、数据结构和扫雷算法等。
|
||||
图1.1 项目开发的总体思路图
|
||||
<img src="figs/overall.png" width=80% /></center>
|
||||
|
||||
|
||||
### 2、开发环境说明
|
||||
(1)系统版本:OpenHarmony 4.0 Release
|
||||
(2)SDK版本:API 10
|
||||
(3)Model类型:Stage
|
||||
(4)DevEco Studio版本:Deveco Studio 4.0 release
|
||||
(5)硬件环境:Unionpi Whale、RK3566开发板
|
||||
(6)预览器参数:(1)DeviceType:default;(2)Resolution:560-1280;(3)DPI:240;其余参数自定。
|
||||
### 3、项目主要函数调用关系图与项目输出界面演进图
|
||||
图3.1 项目主要函数调用关系图
|
||||
<img src="figs/relation.png" width=80% /></center>
|
||||
|
||||
|
||||
图3.2 项目输出界面演进图
|
||||
<img src="figs/evolution.png" width=80% /></center>
|
||||
|
After Width: | Height: | Size: 610 KiB |
|
After Width: | Height: | Size: 320 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
|
@ -0,0 +1,11 @@
|
|||
/node_modules
|
||||
/oh_modules
|
||||
/local.properties
|
||||
/.idea
|
||||
**/build
|
||||
/.hvigor
|
||||
.cxx
|
||||
/.clangd
|
||||
/.clang-format
|
||||
/.clang-tidy
|
||||
**/.test
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"app": {
|
||||
"bundleName": "com.example.filereality",
|
||||
"vendor": "example",
|
||||
"versionCode": 1000000,
|
||||
"versionName": "1.0.0",
|
||||
"icon": "$media:app_icon",
|
||||
"label": "$string:app_name"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "app_name",
|
||||
"value": "FileReality"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"app": {
|
||||
"signingConfigs": [],
|
||||
"products": [
|
||||
{
|
||||
"name": "default",
|
||||
"signingConfig": "default",
|
||||
"compileSdkVersion": 10,
|
||||
"compatibleSdkVersion": 9,
|
||||
"runtimeOS": "OpenHarmony",
|
||||
}
|
||||
],
|
||||
"buildModeSet": [
|
||||
{
|
||||
"name": "debug",
|
||||
},
|
||||
{
|
||||
"name": "release"
|
||||
}
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "entry",
|
||||
"srcPath": "./entry",
|
||||
"targets": [
|
||||
{
|
||||
"name": "default",
|
||||
"applyToProducts": [
|
||||
"default"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
/node_modules
|
||||
/oh_modules
|
||||
/.preview
|
||||
/build
|
||||
/.cxx
|
||||
/.test
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"apiType": "stageMode",
|
||||
"buildOption": {
|
||||
"arkOptions": {
|
||||
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
|
||||
}
|
||||
},
|
||||
"buildOptionSet": [
|
||||
{
|
||||
"name": "release",
|
||||
"arkOptions": {
|
||||
"obfuscation": {
|
||||
"ruleOptions": {
|
||||
"enable": true,
|
||||
"files": [
|
||||
"./obfuscation-rules.txt"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
"targets": [
|
||||
{
|
||||
"name": "default"
|
||||
},
|
||||
{
|
||||
"name": "ohosTest",
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
|
||||
|
||||
export default {
|
||||
system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
||||
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Define project specific obfuscation rules here.
|
||||
# You can include the obfuscation configuration files in the current module's build-profile.json5.
|
||||
#
|
||||
# For more details, see
|
||||
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
|
||||
|
||||
# Obfuscation options:
|
||||
# -disable-obfuscation: disable all obfuscations
|
||||
# -enable-property-obfuscation: obfuscate the property names
|
||||
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
|
||||
# -compact: remove unnecessary blank spaces and all line feeds
|
||||
# -remove-log: remove all console.* statements
|
||||
# -print-namecache: print the name cache that contains the mapping from the old names to new names
|
||||
# -apply-namecache: reuse the given cache file
|
||||
|
||||
# Keep options:
|
||||
# -keep-property-name: specifies property names that you want to keep
|
||||
# -keep-global-name: specifies names that you want to keep in the global scope
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"license": "",
|
||||
"devDependencies": {},
|
||||
"author": "",
|
||||
"name": "entry",
|
||||
"description": "Please describe the basic information.",
|
||||
"main": "",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
//公共常量
|
||||
export const boardNum: number = 11 // 行列数
|
||||
export const gridSize: number = 19 // 格子大小
|
||||
export const blockSize: number = 17 // 方块大小
|
||||
|
||||
// 绘制Fat区域背景
|
||||
export const settings: RenderingContextSettings = new RenderingContextSettings(true)
|
||||
export const context: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings)
|
||||
|
||||
// 绘制Fat区域信息
|
||||
export const settings2: RenderingContextSettings = new RenderingContextSettings(true)
|
||||
export const context2: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings2)
|
||||
|
||||
// 绘制Disk区域背景
|
||||
export const settings3: RenderingContextSettings = new RenderingContextSettings(true)
|
||||
export const context3: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings3)
|
||||
|
||||
// 绘制Disk区域信息
|
||||
export const settings4: RenderingContextSettings = new RenderingContextSettings(true)
|
||||
export const context4: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings4)
|
||||
|
||||
// 绘制模拟区域信息
|
||||
export const settings5: RenderingContextSettings = new RenderingContextSettings(true)
|
||||
export const context5: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings5)
|
||||
|
||||
// 绘制文件夹区域信息
|
||||
export const settings6: RenderingContextSettings = new RenderingContextSettings(true);
|
||||
export const context6: CanvasRenderingContext2D = new CanvasRenderingContext2D(settings6);
|
||||
|
||||
export const img1:ImageBitmap = new ImageBitmap("/common/image/fk1.png")
|
||||
export const img2:ImageBitmap = new ImageBitmap("/common/image/fk2.png")
|
||||
export const img3:ImageBitmap = new ImageBitmap("/common/image/fk3.png")
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,744 @@
|
|||
import {initialize_simdisk,initialize_simfat,drawFatMessage,clearEmulation,draw_blocks,drawDiskText,clearFatMessage,clearBlock,clearDiskText,read_sim_fat,draw_blocks_emulation,
|
||||
draw_files,
|
||||
clearFiles
|
||||
} from '../utils/functions'
|
||||
|
||||
// 文件项的唯一集合
|
||||
let file_name_set: Set<string> = new Set()
|
||||
|
||||
// 文件标签的唯一集合
|
||||
let blocks_label_set: Set<string> = new Set()
|
||||
|
||||
// 获取唯一字母标签
|
||||
function get_unique_tag(): string | null {
|
||||
for (let ascii_code = 65; ascii_code <= 90; ascii_code++) {
|
||||
let character = String.fromCharCode(ascii_code)
|
||||
if (!blocks_label_set.has(character)) {
|
||||
blocks_label_set.add(character)
|
||||
return character
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function initialize_fileblock(block_num: string, code: string): string[] {
|
||||
let files: string[] = []
|
||||
for (let n = 0; n < parseInt(block_num); n++) {
|
||||
files.push(`${code}${n + 1}`)
|
||||
}
|
||||
if (code === "Z") {
|
||||
blocks_label_set.clear() // 确保blocks_label_set已经声明
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
export class InterfaceFile {
|
||||
messages: string[] // 系统消息队列
|
||||
sim_fat_copy: string[][] // 拷贝simFAT
|
||||
ex_disk_oc: boolean // 交替显示保存占用和添加占用标志
|
||||
ex_disk_la: boolean // 修改保存标签和清除标签的标志
|
||||
sim_disk_copy: string[][] // 拷贝simDisk
|
||||
block_modi_tag: boolean // 磁盘块修改标志
|
||||
block_modi_lb: string // 磁盘块标签值初始化
|
||||
old_key: number[] // FAT表上一次的记录值
|
||||
fat_modi_num: string // 打开下一个FAT单元格之前的修改数值
|
||||
fat_modi_tag: boolean // 修改状态标签,为True时进入修改状态
|
||||
clear_tag: boolean // 清除标签,让标签清理和fat清理操作互斥
|
||||
check: boolean // 检查磁盘条件
|
||||
code: string // 当前磁盘块标签字母
|
||||
creating: boolean // 正在创建的状态
|
||||
simFAT: string[][] // SimFAT 表初始化
|
||||
simDisk: string[][] // SimDisk 区域初始化
|
||||
folder_items: any[] // 文件项临时储存
|
||||
fat_unique_set: Set<string> // fat表去重集合,防止在一个位置建立多个磁盘块
|
||||
file_name_label: string // 输入文件名输入框
|
||||
blocks_num_label: string // 块数输入框
|
||||
path_name_label: string // 创建目录项输入框
|
||||
file_label:string[]
|
||||
fat_tags: string[][] // FAT删除标志
|
||||
fat_disks: string[][] // Disk方块删除标志
|
||||
label_disks: string[][] // Disk标签删除标志
|
||||
default: string // MessageDialog传参
|
||||
|
||||
constructor(len: number) {
|
||||
this. messages = []
|
||||
this.sim_fat_copy = null
|
||||
this.ex_disk_oc = true
|
||||
this.ex_disk_la = true
|
||||
this.sim_disk_copy = null
|
||||
this.block_modi_tag = false
|
||||
this.block_modi_lb = ''
|
||||
this.old_key = null
|
||||
this.fat_modi_num = null
|
||||
this.fat_modi_tag = false
|
||||
this.clear_tag = true // 清除标签,让标签清理和FAT清理操作互斥
|
||||
this.check = false // 检查磁盘条件
|
||||
this.code = null // 当前磁盘块标签字母
|
||||
this.creating = true // 正在创建的状态
|
||||
this.simFAT = initialize_simfat() // SimFAT 表初始化
|
||||
this.simDisk = initialize_simdisk() // SimDisk 区域初始化
|
||||
this.folder_items = []
|
||||
this.fat_unique_set = new Set(['0'])
|
||||
this.file_name_label = ''
|
||||
this.blocks_num_label = ''
|
||||
this.path_name_label = ''
|
||||
this.default = ''
|
||||
this.file_label= new Array(0)
|
||||
this.fat_tags = new Array(len)
|
||||
this.fat_disks = new Array(len)
|
||||
this.label_disks = new Array(len)
|
||||
for (let i = 0; i < len; i++) {
|
||||
this.fat_tags[i] = new Array(len)
|
||||
this.fat_disks[i] = new Array(len)
|
||||
this.label_disks[i] = new Array(len)
|
||||
|
||||
for (let j = 0; j < 10; j++) {
|
||||
this.fat_tags[i][j] = ''
|
||||
this.fat_disks[i][j] = ''
|
||||
this.label_disks[i][j] = ''
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
create_file(file_name?: string, f_block?: string, block_num?: string) {
|
||||
console.log("创建文件")
|
||||
file_name = file_name ?? this.file_name_label // 输入文件名
|
||||
block_num = block_num ?? this.blocks_num_label // 块数
|
||||
f_block = f_block ?? this.select_fat_unique()
|
||||
|
||||
this.check = this.check_condition(file_name, f_block, block_num) // 执行数据合规检查
|
||||
|
||||
if (this.check) { // 合规时执行
|
||||
if (this.creating) { // 初始时获取字母
|
||||
this.code = get_unique_tag()
|
||||
this.creating = false // 获取后除非触发保存,下次创建不更新字母
|
||||
}
|
||||
this.file_label = initialize_fileblock(block_num, this.code!)
|
||||
this.creat_file_blocks()
|
||||
this.sys_info("创建文件成功!")
|
||||
}
|
||||
}
|
||||
|
||||
// 获取唯一的FAT表编号
|
||||
select_fat_unique(): string | null {
|
||||
while (true) {
|
||||
const unique_num = Math.floor(Math.random() * 99).toString()
|
||||
if (!this.fat_unique_set.has(unique_num)) {
|
||||
return unique_num
|
||||
}
|
||||
if (this.fat_unique_set.size >= 100) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 检查创建和保存条件
|
||||
check_condition(file_name: string, start_block_num: string, block_num: string): boolean {
|
||||
// 更新唯一SimFAT表
|
||||
this.simFAT.forEach(row => { // 更新唯一SimFAT表
|
||||
row.forEach(item => this.fat_unique_set.add(item))
|
||||
})
|
||||
|
||||
if (this.fat_unique_set.has('FF')) { // 判断磁盘空间时,排除掉非位置字符
|
||||
this.fat_unique_set.delete('FF')
|
||||
}
|
||||
this.fat_unique_set.delete('100') // 收藏判断需要删除100这个非位置值
|
||||
|
||||
if (this.clear_tag) {
|
||||
if (file_name !== "" && block_num !== "") { // 文件名和块数不为空才能保存
|
||||
if (/^\d+$/.test(block_num)) { // 检查块数为正整数
|
||||
if (!file_name_set.has(file_name)) { // 文件名不重复
|
||||
if (this.fat_unique_set.size + parseInt(block_num) <= 100) {
|
||||
if (start_block_num) {
|
||||
if (!this.fat_unique_set.has(start_block_num)) {
|
||||
return true
|
||||
} else {
|
||||
this.sys_info("首块位置已被占用!")
|
||||
}
|
||||
} else {
|
||||
this.sys_info("磁盘已满!")
|
||||
}
|
||||
} else {
|
||||
this.sys_info("磁盘空间不足!")
|
||||
}
|
||||
} else {
|
||||
this.sys_info("文件名不能重复!")
|
||||
}
|
||||
} else {
|
||||
this.sys_info("请输入正整数!")
|
||||
}
|
||||
} else {
|
||||
this.sys_info("文件名或块数不能为空!")
|
||||
}
|
||||
} else {
|
||||
this.sys_info("正在执行磁盘修改任务!")
|
||||
}
|
||||
}
|
||||
|
||||
creat_file_start_end_label() {
|
||||
|
||||
}
|
||||
|
||||
creat_file_blocks(): void {
|
||||
const left_x: number = 210
|
||||
const left_y: number = 40
|
||||
const side: number = 20 // 元素边
|
||||
const n: number = this.file_label.length
|
||||
|
||||
if (n <= 11) {
|
||||
for (let i = 0; i < n; i++) {
|
||||
const x: number = left_x - i * side
|
||||
const y: number = left_y
|
||||
draw_blocks_emulation(x,y,this.file_label[i])
|
||||
}
|
||||
}
|
||||
else {
|
||||
let end_i: number = n - 11 // 取最后5块
|
||||
for (let i = 0; i < n; i++) { // i < 11 确保循环在最后5块内
|
||||
const x: number = left_x - i * side
|
||||
const y: number = left_y
|
||||
|
||||
if (i < 5) {
|
||||
draw_blocks_emulation(x,y,this.file_label[i])
|
||||
} else if (i === 5) {
|
||||
draw_blocks_emulation(x,y,'...')
|
||||
} else if (i < 11) {
|
||||
draw_blocks_emulation(x,y,this.file_label[i+end_i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//显示文件夹
|
||||
show_files(path_name: any[]){
|
||||
draw_files(path_name)
|
||||
}
|
||||
|
||||
|
||||
// 映射显示FAT表
|
||||
show_fat(row: number, column: number): void {
|
||||
// 获取FAT表中的值
|
||||
const num = this.simFAT[row][column]
|
||||
if (num !== "0") { // 检查FAT表中的值是否为非零
|
||||
// 定义删除标志
|
||||
this.fat_tags[row][column] = "fat_tag"
|
||||
drawFatMessage(num, row, column)
|
||||
}
|
||||
}
|
||||
|
||||
// 显示整个FAT表
|
||||
show_all_fat(): void {
|
||||
// 清空画布上所有的"FAT_tag"标签
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let n = 0; n < 10; n++) {
|
||||
if (this.fat_tags[i][n] == "fat_tag") {
|
||||
clearFatMessage(i,n)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 遍历FAT表的行和列,显示FAT表中的所有元素
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let n = 0; n < 10; n++) {
|
||||
this.show_fat(i, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
show_disk(row: number, column: number, color_tag: boolean | null = null): void {
|
||||
// 获取磁盘块上的文本内容
|
||||
const text = this.simDisk[row][column]
|
||||
if (text !== "0") { // 检查磁盘块内容是否为非零值
|
||||
console.log("text="+text+"+row="+row+"+column="+column)
|
||||
// 定义删除标志
|
||||
this.fat_disks[row][column] = 'fat_disk'
|
||||
this.label_disks[row][column] = "label_disk"
|
||||
if (color_tag) {
|
||||
// 根据颜色标签绘制磁盘块 黄色 初始创建
|
||||
draw_blocks(row, column, true)
|
||||
} else {
|
||||
// 绘制普通磁盘块 灰色 占用
|
||||
draw_blocks(row, column, false)
|
||||
}
|
||||
drawDiskText(text,row,column)
|
||||
}
|
||||
}
|
||||
|
||||
// 显示所有磁盘块
|
||||
show_all_disk(): void {
|
||||
// 清除之前的磁盘块和标签
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let n = 0; n < 10; n++) {
|
||||
if (this.fat_disks[i][n] == 'fat_disk') {
|
||||
clearBlock(i,n)
|
||||
}
|
||||
if (this.label_disks[i][n] == "label_disk") {
|
||||
clearDiskText(i,n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 遍历所有行和列,显示每个磁盘块
|
||||
for (let row = 0; row < 10; row++) {
|
||||
for (let column = 0; column < 10; column++) {
|
||||
this.show_disk(row, column)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save_file(file_name: string | null = null, f_block: string | null = null, blocks: string | null = null) {
|
||||
console.log("保存文件")
|
||||
|
||||
file_name = file_name ?? this.file_name_label // 输入文件名
|
||||
blocks = blocks ?? this.blocks_num_label // 块数
|
||||
|
||||
if (this.creating) {
|
||||
this.create_file(file_name, f_block, blocks)
|
||||
}
|
||||
|
||||
if (this.check) {
|
||||
let fat_block = f_block ? f_block : this.select_fat_unique()
|
||||
let fat_arr = this.generate_fat_array(fat_block, parseInt(blocks)) // 生成fat表
|
||||
this.folder_items.push([file_name, fat_block, blocks, this.code]) // 添加到文件夹
|
||||
file_name_set.add(file_name) // 添加唯一性文件名集合
|
||||
fat_arr.forEach((block) => this.fat_unique_set.add(block)) // 将占用的磁盘位置信息添加进唯一集合,防止重复取数
|
||||
this.load_files_list(fat_arr, this.code) // 根据fat表向磁盘装载文件数据并显示
|
||||
this.show_path_info() // 保存后显示文件夹
|
||||
this.creating = true // 上一次保存执行完成后才能开始二次执行
|
||||
this.sys_info("保存成功")
|
||||
}
|
||||
}
|
||||
|
||||
generate_fat_array(first_block: string, blockNum: number): string[] {
|
||||
const fat_arr = [first_block]
|
||||
|
||||
// 放入首块信息
|
||||
this.fat_unique_set.add(first_block)
|
||||
|
||||
for (let i = 0; i < blockNum - 1; i++) {
|
||||
let num: number | null
|
||||
while (true) {
|
||||
num = Math.floor(Math.random() * 99) + 1
|
||||
if (this.fat_unique_set.size >= 101) {
|
||||
num = null
|
||||
break
|
||||
}
|
||||
if (!this.fat_unique_set.has(num.toString())) {
|
||||
this.fat_unique_set.add(num.toString())
|
||||
break
|
||||
}
|
||||
}
|
||||
if (num !== null) {
|
||||
fat_arr.push(num.toString())
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return fat_arr
|
||||
}
|
||||
|
||||
load_files_list(fat_ls: string[], block_label: string = "default") {
|
||||
this.show_all_disk() // 更新磁盘显示
|
||||
|
||||
fat_ls.forEach((value, index) => {
|
||||
const row = Math.floor(parseInt(value) / 10)
|
||||
const column = parseInt(value) % 10
|
||||
|
||||
if (block_label == "default") {
|
||||
block_label = this.simDisk[row][column][0]
|
||||
|
||||
}
|
||||
if (index < fat_ls.length - 1) {
|
||||
this.simFAT[row][column] = fat_ls[index + 1]
|
||||
} else {
|
||||
this.simFAT[row][column] = "FF"
|
||||
}
|
||||
|
||||
this.simDisk[row][column] = `${block_label}${index + 1}`
|
||||
this.show_disk(row, column, true) // 最后创建颜色才为黄色
|
||||
})
|
||||
|
||||
this.show_all_fat() // 更新fat表显示
|
||||
}
|
||||
|
||||
// 查询文件功能
|
||||
query_file() {
|
||||
const file_name = this.file_name_label
|
||||
if(file_name_set.has(file_name)) {
|
||||
console.log('folder_items='+this.folder_items)
|
||||
this.folder_items.forEach((item) => {
|
||||
if (file_name === item[0]) {
|
||||
this.file_label = initialize_fileblock(item[2], item[3])
|
||||
this.creat_file_blocks()
|
||||
const block_nums = read_sim_fat(item[1], this.simFAT) // 通过首块fat获取全部文件fat
|
||||
this.load_files_list(block_nums)
|
||||
}
|
||||
})
|
||||
this.sys_info('查询成功')
|
||||
} else {
|
||||
console.log('文件夹中无该文件')
|
||||
this.sys_info('文件夹中无该文件')
|
||||
}
|
||||
}
|
||||
|
||||
// FAT校验功能
|
||||
fat_checkout() {
|
||||
console.log('FAT校验')
|
||||
if (this.sim_fat_copy) {
|
||||
let num = 0
|
||||
let tag = false
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let n = 0; n < 10; n++) {
|
||||
num++
|
||||
if (this.simFAT[i][n] !== this.sim_fat_copy[i][n]) {
|
||||
this.sys_info(`校验失败\n${i}行${n}列错误`)
|
||||
tag = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (tag) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (num === 100) {
|
||||
this.sys_info('校验正确')
|
||||
}
|
||||
} else {
|
||||
this.sys_info('未进行修改操作,不可校验')
|
||||
}
|
||||
}
|
||||
|
||||
// 清除表单项
|
||||
clear_fat_label() {
|
||||
console.log('清除表单项')
|
||||
if (this.clear_tag) {
|
||||
// 清空画布上所有的"fat_tag"标签
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let n = 0; n < 10; n++) {
|
||||
if (this.fat_tags[i][n] == "fat_tag") {
|
||||
clearFatMessage(i,n)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.clear_tag = false
|
||||
if (!this.sim_fat_copy) {
|
||||
this.sim_fat_copy = JSON.parse(JSON.stringify(this.simFAT)) // # 深拷贝simFAT复制一份原正确列表并保存为复制对象
|
||||
}
|
||||
this.simFAT = initialize_simfat() // 清空原FAT表
|
||||
this.sys_info("清除成功!")
|
||||
} else {
|
||||
this.sys_info("正在执行标注任务, 无法清除表单项!")
|
||||
}
|
||||
}
|
||||
|
||||
// 保存表单项
|
||||
modi_fat_save() {
|
||||
console.log("保存表单项")
|
||||
this.fat_modi_tag = false // 关闭修改模式
|
||||
this.clear_tag = true // 保存后可以清除
|
||||
if (this.fat_modi_num && this.old_key) {
|
||||
if (this.fat_modi_num.match(/^\d+$/) || this.fat_modi_num === "FF") {
|
||||
this.simFAT[this.old_key[0]][this.old_key[1]] = this.fat_modi_num.match(/^\d+$/) ? this.fat_modi_num : "FF"
|
||||
} else {
|
||||
this.sys_info("请输入正整数或FF!")
|
||||
}
|
||||
}
|
||||
|
||||
this.show_all_fat()
|
||||
this.old_key = null
|
||||
|
||||
for(let i = 0; i < 10; i++) {
|
||||
for (let n = 0; n < 10; n++) {
|
||||
if (this.simFAT[i][n] != '0') {
|
||||
let num = i * 10 + n
|
||||
this.fat_unique_set.add(num.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
this.sys_info("保存表单成功!")
|
||||
}
|
||||
|
||||
// 修改表单项
|
||||
modi_fat() {
|
||||
this.sys_info("正在修改表单项!")
|
||||
this.fat_modi_tag = true
|
||||
if (!this.sim_fat_copy) {
|
||||
this.sim_fat_copy = JSON.parse(JSON.stringify(this.simFAT)) // # 深拷贝simFAT复制一份原正确列表并保存为复制对象
|
||||
}
|
||||
}
|
||||
|
||||
modi_fat_entry(row: number, column: number) {
|
||||
if (this.fat_modi_num && this.old_key) {
|
||||
if (/^\d+$/.test(this.fat_modi_num) || this.fat_modi_num === "FF") {
|
||||
if (/^\d+$/.test(this.fat_modi_num)) {
|
||||
this.simFAT[this.old_key[0]][this.old_key[1]] = this.fat_modi_num
|
||||
} else {
|
||||
this.simFAT[this.old_key[0]][this.old_key[1]] = "FF"
|
||||
}
|
||||
} else {
|
||||
this.sys_info("请输入正整数,或FF!")
|
||||
}
|
||||
}
|
||||
this.old_key = [column, row]
|
||||
this.show_all_fat()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Disk校验方法
|
||||
disk_checkout() {
|
||||
console.log("Disk校验")
|
||||
if (this.sim_disk_copy) {
|
||||
let num = 0
|
||||
let tag = false
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let n = 0; n < 10; n++) {
|
||||
num ++
|
||||
const diskValue = this.simDisk[i][n]
|
||||
|
||||
// 匹配 [A-Za-z]开头,后面跟数字的字符串
|
||||
if (/^[A-Za-z]\d+$/.test(diskValue)) {
|
||||
if (this.simDisk[i][n] !== this.sim_disk_copy[i][n]) {
|
||||
this.sys_info(`校验失败\n${i}行${n}列错误`)
|
||||
tag = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tag) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (num === 100) {
|
||||
this.sys_info("校验正确")
|
||||
}
|
||||
} else {
|
||||
this.sys_info("未进行修改操作,不可校验")
|
||||
}
|
||||
}
|
||||
|
||||
// 添加占用
|
||||
add_occupy() {
|
||||
console.log("添加占用")
|
||||
this.sys_info("正在添加占用...")
|
||||
}
|
||||
|
||||
// 点击添加占用
|
||||
add_occupy_click(row: number, col: number) {
|
||||
if (!this.ex_disk_oc) {
|
||||
this.simDisk[col][row] = '' // 清空simDisk中对应位置的值
|
||||
console.log(col.toString(), row.toString())
|
||||
this.show_all_disk() // 假设 show_all_disk 是更新磁盘显示的方法
|
||||
this.sys_info(`(${[col, row]}) 添加成功`)
|
||||
}
|
||||
}
|
||||
|
||||
// 保存占用
|
||||
save_occupy() {
|
||||
console.log("保存占用")
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let n = 0; n < 10; n++) {
|
||||
if (this.simDisk[i][n] != '0') {
|
||||
let num = i * 10 + n
|
||||
this.fat_unique_set.add(num.toString()) // 将占用块号添加到 fat_unique_set 中
|
||||
}
|
||||
}
|
||||
}
|
||||
this.sys_info("保存占用成功!")
|
||||
}
|
||||
|
||||
// 修改标签
|
||||
modi_block_lb() {
|
||||
console.info("修改标签")
|
||||
this.sys_info("正在修改标签...")
|
||||
this.block_modi_tag = true // 磁盘块修改标志
|
||||
this.clear_tag = false // 修改磁盘标签时冻结文件分配表的按钮
|
||||
if (!this.sim_disk_copy) {
|
||||
this.sim_disk_copy = JSON.parse(JSON.stringify(this.simDisk)) // 深拷贝数组
|
||||
}
|
||||
}
|
||||
|
||||
// 修改标签条目
|
||||
modi_block_entry(row: number, column: number) {
|
||||
let label = this.block_modi_lb
|
||||
|
||||
if (this.block_modi_lb) {
|
||||
if (label !== "0") {
|
||||
const regex = /^[A-Za-z]\d+$/ // 正则表达式将匹配如 "A1"、"b2"、"Z9" 等形式的字符串
|
||||
if (regex.test(label)) {
|
||||
this.simDisk[this.old_key[0]][this.old_key[1]] = label
|
||||
this.sys_info(`${this.old_key} -> ${label}添加成功!`)
|
||||
} else {
|
||||
this.sys_info("请输入正确格式,如:A1!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.old_key = [column, row]
|
||||
this.show_all_disk()
|
||||
}
|
||||
|
||||
// 保存标签
|
||||
modi_block_save() {
|
||||
console.info("保存标签")
|
||||
|
||||
if (this.block_modi_lb) {
|
||||
let label = this.block_modi_lb
|
||||
if (label !== "0") {
|
||||
const regex = /^[A-Za-z]\d+$/
|
||||
if (regex.test(label)) {
|
||||
this.simDisk[this.old_key[0]][this.old_key[1]] = label
|
||||
this.sys_info(`${this.old_key} -> ${label}添加成功!`)
|
||||
} else {
|
||||
this.sys_info("请输入正确格式,如:A1!")
|
||||
}
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let n = 0; n < 10; n++) {
|
||||
if (this.simDisk[i][n] !== '0' && this.simDisk[i][n] !== '') {
|
||||
let num = i * 10 + n
|
||||
let code = this.simDisk[i][n][0] // 取第一个字母
|
||||
blocks_label_set.add(code) // 添加到唯一集合
|
||||
this.fat_unique_set.add(num.toString()) // 添加到FAT表
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.block_modi_lb = '' // 重置 block_modi_lb
|
||||
this.show_all_disk()
|
||||
this.block_modi_tag = false // 关闭标签修改状态
|
||||
this.clear_tag = true
|
||||
this.sys_info("保存标签成功!")
|
||||
}
|
||||
|
||||
// 清除标签
|
||||
clear_disk_label() {
|
||||
console.info("清除标签")
|
||||
|
||||
if (this.clear_tag) {
|
||||
// 清除之前的标签
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let n = 0; n < 10; n++) {
|
||||
if (this.label_disks[i][n] == "label_disk") {
|
||||
clearDiskText(i,n)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.clear_tag = false // 将清除标志置否,防止其他模块改动
|
||||
|
||||
if (!this.sim_disk_copy) {
|
||||
this.sim_disk_copy = JSON.parse(JSON.stringify(this.simDisk)) // 深拷贝原列表
|
||||
}
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let j = 0; j < 10; j++) {
|
||||
if (this.simDisk[i][j] !== '0') {
|
||||
this.simDisk[i][j] = "" // 清除标签
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.sys_info("清除成功!")
|
||||
} else {
|
||||
this.sys_info("正在执行标注任务,无法清除标签")
|
||||
}
|
||||
}
|
||||
|
||||
show_path_info() {
|
||||
|
||||
}
|
||||
|
||||
//创建目录项
|
||||
create_path(path_name:string){
|
||||
if(this.clear_tag){
|
||||
const text_list = path_name.split(',')
|
||||
if(!file_name_set.has(text_list[0])){
|
||||
if(text_list.length===3 && !isNaN(parseInt(text_list[1])) && !isNaN(parseInt(text_list[2]))){
|
||||
if(this.check_condition(text_list[0],text_list[1],text_list[2])){
|
||||
this.save_file(text_list[0],text_list[1],text_list[2])
|
||||
this.show_files(this.folder_items)
|
||||
this.sys_info('创建目录成功!')
|
||||
}
|
||||
}else{
|
||||
this.sys_info('请检查输入格式{\'str\',\'int\',\'int\'}!')
|
||||
}
|
||||
}else{
|
||||
this.sys_info('文件名重复')
|
||||
}
|
||||
}else{
|
||||
this.sys_info('目前正在执行磁盘修复任务!')
|
||||
}
|
||||
}
|
||||
|
||||
// 重置功能
|
||||
reset_path(len:number) {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let n = 0; n < 10; n++) {
|
||||
clearFatMessage(i, n)
|
||||
clearDiskText(i, n)
|
||||
clearBlock(i, n)
|
||||
}
|
||||
}
|
||||
clearEmulation()
|
||||
clearFiles()
|
||||
|
||||
file_name_set = new Set()
|
||||
blocks_label_set = new Set()
|
||||
|
||||
this. messages = []
|
||||
this.sim_fat_copy = null
|
||||
this.ex_disk_oc = true
|
||||
this.ex_disk_la = true
|
||||
this.sim_disk_copy = null
|
||||
this.block_modi_tag = false
|
||||
this.block_modi_lb = ''
|
||||
this.old_key = null
|
||||
this.fat_modi_num = null
|
||||
this.fat_modi_tag = false
|
||||
this.clear_tag = true // 清除标签,让标签清理和FAT清理操作互斥
|
||||
this.check = null // 检查磁盘条件
|
||||
this.code = null // 当前磁盘块标签字母
|
||||
this.creating = true // 正在创建的状态
|
||||
this.simFAT = initialize_simfat() // SimFAT 表初始化
|
||||
this.simDisk = initialize_simdisk() // SimDisk 区域初始化
|
||||
this.folder_items = []
|
||||
this.fat_unique_set = new Set(['0'])
|
||||
this.default = ''
|
||||
this.file_label = new Array(0)
|
||||
this.fat_tags = new Array(len)
|
||||
this.fat_disks = new Array(len)
|
||||
this.label_disks = new Array(len)
|
||||
for (let i = 0; i < len; i++) {
|
||||
this.fat_tags[i] = new Array(len)
|
||||
this.fat_disks[i] = new Array(len)
|
||||
this.label_disks[i] = new Array(len)
|
||||
|
||||
for (let j = 0; j < 10; j++) {
|
||||
this.fat_tags[i][j] = ''
|
||||
this.fat_disks[i][j] = ''
|
||||
this.label_disks[i][j] = ''
|
||||
|
||||
}
|
||||
}
|
||||
this.sys_info('重置成功!')
|
||||
}
|
||||
|
||||
sys_info(message:string) {
|
||||
if(this.messages.length < 9){
|
||||
this.messages.unshift(message)
|
||||
}else{
|
||||
this.messages.pop()
|
||||
this.messages.unshift(message)
|
||||
}
|
||||
this.messages = [...this.messages]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
//信息提示弹窗
|
||||
import { InterfaceFile } from './InterfaceFile'
|
||||
|
||||
@CustomDialog
|
||||
export default struct MessageDialog {
|
||||
controller: CustomDialogController
|
||||
@Link File:InterfaceFile
|
||||
build(){
|
||||
Column({space:5}){
|
||||
Text(`${this.File.old_key[0]}行${this.File.old_key[1]}列`)
|
||||
.fontSize(20)
|
||||
.height(45)
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.fontColor(Color.White)
|
||||
|
||||
TextInput({placeholder:this.File.default})
|
||||
.fontSize(20)
|
||||
.height(45)
|
||||
.placeholderColor(Color.White)
|
||||
.placeholderFont({size:20, weight:FontWeight.Bold})
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.fontColor(Color.White)
|
||||
.onChange((value: string) => {
|
||||
if(this.File.fat_modi_tag) {
|
||||
this.File.fat_modi_num = value
|
||||
}
|
||||
else if (this.File.block_modi_tag) {
|
||||
this.File.block_modi_lb = value
|
||||
}
|
||||
})
|
||||
|
||||
Text('确定')
|
||||
.fontSize(20)
|
||||
.textAlign(TextAlign.Center)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.fontColor(Color.White)
|
||||
.onClick(()=>{
|
||||
this.controller.close()
|
||||
})
|
||||
}
|
||||
.backgroundColor('#00a5df')
|
||||
.justifyContent(FlexAlign.Center)
|
||||
.width(500)
|
||||
.height(150)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
// 第五章
|
||||
// 编程7.15
|
||||
// 产生一个FAT表
|
||||
function create_sim_fat(): string[][] {
|
||||
let sim_fat: string[][] = [
|
||||
['00', '01', 'FF', '03', 'FF', '05', '06', '07', '08', '09'],
|
||||
['0A', '0B', '0C', '0D', '0E', '0F', '10', '11', '12', '13'],
|
||||
['14', '15', '16', '17', '18', '19', '1A', '1B', '1C', '1D'],
|
||||
['1E', '1F', '20', '21', '22', '23', '24', '25', '26', '27'],
|
||||
['28', '29', '2A', '2B', '2C', '2D', '2E', '2F', '30', '31'],
|
||||
['32', '33', '34', '35', '36', '37', '38', '39', '3A', '3B'],
|
||||
['3C', '3D', '3E', '3F', '40', '41', '42', '43', '44', '45'],
|
||||
['46', '47', '48', '49', '4A', '4B', '4C', '4D', '4E', '4F'],
|
||||
['50', '51', '52', '53', '54', '55', '56', '57', '58', '59'],
|
||||
['5A', '5B', '5C', '5D', '5E', '5F', '60', '61', '62', '63']
|
||||
];
|
||||
return sim_fat;
|
||||
}
|
||||
|
||||
// 恢复文件夹信息根据FAT表
|
||||
function restore_folder_by_fat(): string[] {
|
||||
let sim_fat = create_sim_fat(); // 创建模拟的FAT表
|
||||
let folder_item: string[] = []; // 用于存储文件夹信息的列表
|
||||
let last_item: Set<number> = new Set(); // 用于跟踪已经处理过的磁盘块
|
||||
|
||||
for (let num = 0; num < 100; num++) { // 主循环,用于分析文件个数
|
||||
let sim_fat_array: string[] = []; // 清除单个文件的磁盘块
|
||||
let data: number | null = null; // 用于跟踪当前磁盘块
|
||||
|
||||
// 寻找下一个可用的磁盘块作为文件的起始磁盘块
|
||||
for (let ab = 0; ab < 100; ab++) {
|
||||
let y = ab % 10;
|
||||
let x = Math.floor(ab / 10);
|
||||
if (sim_fat[x][y] === 'FF' && !last_item.has(ab)) {
|
||||
data = ab;
|
||||
last_item.add(ab);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (data === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 遍历链接的磁盘块,构建文件
|
||||
while (data !== null) {
|
||||
let x = Math.floor(data / 10);
|
||||
let y = data % 10;
|
||||
sim_fat_array.push(sim_fat[x][y]);
|
||||
let next_data = parseInt(sim_fat[x][y], 16);
|
||||
// 如果下一个磁盘块是0xFF,表示文件结束
|
||||
if (next_data === 0xFF) {
|
||||
break;
|
||||
}
|
||||
data = next_data;
|
||||
}
|
||||
|
||||
// 构建文件项,并将其添加到文件夹列表
|
||||
let fileName = `test${num}`;
|
||||
let filestr = `<${fileName},${sim_fat_array[0]},${sim_fat_array.length + 1}>`;
|
||||
folder_item.push(filestr);
|
||||
}
|
||||
return folder_item;
|
||||
}
|
||||
|
||||
let folder_item = restore_folder_by_fat();
|
||||
folder_item.forEach(item => console.log(item));
|
||||
|
||||
|
||||
// ————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
|
||||
// 编程7.16
|
||||
// 模拟一个虚拟的磁盘扇区
|
||||
let virtual_sector_data: number[] = Array.from("This is a simulated disk sector.").map(c => c.charCodeAt(0));
|
||||
|
||||
// 将数字数组转换为字符串
|
||||
function decodeToString(data: number[]): string {
|
||||
return data.map(byte => String.fromCharCode(byte)).join('');
|
||||
}
|
||||
|
||||
// 读取虚拟扇区内容
|
||||
function read_zero(data: number[]): void {
|
||||
// 将二进制数据(数字数组)转换为字符串
|
||||
let sector_content = decodeToString(data);
|
||||
// 读取并打印扇区内容
|
||||
console.log(sector_content);
|
||||
}
|
||||
|
||||
// 主程序执行
|
||||
read_zero(virtual_sector_data);
|
||||
|
||||
|
||||
// ————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
|
||||
// 编程7.17
|
||||
// 模拟一个简单的FAT表的二进制数据
|
||||
let fat_table_data: Uint8Array = new Uint8Array([
|
||||
0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
]);
|
||||
|
||||
// 读取FAT表数据并转换为十六进制编号字符串
|
||||
function read_fat_table(data: Uint8Array): string {
|
||||
let hex_values: string[] = []
|
||||
for (let i = 0; i < data.length; i += 2) {
|
||||
// 从二进制数据中提取两个字节作为一个FAT项
|
||||
let fat_entry = (data[i] | (data[i + 1] << 8))
|
||||
// 将FAT项转换成十六进制编号并添加到列表中
|
||||
let hex_value = `0x${fat_entry.toString(16).toUpperCase().padStart(4, '0')}`
|
||||
hex_values.push(hex_value)
|
||||
}
|
||||
// 将十六进制编号字符串列表连接为一个输出字符串
|
||||
let output_string = hex_values.join(' ')
|
||||
return output_string
|
||||
}
|
||||
|
||||
let output = read_fat_table(fat_table_data)
|
||||
console.log(output)
|
||||
|
||||
|
||||
// ————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
|
||||
// 编程7.18
|
||||
// 模拟文件夹数据
|
||||
let folder_data: string[] = [
|
||||
"File1 TXT 07 1B 00 0A 15 21 02 3E 01 00 00 00 0E 00 00 00", // 文件1
|
||||
"File2 TXT 07 1B 00 0A 15 21 02 3E 01 00 00 00 0F 00 00 00", // 文件2
|
||||
"Folder1 DIR 07 1B 00 0A 15 21 02 3E 01 00 00 00 10 00 00 00", // 文件夹1
|
||||
"File3 TXT 07 1B 00 0A 15 21 02 3E 01 00 00 00 12 00 00 00", // 文件3
|
||||
"Folder2 DIR 07 1B 00 0A 15 21 02 3E 01 00 00 00 14 00 00 00", // 文件夹2
|
||||
];
|
||||
|
||||
// 读取文件夹数据并解析
|
||||
function read_folder_parse(data: string[]): void {
|
||||
data.forEach(line => {
|
||||
// 解析每一行的信息
|
||||
// 获取文件名,前20个字符为文件名,使用trim()去掉额外空白字符
|
||||
let filename = line.substring(0, 20).trim();
|
||||
// 获取文件类型,接下来的11个字符为文件类型,使用trim()去掉额外空白字符
|
||||
let filetype = line.substring(21, 32).trim();
|
||||
// 获取创建时间,接下来的14个字符为创建时间,使用trim()去掉额外空白字符
|
||||
let create_time = line.substring(32, 46).trim();
|
||||
// 获取修改时间,接下来的14个字符为修改时间,使用trim()去掉额外空白字符
|
||||
let update_time = line.substring(46, 60).trim();
|
||||
// 打印可读信息
|
||||
console.log("文件名: " + filename);
|
||||
console.log("类型: " + filetype);
|
||||
console.log("创建时间: " + create_time);
|
||||
console.log("修改时间: " + update_time);
|
||||
});
|
||||
}
|
||||
|
||||
read_folder_parse(folder_data);
|
||||
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
// 第一章
|
||||
// 编程7.1
|
||||
// 定义文件块数组
|
||||
let FOLDER_ITEM: any[] = []
|
||||
let SIM_FAT: string[][] = Array.from({ length: 3 }, () => Array(5).fill("0"))
|
||||
|
||||
// 初始化基本数组
|
||||
export function init_base_array(): string[] {
|
||||
let xy: number = Math.floor(Math.random() * 101)
|
||||
let num: number = Math.floor(Math.random() * 28)
|
||||
let sim_fat_back: string[] = [xy.toString()]
|
||||
let flag: number = 0
|
||||
for (let i = 0; i < num; i++) {
|
||||
xy = Math.floor(Math.random() * 101)
|
||||
let ab = xy.toString()
|
||||
if (!sim_fat_back.includes(ab)) {
|
||||
sim_fat_back.push(ab)
|
||||
flag += 1
|
||||
if (sim_fat_back.length === num) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return sim_fat_back
|
||||
}
|
||||
|
||||
// 生成数据块
|
||||
export function create_file_block(): string[] {
|
||||
let num = Math.floor(Math.random() * 28) // 取随机数据
|
||||
const zm: string[] = ['A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] // 定义字母数组
|
||||
let file_block: string[] = zm.slice(0, num) // 截取数组字符串
|
||||
return file_block
|
||||
}
|
||||
|
||||
// 生成仿真目录/文件夹
|
||||
export function create_folder_item(): any[] {
|
||||
let file_name: string = "测试文件" // 定义文件名称
|
||||
let xy: number = Math.floor(Math.random() * 101) // 定义100以内的随机数据
|
||||
let num: number = Math.floor(Math.random() * 28) // 定义字符串标签数组
|
||||
let folder_item: any[] = [file_name, xy, num] // 定义文件目录项
|
||||
return folder_item
|
||||
}
|
||||
|
||||
// 仿真磁盘区域
|
||||
export function create_sim_disk(): string[][] {
|
||||
const zm: string[] = ['A', 'B', 'C', 'D', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] // 定义字母数组
|
||||
let base_array: string[] = init_base_array() // 初始生成数组
|
||||
let sim_disk: string[][] = [] // 定义磁盘仿真区域数组
|
||||
let flag: number = 0 // 定义数组序号
|
||||
for (let i = 0; i < 10; i++) { // 定义数组序号
|
||||
let element: string[] = []
|
||||
for (let j = 0; j < 10; j++) {
|
||||
let ab: string = i.toString() + j.toString()
|
||||
if (base_array.includes(ab)) {
|
||||
element.push(zm[flag])
|
||||
flag += 1
|
||||
}
|
||||
else {
|
||||
element.push("0")
|
||||
}
|
||||
}
|
||||
sim_disk.push(element)
|
||||
}
|
||||
return sim_disk
|
||||
}
|
||||
|
||||
// 仿真文件分配表
|
||||
export function create_sim_fat(): string[][] {
|
||||
let sim_fat: string[][] = []
|
||||
let base_array: string[] = init_base_array() // 初始生成数组
|
||||
for (let i = 0; i < 10; i++) { // 循环仿真文件分配二维数组
|
||||
let element: string[] = []
|
||||
for (let j = 0; j < 10; j++) {
|
||||
let ab: string = i.toString() + j.toString()
|
||||
if (base_array.includes(ab)) {
|
||||
if (base_array.indexOf(ab) + 1 === base_array.length) {
|
||||
element.push("FF")
|
||||
} else {
|
||||
element.push(base_array[base_array.indexOf(ab) + 1])
|
||||
}
|
||||
} else {
|
||||
element.push("0")
|
||||
}
|
||||
}
|
||||
sim_fat.push(element)
|
||||
}
|
||||
return sim_fat
|
||||
}
|
||||
|
||||
// 总函数创建
|
||||
export function createData(): void {
|
||||
console.log('create_file_block()='+create_file_block()) // 文件块
|
||||
console.log('create_folder_item()='+create_folder_item()) // 文件目录项
|
||||
console.log('create_sim_disk()='+create_sim_disk()) // 文件磁盘区域
|
||||
console.log('create_sim_fat()='+create_sim_fat()) // 仿真文件分配表
|
||||
}
|
||||
|
||||
|
||||
// ——————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
|
||||
// 编程7.2
|
||||
// 统计磁盘空间大小
|
||||
export function count_sim_fat_size(): void {
|
||||
let n: number = 0
|
||||
for (let element of SIM_FAT) {
|
||||
console.log('element='+element) // 打印每一行的内容
|
||||
for (let i of element) {
|
||||
if (i === "0") {
|
||||
n += 1 // 统计空闲扇区数量
|
||||
}
|
||||
}
|
||||
}
|
||||
let size: string = (64 * n) + " KB" // 计算总的空闲磁盘空间大小
|
||||
console.log(size)
|
||||
}
|
||||
|
||||
|
||||
// ——————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
|
||||
// 编程7.3
|
||||
// 创建FAT表
|
||||
export function create_fat(): string[][] {
|
||||
let sim_fat_array = init_base_array()
|
||||
console.log('sim_fat_array='+sim_fat_array)
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let j = 0; j < 10; j++) {
|
||||
let ab: string = i.toString() + j.toString()
|
||||
if (sim_fat_array.includes(ab)) {
|
||||
if (sim_fat_array.indexOf(ab) + 1 === sim_fat_array.length) {
|
||||
SIM_FAT[i][j] = "FF" // 注意数组越界问题
|
||||
}
|
||||
else {
|
||||
SIM_FAT[i][j] = sim_fat_array[sim_fat_array.indexOf(ab) + 1]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return SIM_FAT
|
||||
}
|
||||
|
||||
|
||||
// ——————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
|
||||
// 编程7.4
|
||||
// 定义FAT链表和第一块FAT位置
|
||||
let sim_fat_chain: { [key: string]: string }[] = [
|
||||
{ '08': '02' },
|
||||
{ '02': '56' },
|
||||
{ '56': '31' },
|
||||
{ '31': '55' },
|
||||
{ '55': '67' },
|
||||
{ '67': '74' },
|
||||
{ '74': 'FF' }
|
||||
]
|
||||
const FIRST_BLOCK: string = '08'
|
||||
|
||||
// 获取磁盘块顺序
|
||||
export function get_disk_block_order(): string[] {
|
||||
let disk_order: string[] = [FIRST_BLOCK]
|
||||
let current_block: string = FIRST_BLOCK
|
||||
|
||||
while (current_block !== 'FF') {
|
||||
let next_block: string = null
|
||||
for (let item of sim_fat_chain) {
|
||||
if (current_block in item) {
|
||||
next_block = item[current_block]
|
||||
break
|
||||
}
|
||||
}
|
||||
if (next_block === null) {
|
||||
break
|
||||
}
|
||||
disk_order.push(next_block)
|
||||
current_block = next_block
|
||||
}
|
||||
return disk_order
|
||||
}
|
||||
|
||||
|
||||
// ——————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
|
||||
// 编程7.5
|
||||
// 插入一个目录项
|
||||
export function add_folder_item(item: any): any[] {
|
||||
FOLDER_ITEM.push(item)
|
||||
return FOLDER_ITEM
|
||||
}
|
||||
|
||||
// 删除一个目录项
|
||||
export function del_folder_item(item: any): any[] {
|
||||
const index = FOLDER_ITEM.indexOf(item)
|
||||
if (index !== -1) {
|
||||
FOLDER_ITEM.splice(index, 1)
|
||||
console.log("删除成功")
|
||||
}
|
||||
else {
|
||||
console.log("删除失败,元素不在目录项中")
|
||||
}
|
||||
return FOLDER_ITEM
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
|
||||
import hilog from '@ohos.hilog';
|
||||
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||
import Want from '@ohos.app.ability.Want';
|
||||
import window from '@ohos.window';
|
||||
|
||||
export default class EntryAbility extends UIAbility {
|
||||
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
|
||||
}
|
||||
|
||||
onDestroy(): void {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
|
||||
}
|
||||
|
||||
onWindowStageCreate(windowStage: window.WindowStage): void {
|
||||
// Main window is created, set main page for this ability
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||
|
||||
windowStage.loadContent('pages/Index', (err, data) => {
|
||||
if (err.code) {
|
||||
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
||||
return;
|
||||
}
|
||||
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
|
||||
});
|
||||
}
|
||||
|
||||
onWindowStageDestroy(): void {
|
||||
// Main window is destroyed, release UI related resources
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
|
||||
}
|
||||
|
||||
onForeground(): void {
|
||||
// Ability has brought to foreground
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
|
||||
}
|
||||
|
||||
onBackground(): void {
|
||||
// Ability has back to background
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,468 @@
|
|||
import *as CommonConstant from '../common/constants/CommonConstants'
|
||||
import {drawFatLine,drawFatLabels,drawDiskLabels,draw_blocks_background} from '../utils/functions'
|
||||
import {InterfaceFile} from '../components/InterfaceFile'
|
||||
import MessageDialog from '../components/MessageDialog'
|
||||
import {createData,count_sim_fat_size,create_fat,get_disk_block_order, init_base_array,create_folder_item,add_folder_item,del_folder_item} from '../components/one'
|
||||
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
@State File:InterfaceFile=new InterfaceFile(10)
|
||||
|
||||
//弹窗控制器
|
||||
MessageDialogController: CustomDialogController = new CustomDialogController({
|
||||
builder: MessageDialog({
|
||||
File: $File
|
||||
})
|
||||
})
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
Column() {
|
||||
Row() {
|
||||
Column() {
|
||||
Row({space:4}) {
|
||||
Text('输入文件名')
|
||||
.fontSize(8)
|
||||
.fontColor(Color.White)
|
||||
|
||||
TextInput()
|
||||
.height(20)
|
||||
.width(35)
|
||||
.backgroundColor(Color.White)
|
||||
.fontColor('#000')
|
||||
.textAlign(TextAlign.Start)
|
||||
.align(Alignment.Center)
|
||||
.fontSize(12)
|
||||
.borderRadius(0)
|
||||
.padding({
|
||||
top: 0
|
||||
, right: 0
|
||||
, bottom: 0
|
||||
, left: 0
|
||||
})
|
||||
.onChange((value: string) => {
|
||||
this.File.file_name_label = value;
|
||||
})
|
||||
|
||||
Text('块数')
|
||||
.fontSize(8)
|
||||
.fontColor(Color.White)
|
||||
|
||||
TextInput()
|
||||
.height(20)
|
||||
.width(35)
|
||||
.backgroundColor(Color.White)
|
||||
.fontColor('#000')
|
||||
.textAlign(TextAlign.Start)
|
||||
.align(Alignment.Center)
|
||||
.fontSize(12)
|
||||
.borderRadius(0)
|
||||
.padding({
|
||||
top: 0
|
||||
, right: 0
|
||||
, bottom: 0
|
||||
, left: 0
|
||||
})
|
||||
.onChange((value: string) => {
|
||||
this.File.blocks_num_label = value;
|
||||
})
|
||||
|
||||
Image($r('app.media.createFile'))
|
||||
.width(30)
|
||||
.height(15)
|
||||
.onClick(()=>{
|
||||
this.File.create_file()
|
||||
})
|
||||
|
||||
Image($r('app.media.save'))
|
||||
.width(30)
|
||||
.height(15)
|
||||
.onClick(()=>{
|
||||
this.File.save_file()
|
||||
this.File.show_files(this.File.folder_items)
|
||||
})
|
||||
|
||||
Image($r('app.media.query'))
|
||||
.width(30)
|
||||
.height(15)
|
||||
.onClick(()=>{
|
||||
this.File.query_file()
|
||||
})
|
||||
}
|
||||
.height(12)
|
||||
.width('100%')
|
||||
.margin({top:6,left:5})
|
||||
|
||||
Column() {
|
||||
// 文字区域
|
||||
Row() {
|
||||
Text('初始文件模拟区:')
|
||||
.fontSize(8)
|
||||
.fontColor(Color.White)
|
||||
}
|
||||
.width('100%')
|
||||
.height('20%')
|
||||
.margin({left:5})
|
||||
|
||||
// 绘制区域
|
||||
Column() {
|
||||
Stack() {
|
||||
Canvas(CommonConstant.context5) // 初始文件模拟区域
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.margin({top: 15})
|
||||
.onReady(() => {
|
||||
// 方块部分
|
||||
this.File.creat_file_blocks()
|
||||
})
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
}
|
||||
.width('47%')
|
||||
.height('100%')
|
||||
.margin({top:5,left:10 })
|
||||
.backgroundImage($r('app.media.pink_bg'))
|
||||
.backgroundImageSize({width:270, height:140})
|
||||
|
||||
// 文件夹(目录)
|
||||
Column() {
|
||||
Row({space:2}) {
|
||||
Text('文件夹(目录)')
|
||||
.fontSize(8)
|
||||
.fontColor(Color.White)
|
||||
|
||||
TextInput()
|
||||
.height(20)
|
||||
.width(60)
|
||||
.backgroundColor(Color.White)
|
||||
.fontColor('#000')
|
||||
.textAlign(TextAlign.Start)
|
||||
.align(Alignment.Center)
|
||||
.fontSize(12)
|
||||
.borderRadius(0)
|
||||
.padding({
|
||||
top: 0
|
||||
, right: 0
|
||||
, bottom: 0
|
||||
, left: 0
|
||||
})
|
||||
.onChange((value:string)=>{
|
||||
this.File.path_name_label = value
|
||||
})
|
||||
|
||||
Image($r('app.media.createDirectory'))
|
||||
.width(50)
|
||||
.height(20)
|
||||
.margin({left:5,right:5})
|
||||
.onClick(()=>{
|
||||
this.File.create_path(this.File.path_name_label)
|
||||
})
|
||||
|
||||
Image($r('app.media.reset'))
|
||||
.width(30)
|
||||
.height(20)
|
||||
.margin({left:5})
|
||||
.onClick(()=>{
|
||||
this.File.reset_path(10)
|
||||
})
|
||||
|
||||
}
|
||||
.height(12)
|
||||
.width('100%')
|
||||
.margin({top:4,left:10})
|
||||
|
||||
Column() {
|
||||
// 文字区域
|
||||
Row({space:10}) {
|
||||
Text('文件名')
|
||||
.fontSize(8)
|
||||
.fontColor(Color.White)
|
||||
|
||||
Text('首块')
|
||||
.fontSize(8)
|
||||
.fontColor(Color.White)
|
||||
|
||||
Text('块数')
|
||||
.fontSize(8)
|
||||
.fontColor(Color.White)
|
||||
|
||||
Text('标签')
|
||||
.fontSize(8)
|
||||
.fontColor(Color.White)
|
||||
}
|
||||
.width('100%')
|
||||
.height('15%')
|
||||
.margin({left:5})
|
||||
// .backgroundColor(Color.Black)
|
||||
.alignItems(VerticalAlign.Bottom)
|
||||
|
||||
// 绘制区域
|
||||
Row(){
|
||||
Canvas(CommonConstant.context6) // 初始文件模拟区域
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
// .margin({top: 15})
|
||||
// .backgroundColor(Color.Black)
|
||||
.onReady(() => {
|
||||
// 方块部分
|
||||
this.File.show_files(this.File.folder_items)
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height('75%')
|
||||
}
|
||||
.justifyContent(FlexAlign.Center)
|
||||
|
||||
}
|
||||
.width('47%')
|
||||
.height('100%')
|
||||
.margin({top:5,left:10 })
|
||||
.backgroundImage($r('app.media.purple_bg'))
|
||||
.backgroundImageSize({width:270, height:140})
|
||||
|
||||
}
|
||||
.height('35%')
|
||||
.width('100%')
|
||||
|
||||
Row() {
|
||||
// 文件分配表FAT
|
||||
Column() {
|
||||
Row({space:2}) {
|
||||
Text('文件分配表FAT')
|
||||
.fontSize(8)
|
||||
.fontColor(Color.White)
|
||||
|
||||
|
||||
Image($r("app.media.check1"))
|
||||
.width(30)
|
||||
.height(15)
|
||||
.onClick(()=>{
|
||||
this.File.fat_checkout()
|
||||
})
|
||||
|
||||
Image($r('app.media.clearFormItem'))
|
||||
.width(45)
|
||||
.height(15)
|
||||
.onClick(()=>{
|
||||
this.File.clear_fat_label()
|
||||
})
|
||||
|
||||
Image($r('app.media.saveFormItem'))
|
||||
.width(45)
|
||||
.height(15)
|
||||
.onClick(()=>{
|
||||
this.File.modi_fat_save()
|
||||
})
|
||||
|
||||
Image($r('app.media.changeFormItem'))
|
||||
.width(45)
|
||||
.height(15)
|
||||
.onClick(()=>{
|
||||
this.File.modi_fat()
|
||||
})
|
||||
}
|
||||
.height(15)
|
||||
.width('100%')
|
||||
.margin({top:4,left:5})
|
||||
|
||||
Column() {
|
||||
Stack() {
|
||||
Canvas(CommonConstant.context) // Fat区域
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.margin({top: 15})
|
||||
.onReady(() => {
|
||||
// Fat区域背景
|
||||
drawFatLine()
|
||||
|
||||
// 数字标签
|
||||
drawFatLabels()
|
||||
})
|
||||
|
||||
Canvas(CommonConstant.context2) // 文字
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.margin({top: 15})
|
||||
|
||||
.onClick((event)=>{
|
||||
//计算点击的的画布横纵坐标
|
||||
let playX = event.x - CommonConstant.gridSize
|
||||
let playY = event.y - CommonConstant.gridSize
|
||||
//计算行列数 横纵坐标/格子大小
|
||||
let row: number = Math.floor(playX / CommonConstant.gridSize)
|
||||
let col: number = Math.floor(playY / CommonConstant.gridSize)
|
||||
|
||||
if (this.File.fat_modi_tag) {
|
||||
this.File.modi_fat_entry(row, col)
|
||||
this.File.default = this.File.simFAT[this.File.old_key[0]][this.File.old_key[1]]
|
||||
this.MessageDialogController.open()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
.width('100%')
|
||||
.padding({left:10})
|
||||
}
|
||||
.width('47%')
|
||||
.height('100%')
|
||||
.margin({top:10,left:10 })
|
||||
.backgroundImage($r('app.media.jade_blue_bg'))
|
||||
.backgroundImageSize({width:270, height:240})
|
||||
|
||||
|
||||
// 磁盘模块
|
||||
Column() {
|
||||
Row({space:2}) {
|
||||
Text('磁盘模块')
|
||||
.fontSize(8)
|
||||
.fontColor(Color.White)
|
||||
|
||||
Image($r("app.media.check2"))
|
||||
.width(30)
|
||||
.height(15)
|
||||
.onClick(()=>{
|
||||
this.File.disk_checkout()
|
||||
})
|
||||
|
||||
Image(this.File.ex_disk_oc ? $r('app.media.add') : $r("app.media.saveOccupy"))
|
||||
.width(45)
|
||||
.height(15)
|
||||
.onClick(()=>{
|
||||
if (this.File.ex_disk_oc) {
|
||||
this.File.ex_disk_oc = false
|
||||
}
|
||||
else {
|
||||
this.File.ex_disk_oc = true
|
||||
}
|
||||
if (this.File.ex_disk_oc == false) {
|
||||
this.File.add_occupy()
|
||||
}
|
||||
else {
|
||||
this.File.save_occupy()
|
||||
}
|
||||
})
|
||||
Image(this.File.ex_disk_la ? $r("app.media.changeLabel") : $r("app.media.saveLabel"))
|
||||
.width(45)
|
||||
.height(15)
|
||||
.onClick(()=>{
|
||||
if (this.File.ex_disk_la) {
|
||||
this.File.ex_disk_la = false
|
||||
}
|
||||
else {
|
||||
this.File.ex_disk_la = true
|
||||
}
|
||||
if (this.File.ex_disk_la == false) {
|
||||
this.File.modi_block_lb()
|
||||
}
|
||||
else {
|
||||
this.File.modi_block_save()
|
||||
}
|
||||
})
|
||||
|
||||
Image($r('app.media.clearLabel'))
|
||||
.width(45)
|
||||
.height(15)
|
||||
.onClick(()=>{
|
||||
this.File.clear_disk_label()
|
||||
})
|
||||
}
|
||||
.height(12)
|
||||
.width('100%')
|
||||
.margin({top:4,left:5})
|
||||
|
||||
Column() {
|
||||
Stack() {
|
||||
Canvas(CommonConstant.context3) // Disk区域
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.margin({top: 15})
|
||||
.onReady(() => {
|
||||
// 数字标签部分
|
||||
drawDiskLabels()
|
||||
|
||||
// 方块部分
|
||||
draw_blocks_background()
|
||||
})
|
||||
|
||||
Canvas(CommonConstant.context4) // 编号
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.margin({top: 5})
|
||||
|
||||
.onClick((event)=>{
|
||||
//计算点击的的画布横纵坐标
|
||||
let playX = event.x - CommonConstant.blockSize
|
||||
let playY = event.y - CommonConstant.blockSize
|
||||
//计算行列数 横纵坐标/格子大小
|
||||
let row: number = Math.floor(playX / CommonConstant.gridSize)
|
||||
let col: number = Math.floor(playY / CommonConstant.gridSize)
|
||||
|
||||
this.File.add_occupy_click(row, col)
|
||||
|
||||
if (this.File.block_modi_tag) {
|
||||
this.File.modi_block_entry(row, col)
|
||||
this.File.default = this.File.simDisk[this.File.old_key[0]][this.File.old_key[1]]
|
||||
this.MessageDialogController.open()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
.padding({left:15})
|
||||
}
|
||||
.width('47%')
|
||||
.height('100%')
|
||||
.margin({top:10,left:10 })
|
||||
.backgroundImage($r('app.media.sky_blue_bg'))
|
||||
.backgroundImageSize({width:270, height:240})
|
||||
}
|
||||
.height('65%')
|
||||
.width('100%')
|
||||
|
||||
}
|
||||
.width('80%')
|
||||
.height('100%')
|
||||
|
||||
Column() {
|
||||
Column() {
|
||||
Text('系统消息框')
|
||||
.fontSize(12)
|
||||
.fontColor(Color.White)
|
||||
.margin({top:3})
|
||||
}
|
||||
.width('100%')
|
||||
.height('6%')
|
||||
.margin({top:2})
|
||||
.backgroundImage($r('app.media.rightbgtop'))
|
||||
|
||||
Column() {
|
||||
ForEach(this.File.messages,message=>{
|
||||
Text(message)
|
||||
.fontSize(10).textAlign(TextAlign.Center)
|
||||
.fontColor(Color.White)
|
||||
.margin({top:4})
|
||||
.backgroundImage($r('app.media.messagebg'))
|
||||
.width('100%')
|
||||
.height('11%')
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
.height('90%')
|
||||
.backgroundImage($r('app.media.rightbg'))
|
||||
|
||||
}
|
||||
.width('20%')
|
||||
.height('100%')
|
||||
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundImage($r('app.media.bg2'))
|
||||
.backgroundImageSize(ImageSize.Cover)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
// 功能函数
|
||||
import * as CommonConstant from '../common/constants/CommonConstants'
|
||||
|
||||
// 初始化FAT矩阵
|
||||
export function initialize_simfat(): string[][] {
|
||||
// 创建一个10x10的二维数组,每个元素都初始化为字符串 "0"
|
||||
const simFat: string[][] = Array.from({ length: 10 }, () => Array(10).fill("0"))
|
||||
simFat[0][0] = "100"; // 将第一个元素(第一行第一列)设置为字符串 "100"
|
||||
return simFat; // 返回初始化的FAT矩阵
|
||||
}
|
||||
|
||||
// 初始化磁盘矩阵
|
||||
export function initialize_simdisk(): string[][] {
|
||||
// 创建一个10x10的二维数组,每个元素都初始化为字符串 "0"
|
||||
const simDisk: string[][] = Array.from({ length: 10 }, () => Array(10).fill("0"))
|
||||
return simDisk // 返回初始化的磁盘矩阵
|
||||
}
|
||||
|
||||
// 绘制Fat区域线条
|
||||
export function drawFatLine() {
|
||||
CommonConstant.context.strokeStyle = '#fff' //线条颜色
|
||||
CommonConstant.context.lineWidth = 1 //线条宽
|
||||
|
||||
for (let i = 0; i < CommonConstant.boardNum; i++) {
|
||||
// 横线
|
||||
CommonConstant.context.beginPath()
|
||||
CommonConstant.context.moveTo(CommonConstant.gridSize, i * CommonConstant.gridSize + CommonConstant.gridSize)
|
||||
CommonConstant.context.lineTo(CommonConstant.gridSize * (CommonConstant.boardNum - 1) + CommonConstant.gridSize, i * CommonConstant.gridSize + CommonConstant.gridSize)
|
||||
CommonConstant.context.stroke()
|
||||
|
||||
// 竖线
|
||||
CommonConstant.context.beginPath()
|
||||
CommonConstant.context.moveTo(i * CommonConstant.gridSize + CommonConstant.gridSize, CommonConstant.gridSize)
|
||||
CommonConstant.context.lineTo(i * CommonConstant.gridSize + CommonConstant.gridSize, CommonConstant.gridSize * (CommonConstant.boardNum - 1) + CommonConstant.gridSize)
|
||||
CommonConstant.context.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制Fat区域边框外侧数字
|
||||
export function drawFatLabels() {
|
||||
CommonConstant.context.fillStyle = 'white' // 设置文字颜色为白色
|
||||
CommonConstant.context.font = '25px Arial' // 设置字体和大小
|
||||
CommonConstant.context.textAlign = 'center' // 设置文字对齐方式为居中
|
||||
CommonConstant.context.textBaseline = 'middle' // 设置文字基线为居中
|
||||
|
||||
// 绘制数字标签
|
||||
for (let i = 0; i < CommonConstant.boardNum - 1; i++) {
|
||||
CommonConstant.context.fillText(i.toString(), i * CommonConstant.gridSize + CommonConstant.gridSize + CommonConstant.gridSize / 2, CommonConstant.gridSize / 2) // 上边标签
|
||||
CommonConstant.context.fillText(i.toString(), CommonConstant.gridSize / 2, i * CommonConstant.gridSize + CommonConstant.gridSize + CommonConstant.gridSize / 2) // 左边标签
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制Disk区域边框外侧数字
|
||||
export function drawDiskLabels() {
|
||||
CommonConstant.context3.fillStyle = 'white' // 设置文字颜色为白色
|
||||
CommonConstant.context3.font = '25px Arial' // 设置字体和大小
|
||||
CommonConstant.context3.textAlign = 'center' // 设置文字对齐方式为居中
|
||||
CommonConstant.context3.textBaseline = 'middle' // 设置文字基线为居中
|
||||
|
||||
// 绘制数字标签
|
||||
for (let i = 0; i < CommonConstant.boardNum - 1; i++) {
|
||||
CommonConstant.context3.fillText(i.toString(), i * CommonConstant.gridSize + CommonConstant.blockSize * 1.5, CommonConstant.blockSize / 2) // 上边标签
|
||||
CommonConstant.context3.fillText(i.toString(), CommonConstant.blockSize / 2, i * CommonConstant.gridSize + CommonConstant.blockSize * 1.5) // 左边标签
|
||||
}
|
||||
}
|
||||
|
||||
//绘制模拟区方块
|
||||
export function draw_blocks_emulation(x:number,y:number,list_label:string) {
|
||||
CommonConstant.context5.fillStyle = 'black' // 设置文字颜色为黑色
|
||||
CommonConstant.context5.font = '20px Arial' // 设置字体和大小
|
||||
CommonConstant.context5.textAlign = 'center' // 设置文字对齐方式为居中
|
||||
CommonConstant.context5.textBaseline = 'middle' // 设置文字基线为居中
|
||||
CommonConstant.context5.clearRect(0,0,x,y+20)
|
||||
CommonConstant.context5.drawImage(CommonConstant.img3, x, y, CommonConstant.gridSize, CommonConstant.gridSize)
|
||||
CommonConstant.context5.fillText(list_label, x + CommonConstant.gridSize / 2, y + CommonConstant.gridSize / 2)
|
||||
CommonConstant.context5.fillStyle = 'white'
|
||||
CommonConstant.context5.fillText('起始', x + CommonConstant.gridSize / 2, y - CommonConstant.gridSize)
|
||||
CommonConstant.context5.clearRect(0,0, 210, 40)
|
||||
CommonConstant.context5.fillText('尾部',x + CommonConstant.gridSize / 2,y - CommonConstant.gridSize/2)
|
||||
CommonConstant.context5.clearRect(x + CommonConstant.gridSize+2,y - 13, 210, CommonConstant.gridSize/2)
|
||||
for (let index = 0; index < (230-x)/20; index++) {
|
||||
CommonConstant.context5.fillText('—', 230-index*4, y - CommonConstant.gridSize/2)
|
||||
}
|
||||
CommonConstant.context5.fillText('<',230-(230-x)/5 , y - CommonConstant.gridSize/2)
|
||||
}
|
||||
|
||||
export function clearEmulation(){
|
||||
CommonConstant.context5.clearRect(0,0,300,300)
|
||||
}
|
||||
|
||||
export function draw_files(text_list:any[]){
|
||||
CommonConstant.context6.fillStyle = 'white'; // 设置文字颜色为白色
|
||||
CommonConstant.context6.font = '30px Arial'; // 设置字体和大小
|
||||
CommonConstant.context6.textAlign = 'center'; // 设置文字对齐方式为居中
|
||||
CommonConstant.context6.textBaseline = 'middle'; // 设置文字基线为居中
|
||||
CommonConstant.context6.clearRect(0,0,300,300)
|
||||
console.log('text_list.length='+text_list.length)
|
||||
for (let index = 0; index < text_list.length; index++) {
|
||||
const x = 10
|
||||
const y = 10
|
||||
CommonConstant.context6.fillText(text_list[index][0],x,y+index*20)
|
||||
CommonConstant.context6.fillText(text_list[index][1],x+30,y+index*20)
|
||||
CommonConstant.context6.fillText(text_list[index][2],x+60,y+index*20)
|
||||
CommonConstant.context6.fillText(text_list[index][3],x+90,y+index*20)
|
||||
}
|
||||
}
|
||||
|
||||
export function clearFiles(){
|
||||
CommonConstant.context6.clearRect(0,0,300,300)
|
||||
}
|
||||
// 绘制Disk区域初始方块
|
||||
export function draw_blocks_background() {
|
||||
for (let row = 0; row < CommonConstant.boardNum - 1; row++) {
|
||||
for (let col = 0; col < CommonConstant.boardNum - 1; col++) {
|
||||
const x = col * CommonConstant.gridSize + CommonConstant.blockSize
|
||||
const y = row * CommonConstant.gridSize + CommonConstant.blockSize
|
||||
CommonConstant.context3.clearRect(x,y, CommonConstant.blockSize, CommonConstant.blockSize)
|
||||
CommonConstant.context3.drawImage(CommonConstant.img1, x, y, CommonConstant.blockSize, CommonConstant.blockSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制Disk区域方块
|
||||
export function draw_blocks(row:number, col:number, color_tag:boolean) {
|
||||
const x = col * CommonConstant.gridSize + CommonConstant.blockSize
|
||||
const y = row * CommonConstant.gridSize + CommonConstant.blockSize
|
||||
|
||||
CommonConstant.context3.clearRect(x,y, CommonConstant.blockSize, CommonConstant.blockSize)
|
||||
|
||||
if (color_tag) {
|
||||
CommonConstant.context3.drawImage(CommonConstant.img3, x, y, CommonConstant.blockSize, CommonConstant.blockSize)
|
||||
}
|
||||
else {
|
||||
CommonConstant.context3.drawImage(CommonConstant.img2, x, y, CommonConstant.blockSize, CommonConstant.blockSize)
|
||||
}
|
||||
}
|
||||
|
||||
export function drawFatMessage(num: string, row: number, clown: number) {
|
||||
CommonConstant.context2.fillStyle = 'white' // 设置文字颜色为白色
|
||||
CommonConstant.context2.font = '20px Arial' // 设置字体和大小
|
||||
CommonConstant.context2.textAlign = 'center' // 设置文字对齐方式为居中
|
||||
CommonConstant.context2.textBaseline = 'middle' // 设置文字基线为居中
|
||||
|
||||
const x = clown * CommonConstant.gridSize + 1.5 * CommonConstant.gridSize
|
||||
const y = row * CommonConstant.gridSize + 1.5 * CommonConstant.gridSize
|
||||
|
||||
CommonConstant.context2.fillText(num, x, y)
|
||||
}
|
||||
|
||||
export function clearFatMessage(row: number, clown: number) {
|
||||
const x = clown * CommonConstant.gridSize + CommonConstant.gridSize
|
||||
const y = row * CommonConstant.gridSize + CommonConstant.gridSize
|
||||
|
||||
CommonConstant.context2.clearRect(x, y, CommonConstant.gridSize, CommonConstant.blockSize)
|
||||
}
|
||||
|
||||
export function drawDiskText(text: string, row: number, clown: number) {
|
||||
CommonConstant.context4.fillStyle = 'black' // 设置文字颜色为白色
|
||||
CommonConstant.context4.font = '20px Arial' // 设置字体和大小
|
||||
|
||||
const x = clown * CommonConstant.gridSize + CommonConstant.gridSize
|
||||
const y = row * CommonConstant.gridSize + 2 * CommonConstant.blockSize
|
||||
|
||||
CommonConstant.context4.clearRect(x,y, CommonConstant.gridSize, CommonConstant.gridSize)
|
||||
CommonConstant.context4.fillText(text, x, y)
|
||||
}
|
||||
|
||||
export function clearBlock(row: number, col: number) {
|
||||
const x = col * CommonConstant.gridSize + CommonConstant.blockSize;
|
||||
const y = row * CommonConstant.gridSize + CommonConstant.blockSize;
|
||||
CommonConstant.context3.clearRect(x,y, CommonConstant.blockSize, CommonConstant.blockSize)
|
||||
CommonConstant.context3.drawImage(CommonConstant.img1, x, y, CommonConstant.blockSize, CommonConstant.blockSize)
|
||||
}
|
||||
|
||||
export function clearDiskText(row: number, col: number) {
|
||||
const x = col * CommonConstant.gridSize + CommonConstant.gridSize;
|
||||
const y = row * CommonConstant.gridSize + CommonConstant.gridSize;
|
||||
CommonConstant.context4.clearRect(x,y, CommonConstant.gridSize, CommonConstant.gridSize)
|
||||
}
|
||||
|
||||
export function read_sim_fat(first_block: string, sim_fat: string[][]): string[] {
|
||||
const block_nums: Array<string> = []; // 创建一个空数组来存储块号
|
||||
block_nums.push(first_block)
|
||||
|
||||
while (true) {
|
||||
const row = Math.floor(parseInt(first_block) / 10);
|
||||
const clown = parseInt(first_block) % 10;
|
||||
const b_num = sim_fat[row][clown];
|
||||
|
||||
if (b_num !== "FF") {
|
||||
block_nums.push(b_num) // 添加下一个块号
|
||||
first_block = b_num // 更新 first_block 以继续查找下一个块
|
||||
} else {
|
||||
break; // 如果找到 "FF",则退出循环
|
||||
}
|
||||
}
|
||||
return block_nums
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"module": {
|
||||
"name": "entry",
|
||||
"type": "entry",
|
||||
"description": "$string:module_desc",
|
||||
"mainElement": "EntryAbility",
|
||||
"deviceTypes": [
|
||||
"default",
|
||||
"tablet"
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
"pages": "$profile:main_pages",
|
||||
"abilities": [
|
||||
{
|
||||
"name": "EntryAbility",
|
||||
"srcEntry": "./ets/entryability/EntryAbility.ets",
|
||||
"description": "$string:EntryAbility_desc",
|
||||
"icon": "$media:icon",
|
||||
"label": "$string:EntryAbility_label",
|
||||
"startWindowIcon": "$media:startIcon",
|
||||
"startWindowBackground": "$color:start_window_background",
|
||||
"exported": true,
|
||||
"skills": [
|
||||
{
|
||||
"entities": [
|
||||
"entity.system.home"
|
||||
],
|
||||
"actions": [
|
||||
"action.system.home"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"color": [
|
||||
{
|
||||
"name": "start_window_background",
|
||||
"value": "#FFFFFF"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "module description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_desc",
|
||||
"value": "description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_label",
|
||||
"value": "label"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 388 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 711 B |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"src": [
|
||||
"pages/Index"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "module description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_desc",
|
||||
"value": "description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_label",
|
||||
"value": "label"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "模块描述"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_desc",
|
||||
"value": "description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_label",
|
||||
"value": "label"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import hilog from '@ohos.hilog';
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
|
||||
export default function abilityTest() {
|
||||
describe('ActsAbilityTest', () => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
it('assertContain', 0, () => {
|
||||
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
|
||||
let a = 'abc';
|
||||
let b = 'b';
|
||||
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||
expect(a).assertContain(b);
|
||||
expect(a).assertEqual(a);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import abilityTest from './Ability.test';
|
||||
|
||||
export default function testsuite() {
|
||||
abilityTest();
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
|
||||
import hilog from '@ohos.hilog';
|
||||
import { Hypium } from '@ohos/hypium';
|
||||
import testsuite from '../test/List.test';
|
||||
import window from '@ohos.window';
|
||||
import Want from '@ohos.app.ability.Want';
|
||||
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
|
||||
|
||||
export default class TestAbility extends UIAbility {
|
||||
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate');
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? '');
|
||||
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator;
|
||||
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
|
||||
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs;
|
||||
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments();
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!');
|
||||
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite);
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy');
|
||||
}
|
||||
|
||||
onWindowStageCreate(windowStage: window.WindowStage) {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate');
|
||||
windowStage.loadContent('testability/pages/Index', (err, data) => {
|
||||
if (err.code) {
|
||||
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
||||
return;
|
||||
}
|
||||
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s',
|
||||
JSON.stringify(data) ?? '');
|
||||
});
|
||||
}
|
||||
|
||||
onWindowStageDestroy() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy');
|
||||
}
|
||||
|
||||
onForeground() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground');
|
||||
}
|
||||
|
||||
onBackground() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
@State message: string = 'Hello World';
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
Column() {
|
||||
Text(this.message)
|
||||
.fontSize(50)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.height('100%')
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import hilog from '@ohos.hilog';
|
||||
import TestRunner from '@ohos.application.testRunner';
|
||||
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
|
||||
import Want from '@ohos.app.ability.Want';
|
||||
|
||||
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator | undefined = undefined
|
||||
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs | undefined = undefined
|
||||
|
||||
async function onAbilityCreateCallback() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback');
|
||||
}
|
||||
|
||||
async function addAbilityMonitorCallback(err : Error) {
|
||||
hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? '');
|
||||
}
|
||||
|
||||
export default class OpenHarmonyTestRunner implements TestRunner {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
onPrepare() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare ');
|
||||
}
|
||||
|
||||
async onRun() {
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run');
|
||||
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
|
||||
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
|
||||
const bundleName = abilityDelegatorArguments.bundleName;
|
||||
const testAbilityName = 'TestAbility';
|
||||
let lMonitor: AbilityDelegatorRegistry.AbilityMonitor = {
|
||||
abilityName: testAbilityName,
|
||||
onAbilityCreate: onAbilityCreateCallback,
|
||||
};
|
||||
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
|
||||
const want: Want = {
|
||||
bundleName: bundleName,
|
||||
abilityName: testAbilityName
|
||||
};
|
||||
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
|
||||
abilityDelegator.startAbility(want, (err, data) => {
|
||||
hilog.info(0x0000, 'testTag', 'startAbility : err : %{public}s', JSON.stringify(err) ?? '');
|
||||
hilog.info(0x0000, 'testTag', 'startAbility : data : %{public}s',JSON.stringify(data) ?? '');
|
||||
})
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"module": {
|
||||
"name": "entry_test",
|
||||
"type": "feature",
|
||||
"description": "$string:module_test_desc",
|
||||
"mainElement": "TestAbility",
|
||||
"deviceTypes": [
|
||||
"default",
|
||||
"tablet"
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
"pages": "$profile:test_pages",
|
||||
"abilities": [
|
||||
{
|
||||
"name": "TestAbility",
|
||||
"srcEntry": "./ets/testability/TestAbility.ets",
|
||||
"description": "$string:TestAbility_desc",
|
||||
"icon": "$media:icon",
|
||||
"label": "$string:TestAbility_label",
|
||||
"exported": true,
|
||||
"startWindowIcon": "$media:icon",
|
||||
"startWindowBackground": "$color:start_window_background",
|
||||
"skills": [
|
||||
{
|
||||
"actions": [
|
||||
"action.system.home"
|
||||
],
|
||||
"entities": [
|
||||
"entity.system.home"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"color": [
|
||||
{
|
||||
"name": "start_window_background",
|
||||
"value": "#FFFFFF"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_test_desc",
|
||||
"value": "test ability description"
|
||||
},
|
||||
{
|
||||
"name": "TestAbility_desc",
|
||||
"value": "the test ability"
|
||||
},
|
||||
{
|
||||
"name": "TestAbility_label",
|
||||
"value": "test label"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 6.6 KiB |
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"src": [
|
||||
"testability/pages/Index"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import localUnitTest from './LocalUnit.test';
|
||||
|
||||
export default function testsuite() {
|
||||
localUnitTest();
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
|
||||
export default function localUnitTest() {
|
||||
describe('localUnitTest',() => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
it('assertContain', 0, () => {
|
||||
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||
let a = 'abc';
|
||||
let b = 'b';
|
||||
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||
expect(a).assertContain(b);
|
||||
expect(a).assertEqual(a);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"hvigorVersion": "3.0.9",
|
||||
"dependencies": {
|
||||
"@ohos/hvigor-ohos-plugin": "3.0.9"
|
||||
},
|
||||
"execution": {
|
||||
// "daemon": true, /* Enable daemon compilation. Default: true */
|
||||
// "incremental": true, /* Enable incremental compilation. Default: true */
|
||||
// "parallel": true, /* Enable parallel compilation. Default: true */
|
||||
// "typeCheck": false, /* Enable typeCheck. Default: false */
|
||||
},
|
||||
"logging": {
|
||||
// "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
|
||||
},
|
||||
"debugging": {
|
||||
// "stacktrace": false /* Disable stacktrace compilation. Default: false */
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import { appTasks } from '@ohos/hvigor-ohos-plugin';
|
||||
|
||||
export default {
|
||||
system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
||||
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#!/bin/bash
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Hvigor startup script, version 1.0.0
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# NODE_HOME - location of a Node home dir
|
||||
# or
|
||||
# Add /usr/local/nodejs/bin to the PATH environment variable
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
HVIGOR_APP_HOME="`pwd -P`"
|
||||
HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js
|
||||
warn() {
|
||||
echo ""
|
||||
echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo ""
|
||||
echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
|
||||
}
|
||||
|
||||
fail() {
|
||||
error "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Determine node to start hvigor wrapper script
|
||||
if [ -n "${NODE_HOME}" ];then
|
||||
EXECUTABLE_NODE="${NODE_HOME}/bin/node"
|
||||
if [ ! -x "$EXECUTABLE_NODE" ];then
|
||||
fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed"
|
||||
fi
|
||||
else
|
||||
EXECUTABLE_NODE="node"
|
||||
which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path"
|
||||
fi
|
||||
|
||||
# Check hvigor wrapper script
|
||||
if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then
|
||||
fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}"
|
||||
fi
|
||||
|
||||
# start hvigor-wrapper script
|
||||
exec "${EXECUTABLE_NODE}" \
|
||||
"${HVIGOR_WRAPPER_SCRIPT}" "$@"
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Hvigor startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js
|
||||
set NODE_EXE=node.exe
|
||||
|
||||
goto start
|
||||
|
||||
:start
|
||||
@rem Find node.exe
|
||||
if defined NODE_HOME goto findNodeFromNodeHome
|
||||
|
||||
%NODE_EXE% --version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the NODE_HOME variable in your environment to match the
|
||||
echo location of your NodeJs installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findNodeFromNodeHome
|
||||
set NODE_HOME=%NODE_HOME:"=%
|
||||
set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE%
|
||||
|
||||
if exist "%NODE_EXE_PATH%" goto execute
|
||||
echo.
|
||||
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the NODE_HOME variable in your environment to match the
|
||||
echo location of your NodeJs installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Execute hvigor
|
||||
"%NODE_EXE%" "%WRAPPER_MODULE_PATH%" %*
|
||||
|
||||
if "%ERRORLEVEL%" == "0" goto hvigorwEnd
|
||||
|
||||
:fail
|
||||
exit /b 1
|
||||
|
||||
:hvigorwEnd
|
||||
if "%OS%" == "Windows_NT" endlocal
|
||||
|
||||
:end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"lockfileVersion": 1,
|
||||
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
||||
"specifiers": {
|
||||
"@ohos/hypium@1.0.11": "@ohos/hypium@1.0.11"
|
||||
},
|
||||
"packages": {
|
||||
"@ohos/hypium@1.0.11": {
|
||||
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.11.tgz",
|
||||
"integrity": "sha512-KawcLnv43C3QIYv1UbDnKCFX3MohtDxGuFvzlUxT/qf2DBilR56Ws6zrj90LdH6PjloJQwOPESuBQIHBACAK7w=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"license": "",
|
||||
"devDependencies": {
|
||||
"@ohos/hypium": "1.0.11"
|
||||
},
|
||||
"author": "",
|
||||
"name": "filereality",
|
||||
"description": "Please describe the basic information.",
|
||||
"main": "",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {}
|
||||
}
|
||||